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

Go to the source code of this file.

Classes

struct  _LOAD_UNLOAD_PARAMS
 

Macros

#define NDEBUG
 
#define TAG_RTLREGISTRY   'vrqR'
 

Typedefs

typedef struct _LOAD_UNLOAD_PARAMS LOAD_UNLOAD_PARAMS
 
typedef struct _LOAD_UNLOAD_PARAMSPLOAD_UNLOAD_PARAMS
 

Functions

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

Variables

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

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 14 of file driver.c.

◆ TAG_RTLREGISTRY

#define TAG_RTLREGISTRY   'vrqR'

Definition at line 35 of file driver.c.

Typedef Documentation

◆ LOAD_UNLOAD_PARAMS

◆ PLOAD_UNLOAD_PARAMS

Function Documentation

◆ IoAllocateDriverObjectExtension()

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

Definition at line 1761 of file driver.c.

1765 {
1766  KIRQL OldIrql;
1767  PIO_CLIENT_EXTENSION DriverExtensions, NewDriverExtension;
1768  BOOLEAN Inserted = FALSE;
1769 
1770  /* Assume failure */
1771  *DriverObjectExtension = NULL;
1772 
1773  /* Allocate the extension */
1774  NewDriverExtension = ExAllocatePoolWithTag(NonPagedPool,
1775  sizeof(IO_CLIENT_EXTENSION) +
1776  DriverObjectExtensionSize,
1778  if (!NewDriverExtension) return STATUS_INSUFFICIENT_RESOURCES;
1779 
1780  /* Clear the extension for teh caller */
1781  RtlZeroMemory(NewDriverExtension,
1782  sizeof(IO_CLIENT_EXTENSION) + DriverObjectExtensionSize);
1783 
1784  /* Acqure lock */
1786 
1787  /* Fill out the extension */
1789 
1790  /* Loop the current extensions */
1791  DriverExtensions = IoGetDrvObjExtension(DriverObject)->
1792  ClientDriverExtension;
1793  while (DriverExtensions)
1794  {
1795  /* Check if the identifier matches */
1796  if (DriverExtensions->ClientIdentificationAddress ==
1798  {
1799  /* We have a collision, break out */
1800  break;
1801  }
1802 
1803  /* Go to the next one */
1804  DriverExtensions = DriverExtensions->NextExtension;
1805  }
1806 
1807  /* Check if we didn't collide */
1808  if (!DriverExtensions)
1809  {
1810  /* Link this one in */
1811  NewDriverExtension->NextExtension =
1812  IoGetDrvObjExtension(DriverObject)->ClientDriverExtension;
1813  IoGetDrvObjExtension(DriverObject)->ClientDriverExtension =
1814  NewDriverExtension;
1815  Inserted = TRUE;
1816  }
1817 
1818  /* Release the lock */
1820 
1821  /* Check if insertion failed */
1822  if (!Inserted)
1823  {
1824  /* Free the entry and fail */
1825  ExFreePoolWithTag(NewDriverExtension, TAG_DRIVER_EXTENSION);
1827  }
1828 
1829  /* Otherwise, return the pointer */
1830  *DriverObjectExtension = NewDriverExtension + 1;
1831  return STATUS_SUCCESS;
1832 }
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG IN OUT PLONG IN LONG Increment KeRaiseIrqlToDpcLevel
Definition: CrNtStubs.h:67
struct _IO_CLIENT_EXTENSION * NextExtension
Definition: iotypes.h:823
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#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:1026
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
#define TAG_DRIVER_EXTENSION
Definition: tag.h:42
#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
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
PVOID ClientIdentificationAddress
Definition: iotypes.h:824
#define IoGetDrvObjExtension(DriverObject)
Definition: io.h:132

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

1515 {
1516  WCHAR NameBuffer[100];
1517  USHORT NameLength;
1518  UNICODE_STRING LocalDriverName;
1519  NTSTATUS Status;
1521  ULONG ObjectSize;
1523  UNICODE_STRING ServiceKeyName;
1524  HANDLE hDriver;
1525  ULONG i, RetryCount = 0;
1526 
1527 try_again:
1528  /* First, create a unique name for the driver if we don't have one */
1529  if (!DriverName)
1530  {
1531  /* Create a random name and set up the string */
1532  NameLength = (USHORT)swprintf(NameBuffer,
1533  DRIVER_ROOT_NAME L"%08u",
1535  LocalDriverName.Length = NameLength * sizeof(WCHAR);
1536  LocalDriverName.MaximumLength = LocalDriverName.Length + sizeof(UNICODE_NULL);
1537  LocalDriverName.Buffer = NameBuffer;
1538  }
1539  else
1540  {
1541  /* So we can avoid another code path, use a local var */
1542  LocalDriverName = *DriverName;
1543  }
1544 
1545  /* Initialize the Attributes */
1546  ObjectSize = sizeof(DRIVER_OBJECT) + sizeof(EXTENDED_DRIVER_EXTENSION);
1548  &LocalDriverName,
1550  NULL,
1551  NULL);
1552 
1553  /* Create the Object */
1557  KernelMode,
1558  NULL,
1559  ObjectSize,
1560  0,
1561  0,
1562  (PVOID*)&DriverObject);
1563  if (!NT_SUCCESS(Status)) return Status;
1564 
1565  DPRINT("IopCreateDriver(): created DO %p\n", DriverObject);
1566 
1567  /* Set up the Object */
1568  RtlZeroMemory(DriverObject, ObjectSize);
1569  DriverObject->Type = IO_TYPE_DRIVER;
1570  DriverObject->Size = sizeof(DRIVER_OBJECT);
1572  DriverObject->DriverExtension = (PDRIVER_EXTENSION)(DriverObject + 1);
1573  DriverObject->DriverExtension->DriverObject = DriverObject;
1574  DriverObject->DriverInit = InitializationFunction;
1575  /* Loop all Major Functions */
1576  for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
1577  {
1578  /* Invalidate each function */
1579  DriverObject->MajorFunction[i] = IopInvalidDeviceRequest;
1580  }
1581 
1582  /* Set up the service key name buffer */
1583  ServiceKeyName.MaximumLength = LocalDriverName.Length + sizeof(UNICODE_NULL);
1584  ServiceKeyName.Buffer = ExAllocatePoolWithTag(PagedPool, LocalDriverName.MaximumLength, TAG_IO);
1585  if (!ServiceKeyName.Buffer)
1586  {
1587  /* Fail */
1591  }
1592 
1593  /* For builtin drivers, the ServiceKeyName is equal to DriverName */
1594  RtlCopyUnicodeString(&ServiceKeyName, &LocalDriverName);
1595  ServiceKeyName.Buffer[ServiceKeyName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1596  DriverObject->DriverExtension->ServiceKeyName = ServiceKeyName;
1597 
1598  /* Make a copy of the driver name to store in the driver object */
1599  DriverObject->DriverName.MaximumLength = LocalDriverName.Length;
1600  DriverObject->DriverName.Buffer = ExAllocatePoolWithTag(PagedPool,
1601  DriverObject->DriverName.MaximumLength,
1602  TAG_IO);
1603  if (!DriverObject->DriverName.Buffer)
1604  {
1605  /* Fail */
1609  }
1610 
1611  RtlCopyUnicodeString(&DriverObject->DriverName, &LocalDriverName);
1612 
1613  /* Add the Object and get its handle */
1615  NULL,
1617  0,
1618  NULL,
1619  &hDriver);
1620 
1621  /* Eliminate small possibility when this function is called more than
1622  once in a row, and KeTickCount doesn't get enough time to change */
1623  if (!DriverName && (Status == STATUS_OBJECT_NAME_COLLISION) && (RetryCount < 100))
1624  {
1625  RetryCount++;
1626  goto try_again;
1627  }
1628 
1629  if (!NT_SUCCESS(Status)) return Status;
1630 
1631  /* Now reference it */
1633  0,
1635  KernelMode,
1636  (PVOID*)&DriverObject,
1637  NULL);
1638 
1639  /* Close the extra handle */
1640  ZwClose(hDriver);
1641 
1642  if (!NT_SUCCESS(Status))
1643  {
1644  /* Fail */
1647  return Status;
1648  }
1649 
1650  /* Finally, call its init function */
1651  DPRINT("Calling driver entrypoint at %p\n", InitializationFunction);
1652  Status = (*InitializationFunction)(DriverObject, NULL);
1653  if (!NT_SUCCESS(Status))
1654  {
1655  /* If it didn't work, then kill the object */
1656  DPRINT1("'%wZ' initialization failed, status (0x%08lx)\n", DriverName, Status);
1659  return Status;
1660  }
1661 
1662  // Windows does this fixup - keep it for compatibility
1663  for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
1664  {
1665  /*
1666  * Make sure the driver didn't set any dispatch entry point to NULL!
1667  * Doing so is illegal; drivers shouldn't touch entry points they
1668  * do not implement.
1669  */
1670 
1671  /* Check if it did so anyway */
1672  if (!DriverObject->MajorFunction[i])
1673  {
1674  /* Print a warning in the debug log */
1675  DPRINT1("Driver <%wZ> set DriverObject->MajorFunction[%lu] to NULL!\n",
1676  &DriverObject->DriverName, i);
1677 
1678  /* Fix it up */
1679  DriverObject->MajorFunction[i] = IopInvalidDeviceRequest;
1680  }
1681  }
1682 
1683  /* Return the Status */
1684  return Status;
1685 }
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
ULONG LowPart
Definition: ketypes.h:917
#define DRVO_BUILTIN_DRIVER
Definition: iotypes.h:2227
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define TAG_IO
Definition: tag.h:69
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
USHORT MaximumLength
Definition: env_spec_w32.h:370
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define IRP_MJ_MAXIMUM_FUNCTION
LONG NTSTATUS
Definition: precomp.h:26
_In_ LPWSTR _In_ ULONG _In_ ULONG _In_ ULONG _Out_ DEVINFO _In_ HDEV _In_ LPWSTR _In_ HANDLE hDriver
Definition: winddi.h:3553
POBJECT_TYPE IoDriverObjectType
Definition: driver.c:33
#define swprintf
Definition: precomp.h:40
NTSTATUS NTAPI IopInvalidDeviceRequest(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: driver.c:67
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:496
#define UNICODE_NULL
#define FILE_READ_DATA
Definition: nt_native.h:628
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
NTSTATUS NTAPI ObCreateObject(IN KPROCESSOR_MODE ProbeMode OPTIONAL, IN POBJECT_TYPE Type, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext OPTIONAL, IN ULONG ObjectSize, IN ULONG PagedPoolCharge OPTIONAL, IN ULONG NonPagedPoolCharge OPTIONAL, OUT PVOID *Object)
Definition: oblife.c:952
Status
Definition: gdiplustypes.h:24
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ObDereferenceObject
Definition: obfuncs.h:203
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
static const WCHAR L[]
Definition: oid.c:1250
NTKERNELAPI volatile KSYSTEM_TIME KeTickCount
Definition: clock.c:19
#define OBJ_PERMANENT
Definition: winternl.h:226
struct _DRIVER_OBJECT DRIVER_OBJECT
NTSTATUS NTAPI ObInsertObject(IN PVOID Object, IN PACCESS_STATE AccessState OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG ObjectPointerBias, OUT PVOID *NewObject OPTIONAL, OUT PHANDLE Handle)
Definition: obhandle.c:2932
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned short USHORT
Definition: pedump.c:61
struct _DRIVER_EXTENSION * PDRIVER_EXTENSION
#define NULL
Definition: types.h:112
#define IO_TYPE_DRIVER
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define DPRINT
Definition: sndvol32.h:71
PDRIVER_INITIALIZE DriverInit
Definition: iotypes.h:2286
#define DRIVER_ROOT_NAME
Definition: ldr.h:5
VOID NTAPI ObMakeTemporaryObject(IN PVOID ObjectBody)
Definition: oblife.c:1361

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

◆ IoDeleteDriver()

VOID NTAPI IoDeleteDriver ( IN PDRIVER_OBJECT  DriverObject)

Definition at line 1692 of file driver.c.

1693 {
1694  /* Simply dereference the Object */
1696 }
_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 1839 of file driver.c.

1841 {
1842  KIRQL OldIrql;
1843  PIO_CLIENT_EXTENSION DriverExtensions;
1844 
1845  /* Acquire lock */
1847 
1848  /* Loop the list until we find the right one */
1849  DriverExtensions = IoGetDrvObjExtension(DriverObject)->ClientDriverExtension;
1850  while (DriverExtensions)
1851  {
1852  /* Check for a match */
1853  if (DriverExtensions->ClientIdentificationAddress ==
1855  {
1856  /* Break out */
1857  break;
1858  }
1859 
1860  /* Keep looping */
1861  DriverExtensions = DriverExtensions->NextExtension;
1862  }
1863 
1864  /* Release lock */
1866 
1867  /* Return nothing or the extension */
1868  if (!DriverExtensions) return NULL;
1869  return DriverExtensions + 1;
1870 }
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG IN OUT PLONG IN LONG Increment KeRaiseIrqlToDpcLevel
Definition: CrNtStubs.h:67
struct _IO_CLIENT_EXTENSION * NextExtension
Definition: iotypes.h:823
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
UCHAR KIRQL
Definition: env_spec_w32.h:591
__drv_aliasesMem _In_ PVOID ClientIdentificationAddress
Definition: iofuncs.h:1026
_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:824
#define IoGetDrvObjExtension(DriverObject)
Definition: io.h:132

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

◆ IopDeleteDriver()

VOID NTAPI IopDeleteDriver ( IN PVOID  ObjectBody)

Definition at line 79 of file driver.c.

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

296 {
297  CHAR TextBuffer[256];
298  UNICODE_STRING DotSys = RTL_CONSTANT_STRING(L".SYS");
299 
300  if (ExpInTextModeSetup) return;
301  if (!KeLoaderBlock) return;
303  snprintf(TextBuffer, sizeof(TextBuffer),
304  "%s%sSystem32\\Drivers\\%wZ%s\r\n",
307  ServiceName,
308  IopSuffixUnicodeString(&DotSys, ServiceName) ? "" : ".SYS");
310 }
BOOLEAN ExpInTextModeSetup
Definition: init.c:67
PSTR ArcBootDeviceName
Definition: arc.h:503
NTSTATUS RtlUpcaseUnicodeString(PUNICODE_STRING dst, PUNICODE_STRING src, BOOLEAN Alloc)
Definition: string_lib.cpp:46
char CHAR
Definition: xmlstorage.h:175
#define snprintf
Definition: wintirpc.h:48
#define FALSE
Definition: types.h:117
PLOADER_PARAMETER_BLOCK KeLoaderBlock
Definition: krnlinit.c:29
LPTSTR ServiceName
Definition: ServiceMain.c:15
static const WCHAR L[]
Definition: oid.c:1250
NTHALAPI VOID NTAPI HalDisplayString(PUCHAR String)
char TextBuffer[BUFFERLEN]
Definition: combotst.c:45
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
BOOLEAN NTAPI IopSuffixUnicodeString(IN PCUNICODE_STRING String1, IN PCUNICODE_STRING String2)
Definition: driver.c:261

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

2036 {
2037  LOAD_UNLOAD_PARAMS LoadParams;
2038 
2039  /* Prepare parameters block */
2040  LoadParams.RegistryPath = RegistryPath;
2041  LoadParams.DriverObject = *DriverObject;
2042 
2044  {
2045  LoadParams.SetEvent = TRUE;
2047 
2048  /* Initialize and queue a work item */
2049  ExInitializeWorkItem(&LoadParams.WorkItem, IopLoadUnloadDriverWorker, &LoadParams);
2051 
2052  /* And wait till it completes */
2054  }
2055  else
2056  {
2057  /* If we're already in a system process, call it right here */
2058  LoadParams.SetEvent = FALSE;
2059  IopLoadUnloadDriverWorker(&LoadParams);
2060  }
2061 
2062  return LoadParams.Status;
2063 }
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:711
static VOID NTAPI IopLoadUnloadDriverWorker(_Inout_ PVOID Parameter)
Definition: driver.c:1987
#define TRUE
Definition: types.h:120
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:213
WORK_QUEUE_ITEM WorkItem
Definition: driver.c:52
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define FALSE
Definition: types.h:117
PEPROCESS PsInitialSystemProcess
Definition: psmgr.c:50
#define PsGetCurrentProcess
Definition: psfuncs.h:17
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
NTSTATUS Status
Definition: driver.c:50
BOOLEAN SetEvent
Definition: driver.c:55
PDRIVER_OBJECT DriverObject
Definition: driver.c:54
PUNICODE_STRING RegistryPath
Definition: driver.c:51
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define NULL
Definition: types.h:112

Referenced by IopUnloadDriver(), and NtLoadDriver().

◆ IopGetDeviceObjectFromDeviceInstance()

PDEVICE_OBJECT IopGetDeviceObjectFromDeviceInstance ( PUNICODE_STRING  DeviceInstance)

Definition at line 122 of file plugplay.c.

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

Referenced by IopInitializeBuiltinDriver().

◆ IopGetDriverNames()

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

Definition at line 125 of file driver.c.

129 {
130  UNICODE_STRING driverName = {.Buffer = NULL}, serviceName;
133 
134  PAGED_CODE();
135 
136  // 1. Check the "ObjectName" field in the driver's registry key (it has the priority)
137  status = IopGetRegistryValue(ServiceHandle, L"ObjectName", &kvInfo);
138  if (NT_SUCCESS(status))
139  {
140  // we're got the ObjectName. Use it to create the DRIVER_OBJECT
141  if (kvInfo->Type != REG_SZ || kvInfo->DataLength == 0)
142  {
143  ExFreePool(kvInfo);
145  }
146 
147  driverName.Length = kvInfo->DataLength - sizeof(WCHAR),
148  driverName.MaximumLength = kvInfo->DataLength,
149  driverName.Buffer = ExAllocatePoolWithTag(NonPagedPool, driverName.MaximumLength, TAG_IO);
150  if (!driverName.Buffer)
151  {
152  ExFreePool(kvInfo);
154  }
155 
156  RtlMoveMemory(driverName.Buffer,
157  (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
158  driverName.Length);
159  ExFreePool(kvInfo);
160  }
161 
162  // check if we need to get ServiceName as well
163  PKEY_BASIC_INFORMATION basicInfo;
164  if (!NT_SUCCESS(status) || ServiceName != NULL)
165  {
166  ULONG infoLength;
167  status = ZwQueryKey(ServiceHandle, KeyBasicInformation, NULL, 0, &infoLength);
169  {
170  basicInfo = ExAllocatePoolWithTag(PagedPool, infoLength, TAG_IO);
171  if (!basicInfo)
172  {
174  }
175 
176  status = ZwQueryKey(ServiceHandle, KeyBasicInformation, basicInfo, infoLength, &infoLength);
177  if (!NT_SUCCESS(status))
178  {
179  ExFreePoolWithTag(basicInfo, TAG_IO);
180  return status;
181  }
182 
183  serviceName.Length = basicInfo->NameLength;
184  serviceName.MaximumLength = basicInfo->NameLength;
185  serviceName.Buffer = basicInfo->Name;
186  }
187  else
188  {
190  }
191  }
192 
193  // 2. there is no "ObjectName" - construct it ourselves. Depending on a driver type,
194  // it will be either "\Driver<ServiceName>" or "\FileSystem<ServiceName>"
195  if (driverName.Buffer == NULL)
196  {
197  status = IopGetRegistryValue(ServiceHandle, L"Type", &kvInfo);
198  if (!NT_SUCCESS(status))
199  {
200  ExFreePoolWithTag(basicInfo, TAG_IO);
201  return status;
202  }
203  if (kvInfo->Type != REG_DWORD)
204  {
205  ExFreePool(kvInfo);
206  ExFreePoolWithTag(basicInfo, TAG_IO); // container for serviceName
208  }
209 
210  UINT32 driverType;
211  RtlMoveMemory(&driverType, (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset), sizeof(UINT32));
212  ExFreePool(kvInfo);
213 
214  driverName.Length = 0;
215  if (driverType == SERVICE_RECOGNIZER_DRIVER || driverType == SERVICE_FILE_SYSTEM_DRIVER)
216  driverName.MaximumLength = sizeof(FILESYSTEM_ROOT_NAME) + serviceName.Length;
217  else
218  driverName.MaximumLength = sizeof(DRIVER_ROOT_NAME) + serviceName.Length;
219  driverName.Buffer = ExAllocatePoolWithTag(NonPagedPool, driverName.MaximumLength, TAG_IO);
220  if (!driverName.Buffer)
221  {
222  ExFreePoolWithTag(basicInfo, TAG_IO); // container for serviceName
224  }
225 
226  if (driverType == SERVICE_RECOGNIZER_DRIVER || driverType == SERVICE_FILE_SYSTEM_DRIVER)
228  else
230 
232  }
233 
234  if (ServiceName)
235  {
237  if (!buf)
238  {
239  ExFreePoolWithTag(basicInfo, TAG_IO); // container for serviceName
240  ExFreePoolWithTag(driverName.Buffer, TAG_IO);
242  }
243  RtlMoveMemory(buf, serviceName.Buffer, serviceName.Length);
244  ServiceName->MaximumLength = serviceName.Length;
245  ServiceName->Length = serviceName.Length;
246  ServiceName->Buffer = buf;
247  }
248  ExFreePoolWithTag(basicInfo, TAG_IO); // container for ServiceName
249 
250  *DriverName = driverName;
251 
252  return STATUS_SUCCESS;
253 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define TAG_IO
Definition: tag.h:69
USHORT MaximumLength
Definition: env_spec_w32.h:370
LONG NTSTATUS
Definition: precomp.h:26
#define FILESYSTEM_ROOT_NAME
Definition: ldr.h:6
uint16_t * PWCHAR
Definition: typedefs.h:56
#define SERVICE_RECOGNIZER_DRIVER
Definition: cmtypes.h:956
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
uint32_t ULONG_PTR
Definition: typedefs.h:65
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
unsigned int UINT32
#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
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
static const WCHAR L[]
Definition: oid.c:1250
NTSTATUS NTAPI IopGetRegistryValue(IN HANDLE Handle, IN PWSTR ValueName, OUT PKEY_VALUE_FULL_INFORMATION *Information)
Definition: pnpmgr.c:1607
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 ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define REG_DWORD
Definition: sdbapi.c:596
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 965 of file driver.c.

966 {
967  PLIST_ENTRY ListHead, NextEntry, NextEntry2;
968  PLDR_DATA_TABLE_ENTRY LdrEntry;
970  UNICODE_STRING DriverName;
971  ULONG i, Index;
972  PDRIVER_INFORMATION DriverInfo, DriverInfoTag;
974  PBOOT_DRIVER_LIST_ENTRY BootEntry;
975  DPRINT("IopInitializeBootDrivers()\n");
976 
977  /* Create the RAW FS built-in driver */
978  RtlInitUnicodeString(&DriverName, L"\\FileSystem\\RAW");
979 
980  Status = IoCreateDriver(&DriverName, RawFsDriverEntry);
981  if (!NT_SUCCESS(Status))
982  {
983  /* Fail */
984  return;
985  }
986 
987  /* Get highest group order index */
989  if (IopGroupIndex == 0xFFFF) ASSERT(FALSE);
990 
991  /* Allocate the group table */
993  IopGroupIndex * sizeof(LIST_ENTRY),
994  TAG_IO);
995  if (IopGroupTable == NULL) ASSERT(FALSE);
996 
997  /* Initialize the group table lists */
998  for (i = 0; i < IopGroupIndex; i++) InitializeListHead(&IopGroupTable[i]);
999 
1000  /* Loop the boot modules */
1001  ListHead = &KeLoaderBlock->LoadOrderListHead;
1002  NextEntry = ListHead->Flink;
1003  while (ListHead != NextEntry)
1004  {
1005  /* Get the entry */
1006  LdrEntry = CONTAINING_RECORD(NextEntry,
1008  InLoadOrderLinks);
1009 
1010  /* Check if the DLL needs to be initialized */
1011  if (LdrEntry->Flags & LDRP_DRIVER_DEPENDENT_DLL)
1012  {
1013  /* Call its entrypoint */
1014  MmCallDllInitialize(LdrEntry, NULL);
1015  }
1016 
1017  /* Go to the next driver */
1018  NextEntry = NextEntry->Flink;
1019  }
1020 
1021  /* Loop the boot drivers */
1022  ListHead = &KeLoaderBlock->BootDriverListHead;
1023  NextEntry = ListHead->Flink;
1024  while (ListHead != NextEntry)
1025  {
1026  /* Get the entry */
1027  BootEntry = CONTAINING_RECORD(NextEntry,
1029  Link);
1030 
1031  /* Get the driver loader entry */
1032  LdrEntry = BootEntry->LdrEntry;
1033 
1034  /* Allocate our internal accounting structure */
1036  sizeof(DRIVER_INFORMATION),
1037  TAG_IO);
1038  if (DriverInfo)
1039  {
1040  /* Zero it and initialize it */
1043  DriverInfo->DataTableEntry = BootEntry;
1044 
1045  /* Open the registry key */
1047  NULL,
1048  &BootEntry->RegistryPath,
1049  KEY_READ);
1050  DPRINT("IopOpenRegistryKeyEx(%wZ) returned 0x%08lx\n", &BootEntry->RegistryPath, Status);
1051 #if 0
1052  if (NT_SUCCESS(Status))
1053 #else // Hack still needed...
1054  if ((NT_SUCCESS(Status)) || /* ReactOS HACK for SETUPLDR */
1055  ((KeLoaderBlock->SetupLdrBlock) && ((KeyHandle = (PVOID)1)))) // yes, it's an assignment!
1056 #endif
1057  {
1058  /* Save the handle */
1060 
1061  /* Get the group oder index */
1063 
1064  /* Get the tag position */
1066 
1067  /* Insert it into the list, at the right place */
1069  NextEntry2 = IopGroupTable[Index].Flink;
1070  while (NextEntry2 != &IopGroupTable[Index])
1071  {
1072  /* Get the driver info */
1073  DriverInfoTag = CONTAINING_RECORD(NextEntry2,
1075  Link);
1076 
1077  /* Check if we found the right tag position */
1078  if (DriverInfoTag->TagPosition > DriverInfo->TagPosition)
1079  {
1080  /* We're done */
1081  break;
1082  }
1083 
1084  /* Next entry */
1085  NextEntry2 = NextEntry2->Flink;
1086  }
1087 
1088  /* Insert us right before the next entry */
1089  NextEntry2 = NextEntry2->Blink;
1090  InsertHeadList(NextEntry2, &DriverInfo->Link);
1091  }
1092  }
1093 
1094  /* Go to the next driver */
1095  NextEntry = NextEntry->Flink;
1096  }
1097 
1098  /* Loop each group index */
1099  for (i = 0; i < IopGroupIndex; i++)
1100  {
1101  /* Loop each group table */
1102  NextEntry = IopGroupTable[i].Flink;
1103  while (NextEntry != &IopGroupTable[i])
1104  {
1105  /* Get the entry */
1106  DriverInfo = CONTAINING_RECORD(NextEntry,
1108  Link);
1109 
1110  /* Get the driver loader entry */
1111  LdrEntry = DriverInfo->DataTableEntry->LdrEntry;
1112 
1113  /* Initialize it */
1114  if (IopInitializeBuiltinDriver(LdrEntry))
1115  {
1116  // it does not make sense to enumerate the tree if there are no new devices added
1119  NULL,
1120  NULL);
1121  }
1122 
1123  /* Next entry */
1124  NextEntry = NextEntry->Flink;
1125  }
1126  }
1127 
1128  /* HAL Root Bus is being initialized before loading the boot drivers so this may cause issues
1129  * when some devices are not being initialized with their drivers. This flag is used to delay
1130  * all actions with devices (except PnP root device) until boot drivers are loaded.
1131  * See PiQueueDeviceAction function
1132  */
1134 
1135  DbgPrint("BOOT DRIVERS LOADED\n");
1136 
1139  NULL,
1140  NULL);
1141 }
NTSTATUS NTAPI RawFsDriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
Definition: rawfs.c:1193
PDEVICE_OBJECT PhysicalDeviceObject
Definition: iotypes.h:850
PDEVICE_NODE IopRootDeviceNode
Definition: devnode.c:18
#define TAG_IO
Definition: tag.h:69
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:2616
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4711
#define DbgPrint
Definition: loader.c:25
#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
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:399
HANDLE ServiceHandle
Definition: io.h:402
NTSTATUS NTAPI IoCreateDriver(_In_opt_ PUNICODE_STRING DriverName, _In_ PDRIVER_INITIALIZE InitializationFunction)
Definition: driver.c:1512
USHORT TagPosition
Definition: io.h:403
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:45
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_ WDFCOLLECTION _In_ ULONG Index
PLIST_ENTRY IopGroupTable
Definition: driver.c:43
LIST_ENTRY BootDriverListHead
Definition: arc.h:495
BOOLEAN IopInitializeBuiltinDriver(IN PLDR_DATA_TABLE_ENTRY BootLdrEntry)
Definition: driver.c:756
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
PBOOT_DRIVER_LIST_ENTRY DataTableEntry
Definition: io.h:401
static const WCHAR L[]
Definition: oid.c:1250
Definition: btrfs_drv.h:1922
Definition: typedefs.h:119
LIST_ENTRY LoadOrderListHead
Definition: arc.h:493
UNICODE_STRING RegistryPath
Definition: arc.h:202
DRIVER_INFORMATION DriverInfo
Definition: main.c:59
NTSTATUS NTAPI IopOpenRegistryKeyEx(PHANDLE KeyHandle, HANDLE ParentKey, PUNICODE_STRING Name, ACCESS_MASK DesiredAccess)
Definition: pnpmgr.c:1456
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
struct _LDR_DATA_TABLE_ENTRY * LdrEntry
Definition: arc.h:203
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define NULL
Definition: types.h:112
BOOLEAN PnPBootDriversLoaded
Definition: pnpinit.c:26
ULONG Flags
Definition: ntddk_ex.h:207
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define DPRINT
Definition: sndvol32.h:71
USHORT IopGroupIndex
Definition: driver.c:42
USHORT NTAPI PipGetDriverTagPriority(IN HANDLE ServiceHandle)
Definition: pnpinit.c:198

Referenced by IoInitSystem().

◆ IopInitializeBuiltinDriver()

BOOLEAN IopInitializeBuiltinDriver ( IN PLDR_DATA_TABLE_ENTRY  BootLdrEntry)

Definition at line 756 of file driver.c.

757 {
760  PWCHAR Buffer, FileNameWithoutPath;
761  PWSTR FileExtension;
762  PUNICODE_STRING ModuleName = &BootLdrEntry->BaseDllName;
763  PLDR_DATA_TABLE_ENTRY LdrEntry;
764  PLIST_ENTRY NextEntry;
767 
768  /*
769  * Display 'Loading XXX...' message
770  */
773 
775  ModuleName->Length + sizeof(UNICODE_NULL),
776  TAG_IO);
777  if (Buffer == NULL)
778  {
779  return FALSE;
780  }
781 
783  Buffer[ModuleName->Length / sizeof(WCHAR)] = UNICODE_NULL;
784 
785  /*
786  * Generate filename without path (not needed by freeldr)
787  */
788  FileNameWithoutPath = wcsrchr(Buffer, L'\\');
789  if (FileNameWithoutPath == NULL)
790  {
791  FileNameWithoutPath = Buffer;
792  }
793  else
794  {
795  FileNameWithoutPath++;
796  }
797 
798  /*
799  * Strip the file extension from ServiceName
800  */
801  Success = RtlCreateUnicodeString(&ServiceName, FileNameWithoutPath);
803  if (!Success)
804  {
805  return FALSE;
806  }
807 
808  FileExtension = wcsrchr(ServiceName.Buffer, L'.');
809  if (FileExtension != NULL)
810  {
811  ServiceName.Length -= (USHORT)wcslen(FileExtension) * sizeof(WCHAR);
812  FileExtension[0] = UNICODE_NULL;
813  }
814 
816 
817  // Make the registry path for the driver
818  RegistryPath.Length = 0;
819  RegistryPath.MaximumLength = sizeof(ServicesKeyName) + ServiceName.Length;
821  if (RegistryPath.Buffer == NULL)
822  {
823  return FALSE;
824  }
828 
829  HANDLE serviceHandle;
830  Status = IopOpenRegistryKeyEx(&serviceHandle, NULL, &RegistryPath, KEY_READ);
832  if (!NT_SUCCESS(Status))
833  {
834  return FALSE;
835  }
836 
837  /* Lookup the new Ldr entry in PsLoadedModuleList */
838  NextEntry = PsLoadedModuleList.Flink;
839  while (NextEntry != &PsLoadedModuleList)
840  {
841  LdrEntry = CONTAINING_RECORD(NextEntry,
843  InLoadOrderLinks);
845  {
846  break;
847  }
848 
849  NextEntry = NextEntry->Flink;
850  }
851  ASSERT(NextEntry != &PsLoadedModuleList);
852 
853  /*
854  * Initialize the driver
855  */
856  NTSTATUS driverEntryStatus;
858  serviceHandle,
859  &DriverObject,
860  &driverEntryStatus);
861 
862  if (!NT_SUCCESS(Status))
863  {
864  DPRINT1("Driver '%wZ' load failed, status (%x)\n", ModuleName, Status);
865  return FALSE;
866  }
867 
868  // The driver has been loaded, now check if where are any PDOs
869  // for that driver, and queue AddDevice call for them.
870  // The check is possible because HKLM/SYSTEM/CCS/Services/<ServiceName>/Enum directory
871  // is populated upon a new device arrival based on a (critical) device database
872 
873  // Legacy drivers may add devices inside DriverEntry.
874  // We're lazy and always assume that they are doing so
875  BOOLEAN deviceAdded = (_Bool)(DriverObject->Flags & DRVO_LEGACY_DRIVER);
876 
877  HANDLE enumServiceHandle;
878  UNICODE_STRING enumName = RTL_CONSTANT_STRING(L"Enum");
879 
880  Status = IopOpenRegistryKeyEx(&enumServiceHandle, serviceHandle, &enumName, KEY_READ);
881  ZwClose(serviceHandle);
882 
883  if (NT_SUCCESS(Status))
884  {
885  UINT32 instanceCount = 0;
887  Status = IopGetRegistryValue(enumServiceHandle, L"Count", &kvInfo);
888  if (!NT_SUCCESS(Status))
889  {
890  goto Cleanup;
891  }
892  if (kvInfo->Type != REG_DWORD)
893  {
894  ExFreePool(kvInfo);
895  goto Cleanup;
896  }
897 
898  RtlMoveMemory(&instanceCount,
899  (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
900  sizeof(UINT32));
901  ExFreePool(kvInfo);
902 
903  DPRINT("Processing %u instances for %wZ module\n", instanceCount, ModuleName);
904 
905  for (UINT32 i = 0; i < instanceCount; i++)
906  {
907  WCHAR num[11];
908  UNICODE_STRING instancePath;
909  RtlStringCchPrintfW(num, sizeof(num), L"%u", i);
910 
911  Status = IopGetRegistryValue(enumServiceHandle, num, &kvInfo);
912  if (!NT_SUCCESS(Status))
913  {
914  continue;
915  }
916  if (kvInfo->Type != REG_SZ || kvInfo->DataLength == 0)
917  {
918  ExFreePool(kvInfo);
919  continue;
920  }
921 
922  instancePath.Length = kvInfo->DataLength - sizeof(WCHAR),
923  instancePath.MaximumLength = kvInfo->DataLength,
925  instancePath.MaximumLength,
926  TAG_IO);
927  if (instancePath.Buffer)
928  {
929  RtlMoveMemory(instancePath.Buffer,
930  (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
931  instancePath.Length);
932 
935  ObDereferenceObject(pdo);
936  deviceAdded = TRUE;
937  }
938 
939  ExFreePool(kvInfo);
940  }
941 
942  ZwClose(enumServiceHandle);
943  }
944 Cleanup:
945  /* Remove extra reference from IopInitializeDriverModule */
947 
948  return deviceAdded;
949 }
#define DRVO_LEGACY_DRIVER
Definition: iotypes.h:2226
VOID NTAPI InbvIndicateProgress(VOID)
Definition: inbv.c:884
#define TAG_IO
Definition: tag.h:69
VOID PiQueueDeviceAction(_In_ PDEVICE_OBJECT DeviceObject, _In_ DEVICE_ACTION Action, _In_opt_ PKEVENT CompletionEvent, _Out_opt_ NTSTATUS *CompletionStatus)
Queue a device operation to a worker thread.
Definition: devaction.c:2616
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:295
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
uint16_t * PWSTR
Definition: typedefs.h:56
NTSTRSAFEVAPI RtlStringCchPrintfW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1110
ACPI_SIZE Length
Definition: actypes.h:1044
LONG NTSTATUS
Definition: precomp.h:26
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:213
ACPI_BUFFER *RetBuffer ACPI_BUFFER *RetBuffer char ACPI_WALK_RESOURCE_CALLBACK void *Context ACPI_BUFFER *RetBuffer UINT16 ACPI_RESOURCE **ResourcePtr ACPI_GENERIC_ADDRESS *Reg UINT32 *ReturnValue UINT8 UINT8 *Slp_TypB ACPI_PHYSICAL_ADDRESS PhysicalAddress64 UINT32 UINT32 *TimeElapsed UINT32 ACPI_STATUS const char UINT32 ACPI_STATUS const char UINT32 const char const char * ModuleName
Definition: acpixf.h:1274
uint16_t * PWCHAR
Definition: typedefs.h:56
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
unsigned int UINT32
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:45
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:34
#define ObDereferenceObject
Definition: obfuncs.h:203
GLuint GLuint num
Definition: glext.h:9618
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
static const WCHAR L[]
Definition: oid.c:1250
Definition: btrfs_drv.h:1922
Definition: typedefs.h:119
#define wcsrchr
Definition: compat.h:16
static const WCHAR Cleanup[]
Definition: register.c:80
NTSTATUS NTAPI IopGetRegistryValue(IN HANDLE Handle, IN PWSTR ValueName, OUT PKEY_VALUE_FULL_INFORMATION *Information)
Definition: pnpmgr.c:1607
NTSTATUS NTAPI IopOpenRegistryKeyEx(PHANDLE KeyHandle, HANDLE ParentKey, PUNICODE_STRING Name, ACCESS_MASK DesiredAccess)
Definition: pnpmgr.c:1456
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:408
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
static const WCHAR ServicesKeyName[]
Definition: driver.c:31
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define DPRINT
Definition: sndvol32.h:71
#define REG_DWORD
Definition: sdbapi.c:596
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 408 of file driver.c.

413 {
416 
417  PAGED_CODE();
418 
419  Status = IopGetDriverNames(ServiceHandle, &DriverName, &ServiceName);
420  if (!NT_SUCCESS(Status))
421  {
422  MmUnloadSystemImage(ModuleObject);
423  return Status;
424  }
425 
426  DPRINT("Driver name: '%wZ'\n", &DriverName);
427 
428  // obtain the registry path for the DriverInit routine
429  PKEY_NAME_INFORMATION nameInfo;
430  ULONG infoLength;
431  Status = ZwQueryKey(ServiceHandle, KeyNameInformation, NULL, 0, &infoLength);
433  {
434  nameInfo = ExAllocatePoolWithTag(NonPagedPool, infoLength, TAG_IO);
435  if (nameInfo)
436  {
437  Status = ZwQueryKey(ServiceHandle,
439  nameInfo,
440  infoLength,
441  &infoLength);
442  if (NT_SUCCESS(Status))
443  {
444  RegistryPath.Length = nameInfo->NameLength;
445  RegistryPath.MaximumLength = nameInfo->NameLength;
446  RegistryPath.Buffer = nameInfo->Name;
447  }
448  else
449  {
450  ExFreePoolWithTag(nameInfo, TAG_IO);
451  }
452  }
453  else
454  {
456  }
457  }
458  else
459  {
461  }
462 
463  if (!NT_SUCCESS(Status))
464  {
466  RtlFreeUnicodeString(&DriverName);
467  MmUnloadSystemImage(ModuleObject);
468  return Status;
469  }
470 
471  // create the driver object
472  UINT32 ObjectSize = sizeof(DRIVER_OBJECT) + sizeof(EXTENDED_DRIVER_EXTENSION);
473  OBJECT_ATTRIBUTES objAttrs;
474  PDRIVER_OBJECT driverObject;
475  InitializeObjectAttributes(&objAttrs,
476  &DriverName,
478  NULL,
479  NULL);
480 
483  &objAttrs,
484  KernelMode,
485  NULL,
486  ObjectSize,
487  0,
488  0,
489  (PVOID*)&driverObject);
490  if (!NT_SUCCESS(Status))
491  {
492  ExFreePoolWithTag(nameInfo, TAG_IO); // container for RegistryPath
494  RtlFreeUnicodeString(&DriverName);
495  MmUnloadSystemImage(ModuleObject);
496  DPRINT1("Error while creating driver object \"%wZ\" status %x\n", &DriverName, Status);
497  return Status;
498  }
499 
500  DPRINT("Created driver object 0x%p for \"%wZ\"\n", driverObject, &DriverName);
501 
502  RtlZeroMemory(driverObject, ObjectSize);
503  driverObject->Type = IO_TYPE_DRIVER;
504  driverObject->Size = sizeof(DRIVER_OBJECT);
505  driverObject->Flags = DRVO_LEGACY_DRIVER; // TODO: check the WDM_DRIVER flag on the module
506  driverObject->DriverSection = ModuleObject;
507  driverObject->DriverStart = ModuleObject->DllBase;
508  driverObject->DriverSize = ModuleObject->SizeOfImage;
509  driverObject->DriverInit = ModuleObject->EntryPoint;
510  driverObject->HardwareDatabase = &IopHardwareDatabaseKey;
511  driverObject->DriverExtension = (PDRIVER_EXTENSION)(driverObject + 1);
512  driverObject->DriverExtension->DriverObject = driverObject;
513 
514  /* Loop all Major Functions */
515  for (INT i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
516  {
517  /* Invalidate each function */
518  driverObject->MajorFunction[i] = IopInvalidDeviceRequest;
519  }
520 
521  /* Add the Object and get its handle */
522  HANDLE hDriver;
523  Status = ObInsertObject(driverObject, NULL, FILE_READ_DATA, 0, NULL, &hDriver);
524  if (!NT_SUCCESS(Status))
525  {
526  ExFreePoolWithTag(nameInfo, TAG_IO);
528  RtlFreeUnicodeString(&DriverName);
529  return Status;
530  }
531 
532  /* Now reference it */
534  0,
536  KernelMode,
537  (PVOID*)&driverObject,
538  NULL);
539 
540  /* Close the extra handle */
541  ZwClose(hDriver);
542 
543  if (!NT_SUCCESS(Status))
544  {
545  ExFreePoolWithTag(nameInfo, TAG_IO); // container for RegistryPath
547  RtlFreeUnicodeString(&DriverName);
548  return Status;
549  }
550 
551  /* Set up the service key name buffer */
552  UNICODE_STRING serviceKeyName;
553  serviceKeyName.Length = 0;
554  // put a NULL character at the end for Windows compatibility
555  serviceKeyName.MaximumLength = ServiceName.MaximumLength + sizeof(UNICODE_NULL);
556  serviceKeyName.Buffer = ExAllocatePoolWithTag(NonPagedPool,
557  serviceKeyName.MaximumLength,
558  TAG_IO);
559  if (!serviceKeyName.Buffer)
560  {
561  ObMakeTemporaryObject(driverObject);
562  ObDereferenceObject(driverObject);
563  ExFreePoolWithTag(nameInfo, TAG_IO); // container for RegistryPath
565  RtlFreeUnicodeString(&DriverName);
567  }
568 
569  /* Copy the name and set it in the driver extension */
570  RtlCopyUnicodeString(&serviceKeyName, &ServiceName);
572  driverObject->DriverExtension->ServiceKeyName = serviceKeyName;
573 
574  /* Make a copy of the driver name to store in the driver object */
575  UNICODE_STRING driverNamePaged;
576  driverNamePaged.Length = 0;
577  // put a NULL character at the end for Windows compatibility
578  driverNamePaged.MaximumLength = DriverName.MaximumLength + sizeof(UNICODE_NULL);
579  driverNamePaged.Buffer = ExAllocatePoolWithTag(PagedPool,
580  driverNamePaged.MaximumLength,
581  TAG_IO);
582  if (!driverNamePaged.Buffer)
583  {
584  ObMakeTemporaryObject(driverObject);
585  ObDereferenceObject(driverObject);
586  ExFreePoolWithTag(nameInfo, TAG_IO); // container for RegistryPath
587  RtlFreeUnicodeString(&DriverName);
589  }
590 
591  RtlCopyUnicodeString(&driverNamePaged, &DriverName);
592  driverObject->DriverName = driverNamePaged;
593 
594  /* Finally, call its init function */
595  Status = driverObject->DriverInit(driverObject, &RegistryPath);
596  *DriverEntryStatus = Status;
597  if (!NT_SUCCESS(Status))
598  {
599  DPRINT1("'%wZ' initialization failed, status (0x%08lx)\n", &DriverName, Status);
600  // return a special status value in case of failure
602  }
603 
604  /* HACK: We're going to say if we don't have any DOs from DriverEntry, then we're not legacy.
605  * Other parts of the I/O manager depend on this behavior */
606  if (!driverObject->DeviceObject)
607  {
608  driverObject->Flags &= ~DRVO_LEGACY_DRIVER;
609  }
610 
611  // Windows does this fixup - keep it for compatibility
612  for (INT i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
613  {
614  /*
615  * Make sure the driver didn't set any dispatch entry point to NULL!
616  * Doing so is illegal; drivers shouldn't touch entry points they
617  * do not implement.
618  */
619 
620  /* Check if it did so anyway */
621  if (!driverObject->MajorFunction[i])
622  {
623  /* Print a warning in the debug log */
624  DPRINT1("Driver <%wZ> set DriverObject->MajorFunction[%lu] to NULL!\n",
625  &driverObject->DriverName, i);
626 
627  /* Fix it up */
628  driverObject->MajorFunction[i] = IopInvalidDeviceRequest;
629  }
630  }
631 
632  // TODO: for legacy drivers, unload the driver if it didn't create any DO
633 
634  ExFreePoolWithTag(nameInfo, TAG_IO); // container for RegistryPath
635  RtlFreeUnicodeString(&DriverName);
636 
637  if (!NT_SUCCESS(Status))
638  {
639  // if the driver entry has been failed, clear the object
640  ObMakeTemporaryObject(driverObject);
641  ObDereferenceObject(driverObject);
642  return Status;
643  }
644 
645  *OutDriverObject = driverObject;
646 
648 
649  /* Set the driver as initialized */
650  IopReadyDeviceObjects(driverObject);
651 
653 
654  return STATUS_SUCCESS;
655 }
#define DRVO_LEGACY_DRIVER
Definition: iotypes.h:2226
VOID NTAPI MmFreeDriverInitialization(IN PLDR_DATA_TABLE_ENTRY LdrEntry)
Definition: sysldr.c:1635
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define TAG_IO
Definition: tag.h:69
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
VOID NTAPI IopReinitializeDrivers(VOID)
Definition: driver.c:1432
USHORT MaximumLength
Definition: env_spec_w32.h:370
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define IRP_MJ_MAXIMUM_FUNCTION
LONG NTSTATUS
Definition: precomp.h:26
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:213
#define STATUS_FAILED_DRIVER_ENTRY
Definition: ntstatus.h:911
PVOID DriverStart
Definition: iotypes.h:2279
_In_ LPWSTR _In_ ULONG _In_ ULONG _In_ ULONG _Out_ DEVINFO _In_ HDEV _In_ LPWSTR _In_ HANDLE hDriver
Definition: winddi.h:3553
POBJECT_TYPE IoDriverObjectType
Definition: driver.c:33
BOOLEAN PnpSystemInit
Definition: iomgr.c:17
NTSTATUS IopGetDriverNames(_In_ HANDLE ServiceHandle, _Out_ PUNICODE_STRING DriverName, _Out_opt_ PUNICODE_STRING ServiceName)
Definition: driver.c:125
NTSTATUS NTAPI IopInvalidDeviceRequest(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: driver.c:67
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
int32_t INT
Definition: typedefs.h:58
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:496
#define UNICODE_NULL
unsigned int UINT32
struct _DRIVER_OBJECT * DriverObject
Definition: iotypes.h:2219
#define FILE_READ_DATA
Definition: nt_native.h:628
PDRIVER_EXTENSION DriverExtension
Definition: iotypes.h:2282
PUNICODE_STRING HardwareDatabase
Definition: iotypes.h:2284
CSHORT Size
Definition: iotypes.h:2276
NTSTATUS NTAPI ObCreateObject(IN KPROCESSOR_MODE ProbeMode OPTIONAL, IN POBJECT_TYPE Type, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext OPTIONAL, IN ULONG ObjectSize, IN ULONG PagedPoolCharge OPTIONAL, IN ULONG NonPagedPoolCharge OPTIONAL, OUT PVOID *Object)
Definition: oblife.c:952
NTSTATUS NTAPI MmUnloadSystemImage(IN PVOID ImageHandle)
Definition: sysldr.c:911
Status
Definition: gdiplustypes.h:24
LPTSTR ServiceName
Definition: ServiceMain.c:15
#define 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
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:2932
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 _DRIVER_EXTENSION * PDRIVER_EXTENSION
UNICODE_STRING IopHardwareDatabaseKey
Definition: driver.c:29
#define NULL
Definition: types.h:112
#define IO_TYPE_DRIVER
#define DPRINT1
Definition: precomp.h:8
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
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
ULONG DriverSize
Definition: iotypes.h:2280
#define DPRINT
Definition: sndvol32.h:71
CSHORT Type
Definition: iotypes.h:2275
PVOID DriverSection
Definition: iotypes.h:2281
PDRIVER_INITIALIZE DriverInit
Definition: iotypes.h:2286
UNICODE_STRING DriverName
Definition: iotypes.h:2283
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2277
#define PAGED_CODE()
VOID NTAPI ObMakeTemporaryObject(IN PVOID ObjectBody)
Definition: oblife.c:1361

Referenced by IopInitializeBuiltinDriver(), and IopLoadDriver().

◆ IopInitializeSystemDrivers()

VOID FASTCALL IopInitializeSystemDrivers ( VOID  )

Definition at line 1146 of file driver.c.

1147 {
1148  PUNICODE_STRING *DriverList, *SavedList;
1149 
1151 
1152  /* No system drivers on the boot cd */
1153  if (KeLoaderBlock->SetupLdrBlock) return; // ExpInTextModeSetup
1154 
1155  /* Get the driver list */
1156  SavedList = DriverList = CmGetSystemDriverList();
1157  ASSERT(DriverList);
1158 
1159  /* Loop it */
1160  while (*DriverList)
1161  {
1162  /* Load the driver */
1163  ZwLoadDriver(*DriverList);
1164 
1165  /* Free the entry */
1166  RtlFreeUnicodeString(*DriverList);
1167  ExFreePool(*DriverList);
1168 
1169  /* Next entry */
1171  DriverList++;
1172  }
1173 
1174  /* Free the list */
1175  ExFreePool(SavedList);
1176 
1179  NULL,
1180  NULL);
1181 }
PDEVICE_OBJECT PhysicalDeviceObject
Definition: iotypes.h:850
VOID NTAPI InbvIndicateProgress(VOID)
Definition: inbv.c:884
PDEVICE_NODE IopRootDeviceNode
Definition: devnode.c:18
PUNICODE_STRING *NTAPI CmGetSystemDriverList(VOID)
Definition: cmsysini.c:1776
VOID PiQueueDeviceAction(_In_ PDEVICE_OBJECT DeviceObject, _In_ DEVICE_ACTION Action, _In_opt_ PKEVENT CompletionEvent, _Out_opt_ NTSTATUS *CompletionStatus)
Queue a device operation to a worker thread.
Definition: devaction.c:2616
struct _SETUP_LOADER_BLOCK * SetupLdrBlock
Definition: arc.h:511
PLOADER_PARAMETER_BLOCK KeLoaderBlock
Definition: krnlinit.c:29
#define ASSERT(a)
Definition: mode.c:45
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:2675
#define NULL
Definition: types.h:112
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

Referenced by IoInitSystem().

◆ IopInvalidDeviceRequest()

NTSTATUS NTAPI IopInvalidDeviceRequest ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 67 of file driver.c.

70 {
71  Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
72  Irp->IoStatus.Information = 0;
75 }
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
_In_ PIRP Irp
Definition: csq.h:116
#define IoCompleteRequest
Definition: irp.c:1240
#define IO_NO_INCREMENT
Definition: iotypes.h:598

Referenced by IoCreateDriver(), and IopInitializeDriverModule().

◆ IopLoadDriver()

NTSTATUS IopLoadDriver ( _In_ HANDLE  ServiceHandle,
_Out_ PDRIVER_OBJECT DriverObject 
)

Definition at line 1873 of file driver.c.

1876 {
1877  UNICODE_STRING ImagePath;
1878  NTSTATUS Status;
1879  PLDR_DATA_TABLE_ENTRY ModuleObject;
1881 
1883  Status = IopGetRegistryValue(ServiceHandle, L"ImagePath", &kvInfo);
1884  if (NT_SUCCESS(Status))
1885  {
1886  if (kvInfo->Type != REG_EXPAND_SZ || kvInfo->DataLength == 0)
1887  {
1888  ExFreePool(kvInfo);
1890  }
1891 
1892  ImagePath.Length = kvInfo->DataLength - sizeof(UNICODE_NULL),
1893  ImagePath.MaximumLength = kvInfo->DataLength,
1895  if (!ImagePath.Buffer)
1896  {
1897  ExFreePool(kvInfo);
1899  }
1900 
1901  RtlMoveMemory(ImagePath.Buffer,
1902  (PVOID)((ULONG_PTR)kvInfo + kvInfo->DataOffset),
1903  ImagePath.Length);
1904  ExFreePool(kvInfo);
1905  }
1906  else
1907  {
1908  return Status;
1909  }
1910 
1911  /*
1912  * Normalize the image path for all later processing.
1913  */
1914  Status = IopNormalizeImagePath(&ImagePath, NULL);
1915  if (!NT_SUCCESS(Status))
1916  {
1917  DPRINT("IopNormalizeImagePath() failed (Status %x)\n", Status);
1918  return Status;
1919  }
1920 
1921  DPRINT("FullImagePath: '%wZ'\n", &ImagePath);
1922 
1925 
1926  /*
1927  * Load the driver module
1928  */
1929  DPRINT("Loading module from %wZ\n", &ImagePath);
1930  Status = MmLoadSystemImage(&ImagePath, NULL, NULL, 0, (PVOID)&ModuleObject, &BaseAddress);
1931  RtlFreeUnicodeString(&ImagePath);
1932 
1933  if (!NT_SUCCESS(Status))
1934  {
1935  DPRINT("MmLoadSystemImage() failed (Status %lx)\n", Status);
1938  return Status;
1939  }
1940 
1941  // Display the loading message
1942  ULONG infoLength;
1943  Status = ZwQueryKey(ServiceHandle, KeyBasicInformation, NULL, 0, &infoLength);
1945  {
1947  if (servName)
1948  {
1949  Status = ZwQueryKey(ServiceHandle,
1951  servName,
1952  infoLength,
1953  &infoLength);
1954  if (NT_SUCCESS(Status))
1955  {
1957  .Length = servName->NameLength,
1958  .MaximumLength = servName->NameLength,
1959  .Buffer = servName->Name
1960  };
1961 
1963  }
1964  ExFreePoolWithTag(servName, TAG_IO);
1965  }
1966  }
1967 
1968  NTSTATUS driverEntryStatus;
1969  Status = IopInitializeDriverModule(ModuleObject,
1970  ServiceHandle,
1971  DriverObject,
1972  &driverEntryStatus);
1973  if (!NT_SUCCESS(Status))
1974  {
1975  DPRINT1("IopInitializeDriverModule() failed (Status %lx)\n", Status);
1976  }
1977 
1980 
1981  return Status;
1982 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define TAG_IO
Definition: tag.h:69
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define TAG_RTLREGISTRY
Definition: driver.c:35
#define TRUE
Definition: types.h:120
VOID FASTCALL IopDisplayLoadingMessage(PUNICODE_STRING ServiceName)
Definition: driver.c:295
LONG NTSTATUS
Definition: precomp.h:26
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
uint32_t ULONG_PTR
Definition: typedefs.h:65
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
#define UNICODE_NULL
NTSTATUS FASTCALL IopNormalizeImagePath(_Inout_ _When_(return >=0, _At_(ImagePath->Buffer, _Post_notnull_ __drv_allocatesMem(Mem))) PUNICODE_STRING ImagePath, _In_ PUNICODE_STRING ServiceName)
Definition: driver.c:334
_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
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
static const WCHAR L[]
Definition: oid.c:1250
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
Definition: btrfs_drv.h:1922
NTSTATUS NTAPI IopGetRegistryValue(IN HANDLE Handle, IN PWSTR ValueName, OUT PKEY_VALUE_FULL_INFORMATION *Information)
Definition: pnpmgr.c:1607
ERESOURCE IopDriverLoadResource
Definition: driver.c:19
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
#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:408
unsigned int ULONG
Definition: retypes.h:1
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define DPRINT
Definition: sndvol32.h:71
#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:2896

Referenced by IopLoadUnloadDriverWorker(), and PiAttachFilterDriversCallback().

◆ IopLoadUnloadDriverWorker()

static VOID NTAPI IopLoadUnloadDriverWorker ( _Inout_ PVOID  Parameter)
static

Definition at line 1987 of file driver.c.

1989 {
1990  PLOAD_UNLOAD_PARAMS LoadParams = Parameter;
1991 
1993 
1994  if (LoadParams->DriverObject)
1995  {
1996  // unload request
1997  LoadParams->DriverObject->DriverUnload(LoadParams->DriverObject);
1998  LoadParams->Status = STATUS_SUCCESS;
1999  }
2000  else
2001  {
2002  // load request
2003  HANDLE serviceHandle;
2004  NTSTATUS status;
2005  status = IopOpenRegistryKeyEx(&serviceHandle, NULL, LoadParams->RegistryPath, KEY_READ);
2006  if (!NT_SUCCESS(status))
2007  {
2008  LoadParams->Status = status;
2009  }
2010  else
2011  {
2012  LoadParams->Status = IopLoadDriver(serviceHandle, &LoadParams->DriverObject);
2013  ZwClose(serviceHandle);
2014  }
2015  }
2016 
2017  if (LoadParams->SetEvent)
2018  {
2019  KeSetEvent(&LoadParams->Event, 0, FALSE);
2020  }
2021 }
#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:1873
_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:45
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS Status
Definition: driver.c:50
PDRIVER_UNLOAD DriverUnload
Definition: iotypes.h:2288
BOOLEAN SetEvent
Definition: driver.c:55
PDRIVER_OBJECT DriverObject
Definition: driver.c:54
PUNICODE_STRING RegistryPath
Definition: driver.c:51
NTSTATUS NTAPI IopOpenRegistryKeyEx(PHANDLE KeyHandle, HANDLE ParentKey, PUNICODE_STRING Name, ACCESS_MASK DesiredAccess)
Definition: pnpmgr.c:1456
#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 334 of file driver.c.

338 {
339  UNICODE_STRING SystemRootString = RTL_CONSTANT_STRING(L"\\SystemRoot\\");
340  UNICODE_STRING DriversPathString = RTL_CONSTANT_STRING(L"\\SystemRoot\\System32\\drivers\\");
341  UNICODE_STRING DotSysString = RTL_CONSTANT_STRING(L".sys");
342  UNICODE_STRING InputImagePath;
343 
344  DPRINT("Normalizing image path '%wZ' for service '%wZ'\n", ImagePath, ServiceName);
345 
346  InputImagePath = *ImagePath;
347  if (InputImagePath.Length == 0)
348  {
349  ImagePath->Length = 0;
350  ImagePath->MaximumLength = DriversPathString.Length +
351  ServiceName->Length +
352  DotSysString.Length +
353  sizeof(UNICODE_NULL);
354  ImagePath->Buffer = ExAllocatePoolWithTag(NonPagedPool,
355  ImagePath->MaximumLength,
356  TAG_IO);
357  if (ImagePath->Buffer == NULL)
358  return STATUS_NO_MEMORY;
359 
360  RtlCopyUnicodeString(ImagePath, &DriversPathString);
362  RtlAppendUnicodeStringToString(ImagePath, &DotSysString);
363  }
364  else if (InputImagePath.Buffer[0] != L'\\')
365  {
366  ImagePath->Length = 0;
367  ImagePath->MaximumLength = SystemRootString.Length +
368  InputImagePath.Length +
369  sizeof(UNICODE_NULL);
370  ImagePath->Buffer = ExAllocatePoolWithTag(NonPagedPool,
371  ImagePath->MaximumLength,
372  TAG_IO);
373  if (ImagePath->Buffer == NULL)
374  return STATUS_NO_MEMORY;
375 
376  RtlCopyUnicodeString(ImagePath, &SystemRootString);
377  RtlAppendUnicodeStringToString(ImagePath, &InputImagePath);
378 
379  /* Free caller's string */
380  ExFreePoolWithTag(InputImagePath.Buffer, TAG_RTLREGISTRY);
381  }
382 
383  DPRINT("Normalized image path is '%wZ' for service '%wZ'\n", ImagePath, ServiceName);
384 
385  return STATUS_SUCCESS;
386 }
#define TAG_IO
Definition: tag.h:69
#define TAG_RTLREGISTRY
Definition: driver.c:35
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define UNICODE_NULL
LPTSTR ServiceName
Definition: ServiceMain.c:15
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
static const WCHAR L[]
Definition: oid.c:1250
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define NULL
Definition: types.h:112
#define STATUS_SUCCESS
Definition: shellext.h:65
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define DPRINT
Definition: sndvol32.h:71
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14

Referenced by IopLoadDriver(), and IopUnloadDriver().

◆ IopReinitializeBootDrivers()

VOID NTAPI IopReinitializeBootDrivers ( 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 */
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 
1501  /* Wait for all device actions being finished*/
1503 }
struct _Entry Entry
Definition: kefuncs.h:627
PVOID Context
Definition: io.h:459
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
KSPIN_LOCK DriverBootReinitListLock
Definition: driver.c:27
#define FALSE
Definition: types.h:117
PDRIVER_EXTENSION DriverExtension
Definition: iotypes.h:2282
PLIST_ENTRY NTAPI ExInterlockedRemoveHeadList(IN OUT PLIST_ENTRY ListHead, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:166
PDRIVER_OBJECT DriverObject
Definition: io.h:457
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
PPCI_DRIVER_EXTENSION DriverExtension
Definition: pci.c:41
#define NULL
Definition: types.h:112
PDRIVER_REINITIALIZE ReinitRoutine
Definition: io.h:458
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:4470

Referenced by IoInitSystem().

◆ IopReinitializeDrivers()

VOID NTAPI IopReinitializeDrivers ( VOID  )

Definition at line 1432 of file driver.c.

1433 {
1434  PDRIVER_REINIT_ITEM ReinitItem;
1436 
1437  /* Get the first entry and start looping */
1440  while (Entry)
1441  {
1442  /* Get the item */
1443  ReinitItem = CONTAINING_RECORD(Entry, DRIVER_REINIT_ITEM, ItemEntry);
1444 
1445  /* Increment reinitialization counter */
1446  ReinitItem->DriverObject->DriverExtension->Count++;
1447 
1448  /* Remove the device object flag */
1449  ReinitItem->DriverObject->Flags &= ~DRVO_REINIT_REGISTERED;
1450 
1451  /* Call the routine */
1452  ReinitItem->ReinitRoutine(ReinitItem->DriverObject,
1453  ReinitItem->Context,
1454  ReinitItem->DriverObject->
1455  DriverExtension->Count);
1456 
1457  /* Free the entry */
1458  ExFreePool(Entry);
1459 
1460  /* Move to the next one */
1463  }
1464 }
struct _Entry Entry
Definition: kefuncs.h:627
PVOID Context
Definition: io.h:459
#define DRVO_REINIT_REGISTERED
Definition: iotypes.h:4468
KSPIN_LOCK DriverReinitListLock
Definition: driver.c:22
PDRIVER_EXTENSION DriverExtension
Definition: iotypes.h:2282
PLIST_ENTRY NTAPI ExInterlockedRemoveHeadList(IN OUT PLIST_ENTRY ListHead, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:166
LIST_ENTRY DriverReinitListHead
Definition: driver.c:21
PDRIVER_OBJECT DriverObject
Definition: io.h:457
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:41
PDRIVER_REINITIALIZE ReinitRoutine
Definition: io.h:458
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 261 of file driver.c.

264 {
265  PWCHAR pc1;
266  PWCHAR pc2;
267  ULONG Length;
268 
269  if (String2->Length < String1->Length)
270  return FALSE;
271 
272  Length = String1->Length / 2;
273  pc1 = String1->Buffer;
274  pc2 = &String2->Buffer[String2->Length / sizeof(WCHAR) - Length];
275 
276  if (pc1 && pc2)
277  {
278  while (Length--)
279  {
280  if( *pc1++ != *pc2++ )
281  return FALSE;
282  }
283  return TRUE;
284  }
285  return FALSE;
286 }
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:2291
unsigned int ULONG
Definition: retypes.h:1

Referenced by IopDisplayLoadingMessage().

◆ IopUnloadDriver()

NTSTATUS NTAPI IopUnloadDriver ( PUNICODE_STRING  DriverServiceName,
BOOLEAN  UnloadPnpDrivers 
)

Definition at line 1205 of file driver.c.

1206 {
1207  UNICODE_STRING Backslash = RTL_CONSTANT_STRING(L"\\");
1209  UNICODE_STRING ImagePath;
1214  PEXTENDED_DEVOBJ_EXTENSION DeviceExtension;
1215  NTSTATUS Status;
1216  USHORT LastBackslash;
1217  BOOLEAN SafeToUnload = TRUE;
1219  UNICODE_STRING CapturedServiceName;
1220 
1221  PAGED_CODE();
1222 
1224 
1225  /* Need the appropriate priviliege */
1227  {
1228  DPRINT1("No unload privilege!\n");
1230  }
1231 
1232  /* Capture the service name */
1233  Status = ProbeAndCaptureUnicodeString(&CapturedServiceName,
1234  PreviousMode,
1235  DriverServiceName);
1236  if (!NT_SUCCESS(Status))
1237  {
1238  return Status;
1239  }
1240 
1241  DPRINT("IopUnloadDriver('%wZ', %u)\n", &CapturedServiceName, UnloadPnpDrivers);
1242 
1243  /* We need a service name */
1244  if (CapturedServiceName.Length == 0 || CapturedServiceName.Buffer == NULL)
1245  {
1246  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1247  return STATUS_INVALID_PARAMETER;
1248  }
1249 
1250  /*
1251  * Get the service name from the registry key name
1252  */
1254  &CapturedServiceName,
1255  &Backslash,
1256  &LastBackslash);
1257  if (NT_SUCCESS(Status))
1258  {
1259  NT_ASSERT(CapturedServiceName.Length >= LastBackslash + sizeof(WCHAR));
1260  ServiceName.Buffer = &CapturedServiceName.Buffer[LastBackslash / sizeof(WCHAR) + 1];
1261  ServiceName.Length = CapturedServiceName.Length - LastBackslash - sizeof(WCHAR);
1262  ServiceName.MaximumLength = CapturedServiceName.MaximumLength - LastBackslash - sizeof(WCHAR);
1263  }
1264  else
1265  {
1266  ServiceName = CapturedServiceName;
1267  }
1268 
1269  /*
1270  * Construct the driver object name
1271  */
1272  Status = RtlUShortAdd(sizeof(DRIVER_ROOT_NAME),
1273  ServiceName.Length,
1274  &ObjectName.MaximumLength);
1275  if (!NT_SUCCESS(Status))
1276  {
1277  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1278  return Status;
1279  }
1280  ObjectName.Length = 0;
1282  ObjectName.MaximumLength,
1283  TAG_IO);
1284  if (!ObjectName.Buffer)
1285  {
1286  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1288  }
1291 
1292  /*
1293  * Find the driver object
1294  */
1296  0,
1297  0,
1298  0,
1300  KernelMode,
1301  0,
1302  (PVOID*)&DriverObject);
1303 
1304  if (!NT_SUCCESS(Status))
1305  {
1306  DPRINT1("Can't locate driver object for %wZ\n", &ObjectName);
1308  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1309  return Status;
1310  }
1311 
1312  /* Free the buffer for driver object name */
1314 
1315  /* Check that driver is not already unloading */
1316  if (DriverObject->Flags & DRVO_UNLOAD_INVOKED)
1317  {
1318  DPRINT1("Driver deletion pending\n");
1320  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1321  return STATUS_DELETE_PENDING;
1322  }
1323 
1324  /*
1325  * Get path of service...
1326  */
1328 
1329  RtlInitUnicodeString(&ImagePath, NULL);
1330 
1331  QueryTable[0].Name = L"ImagePath";
1333  QueryTable[0].EntryContext = &ImagePath;
1334 
1336  CapturedServiceName.Buffer,
1337  QueryTable,
1338  NULL,
1339  NULL);
1340 
1341  /* We no longer need service name */
1342  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
1343 
1344  if (!NT_SUCCESS(Status))
1345  {
1346  DPRINT1("RtlQueryRegistryValues() failed (Status %x)\n", Status);
1348  return Status;
1349  }
1350 
1351  /*
1352  * Normalize the image path for all later processing.
1353  */
1354  Status = IopNormalizeImagePath(&ImagePath, &ServiceName);
1355 
1356  if (!NT_SUCCESS(Status))
1357  {
1358  DPRINT1("IopNormalizeImagePath() failed (Status %x)\n", Status);
1360  return Status;
1361  }
1362 
1363  /* Free the service path */
1364  ExFreePool(ImagePath.Buffer);
1365 
1366  /*
1367  * Unload the module and release the references to the device object
1368  */
1369 
1370  /* Call the load/unload routine, depending on current process */
1371  if (DriverObject->DriverUnload && DriverObject->DriverSection &&
1372  (UnloadPnpDrivers || (DriverObject->Flags & DRVO_LEGACY_DRIVER)))
1373  {
1374  /* Loop through each device object of the driver
1375  and set DOE_UNLOAD_PENDING flag */
1376  DeviceObject = DriverObject->DeviceObject;
1377  while (DeviceObject)
1378  {
1379  /* Set the unload pending flag for the device */
1380  DeviceExtension = IoGetDevObjExtension(DeviceObject);
1381  DeviceExtension->ExtensionFlags |= DOE_UNLOAD_PENDING;
1382 
1383  /* Make sure there are no attached devices or no reference counts */
1384  if ((DeviceObject->ReferenceCount) || (DeviceObject->AttachedDevice))
1385  {
1386  /* Not safe to unload */
1387  DPRINT1("Drivers device object is referenced or has attached devices\n");
1388 
1389  SafeToUnload = FALSE;
1390  }
1391 
1392  DeviceObject = DeviceObject->NextDevice;
1393  }
1394 
1395  /* If not safe to unload, then return success */
1396  if (!SafeToUnload)
1397  {
1399  return STATUS_SUCCESS;
1400  }
1401 
1402  DPRINT1("Unloading driver '%wZ' (manual)\n", &DriverObject->DriverName);
1403 
1404  /* Set the unload invoked flag and call the unload routine */
1408 
1409  /* Mark the driver object temporary, so it could be deleted later */
1411 
1412  /* Dereference it 2 times */
1415 
1416  return Status;
1417  }
1418  else
1419  {
1420  DPRINT1("No DriverUnload function! '%wZ' will not be unloaded!\n", &DriverObject->DriverName);
1421 
1422  /* Dereference one time (refd inside this function) */
1424 
1425  /* Return unloading failure */
1427  }
1428 }
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:4142
#define STATUS_DELETE_PENDING
Definition: ntstatus.h:322
#define DRVO_LEGACY_DRIVER
Definition: iotypes.h:2226
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define TAG_IO
Definition: tag.h:69
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSTATUS IopDoLoadUnloadDriver(_In_opt_ PUNICODE_STRING RegistryPath, _Inout_ PDRIVER_OBJECT *DriverObject)
Process load and unload driver operations. This is mostly for NtLoadDriver and NtUnloadDriver,...
Definition: driver.c:2033
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
BOOLEAN NTAPI SeSinglePrivilegeCheck(IN LUID PrivilegeValue, IN KPROCESSOR_MODE PreviousMode)
Definition: priv.c:520
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:3066
POBJECT_TYPE IoDriverObjectType
Definition: driver.c:33
#define NT_VERIFY(exp)
Definition: rtlfuncs.h:3289
_In_ PVOID _Out_opt_ PULONG_PTR _Outptr_opt_ PCUNICODE_STRING * ObjectName
Definition: cmfuncs.h:62
NTSTATUS NTAPI RtlFindCharInUnicodeString(_In_ ULONG Flags, _In_ PCUNICODE_STRING SearchString, _In_ PCUNICODE_STRING MatchString, _Out_ PUSHORT Position)
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
NTSTATUS FASTCALL IopNormalizeImagePath(_Inout_ _When_(return >=0, _At_(ImagePath->Buffer, _Post_notnull_ __drv_allocatesMem(Mem))) PUNICODE_STRING ImagePath, _In_ PUNICODE_STRING ServiceName)
Definition: driver.c:334
const LUID SeLoadDriverPrivilege
Definition: priv.c:27
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
#define DRVO_UNLOAD_INVOKED
Definition: iotypes.h:2225
Status
Definition: gdiplustypes.h:24
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
static __inline VOID ReleaseCapturedUnicodeString(IN PUNICODE_STRING CapturedString, IN KPROCESSOR_MODE CurrentMode)
Definition: probe.h:239
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
LPTSTR ServiceName
Definition: ServiceMain.c:15
#define ASSERT(a)
Definition: mode.c:45
#define DOE_UNLOAD_PENDING
Definition: iotypes.h:149
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ObDereferenceObject
Definition: obfuncs.h:203
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
static const WCHAR L[]
Definition: oid.c:1250
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
unsigned short USHORT
Definition: pedump.c:61
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
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 ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define DPRINT
Definition: sndvol32.h:71
#define IoGetDevObjExtension(DeviceObject)
Definition: io.h:125
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:411
#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:3312
VOID NTAPI ObMakeTemporaryObject(IN PVOID ObjectBody)
Definition: oblife.c:1361

Referenced by NtUnloadDriver().

◆ IoRegisterBootDriverReinitialization()

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

Definition at line 1703 of file driver.c.

1706 {
1707  PDRIVER_REINIT_ITEM ReinitItem;
1708 
1709  /* Allocate the entry */
1710  ReinitItem = ExAllocatePoolWithTag(NonPagedPool,
1711  sizeof(DRIVER_REINIT_ITEM),
1712  TAG_REINIT);
1713  if (!ReinitItem) return;
1714 
1715  /* Fill it out */
1716  ReinitItem->DriverObject = DriverObject;
1717  ReinitItem->ReinitRoutine = ReinitRoutine;
1718  ReinitItem->Context = Context;
1719 
1720  /* Set the Driver Object flag and insert the entry into the list */
1723  &ReinitItem->ItemEntry,
1725 }
PVOID Context
Definition: io.h:459
PLIST_ENTRY NTAPI ExInterlockedInsertTailList(IN OUT PLIST_ENTRY ListHead, IN OUT PLIST_ENTRY ListEntry, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:140
LIST_ENTRY DriverBootReinitListHead
Definition: driver.c:26
LIST_ENTRY ItemEntry
Definition: io.h:456
KSPIN_LOCK DriverBootReinitListLock
Definition: driver.c:27
PDRIVER_OBJECT DriverObject
Definition: io.h:457
#define TAG_REINIT
Definition: tag.h:73
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
struct tagContext Context
Definition: acpixf.h:1034
PDRIVER_REINITIALIZE ReinitRoutine
Definition: io.h:458
#define DRVO_BOOTREINIT_REGISTERED
Definition: iotypes.h:4470

Referenced by _Function_class_(), and DriverEntry().

◆ IoRegisterDriverReinitialization()

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

Definition at line 1732 of file driver.c.

1735 {
1736  PDRIVER_REINIT_ITEM ReinitItem;
1737 
1738  /* Allocate the entry */
1739  ReinitItem = ExAllocatePoolWithTag(NonPagedPool,
1740  sizeof(DRIVER_REINIT_ITEM),
1741  TAG_REINIT);
1742  if (!ReinitItem) return;
1743 
1744  /* Fill it out */
1745  ReinitItem->DriverObject = DriverObject;
1746  ReinitItem->ReinitRoutine = ReinitRoutine;
1747  ReinitItem->Context = Context;
1748 
1749  /* Set the Driver Object flag and insert the entry into the list */
1752  &ReinitItem->ItemEntry,
1754 }
PVOID Context
Definition: io.h:459
PLIST_ENTRY NTAPI ExInterlockedInsertTailList(IN OUT PLIST_ENTRY ListHead, IN OUT PLIST_ENTRY ListEntry, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:140
#define DRVO_REINIT_REGISTERED
Definition: iotypes.h:4468
LIST_ENTRY ItemEntry
Definition: io.h:456
KSPIN_LOCK DriverReinitListLock
Definition: driver.c:22
LIST_ENTRY DriverReinitListHead
Definition: driver.c:21
PDRIVER_OBJECT DriverObject
Definition: io.h:457
#define TAG_REINIT
Definition: tag.h:73
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
struct tagContext Context
Definition: acpixf.h:1034
PDRIVER_REINITIALIZE ReinitRoutine
Definition: io.h:458

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

675 {
677  UNICODE_STRING BaseName, BaseDirectory;
678  PLOAD_IMPORTS LoadedImports = (PVOID)-2;
679  PCHAR MissingApiName, Buffer;
680  PWCHAR MissingDriverName;
681  PVOID DriverBase = LdrEntry->DllBase;
682 
683  /* Allocate a buffer we'll use for names */
686  TAG_LDR_WSTR);
687  if (!Buffer)
688  {
689  /* Fail */
691  }
692 
693  /* Check for a separator */
694  if (FileName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR)
695  {
696  PWCHAR p;
697  ULONG BaseLength;
698 
699  /* Loop the path until we get to the base name */
700  p = &FileName->Buffer[FileName->Length / sizeof(WCHAR)];
701  while (*(p - 1) != OBJ_NAME_PATH_SEPARATOR) p--;
702 
703  /* Get the length */
704  BaseLength = (ULONG)(&FileName->Buffer[FileName->Length / sizeof(WCHAR)] - p);
705  BaseLength *= sizeof(WCHAR);
706 
707  /* Setup the string */
708  BaseName.Length = (USHORT)BaseLength;
709  BaseName.Buffer = p;
710  }
711  else
712  {
713  /* Otherwise, we already have a base name */
714  BaseName.Length = FileName->Length;
715  BaseName.Buffer = FileName->Buffer;
716  }
717 
718  /* Setup the maximum length */
719  BaseName.MaximumLength = BaseName.Length;
720 
721  /* Now compute the base directory */
722  BaseDirectory = *FileName;
723  BaseDirectory.Length -= BaseName.Length;
724  BaseDirectory.MaximumLength = BaseDirectory.Length;
725 
726  /* Resolve imports */
727  MissingApiName = Buffer;
728  Status = MiResolveImageReferences(DriverBase,
729  &BaseDirectory,
730  NULL,
731  &MissingApiName,
732  &MissingDriverName,
733  &LoadedImports);
734 
735  /* Free the temporary buffer */
737 
738  /* Check the result of the imports resolution */
739  if (!NT_SUCCESS(Status)) return Status;
740 
741  /* Return */
742  *ModuleObject = LdrEntry;
743  return STATUS_SUCCESS;
744 }
signed char * PCHAR
Definition: retypes.h:7
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
USHORT MaximumLength
Definition: env_spec_w32.h:370
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
LONG NTSTATUS
Definition: precomp.h:26
uint16_t * PWCHAR
Definition: typedefs.h:56
#define MAXIMUM_FILENAME_LENGTH
Definition: env_spec_w32.h:41
PVOID DllBase
Definition: btrfs_drv.h:1926
#define TAG_LDR_WSTR
Definition: tag.h:110
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
Definition: bufpool.h:45
void * PVOID
Definition: retypes.h:9
Status
Definition: gdiplustypes.h:24
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI MiResolveImageReferences(IN PVOID ImageBase, IN PUNICODE_STRING ImageFileDirectory, IN PUNICODE_STRING NamePrefix OPTIONAL, OUT PCHAR *MissingApi, OUT PWCHAR *MissingDriver, OUT PLOAD_IMPORTS *LoadImports)
Definition: sysldr.c:1000
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
struct _FileName FileName
Definition: fatprocs.h:893
unsigned short USHORT
Definition: pedump.c:61
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_SUCCESS
Definition: shellext.h:65
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
GLfloat GLfloat p
Definition: glext.h:8902

◆ 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:167
LONG NTSTATUS
Definition: precomp.h:26
struct _LOAD_IMPORTS * PLOAD_IMPORTS
#define MM_SYSLDR_SINGLE_ENTRY
Definition: miarm.h:203
NTSTATUS NTAPI MiDereferenceImports(IN PLOAD_IMPORTS ImportList)
Definition: sysldr.c:395
#define TAG_LDR_IMPORTS
Definition: tag.h:111
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
Definition: fs_rec.h:186
#define STATUS_DRIVER_ENTRYPOINT_NOT_FOUND
Definition: ntstatus.h:736
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
uint32_t ULONG_PTR
Definition: typedefs.h:65
PVOID DllBase
Definition: btrfs_drv.h:1926
#define TAG_LDR_WSTR
Definition: tag.h:110
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
#define ERROR_DBGBREAK(...)
Definition: debug.h:221
unsigned char BOOLEAN
void * PVOID
Definition: retypes.h:9
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define PCHAR
Definition: match.c:90
Status
Definition: gdiplustypes.h:24
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define ASSERT(a)
Definition: mode.c:45
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define _strnicmp(_String1, _String2, _MaxCount)
Definition: compat.h:23
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
static const WCHAR L[]
Definition: oid.c:1250
#define RtlImageDirectoryEntryToData
Definition: compat.h:668
Definition: btrfs_drv.h:1922
NTSTATUS NTAPI MmLoadSystemImage(IN PUNICODE_STRING FileName, IN PUNICODE_STRING NamePrefix OPTIONAL, IN PUNICODE_STRING LoadedName OPTIONAL, IN ULONG Flags, OUT PVOID *ModuleObject, OUT PVOID *ImageBaseAddress)
Definition: sysldr.c:2896
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:200
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
union _IMAGE_THUNK_DATA32::@2108 u1
#define STATUS_SUCCESS
Definition: shellext.h:65
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define DPRINT
Definition: sndvol32.h:71
#define __FUNCTION__
Definition: types.h:112
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 2081 of file driver.c.

2082 {
2083  UNICODE_STRING CapturedServiceName = { 0, 0, NULL };
2086  NTSTATUS Status;
2087 
2088  PAGED_CODE();
2089 
2091 
2092  /* Need the appropriate priviliege */
2094  {
2095  DPRINT1("No load privilege!\n");
2097  }
2098 
2099  /* Capture the service name */
2100  Status = ProbeAndCaptureUnicodeString(&CapturedServiceName,
2101  PreviousMode,
2102  DriverServiceName);
2103  if (!NT_SUCCESS(Status))
2104  {
2105  return Status;
2106  }
2107 
2108  DPRINT("NtLoadDriver('%wZ')\n", &CapturedServiceName);
2109 
2110  /* We need a service name */
2111  if (CapturedServiceName.Length == 0 || CapturedServiceName.Buffer == NULL)
2112  {
2113  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
2114  return STATUS_INVALID_PARAMETER;
2115  }
2116 
2117  /* Load driver and call its entry point */
2118  DriverObject = NULL;
2119  Status = IopDoLoadUnloadDriver(&CapturedServiceName, &DriverObject);
2120 
2121  ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
2122  return Status;
2123 }
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:2033
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI SeSinglePrivilegeCheck(IN LUID PrivilegeValue, IN KPROCESSOR_MODE PreviousMode)
Definition: priv.c:520
const LUID SeLoadDriverPrivilege
Definition: priv.c:27
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
Status
Definition: gdiplustypes.h:24
static __inline VOID ReleaseCapturedUnicodeString(IN PUNICODE_STRING CapturedString, IN KPROCESSOR_MODE CurrentMode)
Definition: probe.h:239
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
#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 2142 of file driver.c.

2143 {
2144  return IopUnloadDriver(DriverServiceName, FALSE);
2145 }
#define FALSE
Definition: types.h:117
NTSTATUS NTAPI IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
Definition: driver.c:1205

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

Variable Documentation

◆ DriverBootReinitListHead

LIST_ENTRY DriverBootReinitListHead

◆ DriverBootReinitListLock

KSPIN_LOCK DriverBootReinitListLock

◆ DriverBootReinitTailEntry

PLIST_ENTRY DriverBootReinitTailEntry

Definition at line 25 of file driver.c.

◆ DriverReinitListHead

LIST_ENTRY DriverReinitListHead

Definition at line 21 of file driver.c.

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

◆ DriverReinitListLock

KSPIN_LOCK DriverReinitListLock

Definition at line 22 of file driver.c.

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

◆ DriverReinitTailEntry

PLIST_ENTRY DriverReinitTailEntry

Definition at line 23 of file driver.c.

◆ ExpInTextModeSetup

BOOLEAN ExpInTextModeSetup

◆ IoDriverObjectType

◆ IopDriverLoadResource

ERESOURCE IopDriverLoadResource

Definition at line 19 of file driver.c.

Referenced by IoInitSystem(), and IopLoadDriver().

◆ IopGroupIndex

USHORT IopGroupIndex

Definition at line 42 of file driver.c.

Referenced by IopInitializeBootDrivers().

◆ IopGroupTable

PLIST_ENTRY IopGroupTable

Definition at line 43 of file driver.c.

Referenced by IopInitializeBootDrivers().

◆ IopHardwareDatabaseKey

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

Definition at line 29 of file driver.c.

Referenced by IopInitializeDriverModule().

◆ PiEnumerationFinished

KEVENT PiEnumerationFinished

Definition at line 50 of file devaction.c.

Referenced by IopReinitializeBootDrivers().

◆ PnPBootDriversLoaded

BOOLEAN PnPBootDriversLoaded

Definition at line 26 of file pnpinit.c.

Referenced by IopInitializeBootDrivers().

◆ PnpSystemInit

BOOLEAN PnpSystemInit

Definition at line 17 of file iomgr.c.

Referenced by IopInitializeDriverModule().

◆ ServicesKeyName

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

Definition at line 31 of file driver.c.

Referenced by IopInitializeBuiltinDriver(), and MmCallDllInitialize().