ReactOS 0.4.15-dev-7788-g1ad9096
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_PARAMSPLOAD_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 1826 of file driver.c.

1830{
1831 KIRQL OldIrql;
1832 PIO_CLIENT_EXTENSION DriverExtensions, NewDriverExtension;
1833 BOOLEAN Inserted = FALSE;
1834
1835 /* Assume failure */
1836 *DriverObjectExtension = NULL;
1837
1838 /* Allocate the extension */
1839 NewDriverExtension = ExAllocatePoolWithTag(NonPagedPool,
1840 sizeof(IO_CLIENT_EXTENSION) +
1841 DriverObjectExtensionSize,
1843 if (!NewDriverExtension) return STATUS_INSUFFICIENT_RESOURCES;
1844
1845 /* Clear the extension for teh caller */
1846 RtlZeroMemory(NewDriverExtension,
1847 sizeof(IO_CLIENT_EXTENSION) + DriverObjectExtensionSize);
1848
1849 /* Acqure lock */
1851
1852 /* Fill out the extension */
1854
1855 /* Loop the current extensions */
1856 DriverExtensions = IoGetDrvObjExtension(DriverObject)->
1857 ClientDriverExtension;
1858 while (DriverExtensions)
1859 {
1860 /* Check if the identifier matches */
1861 if (DriverExtensions->ClientIdentificationAddress ==
1863 {
1864 /* We have a collision, break out */
1865 break;
1866 }
1867
1868 /* Go to the next one */
1869 DriverExtensions = DriverExtensions->NextExtension;
1870 }
1871
1872 /* Check if we didn't collide */
1873 if (!DriverExtensions)
1874 {
1875 /* Link this one in */
1876 NewDriverExtension->NextExtension =
1877 IoGetDrvObjExtension(DriverObject)->ClientDriverExtension;
1878 IoGetDrvObjExtension(DriverObject)->ClientDriverExtension =
1879 NewDriverExtension;
1880 Inserted = TRUE;
1881 }
1882
1883 /* Release the lock */
1885
1886 /* Check if insertion failed */
1887 if (!Inserted)
1888 {
1889 /* Free the entry and fail */
1890 ExFreePoolWithTag(NewDriverExtension, TAG_DRIVER_EXTENSION);
1892 }
1893
1894 /* Otherwise, return the pointer */
1895 *DriverObjectExtension = NewDriverExtension + 1;
1896 return STATUS_SUCCESS;
1897}
unsigned char BOOLEAN
#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:136
#define STATUS_SUCCESS
Definition: shellext.h:65
PVOID ClientIdentificationAddress
Definition: iotypes.h:866
struct _IO_CLIENT_EXTENSION * NextExtension
Definition: iotypes.h:865
#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 1576 of file driver.c.

1579{
1580 WCHAR NameBuffer[100];
1581 USHORT NameLength;
1582 UNICODE_STRING LocalDriverName;
1585 ULONG ObjectSize;
1587 UNICODE_STRING ServiceKeyName;
1589 ULONG i, RetryCount = 0;
1590
1591try_again:
1592 /* First, create a unique name for the driver if we don't have one */
1593 if (!DriverName)
1594 {
1595 /* Create a random name and set up the string */
1596 NameLength = (USHORT)swprintf(NameBuffer,
1597 DRIVER_ROOT_NAME L"%08u",
1599 LocalDriverName.Length = NameLength * sizeof(WCHAR);
1600 LocalDriverName.MaximumLength = LocalDriverName.Length + sizeof(UNICODE_NULL);
1601 LocalDriverName.Buffer = NameBuffer;
1602 }
1603 else
1604 {
1605 /* So we can avoid another code path, use a local var */
1606 LocalDriverName = *DriverName;
1607 }
1608
1609 /* Initialize the Attributes */
1610 ObjectSize = sizeof(DRIVER_OBJECT) + sizeof(EXTENDED_DRIVER_EXTENSION);
1612 &LocalDriverName,
1614 NULL,
1615 NULL);
1616
1617 /* Create the Object */
1621 KernelMode,
1622 NULL,
1623 ObjectSize,
1624 0,
1625 0,
1626 (PVOID*)&DriverObject);
1627 if (!NT_SUCCESS(Status)) return Status;
1628
1629 DPRINT("IopCreateDriver(): created DO %p\n", DriverObject);
1630
1631 /* Set up the Object */
1632 RtlZeroMemory(DriverObject, ObjectSize);
1634 DriverObject->Size = sizeof(DRIVER_OBJECT);
1636 DriverObject->DriverExtension = (PDRIVER_EXTENSION)(DriverObject + 1);
1637 DriverObject->DriverExtension->DriverObject = DriverObject;
1638 DriverObject->DriverInit = InitializationFunction;
1639 /* Loop all Major Functions */
1640 for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
1641 {
1642 /* Invalidate each function */
1643 DriverObject->MajorFunction[i] = IopInvalidDeviceRequest;
1644 }
1645
1646 /* Set up the service key name buffer */
1647 ServiceKeyName.MaximumLength = LocalDriverName.Length + sizeof(UNICODE_NULL);
1648 ServiceKeyName.Buffer = ExAllocatePoolWithTag(PagedPool, LocalDriverName.MaximumLength, TAG_IO);
1649 if (!ServiceKeyName.Buffer)
1650 {
1651 /* Fail */
1655 }
1656
1657 /* For builtin drivers, the ServiceKeyName is equal to DriverName */
1658 RtlCopyUnicodeString(&ServiceKeyName, &LocalDriverName);
1659 ServiceKeyName.Buffer[ServiceKeyName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1660 DriverObject->DriverExtension->ServiceKeyName = ServiceKeyName;
1661
1662 /* Make a copy of the driver name to store in the driver object */
1663 DriverObject->DriverName.MaximumLength = LocalDriverName.Length;
1664 DriverObject->DriverName.Buffer = ExAllocatePoolWithTag(PagedPool,
1665 DriverObject->DriverName.MaximumLength,
1666 TAG_IO);
1667 if (!DriverObject->DriverName.Buffer)
1668 {
1669 /* Fail */
1673 }
1674
1675 RtlCopyUnicodeString(&DriverObject->DriverName, &LocalDriverName);
1676
1677 /* Add the Object and get its handle */
1679 NULL,
1681 0,
1682 NULL,
1683 &hDriver);
1684
1685 /* Eliminate small possibility when this function is called more than
1686 once in a row, and KeTickCount doesn't get enough time to change */
1687 if (!DriverName && (Status == STATUS_OBJECT_NAME_COLLISION) && (RetryCount < 100))
1688 {
1689 RetryCount++;
1690 goto try_again;
1691 }
1692
1693 if (!NT_SUCCESS(Status)) return Status;
1694
1695 /* Now reference it */
1697 0,
1699 KernelMode,
1701 NULL);
1702
1703 /* Close the extra handle */
1705
1706 if (!NT_SUCCESS(Status))
1707 {
1708 /* Fail */
1711 return Status;
1712 }
1713
1714 /* Finally, call its init function */
1715 DPRINT("Calling driver entrypoint at %p\n", InitializationFunction);
1716 Status = InitializationFunction(DriverObject, NULL);
1717 if (!NT_SUCCESS(Status))
1718 {
1719 /* If it didn't work, then kill the object */
1720 DPRINT1("'%wZ' initialization failed, status (0x%08lx)\n", &LocalDriverName, Status);
1723 return Status;
1724 }
1725
1726 /* Windows does this fixup, keep it for compatibility */
1727 for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
1728 {
1729 /*
1730 * Make sure the driver didn't set any dispatch entry point to NULL!
1731 * Doing so is illegal; drivers shouldn't touch entry points they
1732 * do not implement.
1733 */
1734
1735 /* Check if it did so anyway */
1736 if (!DriverObject->MajorFunction[i])
1737 {
1738 /* Print a warning in the debug log */
1739 DPRINT1("Driver <%wZ> set DriverObject->MajorFunction[%lu] to NULL!\n",
1740 &DriverObject->DriverName, i);
1741
1742 /* Fix it up */
1743 DriverObject->MajorFunction[i] = IopInvalidDeviceRequest;
1744 }
1745 }
1746
1747 /* Return the Status */
1748 return Status;
1749}
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:32
#define swprintf
Definition: precomp.h:40
#define PagedPool
Definition: env_spec_w32.h:308
Status
Definition: gdiplustypes.h:25
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
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define OBJ_PERMANENT
Definition: winternl.h:226
#define DRIVER_ROOT_NAME
Definition: ldr.h:5
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define KernelMode
Definition: asm.h:34
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
#define L(x)
Definition: ntvdm.h:50
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:2935
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:1039
VOID NTAPI ObMakeTemporaryObject(IN PVOID ObjectBody)
Definition: oblife.c:1449
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:494
unsigned short USHORT
Definition: pedump.c:61
#define DPRINT
Definition: sndvol32.h:71
PDRIVER_INITIALIZE DriverInit
Definition: iotypes.h:2286
ULONG LowPart
Definition: ketypes.h:929
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define TAG_IO
Definition: tag.h:80
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:2227
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
__wchar_t WCHAR
Definition: xmlstorage.h:180

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

◆ IoDeleteDriver()

VOID NTAPI IoDeleteDriver ( _In_ PDRIVER_OBJECT  DriverObject)

Definition at line 1756 of file driver.c.

1758{
1759 /* Simply dereference the Object */
1761}

Referenced by KdpDriverReinit().

◆ IoGetDriverObjectExtension()

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

Definition at line 1904 of file driver.c.

1906{
1907 KIRQL OldIrql;
1908 PIO_CLIENT_EXTENSION DriverExtensions;
1909
1910 /* Acquire lock */
1912
1913 /* Loop the list until we find the right one */
1914 DriverExtensions = IoGetDrvObjExtension(DriverObject)->ClientDriverExtension;
1915 while (DriverExtensions)
1916 {
1917 /* Check for a match */
1918 if (DriverExtensions->ClientIdentificationAddress ==
1920 {
1921 /* Break out */
1922 break;
1923 }
1924
1925 /* Keep looping */
1926 DriverExtensions = DriverExtensions->NextExtension;
1927 }
1928
1929 /* Release lock */
1931
1932 /* Return nothing or the extension */
1933 if (!DriverExtensions) return NULL;
1934 return DriverExtensions + 1;
1935}

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(), PciIdeXAddDevice(), PciIdeXStartMiniport(), 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:944
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 328 of file driver.c.

330{
331 extern BOOLEAN SosEnabled; // See ex/init.c
332 static const UNICODE_STRING DotSys = RTL_CONSTANT_STRING(L".SYS");
333 CHAR TextBuffer[256];
334
335 if (!SosEnabled) return;
336 if (!KeLoaderBlock) return;
338 "%s%sSystem32\\Drivers\\%wZ%s\r\n",
343 ? "" : ".SYS");
345}
static WCHAR ServiceName[]
Definition: browser.c:19
char TextBuffer[BUFFERLEN]
Definition: combotst.c:45
NTHALAPI VOID NTAPI HalDisplayString(PUCHAR String)
PLOADER_PARAMETER_BLOCK KeLoaderBlock
Definition: krnlinit.c:29
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:280
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
PSTR ArcBootDeviceName
Definition: arc.h:550
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
BOOLEAN SosEnabled
Definition: winldr.c:33
char CHAR
Definition: xmlstorage.h:175

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 2099 of file driver.c.

2102{
2103 LOAD_UNLOAD_PARAMS LoadParams;
2104
2105 /* Prepare parameters block */
2106 LoadParams.RegistryPath = RegistryPath;
2107 LoadParams.DriverObject = *DriverObject;
2108
2110 {
2111 LoadParams.SetEvent = TRUE;
2113
2114 /* Initialize and queue a work item */
2115 ExInitializeWorkItem(&LoadParams.WorkItem, IopLoadUnloadDriverWorker, &LoadParams);
2117
2118 /* And wait till it completes */
2120 }
2121 else
2122 {
2123 /* If we're already in a system process, call it right here */
2124 LoadParams.SetEvent = FALSE;
2125 IopLoadUnloadDriverWorker(&LoadParams);
2126 }
2127
2128 return LoadParams.Status;
2129}
#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:2053
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:723
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
@ DelayedWorkQueue
Definition: extypes.h:190
@ UserRequest
Definition: ketypes.h:421
#define PsGetCurrentProcess
Definition: psfuncs.h:17

Referenced by IopUnloadDriver(), and NtLoadDriver().

◆ IopGetDeviceObjectFromDeviceInstance()

PDEVICE_OBJECT IopGetDeviceObjectFromDeviceInstance ( PUNICODE_STRING  DeviceInstance)

Definition at line 206 of file plugplay.c.

207{
209 IOP_FIND_DEVICE_INSTANCE_TRAVERSE_CONTEXT DeviceInstanceContext;
210
211 if (IopRootDeviceNode == NULL)
212 return NULL;
213
214 if (DeviceInstance == NULL ||
215 DeviceInstance->Length == 0)
216 {
218 {
221 }
222 else
223 return NULL;
224 }
225
226 /* Traverse the device tree to find the matching device node */
227 DeviceInstanceContext.InstancePath = DeviceInstance;
228 DeviceInstanceContext.DeviceObject = NULL;
232 &DeviceInstanceContext);
234
235 /* In case of error or instance not found, this will still be NULL from above. */
236 return DeviceInstanceContext.DeviceObject;
237}
static const WCHAR DeviceInstance[]
Definition: interface.c:28
#define IopInitDeviceTreeTraverseContext( _DeviceTreeTraverseContext, _DeviceNode, _Action, _Context)
Definition: io.h:229
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:186
PDEVICE_OBJECT PhysicalDeviceObject
Definition: iotypes.h:892
#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 || kvInfo->DataLength == 0)
140 {
141 ExFreePool(kvInfo);
143 }
144
145 driverName.Length = kvInfo->DataLength - sizeof(UNICODE_NULL);
146 driverName.MaximumLength = kvInfo->DataLength;
148 if (!driverName.Buffer)
149 {
150 ExFreePool(kvInfo);
152 }
153
154 RtlMoveMemory(driverName.Buffer,
155 (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
156 driverName.Length);
157 driverName.Buffer[driverName.Length / sizeof(WCHAR)] = UNICODE_NULL;
158 ExFreePool(kvInfo);
159 }
160
161 /* Check whether we need to get ServiceName as well, either to construct
162 * the driver name (because we could not use "ObjectName"), or because
163 * it is requested by the caller. */
164 PKEY_BASIC_INFORMATION basicInfo = NULL;
165 if (!NT_SUCCESS(status) || ServiceName != NULL)
166 {
167 /* Retrieve the necessary buffer size */
168 ULONG infoLength;
169 status = ZwQueryKey(ServiceHandle, KeyBasicInformation, NULL, 0, &infoLength);
171 {
173 goto Cleanup;
174 }
175
176 /* Allocate the buffer and retrieve the data */
177 basicInfo = ExAllocatePoolWithTag(PagedPool, infoLength, TAG_IO);
178 if (!basicInfo)
179 {
181 goto Cleanup;
182 }
183
184 status = ZwQueryKey(ServiceHandle, KeyBasicInformation, basicInfo, infoLength, &infoLength);
185 if (!NT_SUCCESS(status))
186 {
187 goto Cleanup;
188 }
189
190 serviceName.Length = basicInfo->NameLength;
191 serviceName.MaximumLength = basicInfo->NameLength;
192 serviceName.Buffer = basicInfo->Name;
193 }
194
195 /* 2. There is no "ObjectName" - construct it ourselves. Depending on the driver type,
196 * it will be either "\Driver<ServiceName>" or "\FileSystem<ServiceName>" */
197 if (driverName.Buffer == NULL)
198 {
199 ASSERT(basicInfo); // Container for serviceName
200
201 /* Retrieve the driver type */
202 ULONG driverType;
203 status = IopGetRegistryValue(ServiceHandle, L"Type", &kvInfo);
204 if (!NT_SUCCESS(status))
205 {
206 goto Cleanup;
207 }
208 if (kvInfo->Type != REG_DWORD || kvInfo->DataLength != sizeof(ULONG))
209 {
210 ExFreePool(kvInfo);
212 goto Cleanup;
213 }
214
215 RtlMoveMemory(&driverType,
216 (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
217 sizeof(ULONG));
218 ExFreePool(kvInfo);
219
220 /* Compute the necessary driver name string size */
221 if (driverType == SERVICE_RECOGNIZER_DRIVER || driverType == SERVICE_FILE_SYSTEM_DRIVER)
222 driverName.MaximumLength = sizeof(FILESYSTEM_ROOT_NAME);
223 else
224 driverName.MaximumLength = sizeof(DRIVER_ROOT_NAME);
225
226 driverName.MaximumLength += serviceName.Length;
227 driverName.Length = 0;
228
229 /* Allocate and build it */
231 if (!driverName.Buffer)
232 {
234 goto Cleanup;
235 }
236
237 if (driverType == SERVICE_RECOGNIZER_DRIVER || driverType == SERVICE_FILE_SYSTEM_DRIVER)
239 else
241
243 }
244
245 if (ServiceName != NULL)
246 {
247 ASSERT(basicInfo); // Container for serviceName
248
249 /* Allocate a copy for the caller */
251 if (!buf)
252 {
254 goto Cleanup;
255 }
256 RtlMoveMemory(buf, serviceName.Buffer, serviceName.Length);
257 ServiceName->MaximumLength = serviceName.Length;
258 ServiceName->Length = serviceName.Length;
259 ServiceName->Buffer = buf;
260 }
261
262 *DriverName = driverName;
264
265Cleanup:
266 if (basicInfo)
267 ExFreePoolWithTag(basicInfo, TAG_IO);
268
269 if (!NT_SUCCESS(status) && driverName.Buffer)
270 ExFreePoolWithTag(driverName.Buffer, TAG_IO);
271
272 return status;
273}
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 REG_SZ
Definition: layer.c:22
#define FILESYSTEM_ROOT_NAME
Definition: ldr.h:6
@ KeyBasicInformation
Definition: nt_native.h:1131
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
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:588
#define REG_DWORD
Definition: sdbapi.c:596
#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:956
#define SERVICE_FILE_SYSTEM_DRIVER
Definition: cmtypes.h:954

Referenced by IopInitializeDriverModule(), and PiAttachFilterDriversCallback().

◆ IopInitializeBootDrivers()

VOID FASTCALL IopInitializeBootDrivers ( VOID  )

Definition at line 1023 of file driver.c.

1024{
1025 PLIST_ENTRY ListHead, NextEntry, NextEntry2;
1026 PLDR_DATA_TABLE_ENTRY LdrEntry;
1028 UNICODE_STRING DriverName;
1029 ULONG i, Index;
1030 PDRIVER_INFORMATION DriverInfo, DriverInfoTag;
1032 PBOOT_DRIVER_LIST_ENTRY BootEntry;
1033 DPRINT("IopInitializeBootDrivers()\n");
1034
1035 /* Create the RAW FS built-in driver */
1036 RtlInitUnicodeString(&DriverName, L"\\FileSystem\\RAW");
1037
1038 Status = IoCreateDriver(&DriverName, RawFsDriverEntry);
1039 if (!NT_SUCCESS(Status))
1040 {
1041 /* Fail */
1042 return;
1043 }
1044
1045 /* Get highest group order index */
1047 if (IopGroupIndex == 0xFFFF)
1048 {
1050 }
1051
1052 /* Allocate the group table */
1054 IopGroupIndex * sizeof(LIST_ENTRY),
1055 TAG_IO);
1056 if (IopGroupTable == NULL)
1057 {
1059 }
1060
1061 /* Initialize the group table lists */
1062 for (i = 0; i < IopGroupIndex; i++) InitializeListHead(&IopGroupTable[i]);
1063
1064 /* Loop the boot modules */
1065 ListHead = &KeLoaderBlock->LoadOrderListHead;
1066 for (NextEntry = ListHead->Flink;
1067 NextEntry != ListHead;
1068 NextEntry = NextEntry->Flink)
1069 {
1070 /* Get the entry */
1071 LdrEntry = CONTAINING_RECORD(NextEntry,
1073 InLoadOrderLinks);
1074
1075 /* Check if the DLL needs to be initialized */
1076 if (LdrEntry->Flags & LDRP_DRIVER_DEPENDENT_DLL)
1077 {
1078 /* Call its entrypoint */
1079 MmCallDllInitialize(LdrEntry, NULL);
1080 }
1081 }
1082
1083 /* Loop the boot drivers */
1084 ListHead = &KeLoaderBlock->BootDriverListHead;
1085 for (NextEntry = ListHead->Flink;
1086 NextEntry != ListHead;
1087 NextEntry = NextEntry->Flink)
1088 {
1089 /* Get the entry */
1090 BootEntry = CONTAINING_RECORD(NextEntry,
1092 Link);
1093
1094 // FIXME: TODO: This LdrEntry is to be used in a special handling
1095 // for SETUPLDR (a similar procedure is done on Windows), where
1096 // the loader would, under certain conditions, be loaded in the
1097 // SETUPLDR-specific code block below...
1098#if 0
1099 /* Get the driver loader entry */
1100 LdrEntry = BootEntry->LdrEntry;
1101#endif
1102
1103 /* Allocate our internal accounting structure */
1105 sizeof(DRIVER_INFORMATION),
1106 TAG_IO);
1107 if (DriverInfo)
1108 {
1109 /* Zero it and initialize it */
1112 DriverInfo->DataTableEntry = BootEntry;
1113
1114 /* Open the registry key */
1116 NULL,
1117 &BootEntry->RegistryPath,
1118 KEY_READ);
1119 DPRINT("IopOpenRegistryKeyEx(%wZ) returned 0x%08lx\n", &BootEntry->RegistryPath, Status);
1120#if 0
1121 if (NT_SUCCESS(Status))
1122#else // Hack still needed...
1123 if ((NT_SUCCESS(Status)) || /* ReactOS HACK for SETUPLDR */
1124 ((KeLoaderBlock->SetupLdrBlock) && ((KeyHandle = (PVOID)1)))) // yes, it's an assignment!
1125#endif
1126 {
1127 /* Save the handle */
1129
1130 /* Get the group oder index */
1132
1133 /* Get the tag position */
1135
1136 /* Insert it into the list, at the right place */
1138 NextEntry2 = IopGroupTable[Index].Flink;
1139 while (NextEntry2 != &IopGroupTable[Index])
1140 {
1141 /* Get the driver info */
1142 DriverInfoTag = CONTAINING_RECORD(NextEntry2,
1144 Link);
1145
1146 /* Check if we found the right tag position */
1147 if (DriverInfoTag->TagPosition > DriverInfo->TagPosition)
1148 {
1149 /* We're done */
1150 break;
1151 }
1152
1153 /* Next entry */
1154 NextEntry2 = NextEntry2->Flink;
1155 }
1156
1157 /* Insert us right before the next entry */
1158 NextEntry2 = NextEntry2->Blink;
1159 InsertHeadList(NextEntry2, &DriverInfo->Link);
1160 }
1161 }
1162 }
1163
1164 /* Loop each group index */
1165 for (i = 0; i < IopGroupIndex; i++)
1166 {
1167 /* Loop each group table */
1168 for (NextEntry = IopGroupTable[i].Flink;
1169 NextEntry != &IopGroupTable[i];
1170 NextEntry = NextEntry->Flink)
1171 {
1172 /* Get the entry */
1173 DriverInfo = CONTAINING_RECORD(NextEntry,
1175 Link);
1176
1177 /* Get the driver loader entry */
1178 LdrEntry = DriverInfo->DataTableEntry->LdrEntry;
1179
1180 /* Initialize it */
1181 if (IopInitializeBuiltinDriver(LdrEntry))
1182 {
1183 // it does not make sense to enumerate the tree if there are no new devices added
1186 NULL,
1187 NULL);
1188 }
1189 }
1190 }
1191
1192 /* HAL Root Bus is being initialized before loading the boot drivers so this may cause issues
1193 * when some devices are not being initialized with their drivers. This flag is used to delay
1194 * all actions with devices (except PnP root device) until boot drivers are loaded.
1195 * See PiQueueDeviceAction function
1196 */
1198
1199 DbgPrint("BOOT DRIVERS LOADED\n");
1200
1203 NULL,
1204 NULL);
1205}
#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:56
_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:59
#define KEY_READ
Definition: nt_native.h:1023
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:527
@ PiActionEnumDeviceTree
Definition: io.h:526
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:2659
NTSTATUS NTAPI MmCallDllInitialize(_In_ PLDR_DATA_TABLE_ENTRY LdrEntry, _In_ PLIST_ENTRY ModuleListHead)
Definition: sysldr.c:432
static BOOLEAN IopInitializeBuiltinDriver(IN PLDR_DATA_TABLE_ENTRY BootLdrEntry)
Definition: driver.c:807
NTSTATUS NTAPI IoCreateDriver(_In_opt_ PUNICODE_STRING DriverName, _In_ PDRIVER_INITIALIZE InitializationFunction)
Definition: driver.c:1576
PLIST_ENTRY IopGroupTable
Definition: driver.c:41
USHORT IopGroupIndex
Definition: driver.c:40
BOOLEAN PnPBootDriversLoaded
Definition: pnpinit.c:20
Definition: arc.h:246
UNICODE_STRING RegistryPath
Definition: arc.h:249
struct _LDR_DATA_TABLE_ENTRY * LdrEntry
Definition: arc.h:250
HANDLE ServiceHandle
Definition: io.h:406
PBOOT_DRIVER_LIST_ENTRY DataTableEntry
Definition: io.h:405
LIST_ENTRY Link
Definition: io.h:403
USHORT TagPosition
Definition: io.h:407
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:542
LIST_ENTRY LoadOrderListHead
Definition: arc.h:540
struct _SETUP_LOADER_BLOCK * SetupLdrBlock
Definition: arc.h:558
#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 807 of file driver.c.

808{
811 PWCHAR Buffer, FileNameWithoutPath;
812 PWSTR FileExtension;
813 PUNICODE_STRING ModuleName = &BootLdrEntry->BaseDllName;
814 PLDR_DATA_TABLE_ENTRY LdrEntry;
815 PLIST_ENTRY NextEntry;
818
819 /*
820 * Display 'Loading XXX...' message
821 */
824
826 ModuleName->Length + sizeof(UNICODE_NULL),
827 TAG_IO);
828 if (Buffer == NULL)
829 {
830 return FALSE;
831 }
832
835
836 /*
837 * Generate filename without path (not needed by freeldr)
838 */
839 FileNameWithoutPath = wcsrchr(Buffer, L'\\');
840 if (FileNameWithoutPath == NULL)
841 {
842 FileNameWithoutPath = Buffer;
843 }
844 else
845 {
846 FileNameWithoutPath++;
847 }
848
849 /*
850 * Strip the file extension from ServiceName
851 */
852 Success = RtlCreateUnicodeString(&ServiceName, FileNameWithoutPath);
854 if (!Success)
855 {
856 return FALSE;
857 }
858
859 FileExtension = wcsrchr(ServiceName.Buffer, L'.');
860 if (FileExtension != NULL)
861 {
862 ServiceName.Length -= (USHORT)wcslen(FileExtension) * sizeof(WCHAR);
863 FileExtension[0] = UNICODE_NULL;
864 }
865
867
868 // Make the registry path for the driver
869 RegistryPath.Length = 0;
870 RegistryPath.MaximumLength = sizeof(ServicesKeyName) + ServiceName.Length;
872 if (RegistryPath.Buffer == NULL)
873 {
874 return FALSE;
875 }
879
880 HANDLE serviceHandle;
883 if (!NT_SUCCESS(Status))
884 {
885 return FALSE;
886 }
887
888 /* Lookup the new Ldr entry in PsLoadedModuleList */
889 for (NextEntry = PsLoadedModuleList.Flink;
890 NextEntry != &PsLoadedModuleList;
891 NextEntry = NextEntry->Flink)
892 {
893 LdrEntry = CONTAINING_RECORD(NextEntry,
895 InLoadOrderLinks);
897 {
898 break;
899 }
900 }
901 ASSERT(NextEntry != &PsLoadedModuleList);
902
903 /*
904 * Initialize the driver
905 */
906 NTSTATUS driverEntryStatus;
908 serviceHandle,
910 &driverEntryStatus);
911
912 if (!NT_SUCCESS(Status))
913 {
914 DPRINT1("Driver '%wZ' load failed, status (%x)\n", ModuleName, Status);
915 return FALSE;
916 }
917
918 // The driver has been loaded, now check if where are any PDOs
919 // for that driver, and queue AddDevice call for them.
920 // The check is possible because HKLM/SYSTEM/CCS/Services/<ServiceName>/Enum directory
921 // is populated upon a new device arrival based on a (critical) device database
922
923 // Legacy drivers may add devices inside DriverEntry.
924 // We're lazy and always assume that they are doing so
925 BOOLEAN deviceAdded = !!(DriverObject->Flags & DRVO_LEGACY_DRIVER);
926
927 HANDLE enumServiceHandle;
928 UNICODE_STRING enumName = RTL_CONSTANT_STRING(L"Enum");
929
930 Status = IopOpenRegistryKeyEx(&enumServiceHandle, serviceHandle, &enumName, KEY_READ);
931 ZwClose(serviceHandle);
932
933 if (NT_SUCCESS(Status))
934 {
935 ULONG instanceCount = 0;
937 Status = IopGetRegistryValue(enumServiceHandle, L"Count", &kvInfo);
938 if (!NT_SUCCESS(Status))
939 {
940 goto Cleanup;
941 }
942 if (kvInfo->Type != REG_DWORD || kvInfo->DataLength != sizeof(ULONG))
943 {
944 ExFreePool(kvInfo);
945 goto Cleanup;
946 }
947
948 RtlMoveMemory(&instanceCount,
949 (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
950 sizeof(ULONG));
951 ExFreePool(kvInfo);
952
953 DPRINT("Processing %u instances for %wZ module\n", instanceCount, ModuleName);
954
955 for (ULONG i = 0; i < instanceCount; i++)
956 {
957 WCHAR num[11];
958 UNICODE_STRING instancePath;
959 RtlStringCbPrintfW(num, sizeof(num), L"%u", i);
960
961 Status = IopGetRegistryValue(enumServiceHandle, num, &kvInfo);
962 if (!NT_SUCCESS(Status))
963 {
964 continue;
965 }
966 if (kvInfo->Type != REG_SZ || kvInfo->DataLength == 0)
967 {
968 ExFreePool(kvInfo);
969 continue;
970 }
971
972 instancePath.Length = kvInfo->DataLength - sizeof(UNICODE_NULL);
973 instancePath.MaximumLength = kvInfo->DataLength;
975 instancePath.MaximumLength,
976 TAG_IO);
977 if (instancePath.Buffer)
978 {
979 RtlMoveMemory(instancePath.Buffer,
980 (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
981 instancePath.Length);
982 instancePath.Buffer[instancePath.Length / sizeof(WCHAR)] = UNICODE_NULL;
983
985 if (pdo != NULL)
986 {
989 deviceAdded = TRUE;
990 }
991 else
992 {
993 DPRINT1("No device node found matching instance path '%wZ'\n", &instancePath);
994 }
995 }
996
997 ExFreePool(kvInfo);
998 }
999
1000 ZwClose(enumServiceHandle);
1001 }
1002Cleanup:
1003 /* Remove extra reference from IopInitializeDriverModule */
1005
1006 return deviceAdded;
1007}
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
@ 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:625
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
@ PiActionAddBootDevices
Definition: io.h:529
static VOID FASTCALL IopDisplayLoadingMessage(_In_ PCUNICODE_STRING ServiceName)
Displays a driver-loading message in SOS mode.
Definition: driver.c:328
PDEVICE_OBJECT IopGetDeviceObjectFromDeviceInstance(PUNICODE_STRING DeviceInstance)
Definition: plugplay.c:206
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:443
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:145
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:2226

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 443 of file driver.c.

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

Referenced by IopInitializeBuiltinDriver(), and IopLoadDriver().

◆ IopInitializeSystemDrivers()

VOID FASTCALL IopInitializeSystemDrivers ( VOID  )

Definition at line 1210 of file driver.c.

1211{
1212 PUNICODE_STRING *DriverList, *SavedList;
1213
1215
1216 /* HACK: No system drivers on the BootCD */
1217 if (KeLoaderBlock->SetupLdrBlock) return;
1218
1219 /* Get the driver list */
1220 SavedList = DriverList = CmGetSystemDriverList();
1221 ASSERT(DriverList);
1222
1223 /* Loop it */
1224 while (*DriverList)
1225 {
1226 /* Load the driver */
1227 ZwLoadDriver(*DriverList);
1228
1229 /* Free the entry */
1230 RtlFreeUnicodeString(*DriverList);
1231 ExFreePool(*DriverList);
1232
1233 /* Next entry */
1235 DriverList++;
1236 }
1237
1238 /* Free the list */
1239 ExFreePool(SavedList);
1240
1243 NULL,
1244 NULL);
1245}
PUNICODE_STRING *NTAPI CmGetSystemDriverList(VOID)
Definition: cmsysini.c:1836
NTSTATUS PiPerformSyncDeviceAction(_In_ PDEVICE_OBJECT DeviceObject, _In_ DEVICE_ACTION Action)
Perfom a device operation synchronously via PiQueueDeviceAction.
Definition: devaction.c:2718

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: csq.h:116
#define IoCompleteRequest
Definition: irp.c:1240
#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 1938 of file driver.c.

1941{
1942 UNICODE_STRING ImagePath;
1944 PLDR_DATA_TABLE_ENTRY ModuleObject;
1946
1948 Status = IopGetRegistryValue(ServiceHandle, L"ImagePath", &kvInfo);
1949 if (NT_SUCCESS(Status))
1950 {
1951 if ((kvInfo->Type != REG_EXPAND_SZ && kvInfo->Type != REG_SZ) || kvInfo->DataLength == 0)
1952 {
1953 ExFreePool(kvInfo);
1955 }
1956
1957 ImagePath.Length = kvInfo->DataLength - sizeof(UNICODE_NULL);
1958 ImagePath.MaximumLength = kvInfo->DataLength;
1960 if (!ImagePath.Buffer)
1961 {
1962 ExFreePool(kvInfo);
1964 }
1965
1966 RtlMoveMemory(ImagePath.Buffer,
1967 (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
1968 ImagePath.Length);
1969 ImagePath.Buffer[ImagePath.Length / sizeof(WCHAR)] = UNICODE_NULL;
1970 ExFreePool(kvInfo);
1971 }
1972 else
1973 {
1974 return Status;
1975 }
1976
1977 /*
1978 * Normalize the image path for all later processing.
1979 */
1980 Status = IopNormalizeImagePath(&ImagePath, NULL);
1981 if (!NT_SUCCESS(Status))
1982 {
1983 DPRINT("IopNormalizeImagePath() failed (Status %x)\n", Status);
1984 return Status;
1985 }
1986
1987 DPRINT("FullImagePath: '%wZ'\n", &ImagePath);
1988
1991
1992 /*
1993 * Load the driver module
1994 */
1995 DPRINT("Loading module from %wZ\n", &ImagePath);
1996 Status = MmLoadSystemImage(&ImagePath, NULL, NULL, 0, (PVOID)&ModuleObject, &BaseAddress);
1997 RtlFreeUnicodeString(&ImagePath);
1998
1999 if (!NT_SUCCESS(Status))
2000 {
2001 DPRINT("MmLoadSystemImage() failed (Status %lx)\n", Status);
2004 return Status;
2005 }
2006
2007 // Display the loading message
2008 ULONG infoLength;
2009 Status = ZwQueryKey(ServiceHandle, KeyBasicInformation, NULL, 0, &infoLength);
2011 {
2013 if (servName)
2014 {
2015 Status = ZwQueryKey(ServiceHandle,
2017 servName,
2018 infoLength,
2019 &infoLength);
2020 if (NT_SUCCESS(Status))
2021 {
2023 .Length = servName->NameLength,
2024 .MaximumLength = servName->NameLength,
2025 .Buffer = servName->Name
2026 };
2027
2029 }
2030 ExFreePoolWithTag(servName, TAG_IO);
2031 }
2032 }
2033
2034 NTSTATUS driverEntryStatus;
2035 Status = IopInitializeDriverModule(ModuleObject,
2036 ServiceHandle,
2038 &driverEntryStatus);
2039 if (!NT_SUCCESS(Status))
2040 {
2041 DPRINT1("IopInitializeDriverModule() failed (Status %lx)\n", Status);
2042 }
2043
2046
2047 return Status;
2048}
#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 PVOID * BaseAddress
Definition: mmfuncs.h:404
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
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:2935
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:369
#define TAG_RTLREGISTRY
Definition: tag.h:97

Referenced by IopLoadUnloadDriverWorker(), and PiAttachFilterDriversCallback().

◆ IopLoadUnloadDriverWorker()

static VOID NTAPI IopLoadUnloadDriverWorker ( _Inout_ PVOID  Parameter)
static

Definition at line 2053 of file driver.c.

2055{
2056 PLOAD_UNLOAD_PARAMS LoadParams = Parameter;
2057
2059
2060 if (LoadParams->DriverObject)
2061 {
2062 // unload request
2063 LoadParams->DriverObject->DriverUnload(LoadParams->DriverObject);
2064 LoadParams->Status = STATUS_SUCCESS;
2065 }
2066 else
2067 {
2068 // load request
2069 HANDLE serviceHandle;
2071 status = IopOpenRegistryKeyEx(&serviceHandle, NULL, LoadParams->RegistryPath, KEY_READ);
2072 if (!NT_SUCCESS(status))
2073 {
2074 LoadParams->Status = status;
2075 }
2076 else
2077 {
2078 LoadParams->Status = IopLoadDriver(serviceHandle, &LoadParams->DriverObject);
2079 ZwClose(serviceHandle);
2080 }
2081 }
2082
2083 if (LoadParams->SetEvent)
2084 {
2085 KeSetEvent(&LoadParams->Event, 0, FALSE);
2086 }
2087}
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
NTSTATUS IopLoadDriver(_In_ HANDLE ServiceHandle, _Out_ PDRIVER_OBJECT *DriverObject)
Definition: driver.c:1938
PDRIVER_UNLOAD DriverUnload
Definition: iotypes.h:2288
_Inout_opt_ PVOID Parameter
Definition: rtltypes.h:323

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 369 of file driver.c.

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

Referenced by IopLoadDriver(), and IopUnloadDriver().

◆ IopReinitializeBootDrivers()

VOID NTAPI IopReinitializeBootDrivers ( VOID  )

Definition at line 1532 of file driver.c.

1533{
1534 PDRIVER_REINIT_ITEM ReinitItem;
1536
1537 /* Get the first entry and start looping */
1540 while (Entry)
1541 {
1542 /* Get the item */
1543 ReinitItem = CONTAINING_RECORD(Entry, DRIVER_REINIT_ITEM, ItemEntry);
1544
1545 /* Increment reinitialization counter */
1546 ReinitItem->DriverObject->DriverExtension->Count++;
1547
1548 /* Remove the device object flag */
1549 ReinitItem->DriverObject->Flags &= ~DRVO_BOOTREINIT_REGISTERED;
1550
1551 /* Call the routine */
1552 ReinitItem->ReinitRoutine(ReinitItem->DriverObject,
1553 ReinitItem->Context,
1554 ReinitItem->DriverObject->
1555 DriverExtension->Count);
1556
1557 /* Free the entry */
1559
1560 /* Move to the next one */
1563 }
1564
1565 /* Wait for all device actions being finished*/
1567}
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
base of all file and directory entries
Definition: entries.h:83
PDRIVER_OBJECT DriverObject
Definition: io.h:449
PDRIVER_REINITIALIZE ReinitRoutine
Definition: io.h:450
PVOID Context
Definition: io.h:451
@ Executive
Definition: ketypes.h:415

Referenced by IoInitSystem().

◆ IopReinitializeDrivers()

VOID NTAPI IopReinitializeDrivers ( VOID  )

Definition at line 1496 of file driver.c.

1497{
1498 PDRIVER_REINIT_ITEM ReinitItem;
1500
1501 /* Get the first entry and start looping */
1504 while (Entry)
1505 {
1506 /* Get the item */
1507 ReinitItem = CONTAINING_RECORD(Entry, DRIVER_REINIT_ITEM, ItemEntry);
1508
1509 /* Increment reinitialization counter */
1510 ReinitItem->DriverObject->DriverExtension->Count++;
1511
1512 /* Remove the device object flag */
1513 ReinitItem->DriverObject->Flags &= ~DRVO_REINIT_REGISTERED;
1514
1515 /* Call the routine */
1516 ReinitItem->ReinitRoutine(ReinitItem->DriverObject,
1517 ReinitItem->Context,
1518 ReinitItem->DriverObject->
1519 DriverExtension->Count);
1520
1521 /* Free the entry */
1523
1524 /* Move to the next one */
1527 }
1528}
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 280 of file driver.c.

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

Referenced by IopDisplayLoadingMessage().

◆ IopUnloadDriver()

NTSTATUS NTAPI IopUnloadDriver ( PUNICODE_STRING  DriverServiceName,
BOOLEAN  UnloadPnpDrivers 
)

Definition at line 1269 of file driver.c.

1270{
1271 UNICODE_STRING Backslash = RTL_CONSTANT_STRING(L"\\");
1273 UNICODE_STRING ImagePath;
1278 PEXTENDED_DEVOBJ_EXTENSION DeviceExtension;
1280 USHORT LastBackslash;
1281 BOOLEAN SafeToUnload = TRUE;
1283 UNICODE_STRING CapturedServiceName;
1284
1285 PAGED_CODE();
1286
1288
1289 /* Need the appropriate priviliege */
1291 {
1292 DPRINT1("No unload privilege!\n");
1294 }
1295
1296 /* Capture the service name */
1297 Status = ProbeAndCaptureUnicodeString(&CapturedServiceName,
1299 DriverServiceName);
1300 if (!NT_SUCCESS(Status))
1301 {
1302 return Status;
1303 }
1304
1305 DPRINT("IopUnloadDriver('%wZ', %u)\n", &CapturedServiceName, UnloadPnpDrivers);
1306
1307 /* We need a service name */
1308 if (CapturedServiceName.Length == 0 || CapturedServiceName.Buffer == NULL)
1309 {
1310 ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1312 }
1313
1314 /*
1315 * Get the service name from the registry key name
1316 */
1318 &CapturedServiceName,
1319 &Backslash,
1320 &LastBackslash);
1321 if (NT_SUCCESS(Status))
1322 {
1323 NT_ASSERT(CapturedServiceName.Length >= LastBackslash + sizeof(WCHAR));
1324 ServiceName.Buffer = &CapturedServiceName.Buffer[LastBackslash / sizeof(WCHAR) + 1];
1325 ServiceName.Length = CapturedServiceName.Length - LastBackslash - sizeof(WCHAR);
1326 ServiceName.MaximumLength = CapturedServiceName.MaximumLength - LastBackslash - sizeof(WCHAR);
1327 }
1328 else
1329 {
1330 ServiceName = CapturedServiceName;
1331 }
1332
1333 /*
1334 * Construct the driver object name
1335 */
1336 Status = RtlUShortAdd(sizeof(DRIVER_ROOT_NAME),
1337 ServiceName.Length,
1338 &ObjectName.MaximumLength);
1339 if (!NT_SUCCESS(Status))
1340 {
1341 ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1342 return Status;
1343 }
1344 ObjectName.Length = 0;
1346 ObjectName.MaximumLength,
1347 TAG_IO);
1348 if (!ObjectName.Buffer)
1349 {
1350 ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1352 }
1355
1356 /*
1357 * Find the driver object
1358 */
1360 0,
1361 0,
1362 0,
1364 KernelMode,
1365 0,
1366 (PVOID*)&DriverObject);
1367
1368 if (!NT_SUCCESS(Status))
1369 {
1370 DPRINT1("Can't locate driver object for %wZ\n", &ObjectName);
1372 ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1373 return Status;
1374 }
1375
1376 /* Free the buffer for driver object name */
1378
1379 /* Check that driver is not already unloading */
1380 if (DriverObject->Flags & DRVO_UNLOAD_INVOKED)
1381 {
1382 DPRINT1("Driver deletion pending\n");
1384 ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1385 return STATUS_DELETE_PENDING;
1386 }
1387
1388 /*
1389 * Get path of service...
1390 */
1392
1393 RtlInitUnicodeString(&ImagePath, NULL);
1394
1395 QueryTable[0].Name = L"ImagePath";
1397 QueryTable[0].EntryContext = &ImagePath;
1398
1400 CapturedServiceName.Buffer,
1401 QueryTable,
1402 NULL,
1403 NULL);
1404
1405 /* We no longer need service name */
1406 ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1407
1408 if (!NT_SUCCESS(Status))
1409 {
1410 DPRINT1("RtlQueryRegistryValues() failed (Status %x)\n", Status);
1412 return Status;
1413 }
1414
1415 /*
1416 * Normalize the image path for all later processing.
1417 */
1419
1420 if (!NT_SUCCESS(Status))
1421 {
1422 DPRINT1("IopNormalizeImagePath() failed (Status %x)\n", Status);
1424 return Status;
1425 }
1426
1427 /* Free the service path */
1428 ExFreePool(ImagePath.Buffer);
1429
1430 /*
1431 * Unload the module and release the references to the device object
1432 */
1433
1434 /* Call the load/unload routine, depending on current process */
1435 if (DriverObject->DriverUnload && DriverObject->DriverSection &&
1436 (UnloadPnpDrivers || (DriverObject->Flags & DRVO_LEGACY_DRIVER)))
1437 {
1438 /* Loop through each device object of the driver
1439 and set DOE_UNLOAD_PENDING flag */
1440 DeviceObject = DriverObject->DeviceObject;
1441 while (DeviceObject)
1442 {
1443 /* Set the unload pending flag for the device */
1444 DeviceExtension = IoGetDevObjExtension(DeviceObject);
1445 DeviceExtension->ExtensionFlags |= DOE_UNLOAD_PENDING;
1446
1447 /* Make sure there are no attached devices or no reference counts */
1448 if ((DeviceObject->ReferenceCount) || (DeviceObject->AttachedDevice))
1449 {
1450 /* Not safe to unload */
1451 DPRINT1("Drivers device object is referenced or has attached devices\n");
1452
1453 SafeToUnload = FALSE;
1454 }
1455
1456 DeviceObject = DeviceObject->NextDevice;
1457 }
1458
1459 /* If not safe to unload, then return success */
1460 if (!SafeToUnload)
1461 {
1463 return STATUS_SUCCESS;
1464 }
1465
1466 DPRINT1("Unloading driver '%wZ' (manual)\n", &DriverObject->DriverName);
1467
1468 /* Set the unload invoked flag and call the unload routine */
1472
1473 /* Mark the driver object temporary, so it could be deleted later */
1475
1476 /* Dereference it 2 times */
1479
1480 return Status;
1481 }
1482 else
1483 {
1484 DPRINT1("No DriverUnload function! '%wZ' will not be unloaded!\n", &DriverObject->DriverName);
1485
1486 /* Dereference one time (refd inside this function) */
1488
1489 /* Return unloading failure */
1491 }
1492}
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
#define ExGetPreviousMode
Definition: ex.h:140
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
#define DOE_UNLOAD_PENDING
Definition: iotypes.h:149
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4208
#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:129
#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:2099
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:322
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:409
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:2055
_In_ PVOID _Out_opt_ PULONG_PTR _Outptr_opt_ PCUNICODE_STRING * ObjectName
Definition: cmfuncs.h:64
#define DRVO_UNLOAD_INVOKED
Definition: iotypes.h:2225
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define NT_ASSERT
Definition: rtlfuncs.h:3310
#define NT_VERIFY(exp)
Definition: rtlfuncs.h:3287
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103

Referenced by NtUnloadDriver().

◆ IoRegisterBootDriverReinitialization()

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

Definition at line 1768 of file driver.c.

1771{
1772 PDRIVER_REINIT_ITEM ReinitItem;
1773
1774 /* Allocate the entry */
1776 sizeof(DRIVER_REINIT_ITEM),
1777 TAG_REINIT);
1778 if (!ReinitItem) return;
1779
1780 /* Fill it out */
1781 ReinitItem->DriverObject = DriverObject;
1782 ReinitItem->ReinitRoutine = ReinitRoutine;
1783 ReinitItem->Context = Context;
1784
1785 /* Set the Driver Object flag and insert the entry into the list */
1788 &ReinitItem->ItemEntry,
1790}
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:448
#define TAG_REINIT
Definition: tag.h:84
#define DRVO_BOOTREINIT_REGISTERED
Definition: iotypes.h:4471

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

◆ IoRegisterDriverReinitialization()

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

Definition at line 1797 of file driver.c.

1800{
1801 PDRIVER_REINIT_ITEM ReinitItem;
1802
1803 /* Allocate the entry */
1805 sizeof(DRIVER_REINIT_ITEM),
1806 TAG_REINIT);
1807 if (!ReinitItem) return;
1808
1809 /* Fill it out */
1810 ReinitItem->DriverObject = DriverObject;
1811 ReinitItem->ReinitRoutine = ReinitRoutine;
1812 ReinitItem->Context = Context;
1813
1814 /* Set the Driver Object flag and insert the entry into the list */
1817 &ReinitItem->ItemEntry,
1819}
#define DRVO_REINIT_REGISTERED
Definition: iotypes.h:4469

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 722 of file driver.c.

725{
727 UNICODE_STRING BaseName, BaseDirectory;
728 PLOAD_IMPORTS LoadedImports = MM_SYSLDR_NO_IMPORTS;
729 PCHAR MissingApiName, Buffer;
730 PWCHAR MissingDriverName;
731 PVOID DriverBase = LdrEntry->DllBase;
732
733 /* Allocate a buffer we'll use for names */
737 if (!Buffer)
738 {
739 /* Fail */
741 }
742
743 /* Check for a separator */
744 if (FileName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR)
745 {
746 PWCHAR p;
747 ULONG BaseLength;
748
749 /* Loop the path until we get to the base name */
750 p = &FileName->Buffer[FileName->Length / sizeof(WCHAR)];
751 while (*(p - 1) != OBJ_NAME_PATH_SEPARATOR) p--;
752
753 /* Get the length */
754 BaseLength = (ULONG)(&FileName->Buffer[FileName->Length / sizeof(WCHAR)] - p);
755 BaseLength *= sizeof(WCHAR);
756
757 /* Setup the string */
758 BaseName.Length = (USHORT)BaseLength;
759 BaseName.Buffer = p;
760 }
761 else
762 {
763 /* Otherwise, we already have a base name */
764 BaseName.Length = FileName->Length;
765 BaseName.Buffer = FileName->Buffer;
766 }
767
768 /* Setup the maximum length */
769 BaseName.MaximumLength = BaseName.Length;
770
771 /* Now compute the base directory */
772 BaseDirectory = *FileName;
773 BaseDirectory.Length -= BaseName.Length;
774 BaseDirectory.MaximumLength = BaseDirectory.Length;
775
776 /* Resolve imports */
777 MissingApiName = Buffer;
778 Status = MiResolveImageReferences(DriverBase,
779 &BaseDirectory,
780 NULL,
781 &MissingApiName,
782 &MissingDriverName,
783 &LoadedImports);
784
785 /* Free the temporary buffer */
787
788 /* Check the result of the imports resolution */
789 if (!NT_SUCCESS(Status)) return Status;
790
791 /* Return */
792 *ModuleObject = LdrEntry;
793 return STATUS_SUCCESS;
794}
#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:896
GLfloat GLfloat p
Definition: glext.h:8902
#define MM_SYSLDR_NO_IMPORTS
Definition: miarm.h:200
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:1033
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 1033 of file sysldr.c.

1039{
1040 static UNICODE_STRING DriversFolderName = RTL_CONSTANT_STRING(L"drivers\\");
1041 PCHAR MissingApiBuffer = *MissingApi, ImportName;
1042 PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor, CurrentImport;
1043 ULONG ImportSize, ImportCount = 0, LoadedImportsSize, ExportSize;
1044 PLOAD_IMPORTS LoadedImports, NewImports;
1045 ULONG i;
1046 BOOLEAN GdiLink, NormalLink;
1047 BOOLEAN ReferenceNeeded, Loaded;
1048 ANSI_STRING TempString;
1049 UNICODE_STRING NameString, DllName;
1050 PLDR_DATA_TABLE_ENTRY LdrEntry = NULL, DllEntry, ImportEntry = NULL;
1051 PVOID ImportBase, DllBase;
1052 PLIST_ENTRY NextEntry;
1053 PIMAGE_EXPORT_DIRECTORY ExportDirectory;
1055 PIMAGE_THUNK_DATA OrigThunk, FirstThunk;
1056
1057 PAGED_CODE();
1058
1059 DPRINT("%s - ImageBase: %p. ImageFileDirectory: %wZ\n",
1060 __FUNCTION__, ImageBase, ImageFileDirectory);
1061
1062 /* No name string buffer yet */
1063 NameString.Buffer = NULL;
1064
1065 /* Assume no imports */
1066 *LoadImports = MM_SYSLDR_NO_IMPORTS;
1067
1068 /* Get the import descriptor */
1069 ImportDescriptor = RtlImageDirectoryEntryToData(ImageBase,
1070 TRUE,
1072 &ImportSize);
1073 if (!ImportDescriptor) return STATUS_SUCCESS;
1074
1075 /* Loop all imports to count them */
1076 for (CurrentImport = ImportDescriptor;
1077 (CurrentImport->Name) && (CurrentImport->OriginalFirstThunk);
1078 CurrentImport++)
1079 {
1080 /* One more */
1081 ImportCount++;
1082 }
1083
1084 /* Make sure we have non-zero imports */
1085 if (ImportCount)
1086 {
1087 /* Calculate and allocate the list we'll need */
1088 LoadedImportsSize = ImportCount * sizeof(PVOID) + sizeof(SIZE_T);
1089 LoadedImports = ExAllocatePoolWithTag(PagedPool,
1090 LoadedImportsSize,
1092 if (LoadedImports)
1093 {
1094 /* Zero it */
1095 RtlZeroMemory(LoadedImports, LoadedImportsSize);
1096 LoadedImports->Count = ImportCount;
1097 }
1098 }
1099 else
1100 {
1101 /* No table */
1102 LoadedImports = NULL;
1103 }
1104
1105 /* Reset the import count and loop descriptors again */
1106 GdiLink = NormalLink = FALSE;
1107 ImportCount = 0;
1108 while ((ImportDescriptor->Name) && (ImportDescriptor->OriginalFirstThunk))
1109 {
1110 /* Get the name */
1111 ImportName = (PCHAR)((ULONG_PTR)ImageBase + ImportDescriptor->Name);
1112
1113 /* Check if this is a GDI driver */
1114 GdiLink = GdiLink ||
1115 !(_strnicmp(ImportName, "win32k", sizeof("win32k") - 1));
1116
1117 /* We can also allow dxapi (for Windows compat, allow IRT and coverage) */
1118 NormalLink = NormalLink ||
1119 ((_strnicmp(ImportName, "win32k", sizeof("win32k") - 1)) &&
1120 (_strnicmp(ImportName, "dxapi", sizeof("dxapi") - 1)) &&
1121 (_strnicmp(ImportName, "coverage", sizeof("coverage") - 1)) &&
1122 (_strnicmp(ImportName, "irt", sizeof("irt") - 1)));
1123
1124 /* Check if this is a valid GDI driver */
1125 if (GdiLink && NormalLink)
1126 {
1127 /* It's not, it's importing stuff it shouldn't be! */
1129 goto Failure;
1130 }
1131
1132 /* Check for user-mode printer or video card drivers, which don't belong */
1133 if (!(_strnicmp(ImportName, "ntdll", sizeof("ntdll") - 1)) ||
1134 !(_strnicmp(ImportName, "winsrv", sizeof("winsrv") - 1)) ||
1135 !(_strnicmp(ImportName, "advapi32", sizeof("advapi32") - 1)) ||
1136 !(_strnicmp(ImportName, "kernel32", sizeof("kernel32") - 1)) ||
1137 !(_strnicmp(ImportName, "user32", sizeof("user32") - 1)) ||
1138 !(_strnicmp(ImportName, "gdi32", sizeof("gdi32") - 1)))
1139 {
1140 /* This is not kernel code */
1142 goto Failure;
1143 }
1144
1145 /* Check if this is a "core" import, which doesn't get referenced */
1146 if (!(_strnicmp(ImportName, "ntoskrnl", sizeof("ntoskrnl") - 1)) ||
1147 !(_strnicmp(ImportName, "win32k", sizeof("win32k") - 1)) ||
1148 !(_strnicmp(ImportName, "hal", sizeof("hal") - 1)))
1149 {
1150 /* Don't reference this */
1151 ReferenceNeeded = FALSE;
1152 }
1153 else
1154 {
1155 /* Reference these modules */
1156 ReferenceNeeded = TRUE;
1157 }
1158
1159 /* Now setup a unicode string for the import */
1160 RtlInitAnsiString(&TempString, ImportName);
1161 Status = RtlAnsiStringToUnicodeString(&NameString, &TempString, TRUE);
1162 if (!NT_SUCCESS(Status))
1163 {
1164 /* Failed */
1165 goto Failure;
1166 }
1167
1168 /* We don't support name prefixes yet */
1169 if (NamePrefix) DPRINT1("Name Prefix not yet supported!\n");
1170
1171 /* Remember that we haven't loaded the import at this point */
1172CheckDllState:
1173 Loaded = FALSE;
1174 ImportBase = NULL;
1175
1176 /* Loop the driver list */
1177 NextEntry = PsLoadedModuleList.Flink;
1178 while (NextEntry != &PsLoadedModuleList)
1179 {
1180 /* Get the loader entry and compare the name */
1181 LdrEntry = CONTAINING_RECORD(NextEntry,
1183 InLoadOrderLinks);
1184 if (RtlEqualUnicodeString(&NameString,
1185 &LdrEntry->BaseDllName,
1186 TRUE))
1187 {
1188 /* Get the base address */
1189 ImportBase = LdrEntry->DllBase;
1190
1191 /* Check if we haven't loaded yet, and we need references */
1192 if (!(Loaded) && (ReferenceNeeded))
1193 {
1194 /* Make sure we're not already loading */
1195 if (!(LdrEntry->Flags & LDRP_LOAD_IN_PROGRESS))
1196 {
1197 /* Increase the load count */
1198 LdrEntry->LoadCount++;
1199 }
1200 }
1201
1202 /* Done, break out */
1203 break;
1204 }
1205
1206 /* Go to the next entry */
1207 NextEntry = NextEntry->Flink;
1208 }
1209
1210 /* Check if we haven't loaded the import yet */
1211 if (!ImportBase)
1212 {
1213 /* Setup the import DLL name */
1214 DllName.MaximumLength = NameString.Length +
1215 ImageFileDirectory->Length +
1216 sizeof(UNICODE_NULL);
1218 DllName.MaximumLength,
1219 TAG_LDR_WSTR);
1220 if (!DllName.Buffer)
1221 {
1222 /* We're out of resources */
1224 goto Failure;
1225 }
1226
1227 /* Add the import name to the base directory */
1228 RtlCopyUnicodeString(&DllName, ImageFileDirectory);
1230 &NameString);
1231
1232 /* Load the image */
1233 Status = MmLoadSystemImage(&DllName,
1234 NamePrefix,
1235 NULL,
1236 FALSE,
1237 (PVOID *)&DllEntry,
1238 &DllBase);
1239
1240 /* win32k / GDI drivers can also import from system32 folder */
1242 (MI_IS_SESSION_ADDRESS(ImageBase) || 1)) // HACK
1243 {
1244 /* Free the old name buffer */
1246
1247 /* Calculate size for a string the adds 'drivers\' */
1248 DllName.MaximumLength += DriversFolderName.Length;
1249
1250 /* Allocate the new buffer */
1252 DllName.MaximumLength,
1253 TAG_LDR_WSTR);
1254 if (!DllName.Buffer)
1255 {
1256 /* We're out of resources */
1258 goto Failure;
1259 }
1260
1261 /* Copy image directory and append 'drivers\' folder name */
1262 RtlCopyUnicodeString(&DllName, ImageFileDirectory);
1263 RtlAppendUnicodeStringToString(&DllName, &DriversFolderName);
1264
1265 /* Now add the import name */
1266 RtlAppendUnicodeStringToString(&DllName, &NameString);
1267
1268 /* Try once again to load the image */
1269 Status = MmLoadSystemImage(&DllName,
1270 NamePrefix,
1271 NULL,
1272 FALSE,
1273 (PVOID *)&DllEntry,
1274 &DllBase);
1275 }
1276
1277 if (!NT_SUCCESS(Status))
1278 {
1279 /* Fill out the information for the error */
1280 *MissingDriver = DllName.Buffer;
1281 *(PULONG)MissingDriver |= 1;
1282 *MissingApi = NULL;
1283
1284 DPRINT1("Failed to load dependency: %wZ\n", &DllName);
1285
1286 /* Don't free the name */
1287 DllName.Buffer = NULL;
1288
1289 /* Cleanup and return */
1290 goto Failure;
1291 }
1292
1293 /* We can free the DLL Name */
1295 DllName.Buffer = NULL;
1296
1297 /* We're now loaded */
1298 Loaded = TRUE;
1299
1300 /* Sanity check */
1301 ASSERT(DllBase == DllEntry->DllBase);
1302
1303 /* Call the initialization routines */
1305 if (!NT_SUCCESS(Status))
1306 {
1307 /* We failed, unload the image */
1308 MmUnloadSystemImage(DllEntry);
1309 ERROR_DBGBREAK("MmCallDllInitialize failed with status 0x%x\n", Status);
1310 Loaded = FALSE;
1311 }
1312
1313 /* Loop again to make sure that everything is OK */
1314 goto CheckDllState;
1315 }
1316
1317 /* Check if we're support to reference this import */
1318 if ((ReferenceNeeded) && (LoadedImports))
1319 {
1320 /* Make sure we're not already loading */
1321 if (!(LdrEntry->Flags & LDRP_LOAD_IN_PROGRESS))
1322 {
1323 /* Add the entry */
1324 LoadedImports->Entry[ImportCount] = LdrEntry;
1325 ImportCount++;
1326 }
1327 }
1328
1329 /* Free the import name */
1330 RtlFreeUnicodeString(&NameString);
1331
1332 /* Set the missing driver name and get the export directory */
1333 *MissingDriver = LdrEntry->BaseDllName.Buffer;
1334 ExportDirectory = RtlImageDirectoryEntryToData(ImportBase,
1335 TRUE,
1337 &ExportSize);
1338 if (!ExportDirectory)
1339 {
1340 /* Cleanup and return */
1341 DPRINT1("Warning: Driver failed to load, %S not found\n", *MissingDriver);
1343 goto Failure;
1344 }
1345
1346 /* Make sure we have an IAT */
1347 if (ImportDescriptor->OriginalFirstThunk)
1348 {
1349 /* Get the first thunks */
1350 OrigThunk = (PVOID)((ULONG_PTR)ImageBase +
1351 ImportDescriptor->OriginalFirstThunk);
1352 FirstThunk = (PVOID)((ULONG_PTR)ImageBase +
1353 ImportDescriptor->FirstThunk);
1354
1355 /* Loop the IAT */
1356 while (OrigThunk->u1.AddressOfData)
1357 {
1358 /* Snap thunk */
1359 Status = MiSnapThunk(ImportBase,
1360 ImageBase,
1361 OrigThunk++,
1362 FirstThunk++,
1363 ExportDirectory,
1364 ExportSize,
1365 FALSE,
1366 MissingApi);
1367 if (!NT_SUCCESS(Status))
1368 {
1369 /* Cleanup and return */
1370 goto Failure;
1371 }
1372
1373 /* Reset the buffer */
1374 *MissingApi = MissingApiBuffer;
1375 }
1376 }
1377
1378 /* Go to the next import */
1379 ImportDescriptor++;
1380 }
1381
1382 /* Check if we have an import list */
1383 if (LoadedImports)
1384 {
1385 /* Reset the count again, and loop entries */
1386 ImportCount = 0;
1387 for (i = 0; i < LoadedImports->Count; i++)
1388 {
1389 if (LoadedImports->Entry[i])
1390 {
1391 /* Got an entry, OR it with 1 in case it's the single entry */
1392 ImportEntry = (PVOID)((ULONG_PTR)LoadedImports->Entry[i] |
1394 ImportCount++;
1395 }
1396 }
1397
1398 /* Check if we had no imports */
1399 if (!ImportCount)
1400 {
1401 /* Free the list and set it to no imports */
1402 ExFreePoolWithTag(LoadedImports, TAG_LDR_IMPORTS);
1403 LoadedImports = MM_SYSLDR_NO_IMPORTS;
1404 }
1405 else if (ImportCount == 1)
1406 {
1407 /* Just one entry, we can free the table and only use our entry */
1408 ExFreePoolWithTag(LoadedImports, TAG_LDR_IMPORTS);
1409 LoadedImports = (PLOAD_IMPORTS)ImportEntry;
1410 }
1411 else if (ImportCount != LoadedImports->Count)
1412 {
1413 /* Allocate a new list */
1414 LoadedImportsSize = ImportCount * sizeof(PVOID) + sizeof(SIZE_T);
1415 NewImports = ExAllocatePoolWithTag(PagedPool,
1416 LoadedImportsSize,
1418 if (NewImports)
1419 {
1420 /* Set count */
1421 NewImports->Count = 0;
1422
1423 /* Loop all the imports */
1424 for (i = 0; i < LoadedImports->Count; i++)
1425 {
1426 /* Make sure it's valid */
1427 if (LoadedImports->Entry[i])
1428 {
1429 /* Copy it */
1430 NewImports->Entry[NewImports->Count] = LoadedImports->Entry[i];
1431 NewImports->Count++;
1432 }
1433 }
1434
1435 /* Free the old copy */
1436 ExFreePoolWithTag(LoadedImports, TAG_LDR_IMPORTS);
1437 LoadedImports = NewImports;
1438 }
1439 }
1440
1441 /* Return the list */
1442 *LoadImports = LoadedImports;
1443 }
1444
1445 /* Return success */
1446 return STATUS_SUCCESS;
1447
1448Failure:
1449
1450 /* Cleanup and return */
1451 RtlFreeUnicodeString(&NameString);
1452
1453 if (LoadedImports)
1454 {
1455 MiDereferenceImports(LoadedImports);
1456 ExFreePoolWithTag(LoadedImports, TAG_LDR_IMPORTS);
1457 }
1458
1459 return Status;
1460}
#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:42
struct _LOAD_IMPORTS * PLOAD_IMPORTS
#define MI_IS_SESSION_ADDRESS(Address)
Definition: miarm.h:171
#define MM_SYSLDR_SINGLE_ENTRY
Definition: miarm.h:202
#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:736
#define STATUS_PROCEDURE_NOT_FOUND
Definition: ntstatus.h:358
#define IMAGE_DIRECTORY_ENTRY_IMPORT
Definition: pedump.c:260
#define ERROR_DBGBREAK(...)
Definition: debug.h:221
union _IMAGE_THUNK_DATA32::@2129 u1
USHORT LoadCount
Definition: ntddk_ex.h:208
SIZE_T Count
Definition: ldrtypes.h:172
PLDR_DATA_TABLE_ENTRY Entry[1]
Definition: ldrtypes.h:173
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:747
NTSTATUS NTAPI MiDereferenceImports(IN PLOAD_IMPORTS ImportList)
Definition: sysldr.c:526
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:2935
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:21
NTSTATUS NTAPI MmCallDllInitialize(_In_ PLDR_DATA_TABLE_ENTRY LdrEntry, _In_ PLIST_ENTRY ModuleListHead)
Definition: sysldr.c:432
NTSTATUS NTAPI MmUnloadSystemImage(IN PVOID ImageHandle)
Definition: sysldr.c:944
#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 2147 of file driver.c.

2148{
2149 UNICODE_STRING CapturedServiceName = { 0, 0, NULL };
2153
2154 PAGED_CODE();
2155
2157
2158 /* Need the appropriate priviliege */
2160 {
2161 DPRINT1("No load privilege!\n");
2163 }
2164
2165 /* Capture the service name */
2166 Status = ProbeAndCaptureUnicodeString(&CapturedServiceName,
2168 DriverServiceName);
2169 if (!NT_SUCCESS(Status))
2170 {
2171 return Status;
2172 }
2173
2174 DPRINT("NtLoadDriver('%wZ')\n", &CapturedServiceName);
2175
2176 /* We need a service name */
2177 if (CapturedServiceName.Length == 0 || CapturedServiceName.Buffer == NULL)
2178 {
2179 ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
2181 }
2182
2183 /* Load driver and call its entry point */
2185 Status = IopDoLoadUnloadDriver(&CapturedServiceName, &DriverObject);
2186
2187 ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
2188 return Status;
2189}
#define KeGetPreviousMode()
Definition: ketypes.h:1115

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

◆ NtUnloadDriver()

NTSTATUS NTAPI NtUnloadDriver ( IN PUNICODE_STRING  DriverServiceName)

Definition at line 2208 of file driver.c.

2209{
2210 return IopUnloadDriver(DriverServiceName, FALSE);
2211}
NTSTATUS NTAPI IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
Definition: driver.c:1269

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 17 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().