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

Go to the source code of this file.

Classes

struct  _LOAD_UNLOAD_PARAMS
 

Macros

#define NDEBUG
 

Typedefs

typedef struct _LOAD_UNLOAD_PARAMS LOAD_UNLOAD_PARAMS
 
typedef struct _LOAD_UNLOAD_PARAMSPLOAD_UNLOAD_PARAMS
 

Functions

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

Variables

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

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 14 of file driver.c.

Typedef Documentation

◆ LOAD_UNLOAD_PARAMS

◆ PLOAD_UNLOAD_PARAMS

Function Documentation

◆ IoAllocateDriverObjectExtension()

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

Definition at line 1838 of file driver.c.

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

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

◆ IoCreateDriver()

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

Definition at line 1588 of file driver.c.

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

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

◆ IoDeleteDriver()

VOID NTAPI IoDeleteDriver ( _In_ PDRIVER_OBJECT  DriverObject)

Definition at line 1768 of file driver.c.

1770{
1771 /* Simply dereference the Object */
1773}

Referenced by KdpDriverReinit().

◆ IoGetDriverObjectExtension()

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

Definition at line 1916 of file driver.c.

1918{
1919 KIRQL OldIrql;
1920 PIO_CLIENT_EXTENSION DriverExtensions;
1921
1922 /* Acquire lock */
1924
1925 /* Loop the list until we find the right one */
1926 DriverExtensions = IoGetDrvObjExtension(DriverObject)->ClientDriverExtension;
1927 while (DriverExtensions)
1928 {
1929 /* Check for a match */
1930 if (DriverExtensions->ClientIdentificationAddress ==
1932 {
1933 /* Break out */
1934 break;
1935 }
1936
1937 /* Keep looping */
1938 DriverExtensions = DriverExtensions->NextExtension;
1939 }
1940
1941 /* Release lock */
1943
1944 /* Return nothing or the extension */
1945 if (!DriverExtensions) return NULL;
1946 return DriverExtensions + 1;
1947}

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

◆ IopDeleteDriver()

VOID NTAPI IopDeleteDriver ( IN PVOID  ObjectBody)

Definition at line 77 of file driver.c.

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

Referenced by IopCreateObjectTypes().

◆ IopDisplayLoadingMessage()

static VOID FASTCALL IopDisplayLoadingMessage ( _In_ PCUNICODE_STRING  ServiceName)
static

Displays a driver-loading message in SOS mode.

Definition at line 334 of file driver.c.

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

Referenced by IopInitializeBuiltinDriver(), and IopLoadDriver().

◆ IopDoLoadUnloadDriver()

NTSTATUS IopDoLoadUnloadDriver ( _In_opt_ PUNICODE_STRING  RegistryPath,
_Inout_ PDRIVER_OBJECT DriverObject 
)

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

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

Definition at line 2117 of file driver.c.

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

Referenced by IopUnloadDriver(), and NtLoadDriver().

◆ IopGetDeviceObjectFromDeviceInstance()

PDEVICE_OBJECT IopGetDeviceObjectFromDeviceInstance ( PUNICODE_STRING  DeviceInstance)

Definition at line 206 of file plugplay.c.

207{
209 IOP_FIND_DEVICE_INSTANCE_TRAVERSE_CONTEXT DeviceInstanceContext;
210
211 if (IopRootDeviceNode == NULL)
212 return NULL;
213
214 if (DeviceInstance == NULL ||
215 DeviceInstance->Length == 0)
216 {
218 {
221 }
222 else
223 return NULL;
224 }
225
226 /* Traverse the device tree to find the matching device node */
227 DeviceInstanceContext.InstancePath = DeviceInstance;
228 DeviceInstanceContext.DeviceObject = NULL;
232 &DeviceInstanceContext);
234
235 /* In case of error or instance not found, this will still be NULL from above. */
236 return DeviceInstanceContext.DeviceObject;
237}
static const WCHAR DeviceInstance[]
Definition: interface.c:28
#define IopInitDeviceTreeTraverseContext( _DeviceTreeTraverseContext, _DeviceNode, _Action, _Context)
Definition: io.h:229
NTSTATUS IopTraverseDeviceTree(PDEVICETREE_TRAVERSE_CONTEXT Context)
PDEVICE_NODE IopRootDeviceNode
Definition: devnode.c:18
NTSTATUS IopFindDeviceInstanceTraverse(_In_ PDEVICE_NODE DeviceNode, _Inout_ PVOID Context)
Definition: plugplay.c:186
PDEVICE_OBJECT PhysicalDeviceObject
Definition: iotypes.h:1010
#define ObReferenceObject
Definition: obfuncs.h:204

Referenced by IopInitializeBuiltinDriver().

◆ IopGetDriverNames()

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

Definition at line 123 of file driver.c.

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

Referenced by IopInitializeDriverModule(), and PiAttachFilterDriversCallback().

◆ IopInitializeBootDrivers()

VOID FASTCALL IopInitializeBootDrivers ( VOID  )

Definition at line 1035 of file driver.c.

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

Referenced by IoInitSystem().

◆ IopInitializeBuiltinDriver()

static BOOLEAN IopInitializeBuiltinDriver ( IN PLDR_DATA_TABLE_ENTRY  BootLdrEntry)
static

Definition at line 813 of file driver.c.

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

Referenced by IopInitializeBootDrivers().

◆ IopInitializeDriverModule()

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

Initialize a loaded driver.

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

Definition at line 449 of file driver.c.

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

Referenced by IopInitializeBuiltinDriver(), and IopLoadDriver().

◆ IopInitializeSystemDrivers()

VOID FASTCALL IopInitializeSystemDrivers ( VOID  )

Definition at line 1222 of file driver.c.

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

Referenced by IoInitSystem().

◆ IopInvalidDeviceRequest()

NTSTATUS NTAPI IopInvalidDeviceRequest ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 65 of file driver.c.

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

Referenced by IoCreateDriver(), and IopInitializeDriverModule().

◆ IopLoadDriver()

NTSTATUS IopLoadDriver ( _In_ HANDLE  ServiceHandle,
_Out_ PDRIVER_OBJECT DriverObject 
)

Definition at line 1950 of file driver.c.

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

Referenced by IopLoadUnloadDriverWorker(), and PiAttachFilterDriversCallback().

◆ IopLoadUnloadDriverWorker()

static VOID NTAPI IopLoadUnloadDriverWorker ( _Inout_ PVOID  Parameter)
static

Definition at line 2071 of file driver.c.

2073{
2074 PLOAD_UNLOAD_PARAMS LoadParams = Parameter;
2075
2077
2078 if (LoadParams->DriverObject)
2079 {
2080 // unload request
2081 LoadParams->DriverObject->DriverUnload(LoadParams->DriverObject);
2082 LoadParams->Status = STATUS_SUCCESS;
2083 }
2084 else
2085 {
2086 // load request
2087 HANDLE serviceHandle;
2089 status = IopOpenRegistryKeyEx(&serviceHandle, NULL, LoadParams->RegistryPath, KEY_READ);
2090 if (!NT_SUCCESS(status))
2091 {
2092 LoadParams->Status = status;
2093 }
2094 else
2095 {
2096 LoadParams->Status = IopLoadDriver(serviceHandle, &LoadParams->DriverObject);
2097 ZwClose(serviceHandle);
2098 }
2099 }
2100
2101 if (LoadParams->SetEvent)
2102 {
2103 KeSetEvent(&LoadParams->Event, 0, FALSE);
2104 }
2105}
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
NTSTATUS IopLoadDriver(_In_ HANDLE ServiceHandle, _Out_ PDRIVER_OBJECT *DriverObject)
Definition: driver.c:1950
PDRIVER_UNLOAD DriverUnload
Definition: iotypes.h:2288
_Inout_opt_ PVOID Parameter
Definition: rtltypes.h:336

Referenced by IopDoLoadUnloadDriver().

◆ IopNormalizeImagePath()

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

Definition at line 375 of file driver.c.

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

Referenced by IopLoadDriver(), and IopUnloadDriver().

◆ IopReinitializeBootDrivers()

VOID NTAPI IopReinitializeBootDrivers ( VOID  )

Definition at line 1544 of file driver.c.

1545{
1546 PDRIVER_REINIT_ITEM ReinitItem;
1548
1549 /* Get the first entry and start looping */
1552 while (Entry)
1553 {
1554 /* Get the item */
1555 ReinitItem = CONTAINING_RECORD(Entry, DRIVER_REINIT_ITEM, ItemEntry);
1556
1557 /* Increment reinitialization counter */
1558 ReinitItem->DriverObject->DriverExtension->Count++;
1559
1560 /* Remove the device object flag */
1561 ReinitItem->DriverObject->Flags &= ~DRVO_BOOTREINIT_REGISTERED;
1562
1563 /* Call the routine */
1564 ReinitItem->ReinitRoutine(ReinitItem->DriverObject,
1565 ReinitItem->Context,
1566 ReinitItem->DriverObject->
1567 DriverExtension->Count);
1568
1569 /* Free the entry */
1571
1572 /* Move to the next one */
1575 }
1576
1577 /* Wait for all device actions being finished*/
1579}
PLIST_ENTRY NTAPI ExInterlockedRemoveHeadList(IN OUT PLIST_ENTRY ListHead, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:166
KEVENT PiEnumerationFinished
Definition: devaction.c:50
KSPIN_LOCK DriverBootReinitListLock
Definition: driver.c:28
LIST_ENTRY DriverBootReinitListHead
Definition: driver.c:27
base of all file and directory entries
Definition: entries.h:83
PDRIVER_OBJECT DriverObject
Definition: io.h:449
PDRIVER_REINITIALIZE ReinitRoutine
Definition: io.h:450
PVOID Context
Definition: io.h:451
@ Executive
Definition: ketypes.h:415

Referenced by IoInitSystem().

◆ IopReinitializeDrivers()

VOID NTAPI IopReinitializeDrivers ( VOID  )

Definition at line 1508 of file driver.c.

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

Referenced by IoInitSystem(), and IopInitializeDriverModule().

◆ IopSuffixUnicodeString()

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

Determines whether String1 may be a suffix of String2.

Returns
TRUE if String2 contains String1 as a suffix.

Definition at line 286 of file driver.c.

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

Referenced by IopDisplayLoadingMessage().

◆ IopUnloadDriver()

NTSTATUS NTAPI IopUnloadDriver ( PUNICODE_STRING  DriverServiceName,
BOOLEAN  UnloadPnpDrivers 
)

Definition at line 1281 of file driver.c.

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

Referenced by NtUnloadDriver().

◆ IoRegisterBootDriverReinitialization()

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

Definition at line 1780 of file driver.c.

1783{
1784 PDRIVER_REINIT_ITEM ReinitItem;
1785
1786 /* Allocate the entry */
1788 sizeof(DRIVER_REINIT_ITEM),
1789 TAG_REINIT);
1790 if (!ReinitItem) return;
1791
1792 /* Fill it out */
1793 ReinitItem->DriverObject = DriverObject;
1794 ReinitItem->ReinitRoutine = ReinitRoutine;
1795 ReinitItem->Context = Context;
1796
1797 /* Set the Driver Object flag and insert the entry into the list */
1800 &ReinitItem->ItemEntry,
1802}
PLIST_ENTRY NTAPI ExInterlockedInsertTailList(IN OUT PLIST_ENTRY ListHead, IN OUT PLIST_ENTRY ListEntry, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:140
LIST_ENTRY ItemEntry
Definition: io.h:448
#define TAG_REINIT
Definition: tag.h:83
#define DRVO_BOOTREINIT_REGISTERED
Definition: iotypes.h:4472

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

◆ IoRegisterDriverReinitialization()

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

Definition at line 1809 of file driver.c.

1812{
1813 PDRIVER_REINIT_ITEM ReinitItem;
1814
1815 /* Allocate the entry */
1817 sizeof(DRIVER_REINIT_ITEM),
1818 TAG_REINIT);
1819 if (!ReinitItem) return;
1820
1821 /* Fill it out */
1822 ReinitItem->DriverObject = DriverObject;
1823 ReinitItem->ReinitRoutine = ReinitRoutine;
1824 ReinitItem->Context = Context;
1825
1826 /* Set the Driver Object flag and insert the entry into the list */
1829 &ReinitItem->ItemEntry,
1831}
#define DRVO_REINIT_REGISTERED
Definition: iotypes.h:4470

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

◆ LdrProcessDriverModule()

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

Definition at line 728 of file driver.c.

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

◆ MiResolveImageReferences()

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

Definition at line 1034 of file sysldr.c.

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

Referenced by LdrProcessDriverModule(), and MmLoadSystemImage().

◆ NtLoadDriver()

NTSTATUS NTAPI NtLoadDriver ( IN PUNICODE_STRING  DriverServiceName)

Definition at line 2165 of file driver.c.

2166{
2167 UNICODE_STRING CapturedServiceName = { 0, 0, NULL };
2171
2172 PAGED_CODE();
2173
2175
2176 /* Need the appropriate priviliege */
2178 {
2179 DPRINT1("No load privilege!\n");
2181 }
2182
2183 /* Capture the service name */
2184 Status = ProbeAndCaptureUnicodeString(&CapturedServiceName,
2186 DriverServiceName);
2187 if (!NT_SUCCESS(Status))
2188 {
2189 return Status;
2190 }
2191
2192 DPRINT("NtLoadDriver('%wZ')\n", &CapturedServiceName);
2193
2194 /* We need a service name */
2195 if (CapturedServiceName.Length == 0 || CapturedServiceName.Buffer == NULL)
2196 {
2197 ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
2199 }
2200
2201 /* Load driver and call its entry point */
2203 Status = IopDoLoadUnloadDriver(&CapturedServiceName, &DriverObject);
2204
2205 ReleaseCapturedUnicodeString(&CapturedServiceName, PreviousMode);
2206 return Status;
2207}
#define KeGetPreviousMode()
Definition: ketypes.h:1115

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

◆ NtUnloadDriver()

NTSTATUS NTAPI NtUnloadDriver ( IN PUNICODE_STRING  DriverServiceName)

Definition at line 2226 of file driver.c.

2227{
2228 return IopUnloadDriver(DriverServiceName, FALSE);
2229}
NTSTATUS NTAPI IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers)
Definition: driver.c:1281

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

Variable Documentation

◆ DriverBootReinitListHead

LIST_ENTRY DriverBootReinitListHead

◆ DriverBootReinitListLock

KSPIN_LOCK DriverBootReinitListLock

◆ DriverBootReinitTailEntry

PLIST_ENTRY DriverBootReinitTailEntry

Definition at line 26 of file driver.c.

◆ DriverReinitListHead

LIST_ENTRY DriverReinitListHead

Definition at line 22 of file driver.c.

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

◆ DriverReinitListLock

KSPIN_LOCK DriverReinitListLock

Definition at line 23 of file driver.c.

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

◆ DriverReinitTailEntry

PLIST_ENTRY DriverReinitTailEntry

Definition at line 24 of file driver.c.

◆ IoDriverObjectType

◆ IopDriverLoadResource

ERESOURCE IopDriverLoadResource

Definition at line 20 of file driver.c.

Referenced by IoInitSystem(), and IopLoadDriver().

◆ IopGroupIndex

USHORT IopGroupIndex

Definition at line 40 of file driver.c.

Referenced by IopInitializeBootDrivers().

◆ IopGroupTable

PLIST_ENTRY IopGroupTable

Definition at line 41 of file driver.c.

Referenced by IopInitializeBootDrivers().

◆ IopHardwareDatabaseKey

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

Definition at line 30 of file driver.c.

Referenced by IopInitializeDriverModule().

◆ PiEnumerationFinished

KEVENT PiEnumerationFinished
extern

Definition at line 50 of file devaction.c.

Referenced by IopReinitializeBootDrivers().

◆ PnPBootDriversLoaded

BOOLEAN PnPBootDriversLoaded
extern

Definition at line 20 of file pnpinit.c.

Referenced by IopInitializeBootDrivers().

◆ PnpSystemInit

BOOLEAN PnpSystemInit
extern

Definition at line 17 of file iomgr.c.

Referenced by IopInitializeDriverModule().

◆ ServicesKeyName

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

Definition at line 32 of file driver.c.

Referenced by IopInitializeBuiltinDriver(), and MmCallDllInitialize().