ReactOS  0.4.15-dev-3720-g4cf9b79
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
 

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.

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

1801 {
1802  KIRQL OldIrql;
1803  PIO_CLIENT_EXTENSION DriverExtensions, NewDriverExtension;
1804  BOOLEAN Inserted = FALSE;
1805 
1806  /* Assume failure */
1807  *DriverObjectExtension = NULL;
1808 
1809  /* Allocate the extension */
1810  NewDriverExtension = ExAllocatePoolWithTag(NonPagedPool,
1811  sizeof(IO_CLIENT_EXTENSION) +
1812  DriverObjectExtensionSize,
1814  if (!NewDriverExtension) return STATUS_INSUFFICIENT_RESOURCES;
1815 
1816  /* Clear the extension for teh caller */
1817  RtlZeroMemory(NewDriverExtension,
1818  sizeof(IO_CLIENT_EXTENSION) + DriverObjectExtensionSize);
1819 
1820  /* Acqure lock */
1822 
1823  /* Fill out the extension */
1825 
1826  /* Loop the current extensions */
1827  DriverExtensions = IoGetDrvObjExtension(DriverObject)->
1828  ClientDriverExtension;
1829  while (DriverExtensions)
1830  {
1831  /* Check if the identifier matches */
1832  if (DriverExtensions->ClientIdentificationAddress ==
1834  {
1835  /* We have a collision, break out */
1836  break;
1837  }
1838 
1839  /* Go to the next one */
1840  DriverExtensions = DriverExtensions->NextExtension;
1841  }
1842 
1843  /* Check if we didn't collide */
1844  if (!DriverExtensions)
1845  {
1846  /* Link this one in */
1847  NewDriverExtension->NextExtension =
1848  IoGetDrvObjExtension(DriverObject)->ClientDriverExtension;
1849  IoGetDrvObjExtension(DriverObject)->ClientDriverExtension =
1850  NewDriverExtension;
1851  Inserted = TRUE;
1852  }
1853 
1854  /* Release the lock */
1856 
1857  /* Check if insertion failed */
1858  if (!Inserted)
1859  {
1860  /* Free the entry and fail */
1861  ExFreePoolWithTag(NewDriverExtension, TAG_DRIVER_EXTENSION);
1863  }
1864 
1865  /* Otherwise, return the pointer */
1866  *DriverObjectExtension = NewDriverExtension + 1;
1867  return STATUS_SUCCESS;
1868 }
#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:828
#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
#define TAG_DRIVER_EXTENSION
Definition: tag.h:56
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#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:829
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 1548 of file driver.c.

1551 {
1552  WCHAR NameBuffer[100];
1553  USHORT NameLength;
1554  UNICODE_STRING LocalDriverName;
1555  NTSTATUS Status;
1557  ULONG ObjectSize;
1559  UNICODE_STRING ServiceKeyName;
1560  HANDLE hDriver;
1561  ULONG i, RetryCount = 0;
1562 
1563 try_again:
1564  /* First, create a unique name for the driver if we don't have one */
1565  if (!DriverName)
1566  {
1567  /* Create a random name and set up the string */
1568  NameLength = (USHORT)swprintf(NameBuffer,
1569  DRIVER_ROOT_NAME L"%08u",
1571  LocalDriverName.Length = NameLength * sizeof(WCHAR);
1572  LocalDriverName.MaximumLength = LocalDriverName.Length + sizeof(UNICODE_NULL);
1573  LocalDriverName.Buffer = NameBuffer;
1574  }
1575  else
1576  {
1577  /* So we can avoid another code path, use a local var */
1578  LocalDriverName = *DriverName;
1579  }
1580 
1581  /* Initialize the Attributes */
1582  ObjectSize = sizeof(DRIVER_OBJECT) + sizeof(EXTENDED_DRIVER_EXTENSION);
1584  &LocalDriverName,
1586  NULL,
1587  NULL);
1588 
1589  /* Create the Object */
1593  KernelMode,
1594  NULL,
1595  ObjectSize,
1596  0,
1597  0,
1598  (PVOID*)&DriverObject);
1599  if (!NT_SUCCESS(Status)) return Status;
1600 
1601  DPRINT("IopCreateDriver(): created DO %p\n", DriverObject);
1602 
1603  /* Set up the Object */
1604  RtlZeroMemory(DriverObject, ObjectSize);
1605  DriverObject->Type = IO_TYPE_DRIVER;
1606  DriverObject->Size = sizeof(DRIVER_OBJECT);
1608  DriverObject->DriverExtension = (PDRIVER_EXTENSION)(DriverObject + 1);
1609  DriverObject->DriverExtension->DriverObject = DriverObject;
1610  DriverObject->DriverInit = InitializationFunction;
1611  /* Loop all Major Functions */
1612  for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
1613  {
1614  /* Invalidate each function */
1615  DriverObject->MajorFunction[i] = IopInvalidDeviceRequest;
1616  }
1617 
1618  /* Set up the service key name buffer */
1619  ServiceKeyName.MaximumLength = LocalDriverName.Length + sizeof(UNICODE_NULL);
1620  ServiceKeyName.Buffer = ExAllocatePoolWithTag(PagedPool, LocalDriverName.MaximumLength, TAG_IO);
1621  if (!ServiceKeyName.Buffer)
1622  {
1623  /* Fail */
1627  }
1628 
1629  /* For builtin drivers, the ServiceKeyName is equal to DriverName */
1630  RtlCopyUnicodeString(&ServiceKeyName, &LocalDriverName);
1631  ServiceKeyName.Buffer[ServiceKeyName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1632  DriverObject->DriverExtension->ServiceKeyName = ServiceKeyName;
1633 
1634  /* Make a copy of the driver name to store in the driver object */
1635  DriverObject->DriverName.MaximumLength = LocalDriverName.Length;
1636  DriverObject->DriverName.Buffer = ExAllocatePoolWithTag(PagedPool,
1637  DriverObject->DriverName.MaximumLength,
1638  TAG_IO);
1639  if (!DriverObject->DriverName.Buffer)
1640  {
1641  /* Fail */
1645  }
1646 
1647  RtlCopyUnicodeString(&DriverObject->DriverName, &LocalDriverName);
1648 
1649  /* Add the Object and get its handle */
1651  NULL,
1653  0,
1654  NULL,
1655  &hDriver);
1656 
1657  /* Eliminate small possibility when this function is called more than
1658  once in a row, and KeTickCount doesn't get enough time to change */
1659  if (!DriverName && (Status == STATUS_OBJECT_NAME_COLLISION) && (RetryCount < 100))
1660  {
1661  RetryCount++;
1662  goto try_again;
1663  }
1664 
1665  if (!NT_SUCCESS(Status)) return Status;
1666 
1667  /* Now reference it */
1669  0,
1671  KernelMode,
1672  (PVOID*)&DriverObject,
1673  NULL);
1674 
1675  /* Close the extra handle */
1676  ZwClose(hDriver);
1677 
1678  if (!NT_SUCCESS(Status))
1679  {
1680  /* Fail */
1683  return Status;
1684  }
1685 
1686  /* Finally, call its init function */
1687  DPRINT("Calling driver entrypoint at %p\n", InitializationFunction);
1688  Status = InitializationFunction(DriverObject, NULL);
1689  if (!NT_SUCCESS(Status))
1690  {
1691  /* If it didn't work, then kill the object */
1692  DPRINT1("'%wZ' initialization failed, status (0x%08lx)\n", DriverName, Status);
1695  return Status;
1696  }
1697 
1698  // Windows does this fixup - keep it for compatibility
1699  for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
1700  {
1701  /*
1702  * Make sure the driver didn't set any dispatch entry point to NULL!
1703  * Doing so is illegal; drivers shouldn't touch entry points they
1704  * do not implement.
1705  */
1706 
1707  /* Check if it did so anyway */
1708  if (!DriverObject->MajorFunction[i])
1709  {
1710  /* Print a warning in the debug log */
1711  DPRINT1("Driver <%wZ> set DriverObject->MajorFunction[%lu] to NULL!\n",
1712  &DriverObject->DriverName, i);
1713 
1714  /* Fix it up */
1715  DriverObject->MajorFunction[i] = IopInvalidDeviceRequest;
1716  }
1717  }
1718 
1719  /* Return the Status */
1720  return Status;
1721 }
#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:75
#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:65
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define L(x)
Definition: ntvdm.h:50
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:951
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
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:2934
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:1360

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

◆ IoDeleteDriver()

VOID NTAPI IoDeleteDriver ( IN PDRIVER_OBJECT  DriverObject)

Definition at line 1728 of file driver.c.

1729 {
1730  /* Simply dereference the Object */
1732 }
_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 1875 of file driver.c.

1877 {
1878  KIRQL OldIrql;
1879  PIO_CLIENT_EXTENSION DriverExtensions;
1880 
1881  /* Acquire lock */
1883 
1884  /* Loop the list until we find the right one */
1885  DriverExtensions = IoGetDrvObjExtension(DriverObject)->ClientDriverExtension;
1886  while (DriverExtensions)
1887  {
1888  /* Check for a match */
1889  if (DriverExtensions->ClientIdentificationAddress ==
1891  {
1892  /* Break out */
1893  break;
1894  }
1895 
1896  /* Keep looping */
1897  DriverExtensions = DriverExtensions->NextExtension;
1898  }
1899 
1900  /* Release lock */
1902 
1903  /* Return nothing or the extension */
1904  if (!DriverExtensions) return NULL;
1905  return DriverExtensions + 1;
1906 }
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:828
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
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define NULL
Definition: types.h:112
PVOID ClientIdentificationAddress
Definition: iotypes.h:829
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 77 of file driver.c.

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

316 {
317  CHAR TextBuffer[256];
318  UNICODE_STRING DotSys = RTL_CONSTANT_STRING(L".SYS");
319 
320  if (ExpInTextModeSetup) return;
321  if (!KeLoaderBlock) return;
323  snprintf(TextBuffer, sizeof(TextBuffer),
324  "%s%sSystem32\\Drivers\\%wZ%s\r\n",
327  ServiceName,
328  IopSuffixUnicodeString(&DotSys, ServiceName) ? "" : ".SYS");
330 }
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 L(x)
Definition: ntvdm.h:50
#define FALSE
Definition: types.h:117
PLOADER_PARAMETER_BLOCK KeLoaderBlock
Definition: krnlinit.c:29
LPTSTR ServiceName
Definition: ServiceMain.c:15
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:281

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

2073 {
2074  LOAD_UNLOAD_PARAMS LoadParams;
2075 
2076  /* Prepare parameters block */
2077  LoadParams.RegistryPath = RegistryPath;
2078  LoadParams.DriverObject = *DriverObject;
2079 
2081  {
2082  LoadParams.SetEvent = TRUE;
2084 
2085  /* Initialize and queue a work item */
2086  ExInitializeWorkItem(&LoadParams.WorkItem, IopLoadUnloadDriverWorker, &LoadParams);
2088 
2089  /* And wait till it completes */
2091  }
2092  else
2093  {
2094  /* If we're already in a system process, call it right here */
2095  LoadParams.SetEvent = FALSE;
2096  IopLoadUnloadDriverWorker(&LoadParams);
2097  }
2098 
2099  return LoadParams.Status;
2100 }
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:2024
#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:50
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:48
BOOLEAN SetEvent
Definition: driver.c:53
PDRIVER_OBJECT DriverObject
Definition: driver.c:52
PUNICODE_STRING RegistryPath
Definition: driver.c:49
#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:855
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 123 of file driver.c.

127 {
128  UNICODE_STRING driverName = {.Buffer = NULL}, serviceName;
131 
132  PAGED_CODE();
133 
134  /* 1. Check the "ObjectName" field in the driver's registry key (it has priority) */
135  status = IopGetRegistryValue(ServiceHandle, L"ObjectName", &kvInfo);
136  if (NT_SUCCESS(status))
137  {
138  /* We've got the ObjectName, use it as the driver name */
139  if (kvInfo->Type != REG_SZ || kvInfo->DataLength == 0)
140  {
141  ExFreePool(kvInfo);
143  }
144 
145  driverName.Length = kvInfo->DataLength - sizeof(UNICODE_NULL);
146  driverName.MaximumLength = kvInfo->DataLength;
147  driverName.Buffer = ExAllocatePoolWithTag(NonPagedPool, driverName.MaximumLength, TAG_IO);
148  if (!driverName.Buffer)
149  {
150  ExFreePool(kvInfo);
152  }
153 
154  RtlMoveMemory(driverName.Buffer,
155  (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
156  driverName.Length);
157  driverName.Buffer[driverName.Length / sizeof(WCHAR)] = UNICODE_NULL;
158  ExFreePool(kvInfo);
159  }
160 
161  /* Check whether we need to get ServiceName as well, either to construct
162  * the driver name (because we could not use "ObjectName"), or because
163  * it is requested by the caller. */
164  PKEY_BASIC_INFORMATION basicInfo = NULL;
165  if (!NT_SUCCESS(status) || ServiceName != NULL)
166  {
167  /* Retrieve the necessary buffer size */
168  ULONG infoLength;
169  status = ZwQueryKey(ServiceHandle, KeyBasicInformation, NULL, 0, &infoLength);
171  {
173  goto Cleanup;
174  }
175 
176  /* Allocate the buffer and retrieve the data */
177  basicInfo = ExAllocatePoolWithTag(PagedPool, infoLength, TAG_IO);
178  if (!basicInfo)
179  {
181  goto Cleanup;
182  }
183 
184  status = ZwQueryKey(ServiceHandle, KeyBasicInformation, basicInfo, infoLength, &infoLength);
185  if (!NT_SUCCESS(status))
186  {
187  goto Cleanup;
188  }
189 
190  serviceName.Length = basicInfo->NameLength;
191  serviceName.MaximumLength = basicInfo->NameLength;
192  serviceName.Buffer = basicInfo->Name;
193  }
194 
195  /* 2. There is no "ObjectName" - construct it ourselves. Depending on the driver type,
196  * it will be either "\Driver<ServiceName>" or "\FileSystem<ServiceName>" */
197  if (driverName.Buffer == NULL)
198  {
199  ASSERT(basicInfo); // Container for serviceName
200 
201  /* Retrieve the driver type */
202  ULONG driverType;
203  status = IopGetRegistryValue(ServiceHandle, L"Type", &kvInfo);
204  if (!NT_SUCCESS(status))
205  {
206  goto Cleanup;
207  }
208  if (kvInfo->Type != REG_DWORD || kvInfo->DataLength != sizeof(ULONG))
209  {
210  ExFreePool(kvInfo);
212  goto Cleanup;
213  }
214 
215  RtlMoveMemory(&driverType,
216  (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
217  sizeof(ULONG));
218  ExFreePool(kvInfo);
219 
220  /* Compute the necessary driver name string size */
221  if (driverType == SERVICE_RECOGNIZER_DRIVER || driverType == SERVICE_FILE_SYSTEM_DRIVER)
222  driverName.MaximumLength = sizeof(FILESYSTEM_ROOT_NAME);
223  else
224  driverName.MaximumLength = sizeof(DRIVER_ROOT_NAME);
225 
226  driverName.MaximumLength += serviceName.Length;
227  driverName.Length = 0;
228 
229  /* Allocate and build it */
230  driverName.Buffer = ExAllocatePoolWithTag(NonPagedPool, driverName.MaximumLength, TAG_IO);
231  if (!driverName.Buffer)
232  {
234  goto Cleanup;
235  }
236 
237  if (driverType == SERVICE_RECOGNIZER_DRIVER || driverType == SERVICE_FILE_SYSTEM_DRIVER)
239  else
241 
243  }
244 
245  if (ServiceName != NULL)
246  {
247  ASSERT(basicInfo); // Container for serviceName
248 
249  /* Allocate a copy for the caller */
251  if (!buf)
252  {
254  goto Cleanup;
255  }
256  RtlMoveMemory(buf, serviceName.Buffer, serviceName.Length);
257  ServiceName->MaximumLength = serviceName.Length;
258  ServiceName->Length = serviceName.Length;
259  ServiceName->Buffer = buf;
260  }
261 
262  *DriverName = driverName;
264 
265 Cleanup:
266  if (basicInfo)
267  ExFreePoolWithTag(basicInfo, TAG_IO);
268 
269  if (!NT_SUCCESS(status) && driverName.Buffer)
270  ExFreePoolWithTag(driverName.Buffer, TAG_IO);
271 
272  return status;
273 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define TAG_IO
Definition: tag.h:75
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 L(x)
Definition: ntvdm.h:50
#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 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 1001 of file driver.c.

1002 {
1003  PLIST_ENTRY ListHead, NextEntry, NextEntry2;
1004  PLDR_DATA_TABLE_ENTRY LdrEntry;
1005  NTSTATUS Status;
1006  UNICODE_STRING DriverName;
1007  ULONG i, Index;
1008  PDRIVER_INFORMATION DriverInfo, DriverInfoTag;
1009  HANDLE KeyHandle;
1010  PBOOT_DRIVER_LIST_ENTRY BootEntry;
1011  DPRINT("IopInitializeBootDrivers()\n");
1012 
1013  /* Create the RAW FS built-in driver */
1014  RtlInitUnicodeString(&DriverName, L"\\FileSystem\\RAW");
1015 
1016  Status = IoCreateDriver(&DriverName, RawFsDriverEntry);
1017  if (!NT_SUCCESS(Status))
1018  {
1019  /* Fail */
1020  return;
1021  }
1022 
1023  /* Get highest group order index */
1025  if (IopGroupIndex == 0xFFFF) ASSERT(FALSE);
1026 
1027  /* Allocate the group table */
1029  IopGroupIndex * sizeof(LIST_ENTRY),
1030  TAG_IO);
1031  if (IopGroupTable == NULL) ASSERT(FALSE);
1032 
1033  /* Initialize the group table lists */
1034  for (i = 0; i < IopGroupIndex; i++) InitializeListHead(&IopGroupTable[i]);
1035 
1036  /* Loop the boot modules */
1037  ListHead = &KeLoaderBlock->LoadOrderListHead;
1038  for (NextEntry = ListHead->Flink;
1039  NextEntry != ListHead;
1040  NextEntry = NextEntry->Flink)
1041  {
1042  /* Get the entry */
1043  LdrEntry = CONTAINING_RECORD(NextEntry,
1045  InLoadOrderLinks);
1046 
1047  /* Check if the DLL needs to be initialized */
1048  if (LdrEntry->Flags & LDRP_DRIVER_DEPENDENT_DLL)
1049  {
1050  /* Call its entrypoint */
1051  MmCallDllInitialize(LdrEntry, NULL);
1052  }
1053  }
1054 
1055  /* Loop the boot drivers */
1056  ListHead = &KeLoaderBlock->BootDriverListHead;
1057  for (NextEntry = ListHead->Flink;
1058  NextEntry != ListHead;
1059  NextEntry = NextEntry->Flink)
1060  {
1061  /* Get the entry */
1062  BootEntry = CONTAINING_RECORD(NextEntry,
1064  Link);
1065 
1066  // FIXME: TODO: This LdrEntry is to be used in a special handling
1067  // for SETUPLDR (a similar procedure is done on Windows), where
1068  // the loader would, under certain conditions, be loaded in the
1069  // SETUPLDR-specific code block below...
1070 #if 0
1071  /* Get the driver loader entry */
1072  LdrEntry = BootEntry->LdrEntry;
1073 #endif
1074 
1075  /* Allocate our internal accounting structure */
1077  sizeof(DRIVER_INFORMATION),
1078  TAG_IO);
1079  if (DriverInfo)
1080  {
1081  /* Zero it and initialize it */
1084  DriverInfo->DataTableEntry = BootEntry;
1085 
1086  /* Open the registry key */
1088  NULL,
1089  &BootEntry->RegistryPath,
1090  KEY_READ);
1091  DPRINT("IopOpenRegistryKeyEx(%wZ) returned 0x%08lx\n", &BootEntry->RegistryPath, Status);
1092 #if 0
1093  if (NT_SUCCESS(Status))
1094 #else // Hack still needed...
1095  if ((NT_SUCCESS(Status)) || /* ReactOS HACK for SETUPLDR */
1096  ((KeLoaderBlock->SetupLdrBlock) && ((KeyHandle = (PVOID)1)))) // yes, it's an assignment!
1097 #endif
1098  {
1099  /* Save the handle */
1101 
1102  /* Get the group oder index */
1104 
1105  /* Get the tag position */
1107 
1108  /* Insert it into the list, at the right place */
1110  NextEntry2 = IopGroupTable[Index].Flink;
1111  while (NextEntry2 != &IopGroupTable[Index])
1112  {
1113  /* Get the driver info */
1114  DriverInfoTag = CONTAINING_RECORD(NextEntry2,
1116  Link);
1117 
1118  /* Check if we found the right tag position */
1119  if (DriverInfoTag->TagPosition > DriverInfo->TagPosition)
1120  {
1121  /* We're done */
1122  break;
1123  }
1124 
1125  /* Next entry */
1126  NextEntry2 = NextEntry2->Flink;
1127  }
1128 
1129  /* Insert us right before the next entry */
1130  NextEntry2 = NextEntry2->Blink;
1131  InsertHeadList(NextEntry2, &DriverInfo->Link);
1132  }
1133  }
1134  }
1135 
1136  /* Loop each group index */
1137  for (i = 0; i < IopGroupIndex; i++)
1138  {
1139  /* Loop each group table */
1140  for (NextEntry = IopGroupTable[i].Flink;
1141  NextEntry != &IopGroupTable[i];
1142  NextEntry = NextEntry->Flink)
1143  {
1144  /* Get the entry */
1145  DriverInfo = CONTAINING_RECORD(NextEntry,
1147  Link);
1148 
1149  /* Get the driver loader entry */
1150  LdrEntry = DriverInfo->DataTableEntry->LdrEntry;
1151 
1152  /* Initialize it */
1153  if (IopInitializeBuiltinDriver(LdrEntry))
1154  {
1155  // it does not make sense to enumerate the tree if there are no new devices added
1158  NULL,
1159  NULL);
1160  }
1161  }
1162  }
1163 
1164  /* HAL Root Bus is being initialized before loading the boot drivers so this may cause issues
1165  * when some devices are not being initialized with their drivers. This flag is used to delay
1166  * all actions with devices (except PnP root device) until boot drivers are loaded.
1167  * See PiQueueDeviceAction function
1168  */
1170 
1171  DbgPrint("BOOT DRIVERS LOADED\n");
1172 
1175  NULL,
1176  NULL);
1177 }
NTSTATUS NTAPI RawFsDriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
Definition: rawfs.c:1193
PDEVICE_OBJECT PhysicalDeviceObject
Definition: iotypes.h:855
PDEVICE_NODE IopRootDeviceNode
Definition: devnode.c:18
#define TAG_IO
Definition: tag.h:75
#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:2635
_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:792
#define L(x)
Definition: ntvdm.h:50
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:1548
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:41
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
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:40
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 792 of file driver.c.

793 {
796  PWCHAR Buffer, FileNameWithoutPath;
797  PWSTR FileExtension;
798  PUNICODE_STRING ModuleName = &BootLdrEntry->BaseDllName;
799  PLDR_DATA_TABLE_ENTRY LdrEntry;
800  PLIST_ENTRY NextEntry;
803 
804  /*
805  * Display 'Loading XXX...' message
806  */
809 
811  ModuleName->Length + sizeof(UNICODE_NULL),
812  TAG_IO);
813  if (Buffer == NULL)
814  {
815  return FALSE;
816  }
817 
819  Buffer[ModuleName->Length / sizeof(WCHAR)] = UNICODE_NULL;
820 
821  /*
822  * Generate filename without path (not needed by freeldr)
823  */
824  FileNameWithoutPath = wcsrchr(Buffer, L'\\');
825  if (FileNameWithoutPath == NULL)
826  {
827  FileNameWithoutPath = Buffer;
828  }
829  else
830  {
831  FileNameWithoutPath++;
832  }
833 
834  /*
835  * Strip the file extension from ServiceName
836  */
837  Success = RtlCreateUnicodeString(&ServiceName, FileNameWithoutPath);
839  if (!Success)
840  {
841  return FALSE;
842  }
843 
844  FileExtension = wcsrchr(ServiceName.Buffer, L'.');
845  if (FileExtension != NULL)
846  {
847  ServiceName.Length -= (USHORT)wcslen(FileExtension) * sizeof(WCHAR);
848  FileExtension[0] = UNICODE_NULL;
849  }
850 
852 
853  // Make the registry path for the driver
854  RegistryPath.Length = 0;
855  RegistryPath.MaximumLength = sizeof(ServicesKeyName) + ServiceName.Length;
857  if (RegistryPath.Buffer == NULL)
858  {
859  return FALSE;
860  }
864 
865  HANDLE serviceHandle;
866  Status = IopOpenRegistryKeyEx(&serviceHandle, NULL, &RegistryPath, KEY_READ);
868  if (!NT_SUCCESS(Status))
869  {
870  return FALSE;
871  }
872 
873  /* Lookup the new Ldr entry in PsLoadedModuleList */
874  for (NextEntry = PsLoadedModuleList.Flink;
875  NextEntry != &PsLoadedModuleList;
876  NextEntry = NextEntry->Flink)
877  {
878  LdrEntry = CONTAINING_RECORD(NextEntry,
880  InLoadOrderLinks);
882  {
883  break;
884  }
885  }
886  ASSERT(NextEntry != &PsLoadedModuleList);
887 
888  /*
889  * Initialize the driver
890  */
891  NTSTATUS driverEntryStatus;
893  serviceHandle,
894  &DriverObject,
895  &driverEntryStatus);
896 
897  if (!NT_SUCCESS(Status))
898  {
899  DPRINT1("Driver '%wZ' load failed, status (%x)\n", ModuleName, Status);
900  return FALSE;
901  }
902 
903  // The driver has been loaded, now check if where are any PDOs
904  // for that driver, and queue AddDevice call for them.
905  // The check is possible because HKLM/SYSTEM/CCS/Services/<ServiceName>/Enum directory
906  // is populated upon a new device arrival based on a (critical) device database
907 
908  // Legacy drivers may add devices inside DriverEntry.
909  // We're lazy and always assume that they are doing so
910  BOOLEAN deviceAdded = !!(DriverObject->Flags & DRVO_LEGACY_DRIVER);
911 
912  HANDLE enumServiceHandle;
913  UNICODE_STRING enumName = RTL_CONSTANT_STRING(L"Enum");
914 
915  Status = IopOpenRegistryKeyEx(&enumServiceHandle, serviceHandle, &enumName, KEY_READ);
916  ZwClose(serviceHandle);
917 
918  if (NT_SUCCESS(Status))
919  {
920  ULONG instanceCount = 0;
922  Status = IopGetRegistryValue(enumServiceHandle, L"Count", &kvInfo);
923  if (!NT_SUCCESS(Status))
924  {
925  goto Cleanup;
926  }
927  if (kvInfo->Type != REG_DWORD || kvInfo->DataLength != sizeof(ULONG))
928  {
929  ExFreePool(kvInfo);
930  goto Cleanup;
931  }
932 
933  RtlMoveMemory(&instanceCount,
934  (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
935  sizeof(ULONG));
936  ExFreePool(kvInfo);
937 
938  DPRINT("Processing %u instances for %wZ module\n", instanceCount, ModuleName);
939 
940  for (ULONG i = 0; i < instanceCount; i++)
941  {
942  WCHAR num[11];
943  UNICODE_STRING instancePath;
944  RtlStringCchPrintfW(num, sizeof(num), L"%u", i);
945 
946  Status = IopGetRegistryValue(enumServiceHandle, num, &kvInfo);
947  if (!NT_SUCCESS(Status))
948  {
949  continue;
950  }
951  if (kvInfo->Type != REG_SZ || kvInfo->DataLength == 0)
952  {
953  ExFreePool(kvInfo);
954  continue;
955  }
956 
957  instancePath.Length = kvInfo->DataLength - sizeof(UNICODE_NULL);
958  instancePath.MaximumLength = kvInfo->DataLength;
960  instancePath.MaximumLength,
961  TAG_IO);
962  if (instancePath.Buffer)
963  {
964  RtlMoveMemory(instancePath.Buffer,
965  (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
966  instancePath.Length);
967  instancePath.Buffer[instancePath.Length / sizeof(WCHAR)] = UNICODE_NULL;
968 
971  ObDereferenceObject(pdo);
972  deviceAdded = TRUE;
973  }
974 
975  ExFreePool(kvInfo);
976  }
977 
978  ZwClose(enumServiceHandle);
979  }
980 Cleanup:
981  /* Remove extra reference from IopInitializeDriverModule */
983 
984  return deviceAdded;
985 }
#define DRVO_LEGACY_DRIVER
Definition: iotypes.h:2226
VOID NTAPI InbvIndicateProgress(VOID)
Definition: inbv.c:880
#define TAG_IO
Definition: tag.h:75
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:2635
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:315
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 L(x)
Definition: ntvdm.h:50
#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)
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:428
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 428 of file driver.c.

433 {
436 
437  PAGED_CODE();
438 
439  Status = IopGetDriverNames(ServiceHandle, &DriverName, &ServiceName);
440  if (!NT_SUCCESS(Status))
441  {
442  MmUnloadSystemImage(ModuleObject);
443  return Status;
444  }
445 
446  DPRINT("Driver name: '%wZ'\n", &DriverName);
447 
448  /*
449  * Retrieve the driver's PE image NT header and perform some sanity checks.
450  * NOTE: We suppose that since the driver has been successfully loaded,
451  * its NT and optional headers are all valid and have expected sizes.
452  */
453  PIMAGE_NT_HEADERS NtHeaders = RtlImageNtHeader(ModuleObject->DllBase);
454  ASSERT(NtHeaders);
455  // NOTE: ModuleObject->SizeOfImage is actually (number of PTEs)*PAGE_SIZE.
456  ASSERT(ModuleObject->SizeOfImage == ROUND_TO_PAGES(NtHeaders->OptionalHeader.SizeOfImage));
457  ASSERT(ModuleObject->EntryPoint == RVA(ModuleObject->DllBase, NtHeaders->OptionalHeader.AddressOfEntryPoint));
458 
459  /* Obtain the registry path for the DriverInit routine */
460  PKEY_NAME_INFORMATION nameInfo;
461  ULONG infoLength;
462  Status = ZwQueryKey(ServiceHandle, KeyNameInformation, NULL, 0, &infoLength);
464  {
465  nameInfo = ExAllocatePoolWithTag(NonPagedPool, infoLength, TAG_IO);
466  if (nameInfo)
467  {
468  Status = ZwQueryKey(ServiceHandle,
470  nameInfo,
471  infoLength,
472  &infoLength);
473  if (NT_SUCCESS(Status))
474  {
475  RegistryPath.Length = nameInfo->NameLength;
476  RegistryPath.MaximumLength = nameInfo->NameLength;
477  RegistryPath.Buffer = nameInfo->Name;
478  }
479  else
480  {
481  ExFreePoolWithTag(nameInfo, TAG_IO);
482  }
483  }
484  else
485  {
487  }
488  }
489  else
490  {
492  }
493 
494  if (!NT_SUCCESS(Status))
495  {
497  RtlFreeUnicodeString(&DriverName);
498  MmUnloadSystemImage(ModuleObject);
499  return Status;
500  }
501 
502  /* Create the driver object */
503  ULONG ObjectSize = sizeof(DRIVER_OBJECT) + sizeof(EXTENDED_DRIVER_EXTENSION);
504  OBJECT_ATTRIBUTES objAttrs;
505  PDRIVER_OBJECT driverObject;
506  InitializeObjectAttributes(&objAttrs,
507  &DriverName,
509  NULL,
510  NULL);
511 
514  &objAttrs,
515  KernelMode,
516  NULL,
517  ObjectSize,
518  0,
519  0,
520  (PVOID*)&driverObject);
521  if (!NT_SUCCESS(Status))
522  {
523  ExFreePoolWithTag(nameInfo, TAG_IO); // container for RegistryPath
525  RtlFreeUnicodeString(&DriverName);
526  MmUnloadSystemImage(ModuleObject);
527  DPRINT1("Error while creating driver object \"%wZ\" status %x\n", &DriverName, Status);
528  return Status;
529  }
530 
531  DPRINT("Created driver object 0x%p for \"%wZ\"\n", driverObject, &DriverName);
532 
533  RtlZeroMemory(driverObject, ObjectSize);
534  driverObject->Type = IO_TYPE_DRIVER;
535  driverObject->Size = sizeof(DRIVER_OBJECT);
536 
537  /* Set the legacy flag if this is not a WDM driver */
539  driverObject->Flags |= DRVO_LEGACY_DRIVER;
540 
541  driverObject->DriverSection = ModuleObject;
542  driverObject->DriverStart = ModuleObject->DllBase;
543  driverObject->DriverSize = ModuleObject->SizeOfImage;
544  driverObject->DriverInit = ModuleObject->EntryPoint;
545  driverObject->HardwareDatabase = &IopHardwareDatabaseKey;
546  driverObject->DriverExtension = (PDRIVER_EXTENSION)(driverObject + 1);
547  driverObject->DriverExtension->DriverObject = driverObject;
548 
549  /* Loop all Major Functions */
550  for (INT i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
551  {
552  /* Invalidate each function */
553  driverObject->MajorFunction[i] = IopInvalidDeviceRequest;
554  }
555 
556  /* Add the Object and get its handle */
557  HANDLE hDriver;
558  Status = ObInsertObject(driverObject, NULL, FILE_READ_DATA, 0, NULL, &hDriver);
559  if (!NT_SUCCESS(Status))
560  {
561  ExFreePoolWithTag(nameInfo, TAG_IO);
563  RtlFreeUnicodeString(&DriverName);
564  return Status;
565  }
566 
567  /* Now reference it */
569  0,
571  KernelMode,
572  (PVOID*)&driverObject,
573  NULL);
574 
575  /* Close the extra handle */
576  ZwClose(hDriver);
577 
578  if (!NT_SUCCESS(Status))
579  {
580  ExFreePoolWithTag(nameInfo, TAG_IO); // container for RegistryPath
582  RtlFreeUnicodeString(&DriverName);
583  return Status;
584  }
585 
586  /* Set up the service key name buffer */
587  UNICODE_STRING serviceKeyName;
588  serviceKeyName.Length = 0;
589  // NULL-terminate for Windows compatibility
590  serviceKeyName.MaximumLength = ServiceName.MaximumLength + sizeof(UNICODE_NULL);
591  serviceKeyName.Buffer = ExAllocatePoolWithTag(NonPagedPool,
592  serviceKeyName.MaximumLength,
593  TAG_IO);
594  if (!serviceKeyName.Buffer)
595  {
596  ObMakeTemporaryObject(driverObject);
597  ObDereferenceObject(driverObject);
598  ExFreePoolWithTag(nameInfo, TAG_IO); // container for RegistryPath
600  RtlFreeUnicodeString(&DriverName);
602  }
603 
604  /* Copy the name and set it in the driver extension */
605  RtlCopyUnicodeString(&serviceKeyName, &ServiceName);
607  driverObject->DriverExtension->ServiceKeyName = serviceKeyName;
608 
609  /* Make a copy of the driver name to store in the driver object */
610  UNICODE_STRING driverNamePaged;
611  driverNamePaged.Length = 0;
612  // NULL-terminate for Windows compatibility
613  driverNamePaged.MaximumLength = DriverName.MaximumLength + sizeof(UNICODE_NULL);
614  driverNamePaged.Buffer = ExAllocatePoolWithTag(PagedPool,
615  driverNamePaged.MaximumLength,
616  TAG_IO);
617  if (!driverNamePaged.Buffer)
618  {
619  ObMakeTemporaryObject(driverObject);
620  ObDereferenceObject(driverObject);
621  ExFreePoolWithTag(nameInfo, TAG_IO); // container for RegistryPath
622  RtlFreeUnicodeString(&DriverName);
624  }
625 
626  RtlCopyUnicodeString(&driverNamePaged, &DriverName);
627  driverObject->DriverName = driverNamePaged;
628 
629  /* Finally, call its init function */
630  Status = driverObject->DriverInit(driverObject, &RegistryPath);
631  *DriverEntryStatus = Status;
632  if (!NT_SUCCESS(Status))
633  {
634  DPRINT1("'%wZ' initialization failed, status (0x%08lx)\n", &DriverName, Status);
635  // return a special status value in case of failure
637  }
638 
639  /* HACK: We're going to say if we don't have any DOs from DriverEntry, then we're not legacy.
640  * Other parts of the I/O manager depend on this behavior */
641  if (!driverObject->DeviceObject)
642  {
643  driverObject->Flags &= ~DRVO_LEGACY_DRIVER;
644  }
645 
646  // Windows does this fixup - keep it for compatibility
647  for (INT i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
648  {
649  /*
650  * Make sure the driver didn't set any dispatch entry point to NULL!
651  * Doing so is illegal; drivers shouldn't touch entry points they
652  * do not implement.
653  */
654 
655  /* Check if it did so anyway */
656  if (!driverObject->MajorFunction[i])
657  {
658  /* Print a warning in the debug log */
659  DPRINT1("Driver <%wZ> set DriverObject->MajorFunction[%lu] to NULL!\n",
660  &driverObject->DriverName, i);
661 
662  /* Fix it up */
663  driverObject->MajorFunction[i] = IopInvalidDeviceRequest;
664  }
665  }
666 
667  // TODO: for legacy drivers, unload the driver if it didn't create any DO
668 
669  ExFreePoolWithTag(nameInfo, TAG_IO); // container for RegistryPath
670  RtlFreeUnicodeString(&DriverName);
671 
672  if (!NT_SUCCESS(Status))
673  {
674  // if the driver entry has been failed, clear the object
675  ObMakeTemporaryObject(driverObject);
676  ObDereferenceObject(driverObject);
677  return Status;
678  }
679 
680  *OutDriverObject = driverObject;
681 
683 
684  /* Set the driver as initialized */
685  IopReadyDeviceObjects(driverObject);
686 
688 
689  return STATUS_SUCCESS;
690 }
#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:75
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
VOID NTAPI IopReinitializeDrivers(VOID)
Definition: driver.c:1468
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:123
NTSTATUS NTAPI IopInvalidDeviceRequest(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: driver.c:65
#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:951
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:2934
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:1360

Referenced by IopInitializeBuiltinDriver(), and IopLoadDriver().

◆ IopInitializeSystemDrivers()

VOID FASTCALL IopInitializeSystemDrivers ( VOID  )

Definition at line 1182 of file driver.c.

1183 {
1184  PUNICODE_STRING *DriverList, *SavedList;
1185 
1187 
1188  /* No system drivers on the boot cd */
1189  if (KeLoaderBlock->SetupLdrBlock) return; // ExpInTextModeSetup
1190 
1191  /* Get the driver list */
1192  SavedList = DriverList = CmGetSystemDriverList();
1193  ASSERT(DriverList);
1194 
1195  /* Loop it */
1196  while (*DriverList)
1197  {
1198  /* Load the driver */
1199  ZwLoadDriver(*DriverList);
1200 
1201  /* Free the entry */
1202  RtlFreeUnicodeString(*DriverList);
1203  ExFreePool(*DriverList);
1204 
1205  /* Next entry */
1207  DriverList++;
1208  }
1209 
1210  /* Free the list */
1211  ExFreePool(SavedList);
1212 
1215  NULL,
1216  NULL);
1217 }
PDEVICE_OBJECT PhysicalDeviceObject
Definition: iotypes.h:855
VOID NTAPI InbvIndicateProgress(VOID)
Definition: inbv.c:880
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:2635
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:2694
#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 65 of file driver.c.

68 {
69  Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
70  Irp->IoStatus.Information = 0;
73 }
#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 1909 of file driver.c.

1912 {
1913  UNICODE_STRING ImagePath;
1914  NTSTATUS Status;
1915  PLDR_DATA_TABLE_ENTRY ModuleObject;
1917 
1919  Status = IopGetRegistryValue(ServiceHandle, L"ImagePath", &kvInfo);
1920  if (NT_SUCCESS(Status))
1921  {
1922  if (kvInfo->Type != REG_EXPAND_SZ || kvInfo->DataLength == 0)
1923  {
1924  ExFreePool(kvInfo);
1926  }
1927 
1928  ImagePath.Length = kvInfo->DataLength - sizeof(UNICODE_NULL);
1929  ImagePath.MaximumLength = kvInfo->DataLength;
1931  if (!ImagePath.Buffer)
1932  {
1933  ExFreePool(kvInfo);
1935  }
1936 
1937  RtlMoveMemory(ImagePath.Buffer,
1938  (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
1939  ImagePath.Length);
1940  ImagePath.Buffer[ImagePath.Length / sizeof(WCHAR)] = UNICODE_NULL;
1941  ExFreePool(kvInfo);
1942  }
1943  else
1944  {
1945  return Status;
1946  }
1947 
1948  /*
1949  * Normalize the image path for all later processing.
1950  */
1951  Status = IopNormalizeImagePath(&ImagePath, NULL);
1952  if (!NT_SUCCESS(Status))
1953  {
1954  DPRINT("IopNormalizeImagePath() failed (Status %x)\n", Status);
1955  return Status;
1956  }
1957 
1958  DPRINT("FullImagePath: '%wZ'\n", &ImagePath);
1959 
1962 
1963  /*
1964  * Load the driver module
1965  */
1966  DPRINT("Loading module from %wZ\n", &ImagePath);
1967  Status = MmLoadSystemImage(&ImagePath, NULL, NULL, 0, (PVOID)&ModuleObject, &BaseAddress);
1968  RtlFreeUnicodeString(&ImagePath);
1969 
1970  if (!NT_SUCCESS(Status))
1971  {
1972  DPRINT("MmLoadSystemImage() failed (Status %lx)\n", Status);
1975  return Status;
1976  }
1977 
1978  // Display the loading message
1979  ULONG infoLength;
1980  Status = ZwQueryKey(ServiceHandle, KeyBasicInformation, NULL, 0, &infoLength);
1982  {
1984  if (servName)
1985  {
1986  Status = ZwQueryKey(ServiceHandle,
1988  servName,
1989  infoLength,
1990  &infoLength);
1991  if (NT_SUCCESS(Status))
1992  {
1994  .Length = servName->NameLength,
1995  .MaximumLength = servName->NameLength,
1996  .Buffer = servName->Name
1997  };
1998 
2000  }
2001  ExFreePoolWithTag(servName, TAG_IO);
2002  }
2003  }
2004 
2005  NTSTATUS driverEntryStatus;
2006  Status = IopInitializeDriverModule(ModuleObject,
2007  ServiceHandle,
2008  DriverObject,
2009  &driverEntryStatus);
2010  if (!NT_SUCCESS(Status))
2011  {
2012  DPRINT1("IopInitializeDriverModule() failed (Status %lx)\n", Status);
2013  }
2014 
2017 
2018  return Status;
2019 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define TAG_IO
Definition: tag.h:75
#define TAG_RTLREGISTRY
Definition: tag.h:92
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define TRUE
Definition: types.h:120
VOID FASTCALL IopDisplayLoadingMessage(PUNICODE_STRING ServiceName)
Definition: driver.c:315
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 L(x)
Definition: ntvdm.h:50
#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:354
_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
#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:428
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 2024 of file driver.c.

2026 {
2027  PLOAD_UNLOAD_PARAMS LoadParams = Parameter;
2028 
2030 
2031  if (LoadParams->DriverObject)
2032  {
2033  // unload request
2034  LoadParams->DriverObject->DriverUnload(LoadParams->DriverObject);
2035  LoadParams->Status = STATUS_SUCCESS;
2036  }
2037  else
2038  {
2039  // load request
2040  HANDLE serviceHandle;
2041  NTSTATUS status;
2042  status = IopOpenRegistryKeyEx(&serviceHandle, NULL, LoadParams->RegistryPath, KEY_READ);
2043  if (!NT_SUCCESS(status))
2044  {
2045  LoadParams->Status = status;
2046  }
2047  else
2048  {
2049  LoadParams->Status = IopLoadDriver(serviceHandle, &LoadParams->DriverObject);
2050  ZwClose(serviceHandle);
2051  }
2052  }
2053 
2054  if (LoadParams->SetEvent)
2055  {
2056  KeSetEvent(&LoadParams->Event, 0, FALSE);
2057  }
2058 }
#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:1909
_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:48
PDRIVER_UNLOAD DriverUnload
Definition: iotypes.h:2288
BOOLEAN SetEvent
Definition: driver.c:53
PDRIVER_OBJECT DriverObject
Definition: driver.c:52
PUNICODE_STRING RegistryPath
Definition: driver.c:49
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 354 of file driver.c.

358 {
359  UNICODE_STRING SystemRootString = RTL_CONSTANT_STRING(L"\\SystemRoot\\");
360  UNICODE_STRING DriversPathString = RTL_CONSTANT_STRING(L"\\SystemRoot\\System32\\drivers\\");
361  UNICODE_STRING DotSysString = RTL_CONSTANT_STRING(L".sys");
362  UNICODE_STRING InputImagePath;
363 
364  DPRINT("Normalizing image path '%wZ' for service '%wZ'\n", ImagePath, ServiceName);
365 
366  InputImagePath = *ImagePath;
367  if (InputImagePath.Length == 0)
368  {
369  ImagePath->Length = 0;
370  ImagePath->MaximumLength = DriversPathString.Length +
371  ServiceName->Length +
372  DotSysString.Length +
373  sizeof(UNICODE_NULL);
374  ImagePath->Buffer = ExAllocatePoolWithTag(NonPagedPool,
375  ImagePath->MaximumLength,
376  TAG_IO);
377  if (ImagePath->Buffer == NULL)
378  return STATUS_NO_MEMORY;
379 
380  RtlCopyUnicodeString(ImagePath, &DriversPathString);
382  RtlAppendUnicodeStringToString(ImagePath, &DotSysString);
383  }
384  else if (InputImagePath.Buffer[0] != L'\\')
385  {
386  ImagePath->Length = 0;
387  ImagePath->MaximumLength = SystemRootString.Length +
388  InputImagePath.Length +
389  sizeof(UNICODE_NULL);
390  ImagePath->Buffer = ExAllocatePoolWithTag(NonPagedPool,
391  ImagePath->MaximumLength,
392  TAG_IO);
393  if (ImagePath->Buffer == NULL)
394  return STATUS_NO_MEMORY;
395 
396  RtlCopyUnicodeString(ImagePath, &SystemRootString);
397  RtlAppendUnicodeStringToString(ImagePath, &InputImagePath);
398 
399  /* Free caller's string */
400  ExFreePoolWithTag(InputImagePath.Buffer, TAG_RTLREGISTRY);
401  }
402 
403  DPRINT("Normalized image path is '%wZ' for service '%wZ'\n", ImagePath, ServiceName);
404 
405  return STATUS_SUCCESS;
406 }
#define TAG_IO
Definition: tag.h:75
#define TAG_RTLREGISTRY
Definition: tag.h:92
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define L(x)
Definition: ntvdm.h:50
#define UNICODE_NULL
LPTSTR ServiceName
Definition: ServiceMain.c:15
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#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 1504 of file driver.c.

1505 {
1506  PDRIVER_REINIT_ITEM ReinitItem;
1508 
1509  /* Get the first entry and start looping */
1512  while (Entry)
1513  {
1514  /* Get the item */
1515  ReinitItem = CONTAINING_RECORD(Entry, DRIVER_REINIT_ITEM, ItemEntry);
1516 
1517  /* Increment reinitialization counter */
1518  ReinitItem->DriverObject->DriverExtension->Count++;
1519 
1520  /* Remove the device object flag */
1522 
1523  /* Call the routine */
1524  ReinitItem->ReinitRoutine(ReinitItem->DriverObject,
1525  ReinitItem->Context,
1526  ReinitItem->DriverObject->
1527  DriverExtension->Count);
1528 
1529  /* Free the entry */
1530  ExFreePool(Entry);
1531 
1532  /* Move to the next one */
1535  }
1536 
1537  /* Wait for all device actions being finished*/
1539 }
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 1468 of file driver.c.

1469 {
1470  PDRIVER_REINIT_ITEM ReinitItem;
1472 
1473  /* Get the first entry and start looping */
1476  while (Entry)
1477  {
1478  /* Get the item */
1479  ReinitItem = CONTAINING_RECORD(Entry, DRIVER_REINIT_ITEM, ItemEntry);
1480 
1481  /* Increment reinitialization counter */
1482  ReinitItem->DriverObject->DriverExtension->Count++;
1483 
1484  /* Remove the device object flag */
1485  ReinitItem->DriverObject->Flags &= ~DRVO_REINIT_REGISTERED;
1486 
1487  /* Call the routine */
1488  ReinitItem->ReinitRoutine(ReinitItem->DriverObject,
1489  ReinitItem->Context,
1490  ReinitItem->DriverObject->
1491  DriverExtension->Count);
1492 
1493  /* Free the entry */
1494  ExFreePool(Entry);
1495 
1496  /* Move to the next one */
1499  }
1500 }
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 281 of file driver.c.

284 {
285  PWCHAR pc1;
286  PWCHAR pc2;
287  ULONG Length;
288 
289  if (String2->Length < String1->Length)
290  return FALSE;
291 
292  Length = String1->Length / 2;
293  pc1 = String1->Buffer;
294  pc2 = &String2->Buffer[String2->Length / sizeof(WCHAR) - Length];
295 
296  if (pc1 && pc2)
297  {
298  while (Length--)
299  {
300  if( *pc1++ != *pc2++ )
301  return FALSE;
302  }
303  return TRUE;
304  }
305  return FALSE;
306 }
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 1241 of file driver.c.

1242 {
1243  UNICODE_STRING Backslash = RTL_CONSTANT_STRING(L"\\");
1245  UNICODE_STRING ImagePath;
1250  PEXTENDED_DEVOBJ_EXTENSION DeviceExtension;
1251  NTSTATUS Status;
1252  USHORT LastBackslash;
1253  BOOLEAN SafeToUnload = TRUE;
1255  UNICODE_STRING CapturedServiceName;
1256 
1257  PAGED_CODE();
1258 
1260 
1261  /* Need the appropriate priviliege */
1263  {
1264  DPRINT1("No unload privilege!\n");
1266  }
1267 
1268  /* Capture the service name */
1269  Status = ProbeAndCaptureUnicodeString(&CapturedServiceName,
1270  PreviousMode,
1271  DriverServiceName);
1272  if (!NT_SUCCESS(Status))
1273  {
1274  return Status;
1275  }
1276 
1277  DPRINT("IopUnloadDriver('%wZ', %u)\n", &CapturedServiceName, UnloadPnpDrivers);
1278 
1279  /* We need a service name */
1280  if (CapturedServiceName.Length == 0 || CapturedServiceName.Buffer == NULL)
1281  {
1282  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1283  return STATUS_INVALID_PARAMETER;
1284  }
1285 
1286  /*
1287  * Get the service name from the registry key name
1288  */
1290  &CapturedServiceName,
1291  &Backslash,
1292  &LastBackslash);
1293  if (NT_SUCCESS(Status))
1294  {
1295  NT_ASSERT(CapturedServiceName.Length >= LastBackslash + sizeof(WCHAR));
1296  ServiceName.Buffer = &CapturedServiceName.Buffer[LastBackslash / sizeof(WCHAR) + 1];
1297  ServiceName.Length = CapturedServiceName.Length - LastBackslash - sizeof(WCHAR);
1298  ServiceName.MaximumLength = CapturedServiceName.MaximumLength - LastBackslash - sizeof(WCHAR);
1299  }
1300  else
1301  {
1302  ServiceName = CapturedServiceName;
1303  }
1304 
1305  /*
1306  * Construct the driver object name
1307  */
1308  Status = RtlUShortAdd(sizeof(DRIVER_ROOT_NAME),
1309  ServiceName.Length,
1310  &ObjectName.MaximumLength);
1311  if (!NT_SUCCESS(Status))
1312  {
1313  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1314  return Status;
1315  }
1316  ObjectName.Length = 0;
1318  ObjectName.MaximumLength,
1319  TAG_IO);
1320  if (!ObjectName.Buffer)
1321  {
1322  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1324  }
1327 
1328  /*
1329  * Find the driver object
1330  */
1332  0,
1333  0,
1334  0,
1336  KernelMode,
1337  0,
1338  (PVOID*)&DriverObject);
1339 
1340  if (!NT_SUCCESS(Status))
1341  {
1342  DPRINT1("Can't locate driver object for %wZ\n", &ObjectName);
1344  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1345  return Status;
1346  }
1347 
1348  /* Free the buffer for driver object name */
1350 
1351  /* Check that driver is not already unloading */
1352  if (DriverObject->Flags & DRVO_UNLOAD_INVOKED)
1353  {
1354  DPRINT1("Driver deletion pending\n");
1356  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1357  return STATUS_DELETE_PENDING;
1358  }
1359 
1360  /*
1361  * Get path of service...
1362  */
1364 
1365  RtlInitUnicodeString(&ImagePath, NULL);
1366 
1367  QueryTable[0].Name = L"ImagePath";
1369  QueryTable[0].EntryContext = &ImagePath;
1370 
1372  CapturedServiceName.Buffer,
1373  QueryTable,
1374  NULL,
1375  NULL);
1376 
1377  /* We no longer need service name */
1378  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1379 
1380  if (!NT_SUCCESS(Status))
1381  {
1382  DPRINT1("RtlQueryRegistryValues() failed (Status %x)\n", Status);
1384  return Status;
1385  }
1386 
1387  /*
1388  * Normalize the image path for all later processing.
1389  */
1390  Status = IopNormalizeImagePath(&ImagePath, &ServiceName);
1391 
1392  if (!NT_SUCCESS(Status))
1393  {
1394  DPRINT1("IopNormalizeImagePath() failed (Status %x)\n", Status);
1396  return Status;
1397  }
1398 
1399  /* Free the service path */
1400  ExFreePool(ImagePath.Buffer);
1401 
1402  /*
1403  * Unload the module and release the references to the device object
1404  */
1405 
1406  /* Call the load/unload routine, depending on current process */
1407  if (DriverObject->DriverUnload && DriverObject->DriverSection &&
1408  (UnloadPnpDrivers || (DriverObject->Flags & DRVO_LEGACY_DRIVER)))
1409  {
1410  /* Loop through each device object of the driver
1411  and set DOE_UNLOAD_PENDING flag */
1412  DeviceObject = DriverObject->DeviceObject;
1413  while (DeviceObject)
1414  {
1415  /* Set the unload pending flag for the device */
1416  DeviceExtension = IoGetDevObjExtension(DeviceObject);
1417  DeviceExtension->ExtensionFlags |= DOE_UNLOAD_PENDING;
1418 
1419  /* Make sure there are no attached devices or no reference counts */
1420  if ((DeviceObject->ReferenceCount) || (DeviceObject->AttachedDevice))
1421  {
1422  /* Not safe to unload */
1423  DPRINT1("Drivers device object is referenced or has attached devices\n");
1424 
1425  SafeToUnload = FALSE;
1426  }
1427 
1428  DeviceObject = DeviceObject->NextDevice;
1429  }
1430 
1431  /* If not safe to unload, then return success */
1432  if (!SafeToUnload)
1433  {
1435  return STATUS_SUCCESS;
1436  }
1437 
1438  DPRINT1("Unloading driver '%wZ' (manual)\n", &DriverObject->DriverName);
1439 
1440  /* Set the unload invoked flag and call the unload routine */
1444 
1445  /* Mark the driver object temporary, so it could be deleted later */
1447 
1448  /* Dereference it 2 times */
1451 
1452  return Status;
1453  }
1454  else
1455  {
1456  DPRINT1("No DriverUnload function! '%wZ' will not be unloaded!\n", &DriverObject->DriverName);
1457 
1458  /* Dereference one time (refd inside this function) */
1460 
1461  /* Return unloading failure */
1463  }
1464 }
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:75
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:2070
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:3063
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 L(x)
Definition: ntvdm.h:50
#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:354
const LUID SeLoadDriverPrivilege
Definition: priv.c:29
_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
#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:744
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:1360

Referenced by NtUnloadDriver().

◆ IoRegisterBootDriverReinitialization()

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

Definition at line 1739 of file driver.c.

1742 {
1743  PDRIVER_REINIT_ITEM ReinitItem;
1744 
1745  /* Allocate the entry */
1746  ReinitItem = ExAllocatePoolWithTag(NonPagedPool,
1747  sizeof(DRIVER_REINIT_ITEM),
1748  TAG_REINIT);
1749  if (!ReinitItem) return;
1750 
1751  /* Fill it out */
1752  ReinitItem->DriverObject = DriverObject;
1753  ReinitItem->ReinitRoutine = ReinitRoutine;
1754  ReinitItem->Context = Context;
1755 
1756  /* Set the Driver Object flag and insert the entry into the list */
1759  &ReinitItem->ItemEntry,
1761 }
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:79
_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 1768 of file driver.c.

1771 {
1772  PDRIVER_REINIT_ITEM ReinitItem;
1773 
1774  /* Allocate the entry */
1775  ReinitItem = ExAllocatePoolWithTag(NonPagedPool,
1776  sizeof(DRIVER_REINIT_ITEM),
1777  TAG_REINIT);
1778  if (!ReinitItem) return;
1779 
1780  /* Fill it out */
1781  ReinitItem->DriverObject = DriverObject;
1782  ReinitItem->ReinitRoutine = ReinitRoutine;
1783  ReinitItem->Context = Context;
1784 
1785  /* Set the Driver Object flag and insert the entry into the list */
1788  &ReinitItem->ItemEntry,
1790 }
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:79
_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 707 of file driver.c.

710 {
712  UNICODE_STRING BaseName, BaseDirectory;
713  PLOAD_IMPORTS LoadedImports = (PVOID)-2;
714  PCHAR MissingApiName, Buffer;
715  PWCHAR MissingDriverName;
716  PVOID DriverBase = LdrEntry->DllBase;
717 
718  /* Allocate a buffer we'll use for names */
721  TAG_LDR_WSTR);
722  if (!Buffer)
723  {
724  /* Fail */
726  }
727 
728  /* Check for a separator */
729  if (FileName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR)
730  {
731  PWCHAR p;
732  ULONG BaseLength;
733 
734  /* Loop the path until we get to the base name */
735  p = &FileName->Buffer[FileName->Length / sizeof(WCHAR)];
736  while (*(p - 1) != OBJ_NAME_PATH_SEPARATOR) p--;
737 
738  /* Get the length */
739  BaseLength = (ULONG)(&FileName->Buffer[FileName->Length / sizeof(WCHAR)] - p);
740  BaseLength *= sizeof(WCHAR);
741 
742  /* Setup the string */
743  BaseName.Length = (USHORT)BaseLength;
744  BaseName.Buffer = p;
745  }
746  else
747  {
748  /* Otherwise, we already have a base name */
749  BaseName.Length = FileName->Length;
750  BaseName.Buffer = FileName->Buffer;
751  }
752 
753  /* Setup the maximum length */
754  BaseName.MaximumLength = BaseName.Length;
755 
756  /* Now compute the base directory */
757  BaseDirectory = *FileName;
758  BaseDirectory.Length -= BaseName.Length;
759  BaseDirectory.MaximumLength = BaseDirectory.Length;
760 
761  /* Resolve imports */
762  MissingApiName = Buffer;
763  Status = MiResolveImageReferences(DriverBase,
764  &BaseDirectory,
765  NULL,
766  &MissingApiName,
767  &MissingDriverName,
768  &LoadedImports);
769 
770  /* Free the temporary buffer */
772 
773  /* Check the result of the imports resolution */
774  if (!NT_SUCCESS(Status)) return Status;
775 
776  /* Return */
777  *ModuleObject = LdrEntry;
778  return STATUS_SUCCESS;
779 }
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:97
#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
union _IMAGE_THUNK_DATA32::@2076 u1
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:98
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 L(x)
Definition: ntvdm.h:50
#define TAG_LDR_WSTR
Definition: tag.h:97
#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
#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
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 2118 of file driver.c.

2119 {
2120  UNICODE_STRING CapturedServiceName = { 0, 0, NULL };
2123  NTSTATUS Status;
2124 
2125  PAGED_CODE();
2126 
2128 
2129  /* Need the appropriate priviliege */
2131  {
2132  DPRINT1("No load privilege!\n");
2134  }
2135 
2136  /* Capture the service name */
2137  Status = ProbeAndCaptureUnicodeString(&CapturedServiceName,
2138  PreviousMode,
2139  DriverServiceName);
2140  if (!NT_SUCCESS(Status))
2141  {
2142  return Status;
2143  }
2144 
2145  DPRINT("NtLoadDriver('%wZ')\n", &CapturedServiceName);
2146 
2147  /* We need a service name */
2148  if (CapturedServiceName.Length == 0 || CapturedServiceName.Buffer == NULL)
2149  {
2150  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
2151  return STATUS_INVALID_PARAMETER;
2152  }
2153 
2154  /* Load driver and call its entry point */
2155  DriverObject = NULL;
2156  Status = IopDoLoadUnloadDriver(&CapturedServiceName, &DriverObject);
2157 
2158  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
2159  return Status;
2160 }
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:2070
LONG NTSTATUS
Definition: precomp.h:26
const LUID SeLoadDriverPrivilege
Definition: priv.c:29
_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:744
#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 2179 of file driver.c.

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

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

Referenced by IopInitializeBootDrivers().

◆ IopGroupTable

PLIST_ENTRY IopGroupTable

Definition at line 41 of file driver.c.

Referenced by IopInitializeBootDrivers().

◆ IopHardwareDatabaseKey

UNICODE_STRING IopHardwareDatabaseKey
Initial value:
=
RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\HARDWARE\\DESCRIPTION\\SYSTEM")
#define L(x)
Definition: ntvdm.h:50
#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().