ReactOS  0.4.15-dev-3175-g222acf5
driver.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for driver.c:

Go to the source code of this file.

Classes

struct  _LOAD_UNLOAD_PARAMS
 

Macros

#define NDEBUG
 
#define TAG_RTLREGISTRY   'vrqR'
 

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. More...
 
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)
 
BOOLEAN NTAPI IopSuffixUnicodeString (IN PCUNICODE_STRING String1, IN PCUNICODE_STRING String2)
 
VOID FASTCALL IopDisplayLoadingMessage (PUNICODE_STRING ServiceName)
 
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. More...
 
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 ExpInTextModeSetup
 
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.

◆ TAG_RTLREGISTRY

#define TAG_RTLREGISTRY   'vrqR'

Definition at line 35 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 1799 of file driver.c.

1803 {
1804  KIRQL OldIrql;
1805  PIO_CLIENT_EXTENSION DriverExtensions, NewDriverExtension;
1806  BOOLEAN Inserted = FALSE;
1807 
1808  /* Assume failure */
1809  *DriverObjectExtension = NULL;
1810 
1811  /* Allocate the extension */
1812  NewDriverExtension = ExAllocatePoolWithTag(NonPagedPool,
1813  sizeof(IO_CLIENT_EXTENSION) +
1814  DriverObjectExtensionSize,
1816  if (!NewDriverExtension) return STATUS_INSUFFICIENT_RESOURCES;
1817 
1818  /* Clear the extension for teh caller */
1819  RtlZeroMemory(NewDriverExtension,
1820  sizeof(IO_CLIENT_EXTENSION) + DriverObjectExtensionSize);
1821 
1822  /* Acqure lock */
1824 
1825  /* Fill out the extension */
1827 
1828  /* Loop the current extensions */
1829  DriverExtensions = IoGetDrvObjExtension(DriverObject)->
1830  ClientDriverExtension;
1831  while (DriverExtensions)
1832  {
1833  /* Check if the identifier matches */
1834  if (DriverExtensions->ClientIdentificationAddress ==
1836  {
1837  /* We have a collision, break out */
1838  break;
1839  }
1840 
1841  /* Go to the next one */
1842  DriverExtensions = DriverExtensions->NextExtension;
1843  }
1844 
1845  /* Check if we didn't collide */
1846  if (!DriverExtensions)
1847  {
1848  /* Link this one in */
1849  NewDriverExtension->NextExtension =
1850  IoGetDrvObjExtension(DriverObject)->ClientDriverExtension;
1851  IoGetDrvObjExtension(DriverObject)->ClientDriverExtension =
1852  NewDriverExtension;
1853  Inserted = TRUE;
1854  }
1855 
1856  /* Release the lock */
1858 
1859  /* Check if insertion failed */
1860  if (!Inserted)
1861  {
1862  /* Free the entry and fail */
1863  ExFreePoolWithTag(NewDriverExtension, TAG_DRIVER_EXTENSION);
1865  }
1866 
1867  /* Otherwise, return the pointer */
1868  *DriverObjectExtension = NewDriverExtension + 1;
1869  return STATUS_SUCCESS;
1870 }
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG IN OUT PLONG IN LONG Increment KeRaiseIrqlToDpcLevel
Definition: CrNtStubs.h:67
struct _IO_CLIENT_EXTENSION * NextExtension
Definition: iotypes.h:823
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define TRUE
Definition: types.h:120
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
__drv_aliasesMem _In_ PVOID ClientIdentificationAddress
Definition: iofuncs.h:1028
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
KIRQL OldIrql
Definition: mm.h:1502
#define TAG_DRIVER_EXTENSION
Definition: tag.h:42
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define NULL
Definition: types.h:112
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define STATUS_SUCCESS
Definition: shellext.h:65
PVOID ClientIdentificationAddress
Definition: iotypes.h:824
VOID NTAPI KeLowerIrql(KIRQL NewIrql)
Definition: spinlock.c:39
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define IoGetDrvObjExtension(DriverObject)
Definition: io.h:136

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

1553 {
1554  WCHAR NameBuffer[100];
1555  USHORT NameLength;
1556  UNICODE_STRING LocalDriverName;
1557  NTSTATUS Status;
1559  ULONG ObjectSize;
1561  UNICODE_STRING ServiceKeyName;
1562  HANDLE hDriver;
1563  ULONG i, RetryCount = 0;
1564 
1565 try_again:
1566  /* First, create a unique name for the driver if we don't have one */
1567  if (!DriverName)
1568  {
1569  /* Create a random name and set up the string */
1570  NameLength = (USHORT)swprintf(NameBuffer,
1571  DRIVER_ROOT_NAME L"%08u",
1573  LocalDriverName.Length = NameLength * sizeof(WCHAR);
1574  LocalDriverName.MaximumLength = LocalDriverName.Length + sizeof(UNICODE_NULL);
1575  LocalDriverName.Buffer = NameBuffer;
1576  }
1577  else
1578  {
1579  /* So we can avoid another code path, use a local var */
1580  LocalDriverName = *DriverName;
1581  }
1582 
1583  /* Initialize the Attributes */
1584  ObjectSize = sizeof(DRIVER_OBJECT) + sizeof(EXTENDED_DRIVER_EXTENSION);
1586  &LocalDriverName,
1588  NULL,
1589  NULL);
1590 
1591  /* Create the Object */
1595  KernelMode,
1596  NULL,
1597  ObjectSize,
1598  0,
1599  0,
1600  (PVOID*)&DriverObject);
1601  if (!NT_SUCCESS(Status)) return Status;
1602 
1603  DPRINT("IopCreateDriver(): created DO %p\n", DriverObject);
1604 
1605  /* Set up the Object */
1606  RtlZeroMemory(DriverObject, ObjectSize);
1607  DriverObject->Type = IO_TYPE_DRIVER;
1608  DriverObject->Size = sizeof(DRIVER_OBJECT);
1610  DriverObject->DriverExtension = (PDRIVER_EXTENSION)(DriverObject + 1);
1611  DriverObject->DriverExtension->DriverObject = DriverObject;
1612  DriverObject->DriverInit = InitializationFunction;
1613  /* Loop all Major Functions */
1614  for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
1615  {
1616  /* Invalidate each function */
1617  DriverObject->MajorFunction[i] = IopInvalidDeviceRequest;
1618  }
1619 
1620  /* Set up the service key name buffer */
1621  ServiceKeyName.MaximumLength = LocalDriverName.Length + sizeof(UNICODE_NULL);
1622  ServiceKeyName.Buffer = ExAllocatePoolWithTag(PagedPool, LocalDriverName.MaximumLength, TAG_IO);
1623  if (!ServiceKeyName.Buffer)
1624  {
1625  /* Fail */
1629  }
1630 
1631  /* For builtin drivers, the ServiceKeyName is equal to DriverName */
1632  RtlCopyUnicodeString(&ServiceKeyName, &LocalDriverName);
1633  ServiceKeyName.Buffer[ServiceKeyName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1634  DriverObject->DriverExtension->ServiceKeyName = ServiceKeyName;
1635 
1636  /* Make a copy of the driver name to store in the driver object */
1637  DriverObject->DriverName.MaximumLength = LocalDriverName.Length;
1638  DriverObject->DriverName.Buffer = ExAllocatePoolWithTag(PagedPool,
1639  DriverObject->DriverName.MaximumLength,
1640  TAG_IO);
1641  if (!DriverObject->DriverName.Buffer)
1642  {
1643  /* Fail */
1647  }
1648 
1649  RtlCopyUnicodeString(&DriverObject->DriverName, &LocalDriverName);
1650 
1651  /* Add the Object and get its handle */
1653  NULL,
1655  0,
1656  NULL,
1657  &hDriver);
1658 
1659  /* Eliminate small possibility when this function is called more than
1660  once in a row, and KeTickCount doesn't get enough time to change */
1661  if (!DriverName && (Status == STATUS_OBJECT_NAME_COLLISION) && (RetryCount < 100))
1662  {
1663  RetryCount++;
1664  goto try_again;
1665  }
1666 
1667  if (!NT_SUCCESS(Status)) return Status;
1668 
1669  /* Now reference it */
1671  0,
1673  KernelMode,
1674  (PVOID*)&DriverObject,
1675  NULL);
1676 
1677  /* Close the extra handle */
1678  ZwClose(hDriver);
1679 
1680  if (!NT_SUCCESS(Status))
1681  {
1682  /* Fail */
1685  return Status;
1686  }
1687 
1688  /* Finally, call its init function */
1689  DPRINT("Calling driver entrypoint at %p\n", InitializationFunction);
1690  Status = InitializationFunction(DriverObject, NULL);
1691  if (!NT_SUCCESS(Status))
1692  {
1693  /* If it didn't work, then kill the object */
1694  DPRINT1("'%wZ' initialization failed, status (0x%08lx)\n", DriverName, Status);
1697  return Status;
1698  }
1699 
1700  // Windows does this fixup - keep it for compatibility
1701  for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
1702  {
1703  /*
1704  * Make sure the driver didn't set any dispatch entry point to NULL!
1705  * Doing so is illegal; drivers shouldn't touch entry points they
1706  * do not implement.
1707  */
1708 
1709  /* Check if it did so anyway */
1710  if (!DriverObject->MajorFunction[i])
1711  {
1712  /* Print a warning in the debug log */
1713  DPRINT1("Driver <%wZ> set DriverObject->MajorFunction[%lu] to NULL!\n",
1714  &DriverObject->DriverName, i);
1715 
1716  /* Fix it up */
1717  DriverObject->MajorFunction[i] = IopInvalidDeviceRequest;
1718  }
1719  }
1720 
1721  /* Return the Status */
1722  return Status;
1723 }
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
ULONG LowPart
Definition: ketypes.h:917
#define DRVO_BUILTIN_DRIVER
Definition: iotypes.h:2227
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define TAG_IO
Definition: tag.h:69
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
USHORT MaximumLength
Definition: env_spec_w32.h:370
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define IRP_MJ_MAXIMUM_FUNCTION
LONG NTSTATUS
Definition: precomp.h:26
_In_ LPWSTR _In_ ULONG _In_ ULONG _In_ ULONG _Out_ DEVINFO _In_ HDEV _In_ LPWSTR _In_ HANDLE hDriver
Definition: winddi.h:3553
POBJECT_TYPE IoDriverObjectType
Definition: driver.c:33
#define swprintf
Definition: precomp.h:40
NTSTATUS NTAPI IopInvalidDeviceRequest(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: driver.c:67
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
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
#define UNICODE_NULL
#define FILE_READ_DATA
Definition: nt_native.h:628
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
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:952
Status
Definition: gdiplustypes.h:24
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ObDereferenceObject
Definition: obfuncs.h:203
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
static const WCHAR L[]
Definition: oid.c:1250
NTKERNELAPI volatile KSYSTEM_TIME KeTickCount
Definition: clock.c:19
#define OBJ_PERMANENT
Definition: winternl.h:226
struct _DRIVER_OBJECT DRIVER_OBJECT
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:2931
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
unsigned short USHORT
Definition: pedump.c:61
struct _DRIVER_EXTENSION * PDRIVER_EXTENSION
#define NULL
Definition: types.h:112
#define IO_TYPE_DRIVER
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define DPRINT
Definition: sndvol32.h:71
PDRIVER_INITIALIZE DriverInit
Definition: iotypes.h:2286
#define DRIVER_ROOT_NAME
Definition: ldr.h:5
VOID NTAPI ObMakeTemporaryObject(IN PVOID ObjectBody)
Definition: oblife.c:1361

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

◆ IoDeleteDriver()

VOID NTAPI IoDeleteDriver ( IN PDRIVER_OBJECT  DriverObject)

Definition at line 1730 of file driver.c.

1731 {
1732  /* Simply dereference the Object */
1734 }
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
#define ObDereferenceObject
Definition: obfuncs.h:203

◆ IoGetDriverObjectExtension()

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

Definition at line 1877 of file driver.c.

1879 {
1880  KIRQL OldIrql;
1881  PIO_CLIENT_EXTENSION DriverExtensions;
1882 
1883  /* Acquire lock */
1885 
1886  /* Loop the list until we find the right one */
1887  DriverExtensions = IoGetDrvObjExtension(DriverObject)->ClientDriverExtension;
1888  while (DriverExtensions)
1889  {
1890  /* Check for a match */
1891  if (DriverExtensions->ClientIdentificationAddress ==
1893  {
1894  /* Break out */
1895  break;
1896  }
1897 
1898  /* Keep looping */
1899  DriverExtensions = DriverExtensions->NextExtension;
1900  }
1901 
1902  /* Release lock */
1904 
1905  /* Return nothing or the extension */
1906  if (!DriverExtensions) return NULL;
1907  return DriverExtensions + 1;
1908 }
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG IN OUT PLONG IN LONG Increment KeRaiseIrqlToDpcLevel
Definition: CrNtStubs.h:67
struct _IO_CLIENT_EXTENSION * NextExtension
Definition: iotypes.h:823
UCHAR KIRQL
Definition: env_spec_w32.h:591
__drv_aliasesMem _In_ PVOID ClientIdentificationAddress
Definition: iofuncs.h:1028
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
KIRQL OldIrql
Definition: mm.h:1502
#define NULL
Definition: types.h:112
PVOID ClientIdentificationAddress
Definition: iotypes.h:824
VOID NTAPI KeLowerIrql(KIRQL NewIrql)
Definition: spinlock.c:39
#define IoGetDrvObjExtension(DriverObject)
Definition: io.h:136

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(), PciIdeXFdoStartDevice(), 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 79 of file driver.c.

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

Referenced by IopCreateObjectTypes().

◆ IopDisplayLoadingMessage()

VOID FASTCALL IopDisplayLoadingMessage ( PUNICODE_STRING  ServiceName)

Definition at line 317 of file driver.c.

318 {
319  CHAR TextBuffer[256];
320  UNICODE_STRING DotSys = RTL_CONSTANT_STRING(L".SYS");
321 
322  if (ExpInTextModeSetup) return;
323  if (!KeLoaderBlock) return;
325  snprintf(TextBuffer, sizeof(TextBuffer),
326  "%s%sSystem32\\Drivers\\%wZ%s\r\n",
329  ServiceName,
330  IopSuffixUnicodeString(&DotSys, ServiceName) ? "" : ".SYS");
332 }
BOOLEAN ExpInTextModeSetup
Definition: init.c:67
PSTR ArcBootDeviceName
Definition: arc.h:503
NTSTATUS RtlUpcaseUnicodeString(PUNICODE_STRING dst, PUNICODE_STRING src, BOOLEAN Alloc)
Definition: string_lib.cpp:46
char CHAR
Definition: xmlstorage.h:175
#define snprintf
Definition: wintirpc.h:48
#define FALSE
Definition: types.h:117
PLOADER_PARAMETER_BLOCK KeLoaderBlock
Definition: krnlinit.c:29
LPTSTR ServiceName
Definition: ServiceMain.c:15
static const WCHAR L[]
Definition: oid.c:1250
NTHALAPI VOID NTAPI HalDisplayString(PUCHAR String)
char TextBuffer[BUFFERLEN]
Definition: combotst.c:45
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
BOOLEAN NTAPI IopSuffixUnicodeString(IN PCUNICODE_STRING String1, IN PCUNICODE_STRING String2)
Definition: driver.c:283

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

2075 {
2076  LOAD_UNLOAD_PARAMS LoadParams;
2077 
2078  /* Prepare parameters block */
2079  LoadParams.RegistryPath = RegistryPath;
2080  LoadParams.DriverObject = *DriverObject;
2081 
2083  {
2084  LoadParams.SetEvent = TRUE;
2086 
2087  /* Initialize and queue a work item */
2088  ExInitializeWorkItem(&LoadParams.WorkItem, IopLoadUnloadDriverWorker, &LoadParams);
2090 
2091  /* And wait till it completes */
2093  }
2094  else
2095  {
2096  /* If we're already in a system process, call it right here */
2097  LoadParams.SetEvent = FALSE;
2098  IopLoadUnloadDriverWorker(&LoadParams);
2099  }
2100 
2101  return LoadParams.Status;
2102 }
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:723
static VOID NTAPI IopLoadUnloadDriverWorker(_Inout_ PVOID Parameter)
Definition: driver.c:2026
#define TRUE
Definition: types.h:120
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:213
WORK_QUEUE_ITEM WorkItem
Definition: driver.c:52
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define FALSE
Definition: types.h:117
PEPROCESS PsInitialSystemProcess
Definition: psmgr.c:50
#define PsGetCurrentProcess
Definition: psfuncs.h:17
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
NTSTATUS Status
Definition: driver.c:50
BOOLEAN SetEvent
Definition: driver.c:55
PDRIVER_OBJECT DriverObject
Definition: driver.c:54
PUNICODE_STRING RegistryPath
Definition: driver.c:51
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define NULL
Definition: types.h:112

Referenced by IopUnloadDriver(), and NtLoadDriver().

◆ IopGetDeviceObjectFromDeviceInstance()

PDEVICE_OBJECT IopGetDeviceObjectFromDeviceInstance ( PUNICODE_STRING  DeviceInstance)

Definition at line 122 of file plugplay.c.

123 {
124  if (IopRootDeviceNode == NULL)
125  return NULL;
126 
127  if (DeviceInstance == NULL ||
128  DeviceInstance->Length == 0)
129  {
131  {
134  }
135  else
136  return NULL;
137  }
138 
140 }
PDEVICE_OBJECT PhysicalDeviceObject
Definition: iotypes.h:850
PDEVICE_NODE IopRootDeviceNode
Definition: devnode.c:18
static PDEVICE_OBJECT IopTraverseDeviceNode(PDEVICE_NODE Node, PUNICODE_STRING DeviceInstance)
Definition: plugplay.c:93
_In_ PNDIS_STRING DeviceInstance
Definition: ndis.h:5202
#define NULL
Definition: types.h:112
#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 125 of file driver.c.

129 {
130  UNICODE_STRING driverName = {.Buffer = NULL}, serviceName;
133 
134  PAGED_CODE();
135 
136  /* 1. Check the "ObjectName" field in the driver's registry key (it has priority) */
137  status = IopGetRegistryValue(ServiceHandle, L"ObjectName", &kvInfo);
138  if (NT_SUCCESS(status))
139  {
140  /* We've got the ObjectName, use it as the driver name */
141  if (kvInfo->Type != REG_SZ || kvInfo->DataLength == 0)
142  {
143  ExFreePool(kvInfo);
145  }
146 
147  driverName.Length = kvInfo->DataLength - sizeof(UNICODE_NULL);
148  driverName.MaximumLength = kvInfo->DataLength;
149  driverName.Buffer = ExAllocatePoolWithTag(NonPagedPool, driverName.MaximumLength, TAG_IO);
150  if (!driverName.Buffer)
151  {
152  ExFreePool(kvInfo);
154  }
155 
156  RtlMoveMemory(driverName.Buffer,
157  (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
158  driverName.Length);
159  driverName.Buffer[driverName.Length / sizeof(WCHAR)] = UNICODE_NULL;
160  ExFreePool(kvInfo);
161  }
162 
163  /* Check whether we need to get ServiceName as well, either to construct
164  * the driver name (because we could not use "ObjectName"), or because
165  * it is requested by the caller. */
166  PKEY_BASIC_INFORMATION basicInfo = NULL;
167  if (!NT_SUCCESS(status) || ServiceName != NULL)
168  {
169  /* Retrieve the necessary buffer size */
170  ULONG infoLength;
171  status = ZwQueryKey(ServiceHandle, KeyBasicInformation, NULL, 0, &infoLength);
173  {
175  goto Cleanup;
176  }
177 
178  /* Allocate the buffer and retrieve the data */
179  basicInfo = ExAllocatePoolWithTag(PagedPool, infoLength, TAG_IO);
180  if (!basicInfo)
181  {
183  goto Cleanup;
184  }
185 
186  status = ZwQueryKey(ServiceHandle, KeyBasicInformation, basicInfo, infoLength, &infoLength);
187  if (!NT_SUCCESS(status))
188  {
189  goto Cleanup;
190  }
191 
192  serviceName.Length = basicInfo->NameLength;
193  serviceName.MaximumLength = basicInfo->NameLength;
194  serviceName.Buffer = basicInfo->Name;
195  }
196 
197  /* 2. There is no "ObjectName" - construct it ourselves. Depending on the driver type,
198  * it will be either "\Driver<ServiceName>" or "\FileSystem<ServiceName>" */
199  if (driverName.Buffer == NULL)
200  {
201  ASSERT(basicInfo); // Container for serviceName
202 
203  /* Retrieve the driver type */
204  ULONG driverType;
205  status = IopGetRegistryValue(ServiceHandle, L"Type", &kvInfo);
206  if (!NT_SUCCESS(status))
207  {
208  goto Cleanup;
209  }
210  if (kvInfo->Type != REG_DWORD || kvInfo->DataLength != sizeof(ULONG))
211  {
212  ExFreePool(kvInfo);
214  goto Cleanup;
215  }
216 
217  RtlMoveMemory(&driverType,
218  (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
219  sizeof(ULONG));
220  ExFreePool(kvInfo);
221 
222  /* Compute the necessary driver name string size */
223  if (driverType == SERVICE_RECOGNIZER_DRIVER || driverType == SERVICE_FILE_SYSTEM_DRIVER)
224  driverName.MaximumLength = sizeof(FILESYSTEM_ROOT_NAME);
225  else
226  driverName.MaximumLength = sizeof(DRIVER_ROOT_NAME);
227 
228  driverName.MaximumLength += serviceName.Length;
229  driverName.Length = 0;
230 
231  /* Allocate and build it */
232  driverName.Buffer = ExAllocatePoolWithTag(NonPagedPool, driverName.MaximumLength, TAG_IO);
233  if (!driverName.Buffer)
234  {
236  goto Cleanup;
237  }
238 
239  if (driverType == SERVICE_RECOGNIZER_DRIVER || driverType == SERVICE_FILE_SYSTEM_DRIVER)
241  else
243 
245  }
246 
247  if (ServiceName != NULL)
248  {
249  ASSERT(basicInfo); // Container for serviceName
250 
251  /* Allocate a copy for the caller */
253  if (!buf)
254  {
256  goto Cleanup;
257  }
258  RtlMoveMemory(buf, serviceName.Buffer, serviceName.Length);
259  ServiceName->MaximumLength = serviceName.Length;
260  ServiceName->Length = serviceName.Length;
261  ServiceName->Buffer = buf;
262  }
263 
264  *DriverName = driverName;
266 
267 Cleanup:
268  if (basicInfo)
269  ExFreePoolWithTag(basicInfo, TAG_IO);
270 
271  if (!NT_SUCCESS(status) && driverName.Buffer)
272  ExFreePoolWithTag(driverName.Buffer, TAG_IO);
273 
274  return status;
275 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define TAG_IO
Definition: tag.h:69
USHORT MaximumLength
Definition: env_spec_w32.h:370
LONG NTSTATUS
Definition: precomp.h:26
#define FILESYSTEM_ROOT_NAME
Definition: ldr.h:6
uint16_t * PWCHAR
Definition: typedefs.h:56
#define SERVICE_RECOGNIZER_DRIVER
Definition: cmtypes.h:956
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
uint32_t ULONG_PTR
Definition: typedefs.h:65
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define UNICODE_NULL
#define SERVICE_FILE_SYSTEM_DRIVER
Definition: cmtypes.h:954
#define STATUS_ILL_FORMED_SERVICE_ENTRY
Definition: ntstatus.h:588
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
char serviceName[]
Definition: tftpd.cpp:34
LPTSTR ServiceName
Definition: ServiceMain.c:15
#define ASSERT(a)
Definition: mode.c:44
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
static const WCHAR L[]
Definition: oid.c:1250
static const WCHAR Cleanup[]
Definition: register.c:80
NTSTATUS NTAPI IopGetRegistryValue(IN HANDLE Handle, IN PWSTR ValueName, OUT PKEY_VALUE_FULL_INFORMATION *Information)
Definition: pnpmgr.c:1606
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_SUCCESS
Definition: shellext.h:65
#define REG_DWORD
Definition: sdbapi.c:596
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
static SERVICE_STATUS status
Definition: service.c:31
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define DRIVER_ROOT_NAME
Definition: ldr.h:5
#define PAGED_CODE()
#define REG_SZ
Definition: layer.c:22
Definition: ps.c:97

Referenced by IopInitializeDriverModule(), and PiAttachFilterDriversCallback().

◆ IopInitializeBootDrivers()

VOID FASTCALL IopInitializeBootDrivers ( VOID  )

Definition at line 1003 of file driver.c.

1004 {
1005  PLIST_ENTRY ListHead, NextEntry, NextEntry2;
1006  PLDR_DATA_TABLE_ENTRY LdrEntry;
1007  NTSTATUS Status;
1008  UNICODE_STRING DriverName;
1009  ULONG i, Index;
1010  PDRIVER_INFORMATION DriverInfo, DriverInfoTag;
1011  HANDLE KeyHandle;
1012  PBOOT_DRIVER_LIST_ENTRY BootEntry;
1013  DPRINT("IopInitializeBootDrivers()\n");
1014 
1015  /* Create the RAW FS built-in driver */
1016  RtlInitUnicodeString(&DriverName, L"\\FileSystem\\RAW");
1017 
1018  Status = IoCreateDriver(&DriverName, RawFsDriverEntry);
1019  if (!NT_SUCCESS(Status))
1020  {
1021  /* Fail */
1022  return;
1023  }
1024 
1025  /* Get highest group order index */
1027  if (IopGroupIndex == 0xFFFF) ASSERT(FALSE);
1028 
1029  /* Allocate the group table */
1031  IopGroupIndex * sizeof(LIST_ENTRY),
1032  TAG_IO);
1033  if (IopGroupTable == NULL) ASSERT(FALSE);
1034 
1035  /* Initialize the group table lists */
1036  for (i = 0; i < IopGroupIndex; i++) InitializeListHead(&IopGroupTable[i]);
1037 
1038  /* Loop the boot modules */
1039  ListHead = &KeLoaderBlock->LoadOrderListHead;
1040  for (NextEntry = ListHead->Flink;
1041  NextEntry != ListHead;
1042  NextEntry = NextEntry->Flink)
1043  {
1044  /* Get the entry */
1045  LdrEntry = CONTAINING_RECORD(NextEntry,
1047  InLoadOrderLinks);
1048 
1049  /* Check if the DLL needs to be initialized */
1050  if (LdrEntry->Flags & LDRP_DRIVER_DEPENDENT_DLL)
1051  {
1052  /* Call its entrypoint */
1053  MmCallDllInitialize(LdrEntry, NULL);
1054  }
1055  }
1056 
1057  /* Loop the boot drivers */
1058  ListHead = &KeLoaderBlock->BootDriverListHead;
1059  for (NextEntry = ListHead->Flink;
1060  NextEntry != ListHead;
1061  NextEntry = NextEntry->Flink)
1062  {
1063  /* Get the entry */
1064  BootEntry = CONTAINING_RECORD(NextEntry,
1066  Link);
1067 
1068  // FIXME: TODO: This LdrEntry is to be used in a special handling
1069  // for SETUPLDR (a similar procedure is done on Windows), where
1070  // the loader would, under certain conditions, be loaded in the
1071  // SETUPLDR-specific code block below...
1072 #if 0
1073  /* Get the driver loader entry */
1074  LdrEntry = BootEntry->LdrEntry;
1075 #endif
1076 
1077  /* Allocate our internal accounting structure */
1079  sizeof(DRIVER_INFORMATION),
1080  TAG_IO);
1081  if (DriverInfo)
1082  {
1083  /* Zero it and initialize it */
1086  DriverInfo->DataTableEntry = BootEntry;
1087 
1088  /* Open the registry key */
1090  NULL,
1091  &BootEntry->RegistryPath,
1092  KEY_READ);
1093  DPRINT("IopOpenRegistryKeyEx(%wZ) returned 0x%08lx\n", &BootEntry->RegistryPath, Status);
1094 #if 0
1095  if (NT_SUCCESS(Status))
1096 #else // Hack still needed...
1097  if ((NT_SUCCESS(Status)) || /* ReactOS HACK for SETUPLDR */
1098  ((KeLoaderBlock->SetupLdrBlock) && ((KeyHandle = (PVOID)1)))) // yes, it's an assignment!
1099 #endif
1100  {
1101  /* Save the handle */
1103 
1104  /* Get the group oder index */
1106 
1107  /* Get the tag position */
1109 
1110  /* Insert it into the list, at the right place */
1112  NextEntry2 = IopGroupTable[Index].Flink;
1113  while (NextEntry2 != &IopGroupTable[Index])
1114  {
1115  /* Get the driver info */
1116  DriverInfoTag = CONTAINING_RECORD(NextEntry2,
1118  Link);
1119 
1120  /* Check if we found the right tag position */
1121  if (DriverInfoTag->TagPosition > DriverInfo->TagPosition)
1122  {
1123  /* We're done */
1124  break;
1125  }
1126 
1127  /* Next entry */
1128  NextEntry2 = NextEntry2->Flink;
1129  }
1130 
1131  /* Insert us right before the next entry */
1132  NextEntry2 = NextEntry2->Blink;
1133  InsertHeadList(NextEntry2, &DriverInfo->Link);
1134  }
1135  }
1136  }
1137 
1138  /* Loop each group index */
1139  for (i = 0; i < IopGroupIndex; i++)
1140  {
1141  /* Loop each group table */
1142  for (NextEntry = IopGroupTable[i].Flink;
1143  NextEntry != &IopGroupTable[i];
1144  NextEntry = NextEntry->Flink)
1145  {
1146  /* Get the entry */
1147  DriverInfo = CONTAINING_RECORD(NextEntry,
1149  Link);
1150 
1151  /* Get the driver loader entry */
1152  LdrEntry = DriverInfo->DataTableEntry->LdrEntry;
1153 
1154  /* Initialize it */
1155  if (IopInitializeBuiltinDriver(LdrEntry))
1156  {
1157  // it does not make sense to enumerate the tree if there are no new devices added
1160  NULL,
1161  NULL);
1162  }
1163  }
1164  }
1165 
1166  /* HAL Root Bus is being initialized before loading the boot drivers so this may cause issues
1167  * when some devices are not being initialized with their drivers. This flag is used to delay
1168  * all actions with devices (except PnP root device) until boot drivers are loaded.
1169  * See PiQueueDeviceAction function
1170  */
1172 
1173  DbgPrint("BOOT DRIVERS LOADED\n");
1174 
1177  NULL,
1178  NULL);
1179 }
NTSTATUS NTAPI RawFsDriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
Definition: rawfs.c:1193
PDEVICE_OBJECT PhysicalDeviceObject
Definition: iotypes.h:850
PDEVICE_NODE IopRootDeviceNode
Definition: devnode.c:18
#define TAG_IO
Definition: tag.h:69
#define DbgPrint
Definition: hal.h:12
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:2620
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4711
#define KEY_READ
Definition: nt_native.h:1023
#define TRUE
Definition: types.h:120
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
LONG NTSTATUS
Definition: precomp.h:26
#define LDRP_DRIVER_DEPENDENT_DLL
Definition: ldrtypes.h:56
static int Link(const char **args)
Definition: vfdcmd.c:2414
USHORT NTAPI PpInitGetGroupOrderIndex(IN HANDLE ServiceHandle)
Definition: pnpinit.c:155
Definition: arc.h:198
static BOOLEAN IopInitializeBuiltinDriver(IN PLDR_DATA_TABLE_ENTRY BootLdrEntry)
Definition: driver.c:794
struct _SETUP_LOADER_BLOCK * SetupLdrBlock
Definition: arc.h:511
#define FALSE
Definition: types.h:117
NTSTATUS NTAPI MmCallDllInitialize(IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN PLIST_ENTRY ListHead)
Definition: sysldr.c:308
LIST_ENTRY Link
Definition: io.h:403
HANDLE ServiceHandle
Definition: io.h:406
NTSTATUS NTAPI IoCreateDriver(_In_opt_ PUNICODE_STRING DriverName, _In_ PDRIVER_INITIALIZE InitializationFunction)
Definition: driver.c:1550
USHORT TagPosition
Definition: io.h:407
PLOADER_PARAMETER_BLOCK KeLoaderBlock
Definition: krnlinit.c:29
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
Status
Definition: gdiplustypes.h:24
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_ WDFCOLLECTION _In_ ULONG Index
PLIST_ENTRY IopGroupTable
Definition: driver.c:43
LIST_ENTRY BootDriverListHead
Definition: arc.h:495
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
PBOOT_DRIVER_LIST_ENTRY DataTableEntry
Definition: io.h:405
static const WCHAR L[]
Definition: oid.c:1250
Definition: btrfs_drv.h:1922
Definition: typedefs.h:119
LIST_ENTRY LoadOrderListHead
Definition: arc.h:493
UNICODE_STRING RegistryPath
Definition: arc.h:202
DRIVER_INFORMATION DriverInfo
Definition: main.c:59
NTSTATUS NTAPI IopOpenRegistryKeyEx(PHANDLE KeyHandle, HANDLE ParentKey, PUNICODE_STRING Name, ACCESS_MASK DesiredAccess)
Definition: pnpmgr.c:1455
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
struct _LDR_DATA_TABLE_ENTRY * LdrEntry
Definition: arc.h:203
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define NULL
Definition: types.h:112
BOOLEAN PnPBootDriversLoaded
Definition: pnpinit.c:26
ULONG Flags
Definition: ntddk_ex.h:207
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define DPRINT
Definition: sndvol32.h:71
USHORT IopGroupIndex
Definition: driver.c:42
USHORT NTAPI PipGetDriverTagPriority(IN HANDLE ServiceHandle)
Definition: pnpinit.c:198

Referenced by IoInitSystem().

◆ IopInitializeBuiltinDriver()

static BOOLEAN IopInitializeBuiltinDriver ( IN PLDR_DATA_TABLE_ENTRY  BootLdrEntry)
static

Definition at line 794 of file driver.c.

795 {
798  PWCHAR Buffer, FileNameWithoutPath;
799  PWSTR FileExtension;
800  PUNICODE_STRING ModuleName = &BootLdrEntry->BaseDllName;
801  PLDR_DATA_TABLE_ENTRY LdrEntry;
802  PLIST_ENTRY NextEntry;
805 
806  /*
807  * Display 'Loading XXX...' message
808  */
811 
813  ModuleName->Length + sizeof(UNICODE_NULL),
814  TAG_IO);
815  if (Buffer == NULL)
816  {
817  return FALSE;
818  }
819 
821  Buffer[ModuleName->Length / sizeof(WCHAR)] = UNICODE_NULL;
822 
823  /*
824  * Generate filename without path (not needed by freeldr)
825  */
826  FileNameWithoutPath = wcsrchr(Buffer, L'\\');
827  if (FileNameWithoutPath == NULL)
828  {
829  FileNameWithoutPath = Buffer;
830  }
831  else
832  {
833  FileNameWithoutPath++;
834  }
835 
836  /*
837  * Strip the file extension from ServiceName
838  */
839  Success = RtlCreateUnicodeString(&ServiceName, FileNameWithoutPath);
841  if (!Success)
842  {
843  return FALSE;
844  }
845 
846  FileExtension = wcsrchr(ServiceName.Buffer, L'.');
847  if (FileExtension != NULL)
848  {
849  ServiceName.Length -= (USHORT)wcslen(FileExtension) * sizeof(WCHAR);
850  FileExtension[0] = UNICODE_NULL;
851  }
852 
854 
855  // Make the registry path for the driver
856  RegistryPath.Length = 0;
857  RegistryPath.MaximumLength = sizeof(ServicesKeyName) + ServiceName.Length;
859  if (RegistryPath.Buffer == NULL)
860  {
861  return FALSE;
862  }
866 
867  HANDLE serviceHandle;
868  Status = IopOpenRegistryKeyEx(&serviceHandle, NULL, &RegistryPath, KEY_READ);
870  if (!NT_SUCCESS(Status))
871  {
872  return FALSE;
873  }
874 
875  /* Lookup the new Ldr entry in PsLoadedModuleList */
876  for (NextEntry = PsLoadedModuleList.Flink;
877  NextEntry != &PsLoadedModuleList;
878  NextEntry = NextEntry->Flink)
879  {
880  LdrEntry = CONTAINING_RECORD(NextEntry,
882  InLoadOrderLinks);
884  {
885  break;
886  }
887  }
888  ASSERT(NextEntry != &PsLoadedModuleList);
889 
890  /*
891  * Initialize the driver
892  */
893  NTSTATUS driverEntryStatus;
895  serviceHandle,
896  &DriverObject,
897  &driverEntryStatus);
898 
899  if (!NT_SUCCESS(Status))
900  {
901  DPRINT1("Driver '%wZ' load failed, status (%x)\n", ModuleName, Status);
902  return FALSE;
903  }
904 
905  // The driver has been loaded, now check if where are any PDOs
906  // for that driver, and queue AddDevice call for them.
907  // The check is possible because HKLM/SYSTEM/CCS/Services/<ServiceName>/Enum directory
908  // is populated upon a new device arrival based on a (critical) device database
909 
910  // Legacy drivers may add devices inside DriverEntry.
911  // We're lazy and always assume that they are doing so
912  BOOLEAN deviceAdded = !!(DriverObject->Flags & DRVO_LEGACY_DRIVER);
913 
914  HANDLE enumServiceHandle;
915  UNICODE_STRING enumName = RTL_CONSTANT_STRING(L"Enum");
916 
917  Status = IopOpenRegistryKeyEx(&enumServiceHandle, serviceHandle, &enumName, KEY_READ);
918  ZwClose(serviceHandle);
919 
920  if (NT_SUCCESS(Status))
921  {
922  ULONG instanceCount = 0;
924  Status = IopGetRegistryValue(enumServiceHandle, L"Count", &kvInfo);
925  if (!NT_SUCCESS(Status))
926  {
927  goto Cleanup;
928  }
929  if (kvInfo->Type != REG_DWORD || kvInfo->DataLength != sizeof(ULONG))
930  {
931  ExFreePool(kvInfo);
932  goto Cleanup;
933  }
934 
935  RtlMoveMemory(&instanceCount,
936  (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
937  sizeof(ULONG));
938  ExFreePool(kvInfo);
939 
940  DPRINT("Processing %u instances for %wZ module\n", instanceCount, ModuleName);
941 
942  for (ULONG i = 0; i < instanceCount; i++)
943  {
944  WCHAR num[11];
945  UNICODE_STRING instancePath;
946  RtlStringCchPrintfW(num, sizeof(num), L"%u", i);
947 
948  Status = IopGetRegistryValue(enumServiceHandle, num, &kvInfo);
949  if (!NT_SUCCESS(Status))
950  {
951  continue;
952  }
953  if (kvInfo->Type != REG_SZ || kvInfo->DataLength == 0)
954  {
955  ExFreePool(kvInfo);
956  continue;
957  }
958 
959  instancePath.Length = kvInfo->DataLength - sizeof(UNICODE_NULL);
960  instancePath.MaximumLength = kvInfo->DataLength;
962  instancePath.MaximumLength,
963  TAG_IO);
964  if (instancePath.Buffer)
965  {
966  RtlMoveMemory(instancePath.Buffer,
967  (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
968  instancePath.Length);
969  instancePath.Buffer[instancePath.Length / sizeof(WCHAR)] = UNICODE_NULL;
970 
973  ObDereferenceObject(pdo);
974  deviceAdded = TRUE;
975  }
976 
977  ExFreePool(kvInfo);
978  }
979 
980  ZwClose(enumServiceHandle);
981  }
982 Cleanup:
983  /* Remove extra reference from IopInitializeDriverModule */
985 
986  return deviceAdded;
987 }
#define DRVO_LEGACY_DRIVER
Definition: iotypes.h:2226
VOID NTAPI InbvIndicateProgress(VOID)
Definition: inbv.c:884
#define TAG_IO
Definition: tag.h:69
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:2620
USHORT MaximumLength
Definition: env_spec_w32.h:370
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
#define KEY_READ
Definition: nt_native.h:1023
#define TRUE
Definition: types.h:120
VOID FASTCALL IopDisplayLoadingMessage(PUNICODE_STRING ServiceName)
Definition: driver.c:317
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
uint16_t * PWSTR
Definition: typedefs.h:56
NTSTRSAFEVAPI RtlStringCchPrintfW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1110
ACPI_SIZE Length
Definition: actypes.h:1044
LONG NTSTATUS
Definition: precomp.h:26
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:213
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:1274
uint16_t * PWCHAR
Definition: typedefs.h:56
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
PDEVICE_OBJECT IopGetDeviceObjectFromDeviceInstance(PUNICODE_STRING DeviceInstance)
Definition: plugplay.c:122
unsigned char BOOLEAN
Definition: bufpool.h:45
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
Status
Definition: gdiplustypes.h:24
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
LPTSTR ServiceName
Definition: ServiceMain.c:15
#define ASSERT(a)
Definition: mode.c:44
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:34
#define ObDereferenceObject
Definition: obfuncs.h:203
GLuint GLuint num
Definition: glext.h:9618
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
static const WCHAR L[]
Definition: oid.c:1250
Definition: btrfs_drv.h:1922
Definition: typedefs.h:119
#define wcsrchr
Definition: compat.h:16
static const WCHAR Cleanup[]
Definition: register.c:80
NTSTATUS NTAPI IopGetRegistryValue(IN HANDLE Handle, IN PWSTR ValueName, OUT PKEY_VALUE_FULL_INFORMATION *Information)
Definition: pnpmgr.c:1606
NTSTATUS NTAPI IopOpenRegistryKeyEx(PHANDLE KeyHandle, HANDLE ParentKey, PUNICODE_STRING Name, ACCESS_MASK DesiredAccess)
Definition: pnpmgr.c:1455
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
unsigned short USHORT
Definition: pedump.c:61
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
#define NULL
Definition: types.h:112
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define DPRINT1
Definition: precomp.h:8
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:430
unsigned int ULONG
Definition: retypes.h:1
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
static const WCHAR ServicesKeyName[]
Definition: driver.c:31
#define DPRINT
Definition: sndvol32.h:71
#define REG_DWORD
Definition: sdbapi.c:596
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
#define REG_SZ
Definition: layer.c:22

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

435 {
438 
439  PAGED_CODE();
440 
441  Status = IopGetDriverNames(ServiceHandle, &DriverName, &ServiceName);
442  if (!NT_SUCCESS(Status))
443  {
444  MmUnloadSystemImage(ModuleObject);
445  return Status;
446  }
447 
448  DPRINT("Driver name: '%wZ'\n", &DriverName);
449 
450  /*
451  * Retrieve the driver's PE image NT header and perform some sanity checks.
452  * NOTE: We suppose that since the driver has been successfully loaded,
453  * its NT and optional headers are all valid and have expected sizes.
454  */
455  PIMAGE_NT_HEADERS NtHeaders = RtlImageNtHeader(ModuleObject->DllBase);
456  ASSERT(NtHeaders);
457  // NOTE: ModuleObject->SizeOfImage is actually (number of PTEs)*PAGE_SIZE.
458  ASSERT(ModuleObject->SizeOfImage == ROUND_TO_PAGES(NtHeaders->OptionalHeader.SizeOfImage));
459  ASSERT(ModuleObject->EntryPoint == RVA(ModuleObject->DllBase, NtHeaders->OptionalHeader.AddressOfEntryPoint));
460 
461  /* Obtain the registry path for the DriverInit routine */
462  PKEY_NAME_INFORMATION nameInfo;
463  ULONG infoLength;
464  Status = ZwQueryKey(ServiceHandle, KeyNameInformation, NULL, 0, &infoLength);
466  {
467  nameInfo = ExAllocatePoolWithTag(NonPagedPool, infoLength, TAG_IO);
468  if (nameInfo)
469  {
470  Status = ZwQueryKey(ServiceHandle,
472  nameInfo,
473  infoLength,
474  &infoLength);
475  if (NT_SUCCESS(Status))
476  {
477  RegistryPath.Length = nameInfo->NameLength;
478  RegistryPath.MaximumLength = nameInfo->NameLength;
479  RegistryPath.Buffer = nameInfo->Name;
480  }
481  else
482  {
483  ExFreePoolWithTag(nameInfo, TAG_IO);
484  }
485  }
486  else
487  {
489  }
490  }
491  else
492  {
494  }
495 
496  if (!NT_SUCCESS(Status))
497  {
499  RtlFreeUnicodeString(&DriverName);
500  MmUnloadSystemImage(ModuleObject);
501  return Status;
502  }
503 
504  /* Create the driver object */
505  ULONG ObjectSize = sizeof(DRIVER_OBJECT) + sizeof(EXTENDED_DRIVER_EXTENSION);
506  OBJECT_ATTRIBUTES objAttrs;
507  PDRIVER_OBJECT driverObject;
508  InitializeObjectAttributes(&objAttrs,
509  &DriverName,
511  NULL,
512  NULL);
513 
516  &objAttrs,
517  KernelMode,
518  NULL,
519  ObjectSize,
520  0,
521  0,
522  (PVOID*)&driverObject);
523  if (!NT_SUCCESS(Status))
524  {
525  ExFreePoolWithTag(nameInfo, TAG_IO); // container for RegistryPath
527  RtlFreeUnicodeString(&DriverName);
528  MmUnloadSystemImage(ModuleObject);
529  DPRINT1("Error while creating driver object \"%wZ\" status %x\n", &DriverName, Status);
530  return Status;
531  }
532 
533  DPRINT("Created driver object 0x%p for \"%wZ\"\n", driverObject, &DriverName);
534 
535  RtlZeroMemory(driverObject, ObjectSize);
536  driverObject->Type = IO_TYPE_DRIVER;
537  driverObject->Size = sizeof(DRIVER_OBJECT);
538 
539  /* Set the legacy flag if this is not a WDM driver */
541  driverObject->Flags |= DRVO_LEGACY_DRIVER;
542 
543  driverObject->DriverSection = ModuleObject;
544  driverObject->DriverStart = ModuleObject->DllBase;
545  driverObject->DriverSize = ModuleObject->SizeOfImage;
546  driverObject->DriverInit = ModuleObject->EntryPoint;
547  driverObject->HardwareDatabase = &IopHardwareDatabaseKey;
548  driverObject->DriverExtension = (PDRIVER_EXTENSION)(driverObject + 1);
549  driverObject->DriverExtension->DriverObject = driverObject;
550 
551  /* Loop all Major Functions */
552  for (INT i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
553  {
554  /* Invalidate each function */
555  driverObject->MajorFunction[i] = IopInvalidDeviceRequest;
556  }
557 
558  /* Add the Object and get its handle */
559  HANDLE hDriver;
560  Status = ObInsertObject(driverObject, NULL, FILE_READ_DATA, 0, NULL, &hDriver);
561  if (!NT_SUCCESS(Status))
562  {
563  ExFreePoolWithTag(nameInfo, TAG_IO);
565  RtlFreeUnicodeString(&DriverName);
566  return Status;
567  }
568 
569  /* Now reference it */
571  0,
573  KernelMode,
574  (PVOID*)&driverObject,
575  NULL);
576 
577  /* Close the extra handle */
578  ZwClose(hDriver);
579 
580  if (!NT_SUCCESS(Status))
581  {
582  ExFreePoolWithTag(nameInfo, TAG_IO); // container for RegistryPath
584  RtlFreeUnicodeString(&DriverName);
585  return Status;
586  }
587 
588  /* Set up the service key name buffer */
589  UNICODE_STRING serviceKeyName;
590  serviceKeyName.Length = 0;
591  // NULL-terminate for Windows compatibility
592  serviceKeyName.MaximumLength = ServiceName.MaximumLength + sizeof(UNICODE_NULL);
593  serviceKeyName.Buffer = ExAllocatePoolWithTag(NonPagedPool,
594  serviceKeyName.MaximumLength,
595  TAG_IO);
596  if (!serviceKeyName.Buffer)
597  {
598  ObMakeTemporaryObject(driverObject);
599  ObDereferenceObject(driverObject);
600  ExFreePoolWithTag(nameInfo, TAG_IO); // container for RegistryPath
602  RtlFreeUnicodeString(&DriverName);
604  }
605 
606  /* Copy the name and set it in the driver extension */
607  RtlCopyUnicodeString(&serviceKeyName, &ServiceName);
609  driverObject->DriverExtension->ServiceKeyName = serviceKeyName;
610 
611  /* Make a copy of the driver name to store in the driver object */
612  UNICODE_STRING driverNamePaged;
613  driverNamePaged.Length = 0;
614  // NULL-terminate for Windows compatibility
615  driverNamePaged.MaximumLength = DriverName.MaximumLength + sizeof(UNICODE_NULL);
616  driverNamePaged.Buffer = ExAllocatePoolWithTag(PagedPool,
617  driverNamePaged.MaximumLength,
618  TAG_IO);
619  if (!driverNamePaged.Buffer)
620  {
621  ObMakeTemporaryObject(driverObject);
622  ObDereferenceObject(driverObject);
623  ExFreePoolWithTag(nameInfo, TAG_IO); // container for RegistryPath
624  RtlFreeUnicodeString(&DriverName);
626  }
627 
628  RtlCopyUnicodeString(&driverNamePaged, &DriverName);
629  driverObject->DriverName = driverNamePaged;
630 
631  /* Finally, call its init function */
632  Status = driverObject->DriverInit(driverObject, &RegistryPath);
633  *DriverEntryStatus = Status;
634  if (!NT_SUCCESS(Status))
635  {
636  DPRINT1("'%wZ' initialization failed, status (0x%08lx)\n", &DriverName, Status);
637  // return a special status value in case of failure
639  }
640 
641  /* HACK: We're going to say if we don't have any DOs from DriverEntry, then we're not legacy.
642  * Other parts of the I/O manager depend on this behavior */
643  if (!driverObject->DeviceObject)
644  {
645  driverObject->Flags &= ~DRVO_LEGACY_DRIVER;
646  }
647 
648  // Windows does this fixup - keep it for compatibility
649  for (INT i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
650  {
651  /*
652  * Make sure the driver didn't set any dispatch entry point to NULL!
653  * Doing so is illegal; drivers shouldn't touch entry points they
654  * do not implement.
655  */
656 
657  /* Check if it did so anyway */
658  if (!driverObject->MajorFunction[i])
659  {
660  /* Print a warning in the debug log */
661  DPRINT1("Driver <%wZ> set DriverObject->MajorFunction[%lu] to NULL!\n",
662  &driverObject->DriverName, i);
663 
664  /* Fix it up */
665  driverObject->MajorFunction[i] = IopInvalidDeviceRequest;
666  }
667  }
668 
669  // TODO: for legacy drivers, unload the driver if it didn't create any DO
670 
671  ExFreePoolWithTag(nameInfo, TAG_IO); // container for RegistryPath
672  RtlFreeUnicodeString(&DriverName);
673 
674  if (!NT_SUCCESS(Status))
675  {
676  // if the driver entry has been failed, clear the object
677  ObMakeTemporaryObject(driverObject);
678  ObDereferenceObject(driverObject);
679  return Status;
680  }
681 
682  *OutDriverObject = driverObject;
683 
685 
686  /* Set the driver as initialized */
687  IopReadyDeviceObjects(driverObject);
688 
690 
691  return STATUS_SUCCESS;
692 }
#define DRVO_LEGACY_DRIVER
Definition: iotypes.h:2226
VOID NTAPI MmFreeDriverInitialization(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:1635
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define TAG_IO
Definition: tag.h:69
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
VOID NTAPI IopReinitializeDrivers(VOID)
Definition: driver.c:1470
USHORT MaximumLength
Definition: env_spec_w32.h:370
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define IRP_MJ_MAXIMUM_FUNCTION
LONG NTSTATUS
Definition: precomp.h:26
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:213
#define STATUS_FAILED_DRIVER_ENTRY
Definition: ntstatus.h:911
PVOID DriverStart
Definition: iotypes.h:2279
_In_ LPWSTR _In_ ULONG _In_ ULONG _In_ ULONG _Out_ DEVINFO _In_ HDEV _In_ LPWSTR _In_ HANDLE hDriver
Definition: winddi.h:3553
POBJECT_TYPE IoDriverObjectType
Definition: driver.c:33
BOOLEAN PnpSystemInit
Definition: iomgr.c:17
NTSTATUS IopGetDriverNames(_In_ HANDLE ServiceHandle, _Out_ PUNICODE_STRING DriverName, _Out_opt_ PUNICODE_STRING ServiceName)
Definition: driver.c:125
NTSTATUS NTAPI IopInvalidDeviceRequest(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: driver.c:67
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
int32_t INT
Definition: typedefs.h:58
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
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
#define UNICODE_NULL
struct _DRIVER_OBJECT * DriverObject
Definition: iotypes.h:2219
#define FILE_READ_DATA
Definition: nt_native.h:628
PDRIVER_EXTENSION DriverExtension
Definition: iotypes.h:2282
PUNICODE_STRING HardwareDatabase
Definition: iotypes.h:2284
CSHORT Size
Definition: iotypes.h:2276
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:952
NTSTATUS NTAPI MmUnloadSystemImage(IN PVOID ImageHandle)
Definition: sysldr.c:911
Status
Definition: gdiplustypes.h:24
LPTSTR ServiceName
Definition: ServiceMain.c:15
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ObDereferenceObject
Definition: obfuncs.h:203
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
VOID NTAPI IopReadyDeviceObjects(IN PDRIVER_OBJECT Driver)
Definition: device.c:34
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define OBJ_PERMANENT
Definition: winternl.h:226
Definition: btrfs_drv.h:1922
struct _DRIVER_OBJECT DRIVER_OBJECT
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
UNICODE_STRING ServiceKeyName
Definition: iotypes.h:2222
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:2931
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 ROUND_TO_PAGES(Size)
UNICODE_STRING IopHardwareDatabaseKey
Definition: driver.c:29
#define IMAGE_DLLCHARACTERISTICS_WDM_DRIVER
Definition: ntimage.h:462
#define NULL
Definition: types.h:112
#define IO_TYPE_DRIVER
#define DPRINT1
Definition: precomp.h:8
#define RtlImageNtHeader
Definition: compat.h:665
DWORD RVA
Definition: compat.h:1121
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION+1]
Definition: iotypes.h:2289
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define STATUS_SUCCESS
Definition: shellext.h:65
ULONG DriverSize
Definition: iotypes.h:2280
#define DPRINT
Definition: sndvol32.h:71
CSHORT Type
Definition: iotypes.h:2275
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
PVOID DriverSection
Definition: iotypes.h:2281
PDRIVER_INITIALIZE DriverInit
Definition: iotypes.h:2286
UNICODE_STRING DriverName
Definition: iotypes.h:2283
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2277
#define PAGED_CODE()
VOID NTAPI ObMakeTemporaryObject(IN PVOID ObjectBody)
Definition: oblife.c:1361

Referenced by IopInitializeBuiltinDriver(), and IopLoadDriver().

◆ IopInitializeSystemDrivers()

VOID FASTCALL IopInitializeSystemDrivers ( VOID  )

Definition at line 1184 of file driver.c.

1185 {
1186  PUNICODE_STRING *DriverList, *SavedList;
1187 
1189 
1190  /* No system drivers on the boot cd */
1191  if (KeLoaderBlock->SetupLdrBlock) return; // ExpInTextModeSetup
1192 
1193  /* Get the driver list */
1194  SavedList = DriverList = CmGetSystemDriverList();
1195  ASSERT(DriverList);
1196 
1197  /* Loop it */
1198  while (*DriverList)
1199  {
1200  /* Load the driver */
1201  ZwLoadDriver(*DriverList);
1202 
1203  /* Free the entry */
1204  RtlFreeUnicodeString(*DriverList);
1205  ExFreePool(*DriverList);
1206 
1207  /* Next entry */
1209  DriverList++;
1210  }
1211 
1212  /* Free the list */
1213  ExFreePool(SavedList);
1214 
1217  NULL,
1218  NULL);
1219 }
PDEVICE_OBJECT PhysicalDeviceObject
Definition: iotypes.h:850
VOID NTAPI InbvIndicateProgress(VOID)
Definition: inbv.c:884
PDEVICE_NODE IopRootDeviceNode
Definition: devnode.c:18
PUNICODE_STRING *NTAPI CmGetSystemDriverList(VOID)
Definition: cmsysini.c:1776
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:2620
struct _SETUP_LOADER_BLOCK * SetupLdrBlock
Definition: arc.h:511
PLOADER_PARAMETER_BLOCK KeLoaderBlock
Definition: krnlinit.c:29
#define ASSERT(a)
Definition: mode.c:44
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
NTSTATUS PiPerformSyncDeviceAction(_In_ PDEVICE_OBJECT DeviceObject, _In_ DEVICE_ACTION Action)
Perfom a device operation synchronously via PiQueueDeviceAction.
Definition: devaction.c:2679
#define NULL
Definition: types.h:112
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

Referenced by IoInitSystem().

◆ IopInvalidDeviceRequest()

NTSTATUS NTAPI IopInvalidDeviceRequest ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 67 of file driver.c.

70 {
71  Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
72  Irp->IoStatus.Information = 0;
75 }
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
_In_ PIRP Irp
Definition: csq.h:116
#define IoCompleteRequest
Definition: irp.c:1240
#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 1911 of file driver.c.

1914 {
1915  UNICODE_STRING ImagePath;
1916  NTSTATUS Status;
1917  PLDR_DATA_TABLE_ENTRY ModuleObject;
1919 
1921  Status = IopGetRegistryValue(ServiceHandle, L"ImagePath", &kvInfo);
1922  if (NT_SUCCESS(Status))
1923  {
1924  if (kvInfo->Type != REG_EXPAND_SZ || kvInfo->DataLength == 0)
1925  {
1926  ExFreePool(kvInfo);
1928  }
1929 
1930  ImagePath.Length = kvInfo->DataLength - sizeof(UNICODE_NULL);
1931  ImagePath.MaximumLength = kvInfo->DataLength;
1933  if (!ImagePath.Buffer)
1934  {
1935  ExFreePool(kvInfo);
1937  }
1938 
1939  RtlMoveMemory(ImagePath.Buffer,
1940  (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
1941  ImagePath.Length);
1942  ImagePath.Buffer[ImagePath.Length / sizeof(WCHAR)] = UNICODE_NULL;
1943  ExFreePool(kvInfo);
1944  }
1945  else
1946  {
1947  return Status;
1948  }
1949 
1950  /*
1951  * Normalize the image path for all later processing.
1952  */
1953  Status = IopNormalizeImagePath(&ImagePath, NULL);
1954  if (!NT_SUCCESS(Status))
1955  {
1956  DPRINT("IopNormalizeImagePath() failed (Status %x)\n", Status);
1957  return Status;
1958  }
1959 
1960  DPRINT("FullImagePath: '%wZ'\n", &ImagePath);
1961 
1964 
1965  /*
1966  * Load the driver module
1967  */
1968  DPRINT("Loading module from %wZ\n", &ImagePath);
1969  Status = MmLoadSystemImage(&ImagePath, NULL, NULL, 0, (PVOID)&ModuleObject, &BaseAddress);
1970  RtlFreeUnicodeString(&ImagePath);
1971 
1972  if (!NT_SUCCESS(Status))
1973  {
1974  DPRINT("MmLoadSystemImage() failed (Status %lx)\n", Status);
1977  return Status;
1978  }
1979 
1980  // Display the loading message
1981  ULONG infoLength;
1982  Status = ZwQueryKey(ServiceHandle, KeyBasicInformation, NULL, 0, &infoLength);
1984  {
1986  if (servName)
1987  {
1988  Status = ZwQueryKey(ServiceHandle,
1990  servName,
1991  infoLength,
1992  &infoLength);
1993  if (NT_SUCCESS(Status))
1994  {
1996  .Length = servName->NameLength,
1997  .MaximumLength = servName->NameLength,
1998  .Buffer = servName->Name
1999  };
2000 
2002  }
2003  ExFreePoolWithTag(servName, TAG_IO);
2004  }
2005  }
2006 
2007  NTSTATUS driverEntryStatus;
2008  Status = IopInitializeDriverModule(ModuleObject,
2009  ServiceHandle,
2010  DriverObject,
2011  &driverEntryStatus);
2012  if (!NT_SUCCESS(Status))
2013  {
2014  DPRINT1("IopInitializeDriverModule() failed (Status %lx)\n", Status);
2015  }
2016 
2019 
2020  return Status;
2021 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define TAG_IO
Definition: tag.h:69
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define TAG_RTLREGISTRY
Definition: driver.c:35
#define TRUE
Definition: types.h:120
VOID FASTCALL IopDisplayLoadingMessage(PUNICODE_STRING ServiceName)
Definition: driver.c:317
LONG NTSTATUS
Definition: precomp.h:26
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
uint32_t ULONG_PTR
Definition: typedefs.h:65
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
#define UNICODE_NULL
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:356
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
#define STATUS_ILL_FORMED_SERVICE_ENTRY
Definition: ntstatus.h:588
Status
Definition: gdiplustypes.h:24
char serviceName[]
Definition: tftpd.cpp:34
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
static const WCHAR L[]
Definition: oid.c:1250
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
Definition: btrfs_drv.h:1922
NTSTATUS NTAPI IopGetRegistryValue(IN HANDLE Handle, IN PWSTR ValueName, OUT PKEY_VALUE_FULL_INFORMATION *Information)
Definition: pnpmgr.c:1606
ERESOURCE IopDriverLoadResource
Definition: driver.c:19
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
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:430
unsigned int ULONG
Definition: retypes.h:1
#define DPRINT
Definition: sndvol32.h:71
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
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:2898

Referenced by IopLoadUnloadDriverWorker(), and PiAttachFilterDriversCallback().

◆ IopLoadUnloadDriverWorker()

static VOID NTAPI IopLoadUnloadDriverWorker ( _Inout_ PVOID  Parameter)
static

Definition at line 2026 of file driver.c.

2028 {
2029  PLOAD_UNLOAD_PARAMS LoadParams = Parameter;
2030 
2032 
2033  if (LoadParams->DriverObject)
2034  {
2035  // unload request
2036  LoadParams->DriverObject->DriverUnload(LoadParams->DriverObject);
2037  LoadParams->Status = STATUS_SUCCESS;
2038  }
2039  else
2040  {
2041  // load request
2042  HANDLE serviceHandle;
2043  NTSTATUS status;
2044  status = IopOpenRegistryKeyEx(&serviceHandle, NULL, LoadParams->RegistryPath, KEY_READ);
2045  if (!NT_SUCCESS(status))
2046  {
2047  LoadParams->Status = status;
2048  }
2049  else
2050  {
2051  LoadParams->Status = IopLoadDriver(serviceHandle, &LoadParams->DriverObject);
2052  ZwClose(serviceHandle);
2053  }
2054  }
2055 
2056  if (LoadParams->SetEvent)
2057  {
2058  KeSetEvent(&LoadParams->Event, 0, FALSE);
2059  }
2060 }
#define KEY_READ
Definition: nt_native.h:1023
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS IopLoadDriver(_In_ HANDLE ServiceHandle, _Out_ PDRIVER_OBJECT *DriverObject)
Definition: driver.c:1911
_In_ PVOID Parameter
Definition: ldrtypes.h:241
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
#define FALSE
Definition: types.h:117
PEPROCESS PsInitialSystemProcess
Definition: psmgr.c:50
#define PsGetCurrentProcess
Definition: psfuncs.h:17
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS Status
Definition: driver.c:50
PDRIVER_UNLOAD DriverUnload
Definition: iotypes.h:2288
BOOLEAN SetEvent
Definition: driver.c:55
PDRIVER_OBJECT DriverObject
Definition: driver.c:54
PUNICODE_STRING RegistryPath
Definition: driver.c:51
NTSTATUS NTAPI IopOpenRegistryKeyEx(PHANDLE KeyHandle, HANDLE ParentKey, PUNICODE_STRING Name, ACCESS_MASK DesiredAccess)
Definition: pnpmgr.c:1455
#define NULL
Definition: types.h:112
#define STATUS_SUCCESS
Definition: shellext.h:65
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

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

360 {
361  UNICODE_STRING SystemRootString = RTL_CONSTANT_STRING(L"\\SystemRoot\\");
362  UNICODE_STRING DriversPathString = RTL_CONSTANT_STRING(L"\\SystemRoot\\System32\\drivers\\");
363  UNICODE_STRING DotSysString = RTL_CONSTANT_STRING(L".sys");
364  UNICODE_STRING InputImagePath;
365 
366  DPRINT("Normalizing image path '%wZ' for service '%wZ'\n", ImagePath, ServiceName);
367 
368  InputImagePath = *ImagePath;
369  if (InputImagePath.Length == 0)
370  {
371  ImagePath->Length = 0;
372  ImagePath->MaximumLength = DriversPathString.Length +
373  ServiceName->Length +
374  DotSysString.Length +
375  sizeof(UNICODE_NULL);
376  ImagePath->Buffer = ExAllocatePoolWithTag(NonPagedPool,
377  ImagePath->MaximumLength,
378  TAG_IO);
379  if (ImagePath->Buffer == NULL)
380  return STATUS_NO_MEMORY;
381 
382  RtlCopyUnicodeString(ImagePath, &DriversPathString);
384  RtlAppendUnicodeStringToString(ImagePath, &DotSysString);
385  }
386  else if (InputImagePath.Buffer[0] != L'\\')
387  {
388  ImagePath->Length = 0;
389  ImagePath->MaximumLength = SystemRootString.Length +
390  InputImagePath.Length +
391  sizeof(UNICODE_NULL);
392  ImagePath->Buffer = ExAllocatePoolWithTag(NonPagedPool,
393  ImagePath->MaximumLength,
394  TAG_IO);
395  if (ImagePath->Buffer == NULL)
396  return STATUS_NO_MEMORY;
397 
398  RtlCopyUnicodeString(ImagePath, &SystemRootString);
399  RtlAppendUnicodeStringToString(ImagePath, &InputImagePath);
400 
401  /* Free caller's string */
402  ExFreePoolWithTag(InputImagePath.Buffer, TAG_RTLREGISTRY);
403  }
404 
405  DPRINT("Normalized image path is '%wZ' for service '%wZ'\n", ImagePath, ServiceName);
406 
407  return STATUS_SUCCESS;
408 }
#define TAG_IO
Definition: tag.h:69
#define TAG_RTLREGISTRY
Definition: driver.c:35
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define UNICODE_NULL
LPTSTR ServiceName
Definition: ServiceMain.c:15
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
static const WCHAR L[]
Definition: oid.c:1250
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define NULL
Definition: types.h:112
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14

Referenced by IopLoadDriver(), and IopUnloadDriver().

◆ IopReinitializeBootDrivers()

VOID NTAPI IopReinitializeBootDrivers ( VOID  )

Definition at line 1506 of file driver.c.

1507 {
1508  PDRIVER_REINIT_ITEM ReinitItem;
1510 
1511  /* Get the first entry and start looping */
1514  while (Entry)
1515  {
1516  /* Get the item */
1517  ReinitItem = CONTAINING_RECORD(Entry, DRIVER_REINIT_ITEM, ItemEntry);
1518 
1519  /* Increment reinitialization counter */
1520  ReinitItem->DriverObject->DriverExtension->Count++;
1521 
1522  /* Remove the device object flag */
1524 
1525  /* Call the routine */
1526  ReinitItem->ReinitRoutine(ReinitItem->DriverObject,
1527  ReinitItem->Context,
1528  ReinitItem->DriverObject->
1529  DriverExtension->Count);
1530 
1531  /* Free the entry */
1532  ExFreePool(Entry);
1533 
1534  /* Move to the next one */
1537  }
1538 
1539  /* Wait for all device actions being finished*/
1541 }
struct _Entry Entry
Definition: kefuncs.h:627
PVOID Context
Definition: io.h:463
LIST_ENTRY DriverBootReinitListHead
Definition: driver.c:26
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
PLIST_ENTRY NTAPI ExInterlockedRemoveHeadList(IN OUT PLIST_ENTRY ListHead, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:166
KSPIN_LOCK DriverBootReinitListLock
Definition: driver.c:27
#define FALSE
Definition: types.h:117
PDRIVER_EXTENSION DriverExtension
Definition: iotypes.h:2282
PDRIVER_OBJECT DriverObject
Definition: io.h:461
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
KEVENT PiEnumerationFinished
Definition: devaction.c:50
Definition: typedefs.h:119
#define NULL
Definition: types.h:112
PPCI_DRIVER_EXTENSION DriverExtension
Definition: pci.c:31
PDRIVER_REINITIALIZE ReinitRoutine
Definition: io.h:462
base of all file and directory entries
Definition: entries.h:82
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define DRVO_BOOTREINIT_REGISTERED
Definition: iotypes.h:4471

Referenced by IoInitSystem().

◆ IopReinitializeDrivers()

VOID NTAPI IopReinitializeDrivers ( VOID  )

Definition at line 1470 of file driver.c.

1471 {
1472  PDRIVER_REINIT_ITEM ReinitItem;
1474 
1475  /* Get the first entry and start looping */
1478  while (Entry)
1479  {
1480  /* Get the item */
1481  ReinitItem = CONTAINING_RECORD(Entry, DRIVER_REINIT_ITEM, ItemEntry);
1482 
1483  /* Increment reinitialization counter */
1484  ReinitItem->DriverObject->DriverExtension->Count++;
1485 
1486  /* Remove the device object flag */
1487  ReinitItem->DriverObject->Flags &= ~DRVO_REINIT_REGISTERED;
1488 
1489  /* Call the routine */
1490  ReinitItem->ReinitRoutine(ReinitItem->DriverObject,
1491  ReinitItem->Context,
1492  ReinitItem->DriverObject->
1493  DriverExtension->Count);
1494 
1495  /* Free the entry */
1496  ExFreePool(Entry);
1497 
1498  /* Move to the next one */
1501  }
1502 }
struct _Entry Entry
Definition: kefuncs.h:627
PVOID Context
Definition: io.h:463
#define DRVO_REINIT_REGISTERED
Definition: iotypes.h:4469
PLIST_ENTRY NTAPI ExInterlockedRemoveHeadList(IN OUT PLIST_ENTRY ListHead, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:166
KSPIN_LOCK DriverReinitListLock
Definition: driver.c:22
PDRIVER_EXTENSION DriverExtension
Definition: iotypes.h:2282
LIST_ENTRY DriverReinitListHead
Definition: driver.c:21
PDRIVER_OBJECT DriverObject
Definition: io.h:461
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
Definition: typedefs.h:119
PPCI_DRIVER_EXTENSION DriverExtension
Definition: pci.c:31
PDRIVER_REINITIALIZE ReinitRoutine
Definition: io.h:462
base of all file and directory entries
Definition: entries.h:82
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

Referenced by IoInitSystem(), and IopInitializeDriverModule().

◆ IopSuffixUnicodeString()

BOOLEAN NTAPI IopSuffixUnicodeString ( IN PCUNICODE_STRING  String1,
IN PCUNICODE_STRING  String2 
)

Definition at line 283 of file driver.c.

286 {
287  PWCHAR pc1;
288  PWCHAR pc2;
289  ULONG Length;
290 
291  if (String2->Length < String1->Length)
292  return FALSE;
293 
294  Length = String1->Length / 2;
295  pc1 = String1->Buffer;
296  pc2 = &String2->Buffer[String2->Length / sizeof(WCHAR) - Length];
297 
298  if (pc1 && pc2)
299  {
300  while (Length--)
301  {
302  if( *pc1++ != *pc2++ )
303  return FALSE;
304  }
305  return TRUE;
306  }
307  return FALSE;
308 }
static const unsigned char pc2[48]
Definition: des.c:68
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
static const unsigned char pc1[56]
Definition: des.c:54
#define TRUE
Definition: types.h:120
uint16_t * PWCHAR
Definition: typedefs.h:56
#define FALSE
Definition: types.h:117
__wchar_t WCHAR
Definition: xmlstorage.h:180
_In_ const STRING * String2
Definition: rtlfuncs.h:2304
unsigned int ULONG
Definition: retypes.h:1

Referenced by IopDisplayLoadingMessage().

◆ IopUnloadDriver()

NTSTATUS NTAPI IopUnloadDriver ( PUNICODE_STRING  DriverServiceName,
BOOLEAN  UnloadPnpDrivers 
)

Definition at line 1243 of file driver.c.

1244 {
1245  UNICODE_STRING Backslash = RTL_CONSTANT_STRING(L"\\");
1247  UNICODE_STRING ImagePath;
1252  PEXTENDED_DEVOBJ_EXTENSION DeviceExtension;
1253  NTSTATUS Status;
1254  USHORT LastBackslash;
1255  BOOLEAN SafeToUnload = TRUE;
1257  UNICODE_STRING CapturedServiceName;
1258 
1259  PAGED_CODE();
1260 
1262 
1263  /* Need the appropriate priviliege */
1265  {
1266  DPRINT1("No unload privilege!\n");
1268  }
1269 
1270  /* Capture the service name */
1271  Status = ProbeAndCaptureUnicodeString(&CapturedServiceName,
1272  PreviousMode,
1273  DriverServiceName);
1274  if (!NT_SUCCESS(Status))
1275  {
1276  return Status;
1277  }
1278 
1279  DPRINT("IopUnloadDriver('%wZ', %u)\n", &CapturedServiceName, UnloadPnpDrivers);
1280 
1281  /* We need a service name */
1282  if (CapturedServiceName.Length == 0 || CapturedServiceName.Buffer == NULL)
1283  {
1284  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1285  return STATUS_INVALID_PARAMETER;
1286  }
1287 
1288  /*
1289  * Get the service name from the registry key name
1290  */
1292  &CapturedServiceName,
1293  &Backslash,
1294  &LastBackslash);
1295  if (NT_SUCCESS(Status))
1296  {
1297  NT_ASSERT(CapturedServiceName.Length >= LastBackslash + sizeof(WCHAR));
1298  ServiceName.Buffer = &CapturedServiceName.Buffer[LastBackslash / sizeof(WCHAR) + 1];
1299  ServiceName.Length = CapturedServiceName.Length - LastBackslash - sizeof(WCHAR);
1300  ServiceName.MaximumLength = CapturedServiceName.MaximumLength - LastBackslash - sizeof(WCHAR);
1301  }
1302  else
1303  {
1304  ServiceName = CapturedServiceName;
1305  }
1306 
1307  /*
1308  * Construct the driver object name
1309  */
1310  Status = RtlUShortAdd(sizeof(DRIVER_ROOT_NAME),
1311  ServiceName.Length,
1312  &ObjectName.MaximumLength);
1313  if (!NT_SUCCESS(Status))
1314  {
1315  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1316  return Status;
1317  }
1318  ObjectName.Length = 0;
1320  ObjectName.MaximumLength,
1321  TAG_IO);
1322  if (!ObjectName.Buffer)
1323  {
1324  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1326  }
1329 
1330  /*
1331  * Find the driver object
1332  */
1334  0,
1335  0,
1336  0,
1338  KernelMode,
1339  0,
1340  (PVOID*)&DriverObject);
1341 
1342  if (!NT_SUCCESS(Status))
1343  {
1344  DPRINT1("Can't locate driver object for %wZ\n", &ObjectName);
1346  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1347  return Status;
1348  }
1349 
1350  /* Free the buffer for driver object name */
1352 
1353  /* Check that driver is not already unloading */
1354  if (DriverObject->Flags & DRVO_UNLOAD_INVOKED)
1355  {
1356  DPRINT1("Driver deletion pending\n");
1358  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1359  return STATUS_DELETE_PENDING;
1360  }
1361 
1362  /*
1363  * Get path of service...
1364  */
1366 
1367  RtlInitUnicodeString(&ImagePath, NULL);
1368 
1369  QueryTable[0].Name = L"ImagePath";
1371  QueryTable[0].EntryContext = &ImagePath;
1372 
1374  CapturedServiceName.Buffer,
1375  QueryTable,
1376  NULL,
1377  NULL);
1378 
1379  /* We no longer need service name */
1380  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1381 
1382  if (!NT_SUCCESS(Status))
1383  {
1384  DPRINT1("RtlQueryRegistryValues() failed (Status %x)\n", Status);
1386  return Status;
1387  }
1388 
1389  /*
1390  * Normalize the image path for all later processing.
1391  */
1392  Status = IopNormalizeImagePath(&ImagePath, &ServiceName);
1393 
1394  if (!NT_SUCCESS(Status))
1395  {
1396  DPRINT1("IopNormalizeImagePath() failed (Status %x)\n", Status);
1398  return Status;
1399  }
1400 
1401  /* Free the service path */
1402  ExFreePool(ImagePath.Buffer);
1403 
1404  /*
1405  * Unload the module and release the references to the device object
1406  */
1407 
1408  /* Call the load/unload routine, depending on current process */
1409  if (DriverObject->DriverUnload && DriverObject->DriverSection &&
1410  (UnloadPnpDrivers || (DriverObject->Flags & DRVO_LEGACY_DRIVER)))
1411  {
1412  /* Loop through each device object of the driver
1413  and set DOE_UNLOAD_PENDING flag */
1414  DeviceObject = DriverObject->DeviceObject;
1415  while (DeviceObject)
1416  {
1417  /* Set the unload pending flag for the device */
1418  DeviceExtension = IoGetDevObjExtension(DeviceObject);
1419  DeviceExtension->ExtensionFlags |= DOE_UNLOAD_PENDING;
1420 
1421  /* Make sure there are no attached devices or no reference counts */
1422  if ((DeviceObject->ReferenceCount) || (DeviceObject->AttachedDevice))
1423  {
1424  /* Not safe to unload */
1425  DPRINT1("Drivers device object is referenced or has attached devices\n");
1426 
1427  SafeToUnload = FALSE;
1428  }
1429 
1430  DeviceObject = DeviceObject->NextDevice;
1431  }
1432 
1433  /* If not safe to unload, then return success */
1434  if (!SafeToUnload)
1435  {
1437  return STATUS_SUCCESS;
1438  }
1439 
1440  DPRINT1("Unloading driver '%wZ' (manual)\n", &DriverObject->DriverName);
1441 
1442  /* Set the unload invoked flag and call the unload routine */
1446 
1447  /* Mark the driver object temporary, so it could be deleted later */
1449 
1450  /* Dereference it 2 times */
1453 
1454  return Status;
1455  }
1456  else
1457  {
1458  DPRINT1("No DriverUnload function! '%wZ' will not be unloaded!\n", &DriverObject->DriverName);
1459 
1460  /* Dereference one time (refd inside this function) */
1462 
1463  /* Return unloading failure */
1465  }
1466 }
static __inline NTSTATUS ProbeAndCaptureUnicodeString(OUT PUNICODE_STRING Dest, IN KPROCESSOR_MODE CurrentMode, IN const UNICODE_STRING *UnsafeSrc)
Definition: probe.h:142
#define RTL_FIND_CHAR_IN_UNICODE_STRING_START_AT_END
Definition: rtl.h:25
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4155
#define STATUS_DELETE_PENDING
Definition: ntstatus.h:322
#define DRVO_LEGACY_DRIVER
Definition: iotypes.h:2226
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define TAG_IO
Definition: tag.h:69
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
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:2072
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:3070
POBJECT_TYPE IoDriverObjectType
Definition: driver.c:33
#define NT_VERIFY(exp)
Definition: rtlfuncs.h:3287
_In_ PVOID _Out_opt_ PULONG_PTR _Outptr_opt_ PCUNICODE_STRING * ObjectName
Definition: cmfuncs.h:62
NTSTATUS NTAPI RtlFindCharInUnicodeString(_In_ ULONG Flags, _In_ PCUNICODE_STRING SearchString, _In_ PCUNICODE_STRING MatchString, _Out_ PUSHORT Position)
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
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:356
const LUID SeLoadDriverPrivilege
Definition: priv.c:27
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
#define DRVO_UNLOAD_INVOKED
Definition: iotypes.h:2225
Status
Definition: gdiplustypes.h:24
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
static __inline VOID ReleaseCapturedUnicodeString(IN PUNICODE_STRING CapturedString, IN KPROCESSOR_MODE CurrentMode)
Definition: probe.h:239
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
LPTSTR ServiceName
Definition: ServiceMain.c:15
#define ASSERT(a)
Definition: mode.c:44
#define DOE_UNLOAD_PENDING
Definition: iotypes.h:149
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ObDereferenceObject
Definition: obfuncs.h:203
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
static const WCHAR L[]
Definition: oid.c:1250
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
unsigned short USHORT
Definition: pedump.c:61
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
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:738
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
#define IoGetDevObjExtension(DeviceObject)
Definition: io.h:129
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
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
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
#define DRIVER_ROOT_NAME
Definition: ldr.h:5
#define PAGED_CODE()
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
#define NT_ASSERT
Definition: rtlfuncs.h:3310
VOID NTAPI ObMakeTemporaryObject(IN PVOID ObjectBody)
Definition: oblife.c:1361

Referenced by NtUnloadDriver().

◆ IoRegisterBootDriverReinitialization()

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

Definition at line 1741 of file driver.c.

1744 {
1745  PDRIVER_REINIT_ITEM ReinitItem;
1746 
1747  /* Allocate the entry */
1748  ReinitItem = ExAllocatePoolWithTag(NonPagedPool,
1749  sizeof(DRIVER_REINIT_ITEM),
1750  TAG_REINIT);
1751  if (!ReinitItem) return;
1752 
1753  /* Fill it out */
1754  ReinitItem->DriverObject = DriverObject;
1755  ReinitItem->ReinitRoutine = ReinitRoutine;
1756  ReinitItem->Context = Context;
1757 
1758  /* Set the Driver Object flag and insert the entry into the list */
1761  &ReinitItem->ItemEntry,
1763 }
PVOID Context
Definition: io.h:463
LIST_ENTRY DriverBootReinitListHead
Definition: driver.c:26
LIST_ENTRY ItemEntry
Definition: io.h:460
KSPIN_LOCK DriverBootReinitListLock
Definition: driver.c:27
PDRIVER_OBJECT DriverObject
Definition: io.h:461
#define TAG_REINIT
Definition: tag.h:73
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
PLIST_ENTRY NTAPI ExInterlockedInsertTailList(IN OUT PLIST_ENTRY ListHead, IN OUT PLIST_ENTRY ListEntry, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:140
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
struct tagContext Context
Definition: acpixf.h:1034
PDRIVER_REINITIALIZE ReinitRoutine
Definition: io.h:462
#define DRVO_BOOTREINIT_REGISTERED
Definition: iotypes.h:4471

Referenced by _Function_class_(), and DriverEntry().

◆ IoRegisterDriverReinitialization()

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

Definition at line 1770 of file driver.c.

1773 {
1774  PDRIVER_REINIT_ITEM ReinitItem;
1775 
1776  /* Allocate the entry */
1777  ReinitItem = ExAllocatePoolWithTag(NonPagedPool,
1778  sizeof(DRIVER_REINIT_ITEM),
1779  TAG_REINIT);
1780  if (!ReinitItem) return;
1781 
1782  /* Fill it out */
1783  ReinitItem->DriverObject = DriverObject;
1784  ReinitItem->ReinitRoutine = ReinitRoutine;
1785  ReinitItem->Context = Context;
1786 
1787  /* Set the Driver Object flag and insert the entry into the list */
1790  &ReinitItem->ItemEntry,
1792 }
PVOID Context
Definition: io.h:463
#define DRVO_REINIT_REGISTERED
Definition: iotypes.h:4469
LIST_ENTRY ItemEntry
Definition: io.h:460
KSPIN_LOCK DriverReinitListLock
Definition: driver.c:22
LIST_ENTRY DriverReinitListHead
Definition: driver.c:21
PDRIVER_OBJECT DriverObject
Definition: io.h:461
#define TAG_REINIT
Definition: tag.h:73
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
PLIST_ENTRY NTAPI ExInterlockedInsertTailList(IN OUT PLIST_ENTRY ListHead, IN OUT PLIST_ENTRY ListEntry, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:140
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
struct tagContext Context
Definition: acpixf.h:1034
PDRIVER_REINITIALIZE ReinitRoutine
Definition: io.h:462

Referenced by DiskBootDriverReinit(), and DriverEntry().

◆ LdrProcessDriverModule()

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

Definition at line 709 of file driver.c.

712 {
714  UNICODE_STRING BaseName, BaseDirectory;
715  PLOAD_IMPORTS LoadedImports = (PVOID)-2;
716  PCHAR MissingApiName, Buffer;
717  PWCHAR MissingDriverName;
718  PVOID DriverBase = LdrEntry->DllBase;
719 
720  /* Allocate a buffer we'll use for names */
723  TAG_LDR_WSTR);
724  if (!Buffer)
725  {
726  /* Fail */
728  }
729 
730  /* Check for a separator */
731  if (FileName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR)
732  {
733  PWCHAR p;
734  ULONG BaseLength;
735 
736  /* Loop the path until we get to the base name */
737  p = &FileName->Buffer[FileName->Length / sizeof(WCHAR)];
738  while (*(p - 1) != OBJ_NAME_PATH_SEPARATOR) p--;
739 
740  /* Get the length */
741  BaseLength = (ULONG)(&FileName->Buffer[FileName->Length / sizeof(WCHAR)] - p);
742  BaseLength *= sizeof(WCHAR);
743 
744  /* Setup the string */
745  BaseName.Length = (USHORT)BaseLength;
746  BaseName.Buffer = p;
747  }
748  else
749  {
750  /* Otherwise, we already have a base name */
751  BaseName.Length = FileName->Length;
752  BaseName.Buffer = FileName->Buffer;
753  }
754 
755  /* Setup the maximum length */
756  BaseName.MaximumLength = BaseName.Length;
757 
758  /* Now compute the base directory */
759  BaseDirectory = *FileName;
760  BaseDirectory.Length -= BaseName.Length;
761  BaseDirectory.MaximumLength = BaseDirectory.Length;
762 
763  /* Resolve imports */
764  MissingApiName = Buffer;
765  Status = MiResolveImageReferences(DriverBase,
766  &BaseDirectory,
767  NULL,
768  &MissingApiName,
769  &MissingDriverName,
770  &LoadedImports);
771 
772  /* Free the temporary buffer */
774 
775  /* Check the result of the imports resolution */
776  if (!NT_SUCCESS(Status)) return Status;
777 
778  /* Return */
779  *ModuleObject = LdrEntry;
780  return STATUS_SUCCESS;
781 }
signed char * PCHAR
Definition: retypes.h:7
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
USHORT MaximumLength
Definition: env_spec_w32.h:370
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
LONG NTSTATUS
Definition: precomp.h:26
uint16_t * PWCHAR
Definition: typedefs.h:56
#define MAXIMUM_FILENAME_LENGTH
Definition: env_spec_w32.h:41
PVOID DllBase
Definition: btrfs_drv.h:1926
#define TAG_LDR_WSTR
Definition: tag.h:110
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
Definition: bufpool.h:45
void * PVOID
Definition: retypes.h:9
Status
Definition: gdiplustypes.h:24
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
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:1000
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
struct _FileName FileName
Definition: fatprocs.h:893
unsigned short USHORT
Definition: pedump.c:61
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_SUCCESS
Definition: shellext.h:65
GLfloat GLfloat p
Definition: glext.h:8902
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099

◆ 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 1000 of file sysldr.c.

1006 {
1007  static UNICODE_STRING DriversFolderName = RTL_CONSTANT_STRING(L"drivers\\");
1008  PCHAR MissingApiBuffer = *MissingApi, ImportName;
1009  PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor, CurrentImport;
1010  ULONG ImportSize, ImportCount = 0, LoadedImportsSize, ExportSize;
1011  PLOAD_IMPORTS LoadedImports, NewImports;
1012  ULONG GdiLink, NormalLink, i;
1013  BOOLEAN ReferenceNeeded, Loaded;
1014  ANSI_STRING TempString;
1015  UNICODE_STRING NameString, DllName;
1016  PLDR_DATA_TABLE_ENTRY LdrEntry = NULL, DllEntry, ImportEntry = NULL;
1017  PVOID ImportBase, DllBase;
1018  PLIST_ENTRY NextEntry;
1019  PIMAGE_EXPORT_DIRECTORY ExportDirectory;
1020  NTSTATUS Status;
1021  PIMAGE_THUNK_DATA OrigThunk, FirstThunk;
1022  PAGED_CODE();
1023  DPRINT("%s - ImageBase: %p. ImageFileDirectory: %wZ\n",
1024  __FUNCTION__, ImageBase, ImageFileDirectory);
1025 
1026  /* No name string buffer yet */
1027  NameString.Buffer = NULL;
1028 
1029  /* Assume no imports */
1030  *LoadImports = MM_SYSLDR_NO_IMPORTS;
1031 
1032  /* Get the import descriptor */
1033  ImportDescriptor = RtlImageDirectoryEntryToData(ImageBase,
1034  TRUE,
1036  &ImportSize);
1037  if (!ImportDescriptor) return STATUS_SUCCESS;
1038 
1039  /* Loop all imports to count them */
1040  for (CurrentImport = ImportDescriptor;
1041  (CurrentImport->Name) && (CurrentImport->OriginalFirstThunk);
1042  CurrentImport++)
1043  {
1044  /* One more */
1045  ImportCount++;
1046  }
1047 
1048  /* Make sure we have non-zero imports */
1049  if (ImportCount)
1050  {
1051  /* Calculate and allocate the list we'll need */
1052  LoadedImportsSize = ImportCount * sizeof(PVOID) + sizeof(SIZE_T);
1053  LoadedImports = ExAllocatePoolWithTag(PagedPool,
1054  LoadedImportsSize,
1055  TAG_LDR_IMPORTS);
1056  if (LoadedImports)
1057  {
1058  /* Zero it */
1059  RtlZeroMemory(LoadedImports, LoadedImportsSize);
1060  LoadedImports->Count = ImportCount;
1061  }
1062  }
1063  else
1064  {
1065  /* No table */
1066  LoadedImports = NULL;
1067  }
1068 
1069  /* Reset the import count and loop descriptors again */
1070  ImportCount = GdiLink = NormalLink = 0;
1071  while ((ImportDescriptor->Name) && (ImportDescriptor->OriginalFirstThunk))
1072  {
1073  /* Get the name */
1074  ImportName = (PCHAR)((ULONG_PTR)ImageBase + ImportDescriptor->Name);
1075 
1076  /* Check if this is a GDI driver */
1077  GdiLink = GdiLink |
1078  !(_strnicmp(ImportName, "win32k", sizeof("win32k") - 1));
1079 
1080  /* We can also allow dxapi (for Windows compat, allow IRT and coverage) */
1081  NormalLink = NormalLink |
1082  ((_strnicmp(ImportName, "win32k", sizeof("win32k") - 1)) &&
1083  (_strnicmp(ImportName, "dxapi", sizeof("dxapi") - 1)) &&
1084  (_strnicmp(ImportName, "coverage", sizeof("coverage") - 1)) &&
1085  (_strnicmp(ImportName, "irt", sizeof("irt") - 1)));
1086 
1087  /* Check if this is a valid GDI driver */
1088  if ((GdiLink) && (NormalLink))
1089  {
1090  /* It's not, it's importing stuff it shouldn't be! */
1092  goto Failure;
1093  }
1094 
1095  /* Check for user-mode printer or video card drivers, which don't belong */
1096  if (!(_strnicmp(ImportName, "ntdll", sizeof("ntdll") - 1)) ||
1097  !(_strnicmp(ImportName, "winsrv", sizeof("winsrv") - 1)) ||
1098  !(_strnicmp(ImportName, "advapi32", sizeof("advapi32") - 1)) ||
1099  !(_strnicmp(ImportName, "kernel32", sizeof("kernel32") - 1)) ||
1100  !(_strnicmp(ImportName, "user32", sizeof("user32") - 1)) ||
1101  !(_strnicmp(ImportName, "gdi32", sizeof("gdi32") - 1)))
1102  {
1103  /* This is not kernel code */
1105  goto Failure;
1106  }
1107 
1108  /* Check if this is a "core" import, which doesn't get referenced */
1109  if (!(_strnicmp(ImportName, "ntoskrnl", sizeof("ntoskrnl") - 1)) ||
1110  !(_strnicmp(ImportName, "win32k", sizeof("win32k") - 1)) ||
1111  !(_strnicmp(ImportName, "hal", sizeof("hal") - 1)))
1112  {
1113  /* Don't reference this */
1114  ReferenceNeeded = FALSE;
1115  }
1116  else
1117  {
1118  /* Reference these modules */
1119  ReferenceNeeded = TRUE;
1120  }
1121 
1122  /* Now setup a unicode string for the import */
1123  RtlInitAnsiString(&TempString, ImportName);
1124  Status = RtlAnsiStringToUnicodeString(&NameString, &TempString, TRUE);
1125  if (!NT_SUCCESS(Status))
1126  {
1127  /* Failed */
1128  goto Failure;
1129  }
1130 
1131  /* We don't support name prefixes yet */
1132  if (NamePrefix) DPRINT1("Name Prefix not yet supported!\n");
1133 
1134  /* Remember that we haven't loaded the import at this point */
1135 CheckDllState:
1136  Loaded = FALSE;
1137  ImportBase = NULL;
1138 
1139  /* Loop the driver list */
1140  NextEntry = PsLoadedModuleList.Flink;
1141  while (NextEntry != &PsLoadedModuleList)
1142  {
1143  /* Get the loader entry and compare the name */
1144  LdrEntry = CONTAINING_RECORD(NextEntry,
1146  InLoadOrderLinks);
1147  if (RtlEqualUnicodeString(&NameString,
1148  &LdrEntry->BaseDllName,
1149  TRUE))
1150  {
1151  /* Get the base address */
1152  ImportBase = LdrEntry->DllBase;
1153 
1154  /* Check if we haven't loaded yet, and we need references */
1155  if (!(Loaded) && (ReferenceNeeded))
1156  {
1157  /* Make sure we're not already loading */
1158  if (!(LdrEntry->Flags & LDRP_LOAD_IN_PROGRESS))
1159  {
1160  /* Increase the load count */
1161  LdrEntry->LoadCount++;
1162  }
1163  }
1164 
1165  /* Done, break out */
1166  break;
1167  }
1168 
1169  /* Go to the next entry */
1170  NextEntry = NextEntry->Flink;
1171  }
1172 
1173  /* Check if we haven't loaded the import yet */
1174  if (!ImportBase)
1175  {
1176  /* Setup the import DLL name */
1177  DllName.MaximumLength = NameString.Length +
1178  ImageFileDirectory->Length +
1179  sizeof(UNICODE_NULL);
1181  DllName.MaximumLength,
1182  TAG_LDR_WSTR);
1183  if (!DllName.Buffer)
1184  {
1185  /* We're out of resources */
1187  goto Failure;
1188  }
1189 
1190  /* Add the import name to the base directory */
1191  RtlCopyUnicodeString(&DllName, ImageFileDirectory);
1193  &NameString);
1194 
1195  /* Load the image */
1196  Status = MmLoadSystemImage(&DllName,
1197  NamePrefix,
1198  NULL,
1199  FALSE,
1200  (PVOID *)&DllEntry,
1201  &DllBase);
1202 
1203  /* win32k / GDI drivers can also import from system32 folder */
1205  (MI_IS_SESSION_ADDRESS(ImageBase) || 1)) // HACK
1206  {
1207  /* Free the old name buffer */
1209 
1210  /* Calculate size for a string the adds 'drivers\' */
1211  DllName.MaximumLength += DriversFolderName.Length;
1212 
1213  /* Allocate the new buffer */
1215  DllName.MaximumLength,
1216  TAG_LDR_WSTR);
1217  if (!DllName.Buffer)
1218  {
1219  /* We're out of resources */
1221  goto Failure;
1222  }
1223 
1224  /* Copy image directory and append 'drivers\' folder name */
1225  RtlCopyUnicodeString(&DllName, ImageFileDirectory);
1226  RtlAppendUnicodeStringToString(&DllName, &DriversFolderName);
1227 
1228  /* Now add the import name */
1229  RtlAppendUnicodeStringToString(&DllName, &NameString);
1230 
1231  /* Try once again to load the image */
1232  Status = MmLoadSystemImage(&DllName,
1233  NamePrefix,
1234  NULL,
1235  FALSE,
1236  (PVOID *)&DllEntry,
1237  &DllBase);
1238  }
1239 
1240  if (!NT_SUCCESS(Status))
1241  {
1242  /* Fill out the information for the error */
1243  *MissingDriver = DllName.Buffer;
1244  *(PULONG)MissingDriver |= 1;
1245  *MissingApi = NULL;
1246 
1247  DPRINT1("Failed to load dependency: %wZ\n", &DllName);
1248 
1249  /* Don't free the name */
1250  DllName.Buffer = NULL;
1251 
1252  /* Cleanup and return */
1253  goto Failure;
1254  }
1255 
1256  /* We can free the DLL Name */
1258  DllName.Buffer = NULL;
1259 
1260  /* We're now loaded */
1261  Loaded = TRUE;
1262 
1263  /* Sanity check */
1264  ASSERT(DllBase == DllEntry->DllBase);
1265 
1266  /* Call the initialization routines */
1268  if (!NT_SUCCESS(Status))
1269  {
1270  /* We failed, unload the image */
1271  MmUnloadSystemImage(DllEntry);
1272  ERROR_DBGBREAK("MmCallDllInitialize failed with status 0x%x\n", Status);
1273  Loaded = FALSE;
1274  }
1275 
1276  /* Loop again to make sure that everything is OK */
1277  goto CheckDllState;
1278  }
1279 
1280  /* Check if we're support to reference this import */
1281  if ((ReferenceNeeded) && (LoadedImports))
1282  {
1283  /* Make sure we're not already loading */
1284  if (!(LdrEntry->Flags & LDRP_LOAD_IN_PROGRESS))
1285  {
1286  /* Add the entry */
1287  LoadedImports->Entry[ImportCount] = LdrEntry;
1288  ImportCount++;
1289  }
1290  }
1291 
1292  /* Free the import name */
1293  RtlFreeUnicodeString(&NameString);
1294 
1295  /* Set the missing driver name and get the export directory */
1296  *MissingDriver = LdrEntry->BaseDllName.Buffer;
1297  ExportDirectory = RtlImageDirectoryEntryToData(ImportBase,
1298  TRUE,
1300  &ExportSize);
1301  if (!ExportDirectory)
1302  {
1303  /* Cleanup and return */
1304  DPRINT1("Warning: Driver failed to load, %S not found\n", *MissingDriver);
1306  goto Failure;
1307  }
1308 
1309  /* Make sure we have an IAT */
1310  if (ImportDescriptor->OriginalFirstThunk)
1311  {
1312  /* Get the first thunks */
1313  OrigThunk = (PVOID)((ULONG_PTR)ImageBase +
1314  ImportDescriptor->OriginalFirstThunk);
1315  FirstThunk = (PVOID)((ULONG_PTR)ImageBase +
1316  ImportDescriptor->FirstThunk);
1317 
1318  /* Loop the IAT */
1319  while (OrigThunk->u1.AddressOfData)
1320  {
1321  /* Snap thunk */
1322  Status = MiSnapThunk(ImportBase,
1323  ImageBase,
1324  OrigThunk++,
1325  FirstThunk++,
1326  ExportDirectory,
1327  ExportSize,
1328  FALSE,
1329  MissingApi);
1330  if (!NT_SUCCESS(Status))
1331  {
1332  /* Cleanup and return */
1333  goto Failure;
1334  }
1335 
1336  /* Reset the buffer */
1337  *MissingApi = MissingApiBuffer;
1338  }
1339  }
1340 
1341  /* Go to the next import */
1342  ImportDescriptor++;
1343  }
1344 
1345  /* Check if we have an import list */
1346  if (LoadedImports)
1347  {
1348  /* Reset the count again, and loop entries */
1349  ImportCount = 0;
1350  for (i = 0; i < LoadedImports->Count; i++)
1351  {
1352  if (LoadedImports->Entry[i])
1353  {
1354  /* Got an entry, OR it with 1 in case it's the single entry */
1355  ImportEntry = (PVOID)((ULONG_PTR)LoadedImports->Entry[i] |
1357  ImportCount++;
1358  }
1359  }
1360 
1361  /* Check if we had no imports */
1362  if (!ImportCount)
1363  {
1364  /* Free the list and set it to no imports */
1365  ExFreePoolWithTag(LoadedImports, TAG_LDR_IMPORTS);
1366  LoadedImports = MM_SYSLDR_NO_IMPORTS;
1367  }
1368  else if (ImportCount == 1)
1369  {
1370  /* Just one entry, we can free the table and only use our entry */
1371  ExFreePoolWithTag(LoadedImports, TAG_LDR_IMPORTS);
1372  LoadedImports = (PLOAD_IMPORTS)ImportEntry;
1373  }
1374  else if (ImportCount != LoadedImports->Count)
1375  {
1376  /* Allocate a new list */
1377  LoadedImportsSize = ImportCount * sizeof(PVOID) + sizeof(SIZE_T);
1378  NewImports = ExAllocatePoolWithTag(PagedPool,
1379  LoadedImportsSize,
1380  TAG_LDR_IMPORTS);
1381  if (NewImports)
1382  {
1383  /* Set count */
1384  NewImports->Count = 0;
1385 
1386  /* Loop all the imports */
1387  for (i = 0; i < LoadedImports->Count; i++)
1388  {
1389  /* Make sure it's valid */
1390  if (LoadedImports->Entry[i])
1391  {
1392  /* Copy it */
1393  NewImports->Entry[NewImports->Count] = LoadedImports->Entry[i];
1394  NewImports->Count++;
1395  }
1396  }
1397 
1398  /* Free the old copy */
1399  ExFreePoolWithTag(LoadedImports, TAG_LDR_IMPORTS);
1400  LoadedImports = NewImports;
1401  }
1402  }
1403 
1404  /* Return the list */
1405  *LoadImports = LoadedImports;
1406  }
1407 
1408  /* Return success */
1409  return STATUS_SUCCESS;
1410 
1411 Failure:
1412 
1413  /* Cleanup and return */
1414  RtlFreeUnicodeString(&NameString);
1415 
1416  if (LoadedImports)
1417  {
1418  MiDereferenceImports(LoadedImports);
1419  ExFreePoolWithTag(LoadedImports, TAG_LDR_IMPORTS);
1420  }
1421 
1422  return Status;
1423 }
signed char * PCHAR
Definition: retypes.h:7
#define LDRP_LOAD_IN_PROGRESS
Definition: ldrtypes.h:42
NTSTATUS NTAPI MmCallDllInitialize(IN PLDR_DATA_TABLE_ENTRY LdrEntry, IN PLIST_ENTRY ListHead)
Definition: sysldr.c:308
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
PLDR_DATA_TABLE_ENTRY Entry[1]
Definition: ldrtypes.h:173
NTSTATUS NTAPI MmUnloadSystemImage(IN PVOID ImageHandle)
Definition: sysldr.c:911
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define TRUE
Definition: types.h:120
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:34
#define MI_IS_SESSION_ADDRESS(Address)
Definition: miarm.h:171
LONG NTSTATUS
Definition: precomp.h:26
struct _LOAD_IMPORTS * PLOAD_IMPORTS
#define MM_SYSLDR_SINGLE_ENTRY
Definition: miarm.h:207
NTSTATUS NTAPI MiDereferenceImports(IN PLOAD_IMPORTS ImportList)
Definition: sysldr.c:395
#define TAG_LDR_IMPORTS
Definition: tag.h:111
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
Definition: fs_rec.h:186
#define STATUS_DRIVER_ENTRYPOINT_NOT_FOUND
Definition: ntstatus.h:736
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
uint32_t ULONG_PTR
Definition: typedefs.h:65
PVOID DllBase
Definition: btrfs_drv.h:1926
#define TAG_LDR_WSTR
Definition: tag.h:110
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
#define ERROR_DBGBREAK(...)
Definition: debug.h:221
unsigned char BOOLEAN
void * PVOID
Definition: retypes.h:9
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define PCHAR
Definition: match.c:90
Status
Definition: gdiplustypes.h:24
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define _strnicmp(_String1, _String2, _MaxCount)
Definition: compat.h:23
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
static const WCHAR L[]
Definition: oid.c:1250
#define RtlImageDirectoryEntryToData
Definition: compat.h:668
Definition: btrfs_drv.h:1922
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:2898
Definition: typedefs.h:119
#define IMAGE_DIRECTORY_ENTRY_EXPORT
Definition: compat.h:151
SIZE_T Count
Definition: ldrtypes.h:172
#define MM_SYSLDR_NO_IMPORTS
Definition: miarm.h:204
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
union _IMAGE_THUNK_DATA32::@2078 u1
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
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
#define STATUS_PROCEDURE_NOT_FOUND
Definition: ntstatus.h:358
#define DPRINT1
Definition: precomp.h:8
#define IMAGE_DIRECTORY_ENTRY_IMPORT
Definition: pedump.c:260
ULONG Flags
Definition: ntddk_ex.h:207
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
#define __FUNCTION__
Definition: types.h:112
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
USHORT LoadCount
Definition: ntddk_ex.h:208
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:691
#define PAGED_CODE()
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14

Referenced by LdrProcessDriverModule(), and MmLoadSystemImage().

◆ NtLoadDriver()

NTSTATUS NTAPI NtLoadDriver ( IN PUNICODE_STRING  DriverServiceName)

Definition at line 2120 of file driver.c.

2121 {
2122  UNICODE_STRING CapturedServiceName = { 0, 0, NULL };
2125  NTSTATUS Status;
2126 
2127  PAGED_CODE();
2128 
2130 
2131  /* Need the appropriate priviliege */
2133  {
2134  DPRINT1("No load privilege!\n");
2136  }
2137 
2138  /* Capture the service name */
2139  Status = ProbeAndCaptureUnicodeString(&CapturedServiceName,
2140  PreviousMode,
2141  DriverServiceName);
2142  if (!NT_SUCCESS(Status))
2143  {
2144  return Status;
2145  }
2146 
2147  DPRINT("NtLoadDriver('%wZ')\n", &CapturedServiceName);
2148 
2149  /* We need a service name */
2150  if (CapturedServiceName.Length == 0 || CapturedServiceName.Buffer == NULL)
2151  {
2152  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
2153  return STATUS_INVALID_PARAMETER;
2154  }
2155 
2156  /* Load driver and call its entry point */
2157  DriverObject = NULL;
2158  Status = IopDoLoadUnloadDriver(&CapturedServiceName, &DriverObject);
2159 
2160  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
2161  return Status;
2162 }
static __inline NTSTATUS ProbeAndCaptureUnicodeString(OUT PUNICODE_STRING Dest, IN KPROCESSOR_MODE CurrentMode, IN const UNICODE_STRING *UnsafeSrc)
Definition: probe.h:142
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define KeGetPreviousMode()
Definition: ketypes.h:1107
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:2072
LONG NTSTATUS
Definition: precomp.h:26
const LUID SeLoadDriverPrivilege
Definition: priv.c:27
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
Status
Definition: gdiplustypes.h:24
static __inline VOID ReleaseCapturedUnicodeString(IN PUNICODE_STRING CapturedString, IN KPROCESSOR_MODE CurrentMode)
Definition: probe.h:239
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
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:738
#define DPRINT
Definition: sndvol32.h:71
#define PAGED_CODE()

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

◆ NtUnloadDriver()

NTSTATUS NTAPI NtUnloadDriver ( IN PUNICODE_STRING  DriverServiceName)

Definition at line 2181 of file driver.c.

2182 {
2183  return IopUnloadDriver(DriverServiceName, FALSE);
2184 }
#define FALSE
Definition: types.h:117
NTSTATUS NTAPI IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
Definition: driver.c:1243

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

◆ DriverReinitListHead

LIST_ENTRY DriverReinitListHead

Definition at line 21 of file driver.c.

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

◆ DriverReinitListLock

KSPIN_LOCK DriverReinitListLock

Definition at line 22 of file driver.c.

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

◆ DriverReinitTailEntry

PLIST_ENTRY DriverReinitTailEntry

Definition at line 23 of file driver.c.

◆ ExpInTextModeSetup

BOOLEAN ExpInTextModeSetup

◆ IoDriverObjectType

◆ IopDriverLoadResource

ERESOURCE IopDriverLoadResource

Definition at line 19 of file driver.c.

Referenced by IoInitSystem(), and IopLoadDriver().

◆ IopGroupIndex

USHORT IopGroupIndex

Definition at line 42 of file driver.c.

Referenced by IopInitializeBootDrivers().

◆ IopGroupTable

PLIST_ENTRY IopGroupTable

Definition at line 43 of file driver.c.

Referenced by IopInitializeBootDrivers().

◆ IopHardwareDatabaseKey

UNICODE_STRING IopHardwareDatabaseKey
Initial value:
=
RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\HARDWARE\\DESCRIPTION\\SYSTEM")
static const WCHAR L[]
Definition: oid.c:1250
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14

Definition at line 29 of file driver.c.

Referenced by IopInitializeDriverModule().

◆ PiEnumerationFinished

KEVENT PiEnumerationFinished

Definition at line 50 of file devaction.c.

Referenced by IopReinitializeBootDrivers().

◆ PnPBootDriversLoaded

BOOLEAN PnPBootDriversLoaded

Definition at line 26 of file pnpinit.c.

Referenced by IopInitializeBootDrivers().

◆ PnpSystemInit

BOOLEAN PnpSystemInit

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

Referenced by IopInitializeBuiltinDriver(), and MmCallDllInitialize().