driver.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874
  1. /*++
  2. Copyright (c) 2012 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. driver.c
  5. Abstract:
  6. This module implements routines that interact with drivers.
  7. Author:
  8. Evan Green 16-Sep-2012
  9. Environment:
  10. Kernel
  11. --*/
  12. //
  13. // ------------------------------------------------------------------- Includes
  14. //
  15. #include <minoca/kernel/kernel.h>
  16. #include "iop.h"
  17. //
  18. // ---------------------------------------------------------------- Definitions
  19. //
  20. //
  21. // ------------------------------------------------------ Data Type Definitions
  22. //
  23. //
  24. // ----------------------------------------------- Internal Function Prototypes
  25. //
  26. KSTATUS
  27. IopInitializeImages (
  28. PKPROCESS Process
  29. );
  30. KSTATUS
  31. IopAddDeviceDatabaseEntry (
  32. PSTR DeviceOrClassId,
  33. PSTR DriverName,
  34. PLIST_ENTRY DatabaseListHead
  35. );
  36. //
  37. // -------------------------------------------------------------------- Globals
  38. //
  39. //
  40. // Store list heads to the device databases. These list entries are of type
  41. // DEVICE_DATABASE_ENTRY, and store the mappings between devices and drivers
  42. // or device classes and drivers. All memory in these databases is paged.
  43. //
  44. LIST_ENTRY IoDeviceDatabaseHead;
  45. LIST_ENTRY IoDeviceClassDatabaseHead;
  46. PQUEUED_LOCK IoDeviceDatabaseLock;
  47. //
  48. // ------------------------------------------------------------------ Functions
  49. //
  50. KERNEL_API
  51. KSTATUS
  52. IoRegisterDriverFunctions (
  53. PDRIVER Driver,
  54. PDRIVER_FUNCTION_TABLE FunctionTable
  55. )
  56. /*++
  57. Routine Description:
  58. This routine is called by a driver to register its function pointers with
  59. the system. Drivers cannot be attached to the system until this is
  60. complete. This routine is usually called by a driver in its entry point.
  61. This routine should only be called once during the lifetime of a driver.
  62. Arguments:
  63. Driver - Supplies a pointer to the driver whose routines are being
  64. registered.
  65. FunctionTable - Supplies a pointer to the function pointer table containing
  66. the drivers dispatch routines.
  67. Return Value:
  68. STATUS_SUCCESS on success.
  69. STATUS_INVALID_PARAMETER if a required parameter or function was not
  70. supplied.
  71. --*/
  72. {
  73. KSTATUS Status;
  74. Status = STATUS_INVALID_PARAMETER;
  75. if ((Driver == NULL) || (FunctionTable == NULL)) {
  76. goto RegisterDriverFunctionsEnd;
  77. }
  78. if (FunctionTable->Version == 0) {
  79. goto RegisterDriverFunctionsEnd;
  80. }
  81. //
  82. // The driver seems to have filled out the correct fields. Save the
  83. // function table in the driver structure.
  84. //
  85. RtlCopyMemory(&(Driver->FunctionTable),
  86. FunctionTable,
  87. sizeof(DRIVER_FUNCTION_TABLE));
  88. Status = STATUS_SUCCESS;
  89. RegisterDriverFunctionsEnd:
  90. return Status;
  91. }
  92. KERNEL_API
  93. KSTATUS
  94. IoAttachDriverToDevice (
  95. PDRIVER Driver,
  96. PDEVICE Device,
  97. PVOID Context
  98. )
  99. /*++
  100. Routine Description:
  101. This routine is called by a driver to attach itself to a device. Once
  102. attached, the driver will participate in all IRPs that go through to the
  103. device. This routine can only be called during a driver's AddDevice routine.
  104. Arguments:
  105. Driver - Supplies a pointer to the driver attaching to the device.
  106. Device - Supplies a pointer to the device to attach to.
  107. Context - Supplies an optional context pointer that will be passed to the
  108. driver each time it is called in relation to this device.
  109. Return Value:
  110. STATUS_SUCCESS on success.
  111. STATUS_TOO_EARLY or STATUS_TOO_LATE if the routine was called outside of a
  112. driver's AddDevice routine.
  113. STATUS_INSUFFICIENT_RESOURCES if allocations failed.
  114. --*/
  115. {
  116. PDRIVER_STACK_ENTRY StackEntry;
  117. KSTATUS Status;
  118. //
  119. // Only allow drivers to attach during the Unreported and Initialized
  120. // states.
  121. //
  122. if ((Device->State != DeviceUnreported) &&
  123. (Device->State != DeviceInitialized)) {
  124. Status = STATUS_TOO_LATE;
  125. goto AttachDriverToDeviceEnd;
  126. }
  127. //
  128. // Allocate and initialize the driver stack entry.
  129. //
  130. StackEntry = MmAllocateNonPagedPool(sizeof(DRIVER_STACK_ENTRY),
  131. DEVICE_ALLOCATION_TAG);
  132. if (StackEntry == NULL) {
  133. Status = STATUS_INSUFFICIENT_RESOURCES;
  134. goto AttachDriverToDeviceEnd;
  135. }
  136. RtlZeroMemory(StackEntry, sizeof(DRIVER_STACK_ENTRY));
  137. StackEntry->Driver = Driver;
  138. StackEntry->DriverContext = Context;
  139. //
  140. // Add the driver to the top of the stack.
  141. //
  142. INSERT_AFTER(&(StackEntry->ListEntry), &(Device->DriverStackHead));
  143. Device->DriverStackSize += 1;
  144. //
  145. // Increase the reference count on the driver so it cannot be unloaded
  146. // while the device is in use.
  147. //
  148. IoDriverAddReference(Driver);
  149. Status = STATUS_SUCCESS;
  150. AttachDriverToDeviceEnd:
  151. return Status;
  152. }
  153. KERNEL_API
  154. VOID
  155. IoDriverAddReference (
  156. PDRIVER Driver
  157. )
  158. /*++
  159. Routine Description:
  160. This routine increments the reference count on a driver.
  161. Arguments:
  162. Driver - Supplies a pointer to the driver.
  163. Return Value:
  164. None.
  165. --*/
  166. {
  167. ASSERT(KeGetRunLevel() == RunLevelLow);
  168. ImImageAddReference(Driver->Image);
  169. return;
  170. }
  171. KERNEL_API
  172. VOID
  173. IoDriverReleaseReference (
  174. PDRIVER Driver
  175. )
  176. /*++
  177. Routine Description:
  178. This routine decrements the reference count on a driver. This routine
  179. must be balanced by a previous call to add a reference on the driver.
  180. Arguments:
  181. Driver - Supplies a pointer to the driver.
  182. Return Value:
  183. None.
  184. --*/
  185. {
  186. ASSERT(KeGetRunLevel() == RunLevelLow);
  187. KeAcquireQueuedLock(IoDeviceDatabaseLock);
  188. ImImageReleaseReference(Driver->Image);
  189. KeReleaseQueuedLock(IoDeviceDatabaseLock);
  190. return;
  191. }
  192. VOID
  193. IoSysLoadDriver (
  194. ULONG SystemCallNumber,
  195. PVOID SystemCallParameter,
  196. PTRAP_FRAME TrapFrame,
  197. PULONG ResultSize
  198. )
  199. /*++
  200. Routine Description:
  201. This routine loads a driver into the kernel's address space.
  202. Arguments:
  203. SystemCallNumber - Supplies the system call number that was requested.
  204. SystemCallParameter - Supplies a pointer to the parameters supplied with
  205. the system call. This structure will be a stack-local copy of the
  206. actual parameters passed from user-mode.
  207. TrapFrame - Supplies a pointer to the trap frame generated by this jump
  208. from user mode to kernel mode.
  209. ResultSize - Supplies a pointer where the system call routine returns the
  210. size of the parameter structure to be copied back to user mode. The
  211. value returned here must be no larger than the original parameter
  212. structure size. The default is the original size of the parameters.
  213. Return Value:
  214. None.
  215. --*/
  216. {
  217. PDRIVER Driver;
  218. PSTR DriverName;
  219. PSYSTEM_CALL_LOAD_DRIVER Parameters;
  220. KSTATUS Status;
  221. DriverName = NULL;
  222. Parameters = SystemCallParameter;
  223. Status = PsCheckPermission(PERMISSION_DRIVER_LOAD);
  224. if (!KSUCCESS(Status)) {
  225. goto SysLoadDriverEnd;
  226. }
  227. Status = MmCreateCopyOfUserModeString(Parameters->DriverName,
  228. Parameters->DriverNameSize,
  229. IO_ALLOCATION_TAG,
  230. &DriverName);
  231. if (!KSUCCESS(Status)) {
  232. goto SysLoadDriverEnd;
  233. }
  234. Status = IoLoadDriver(DriverName, &Driver);
  235. if (!KSUCCESS(Status)) {
  236. goto SysLoadDriverEnd;
  237. }
  238. //
  239. // Immediately release the reference taken on the driver.
  240. //
  241. IoDriverReleaseReference(Driver);
  242. SysLoadDriverEnd:
  243. if (DriverName != NULL) {
  244. MmFreePagedPool(DriverName);
  245. }
  246. Parameters->Status = Status;
  247. return;
  248. }
  249. KSTATUS
  250. IoLoadDriver (
  251. PSTR DriverName,
  252. PDRIVER *DriverOut
  253. )
  254. /*++
  255. Routine Description:
  256. This routine loads a driver into memory. This routine must be called at low
  257. level. The returned driver will come with an incremented reference count
  258. that must be released by the caller.
  259. Arguments:
  260. DriverName - Supplies the name of the driver to load.
  261. DriverOut - Supplies a pointer where the pointer to the driver will be
  262. returned on success. The driver will be returned with an incremented
  263. reference count, it's up to the caller to release that reference when
  264. finished.
  265. Return Value:
  266. Status code.
  267. --*/
  268. {
  269. PLOADED_IMAGE DriverImage;
  270. PKPROCESS KernelProcess;
  271. ULONG LoadFlags;
  272. KSTATUS Status;
  273. ASSERT(KeGetRunLevel() == RunLevelLow);
  274. LoadFlags = IMAGE_LOAD_FLAG_IGNORE_INTERPRETER |
  275. IMAGE_LOAD_FLAG_NO_STATIC_CONSTRUCTORS |
  276. IMAGE_LOAD_FLAG_BIND_NOW;
  277. KernelProcess = PsGetKernelProcess();
  278. *DriverOut = NULL;
  279. //
  280. // The driver image list is guarded by the device database lock since
  281. // acquiring the kernel process lock is too heavy (prevents the creation of
  282. // threads).
  283. //
  284. KeAcquireQueuedLock(IoDeviceDatabaseLock);
  285. Status = ImLoadExecutable(&(KernelProcess->ImageListHead),
  286. DriverName,
  287. NULL,
  288. NULL,
  289. KernelProcess,
  290. LoadFlags,
  291. 0,
  292. &DriverImage,
  293. NULL);
  294. if (KSUCCESS(Status)) {
  295. Status = IopInitializeImages(KernelProcess);
  296. if (!KSUCCESS(Status)) {
  297. ImImageReleaseReference(DriverImage);
  298. DriverImage = NULL;
  299. }
  300. }
  301. KeReleaseQueuedLock(IoDeviceDatabaseLock);
  302. if (!KSUCCESS(Status)) {
  303. goto LoadDriverEnd;
  304. }
  305. *DriverOut = DriverImage->SystemExtension;
  306. LoadDriverEnd:
  307. return Status;
  308. }
  309. KSTATUS
  310. IoAddDeviceDatabaseEntry (
  311. PSTR DeviceId,
  312. PSTR DriverName
  313. )
  314. /*++
  315. Routine Description:
  316. This routine adds a mapping between a device and a driver. Only one device
  317. to driver mapping can exist in the database at once.
  318. Arguments:
  319. DeviceId - Supplies the device ID of the device to associate with a driver.
  320. This memory does not need to be retained, a copy of this string will
  321. be created.
  322. DriverName - Supplies the name of the driver corresponding to the device.
  323. This memory does not need to be retained, a copy of this string will be
  324. created.
  325. Return Value:
  326. STATUS_SUCCESS on success.
  327. STATUS_INVALID_PARAMETER if a required parameter or function was not
  328. supplied.
  329. STATUS_INSUFFICIENT_RESOURCE on allocation failure.
  330. STATUS_DUPLICATE_ENTRY if the device ID already exists in the database.
  331. --*/
  332. {
  333. KSTATUS Status;
  334. ASSERT(KeGetRunLevel() == RunLevelLow);
  335. Status = IopAddDeviceDatabaseEntry(DeviceId,
  336. DriverName,
  337. &IoDeviceDatabaseHead);
  338. return Status;
  339. }
  340. KSTATUS
  341. IoAddDeviceClassDatabaseEntry (
  342. PSTR ClassId,
  343. PSTR DriverName
  344. )
  345. /*++
  346. Routine Description:
  347. This routine adds a mapping between a device class and a driver. Only one
  348. device class to driver mapping can exist in the database at once.
  349. Arguments:
  350. ClassId - Supplies the device class identifier of the device to associate
  351. with a driver. This memory does not need to be retained, a copy of this
  352. string will be created.
  353. DriverName - Supplies the name of the driver corresponding to the device
  354. class. This memory does not need to be retained, a copy of this string
  355. will be created.
  356. Return Value:
  357. STATUS_SUCCESS on success.
  358. STATUS_INVALID_PARAMETER if a required parameter or function was not
  359. supplied.
  360. STATUS_INSUFFICIENT_RESOURCES on allocation failure.
  361. STATUS_DUPLICATE_ENTRY if the device ID already exists in the database.
  362. --*/
  363. {
  364. KSTATUS Status;
  365. ASSERT(KeGetRunLevel() == RunLevelLow);
  366. Status = IopAddDeviceDatabaseEntry(ClassId,
  367. DriverName,
  368. &IoDeviceClassDatabaseHead);
  369. return Status;
  370. }
  371. KSTATUS
  372. IoCreateDriverStructure (
  373. PVOID LoadedImage
  374. )
  375. /*++
  376. Routine Description:
  377. This routine is called to create a new driver structure for a loaded image.
  378. This routine should only be called internally by the system.
  379. Arguments:
  380. LoadedImage - Supplies a pointer to the image associated with the driver.
  381. Return Value:
  382. Status code.
  383. --*/
  384. {
  385. PLOADED_IMAGE Image;
  386. PDRIVER NewDriver;
  387. KSTATUS Status;
  388. ASSERT(KeGetRunLevel() == RunLevelLow);
  389. ASSERT(KeIsQueuedLockHeld(IoDeviceDatabaseLock) != FALSE);
  390. Image = LoadedImage;
  391. NewDriver = MmAllocateNonPagedPool(sizeof(DRIVER), IO_ALLOCATION_TAG);
  392. if (NewDriver == NULL) {
  393. Status = STATUS_INSUFFICIENT_RESOURCES;
  394. goto CreateDriverStructureEnd;
  395. }
  396. RtlZeroMemory(NewDriver, sizeof(DRIVER));
  397. Image->SystemExtension = NewDriver;
  398. NewDriver->Image = Image;
  399. Status = STATUS_SUCCESS;
  400. CreateDriverStructureEnd:
  401. if (!KSUCCESS(Status)) {
  402. if (NewDriver != NULL) {
  403. MmFreeNonPagedPool(NewDriver);
  404. NewDriver = NULL;
  405. Image->SystemExtension = NULL;
  406. }
  407. }
  408. return Status;
  409. }
  410. VOID
  411. IoDestroyDriverStructure (
  412. PVOID LoadedImage
  413. )
  414. /*++
  415. Routine Description:
  416. This routine is called to destroy a driver structure in association with
  417. a driver being torn down. This routine should only be called internally by
  418. the system.
  419. Arguments:
  420. LoadedImage - Supplies a pointer to the image being destroyed.
  421. Return Value:
  422. None.
  423. --*/
  424. {
  425. PDRIVER Driver;
  426. PLOADED_IMAGE Image;
  427. PDRIVER_UNLOAD UnloadRoutine;
  428. ASSERT(KeGetRunLevel() == RunLevelLow);
  429. ASSERT(KeIsQueuedLockHeld(IoDeviceDatabaseLock) != FALSE);
  430. Image = LoadedImage;
  431. Driver = Image->SystemExtension;
  432. if (Driver != NULL) {
  433. //
  434. // Call the unload routine if supplied.
  435. //
  436. UnloadRoutine = Driver->FunctionTable.Unload;
  437. if (UnloadRoutine != NULL) {
  438. UnloadRoutine(Driver);
  439. }
  440. Image->SystemExtension = NULL;
  441. Driver->Image = NULL;
  442. MmFreeNonPagedPool(Driver);
  443. }
  444. return;
  445. }
  446. KSTATUS
  447. IopInitializeDriver (
  448. PVOID LoadedImage
  449. )
  450. /*++
  451. Routine Description:
  452. This routine is called to initialize a newly loaded driver. This routine
  453. should only be called internally by the system.
  454. Arguments:
  455. LoadedImage - Supplies a pointer to the image associated with the driver.
  456. Return Value:
  457. Status code.
  458. --*/
  459. {
  460. PDRIVER Driver;
  461. PDRIVER_ENTRY DriverEntry;
  462. PLOADED_IMAGE Image;
  463. KSTATUS Status;
  464. Image = LoadedImage;
  465. ASSERT(KeIsQueuedLockHeld(IoDeviceDatabaseLock) != FALSE);
  466. ASSERT(KeGetRunLevel() == RunLevelLow);
  467. Driver = Image->SystemExtension;
  468. Status = STATUS_SUCCESS;
  469. if ((Driver->Flags & DRIVER_FLAG_ENTRY_CALLED) == 0) {
  470. //
  471. // Call the driver's entry point.
  472. //
  473. DriverEntry = (PDRIVER_ENTRY)Image->EntryPoint;
  474. if (DriverEntry != NULL) {
  475. Status = DriverEntry(Driver);
  476. Driver->Flags |= DRIVER_FLAG_ENTRY_CALLED;
  477. if (!KSUCCESS(Status)) {
  478. Driver->Flags |= DRIVER_FLAG_FAILED_DRIVER_ENTRY;
  479. }
  480. }
  481. }
  482. return Status;
  483. }
  484. //
  485. // --------------------------------------------------------- Internal Functions
  486. //
  487. KSTATUS
  488. IopInitializeImages (
  489. PKPROCESS Process
  490. )
  491. /*++
  492. Routine Description:
  493. This routine initializes any newly loaded images. This routine assumes the
  494. image list queued lock is already held.
  495. Arguments:
  496. Process - Supplies a pointer to the process whose images should be
  497. initialized.
  498. Return Value:
  499. Status code.
  500. --*/
  501. {
  502. PLIST_ENTRY CurrentEntry;
  503. PLOADED_IMAGE Image;
  504. KSTATUS Status;
  505. KSTATUS TotalStatus;
  506. ASSERT(Process == PsGetKernelProcess());
  507. //
  508. // Iterate backwards to initialize dependency modules first.
  509. //
  510. TotalStatus = STATUS_SUCCESS;
  511. CurrentEntry = Process->ImageListHead.Previous;
  512. while (CurrentEntry != &(Process->ImageListHead)) {
  513. Image = LIST_VALUE(CurrentEntry, LOADED_IMAGE, ListEntry);
  514. CurrentEntry = CurrentEntry->Previous;
  515. if ((Image->Flags & IMAGE_FLAG_INITIALIZED) == 0) {
  516. Status = IopInitializeDriver(Image);
  517. if (KSUCCESS(Status)) {
  518. Image->Flags |= IMAGE_FLAG_INITIALIZED;
  519. } else {
  520. TotalStatus = Status;
  521. }
  522. }
  523. }
  524. return TotalStatus;
  525. }
  526. KSTATUS
  527. IopAddDeviceDatabaseEntry (
  528. PSTR DeviceOrClassId,
  529. PSTR DriverName,
  530. PLIST_ENTRY DatabaseListHead
  531. )
  532. /*++
  533. Routine Description:
  534. This routine adds a mapping between a device and a driver or a device class
  535. and a driver. Only one device (or device class) to driver mapping can exist
  536. in the database at once. This routine must be called at low level.
  537. Arguments:
  538. DeviceOrClassId - Supplies the device ID or class ID to associate with a
  539. driver. This memory does not need to be retained, a copy of this string
  540. will be created.
  541. DriverName - Supplies the name of the driver corresponding to the device.
  542. This memory does not need to be retained, a copy of this string will be
  543. created.
  544. DatabaseListHead - Supplies the list head of the database to insert this
  545. mapping in.
  546. Return Value:
  547. STATUS_SUCCESS on success.
  548. STATUS_INSUFFICIENT_RESOURCES on an allocation failure.
  549. STATUS_DUPLICATE_ENTRY if the device ID already exists in the database.
  550. --*/
  551. {
  552. ULONG AllocationSize;
  553. PLIST_ENTRY CurrentEntry;
  554. PDEVICE_DATABASE_ENTRY DatabaseEntry;
  555. BOOL Equal;
  556. KSTATUS Status;
  557. ASSERT(KeGetRunLevel() == RunLevelLow);
  558. KeAcquireQueuedLock(IoDeviceDatabaseLock);
  559. //
  560. // Loop through all mappings looking for an existing one, and fail if one
  561. // is found.
  562. //
  563. CurrentEntry = DatabaseListHead->Next;
  564. while (CurrentEntry != DatabaseListHead) {
  565. DatabaseEntry = LIST_VALUE(CurrentEntry,
  566. DEVICE_DATABASE_ENTRY,
  567. ListEntry);
  568. CurrentEntry = CurrentEntry->Next;
  569. Equal = RtlAreStringsEqual(DatabaseEntry->U.DeviceId,
  570. DeviceOrClassId,
  571. MAX_DEVICE_ID);
  572. if (Equal != FALSE) {
  573. Status = STATUS_DUPLICATE_ENTRY;
  574. goto AddDeviceDatabaseEntryEnd;
  575. }
  576. }
  577. //
  578. // Allocate space for the entry including both strings.
  579. //
  580. AllocationSize = sizeof(DEVICE_DATABASE_ENTRY);
  581. AllocationSize += RtlStringLength(DeviceOrClassId) + 1;
  582. AllocationSize += RtlStringLength(DriverName) + 1;
  583. DatabaseEntry = MmAllocatePagedPool(AllocationSize, IO_ALLOCATION_TAG);
  584. if (DatabaseEntry == NULL) {
  585. Status = STATUS_INSUFFICIENT_RESOURCES;
  586. goto AddDeviceDatabaseEntryEnd;
  587. }
  588. RtlZeroMemory(DatabaseEntry, sizeof(DEVICE_DATABASE_ENTRY));
  589. //
  590. // Copy the strings into the extra space in the allocation.
  591. //
  592. DatabaseEntry->U.DeviceId = (PSTR)(DatabaseEntry + 1);
  593. RtlStringCopy(DatabaseEntry->U.DeviceId,
  594. DeviceOrClassId,
  595. RtlStringLength(DeviceOrClassId) + 1);
  596. DatabaseEntry->DriverName = DatabaseEntry->U.DeviceId +
  597. RtlStringLength(DatabaseEntry->U.DeviceId) + 1;
  598. RtlStringCopy(DatabaseEntry->DriverName,
  599. DriverName,
  600. RtlStringLength(DriverName) + 1);
  601. INSERT_AFTER(&(DatabaseEntry->ListEntry), DatabaseListHead);
  602. Status = STATUS_SUCCESS;
  603. AddDeviceDatabaseEntryEnd:
  604. KeReleaseQueuedLock(IoDeviceDatabaseLock);
  605. return Status;
  606. }