ktestdrv.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720
  1. /*++
  2. Copyright (c) 2013 Minoca Corp.
  3. This file is licensed under the terms of the GNU General Public License
  4. version 3. Alternative licensing terms are available. Contact
  5. info@minocacorp.com for details. See the LICENSE file at the root of this
  6. project for complete licensing information.
  7. Module Name:
  8. ktestdrv.c
  9. Abstract:
  10. This module implements the kernel test driver.
  11. Author:
  12. Evan Green 5-Nov-2013
  13. Environment:
  14. Kernel
  15. --*/
  16. //
  17. // ------------------------------------------------------------------- Includes
  18. //
  19. #include <minoca/kernel/driver.h>
  20. #include "../ktestdrv.h"
  21. #include "testsup.h"
  22. //
  23. // ---------------------------------------------------------------- Definitions
  24. //
  25. //
  26. // ------------------------------------------------------ Data Type Definitions
  27. //
  28. //
  29. // ----------------------------------------------- Internal Function Prototypes
  30. //
  31. VOID
  32. KTestUnload (
  33. PVOID Driver
  34. );
  35. KSTATUS
  36. KTestAddDevice (
  37. PVOID Driver,
  38. PCSTR DeviceId,
  39. PCSTR ClassId,
  40. PCSTR CompatibleIds,
  41. PVOID DeviceToken
  42. );
  43. VOID
  44. KTestDispatchStateChange (
  45. PIRP Irp,
  46. PVOID DeviceContext,
  47. PVOID IrpContext
  48. );
  49. VOID
  50. KTestDispatchOpen (
  51. PIRP Irp,
  52. PVOID DeviceContext,
  53. PVOID IrpContext
  54. );
  55. VOID
  56. KTestDispatchClose (
  57. PIRP Irp,
  58. PVOID DeviceContext,
  59. PVOID IrpContext
  60. );
  61. VOID
  62. KTestDispatchIo (
  63. PIRP Irp,
  64. PVOID DeviceContext,
  65. PVOID IrpContext
  66. );
  67. VOID
  68. KTestDispatchSystemControl (
  69. PIRP Irp,
  70. PVOID DeviceContext,
  71. PVOID IrpContext
  72. );
  73. VOID
  74. KTestDispatchUserControl (
  75. PIRP Irp,
  76. PVOID DeviceContext,
  77. PVOID IrpContext
  78. );
  79. VOID
  80. KTestpHandleDeviceInformationRequest (
  81. PIRP Irp,
  82. PVOID DeviceContext
  83. );
  84. //
  85. // -------------------------------------------------------------------- Globals
  86. //
  87. PDRIVER KTestDriver = NULL;
  88. PDEVICE KTestDevice = NULL;
  89. BOOL KTestDeviceUnloaded = FALSE;
  90. UUID KTestTestDeviceInformationUuid = TEST_DEVICE_INFORMATION_UUID;
  91. //
  92. // ------------------------------------------------------------------ Functions
  93. //
  94. __USED
  95. KSTATUS
  96. DriverEntry (
  97. PDRIVER Driver
  98. )
  99. /*++
  100. Routine Description:
  101. This routine is the entry point for the kernel stress test driver. It
  102. registers its other dispatch functions, and performs driver-wide
  103. initialization.
  104. Arguments:
  105. Driver - Supplies a pointer to the driver object.
  106. Return Value:
  107. STATUS_SUCCESS on success.
  108. Failure code on error.
  109. --*/
  110. {
  111. DRIVER_FUNCTION_TABLE FunctionTable;
  112. KSTATUS Status;
  113. ASSERT((KTestDriver == NULL) && (KTestDevice == NULL));
  114. Status = KTestInitializeTestSupport();
  115. if (!KSUCCESS(Status)) {
  116. goto DriverEntryEnd;
  117. }
  118. KTestDriver = Driver;
  119. RtlZeroMemory(&FunctionTable, sizeof(DRIVER_FUNCTION_TABLE));
  120. FunctionTable.Version = DRIVER_FUNCTION_TABLE_VERSION;
  121. FunctionTable.Unload = KTestUnload;
  122. FunctionTable.AddDevice = KTestAddDevice;
  123. FunctionTable.DispatchStateChange = KTestDispatchStateChange;
  124. FunctionTable.DispatchOpen = KTestDispatchOpen;
  125. FunctionTable.DispatchClose = KTestDispatchClose;
  126. FunctionTable.DispatchIo = KTestDispatchIo;
  127. FunctionTable.DispatchSystemControl = KTestDispatchSystemControl;
  128. FunctionTable.DispatchUserControl = KTestDispatchUserControl;
  129. Status = IoRegisterDriverFunctions(Driver, &FunctionTable);
  130. if (!KSUCCESS(Status)) {
  131. goto DriverEntryEnd;
  132. }
  133. //
  134. // Increment the reference count on the driver so it doesn't disappear
  135. // in between the device being created and enumerated. This extra reference
  136. // is released in add device.
  137. //
  138. IoDriverAddReference(KTestDriver);
  139. Status = IoCreateDevice(NULL,
  140. NULL,
  141. NULL,
  142. KTEST_DEVICE_NAME,
  143. NULL,
  144. NULL,
  145. &KTestDevice);
  146. if (!KSUCCESS(Status)) {
  147. goto DriverEntryEnd;
  148. }
  149. DriverEntryEnd:
  150. if (KSUCCESS(Status)) {
  151. RtlDebugPrint("KTest driver loaded.\n");
  152. }
  153. return Status;
  154. }
  155. VOID
  156. KTestUnload (
  157. PVOID Driver
  158. )
  159. /*++
  160. Routine Description:
  161. This routine is called before a driver is about to be unloaded from memory.
  162. The driver should take this opportunity to free any resources it may have
  163. set up in the driver entry routine.
  164. Arguments:
  165. Driver - Supplies a pointer to the driver being torn down.
  166. Return Value:
  167. None.
  168. --*/
  169. {
  170. RtlDebugPrint("KTest driver unloaded.\n");
  171. return;
  172. }
  173. KSTATUS
  174. KTestAddDevice (
  175. PVOID Driver,
  176. PCSTR DeviceId,
  177. PCSTR ClassId,
  178. PCSTR CompatibleIds,
  179. PVOID DeviceToken
  180. )
  181. /*++
  182. Routine Description:
  183. This routine is called when a device is detected for which the null device
  184. acts as the function driver. The driver will attach itself to the stack.
  185. Arguments:
  186. Driver - Supplies a pointer to the driver being called.
  187. DeviceId - Supplies a pointer to a string with the device ID.
  188. ClassId - Supplies a pointer to a string containing the device's class ID.
  189. CompatibleIds - Supplies a pointer to a string containing device IDs
  190. that would be compatible with this device.
  191. DeviceToken - Supplies an opaque token that the driver can use to identify
  192. the device in the system. This token should be used when attaching to
  193. the stack.
  194. Return Value:
  195. STATUS_SUCCESS on success.
  196. Failure code if the driver was unsuccessful in attaching itself.
  197. --*/
  198. {
  199. KSTATUS Status;
  200. Status = IoAttachDriverToDevice(Driver, DeviceToken, NULL);
  201. if (KSUCCESS(Status)) {
  202. //
  203. // On success, release the reference that was taken up in driver entry.
  204. // The device itself has now taken a reference on the driver.
  205. //
  206. IoDriverReleaseReference(KTestDriver);
  207. }
  208. return Status;
  209. }
  210. VOID
  211. KTestDispatchStateChange (
  212. PIRP Irp,
  213. PVOID DeviceContext,
  214. PVOID IrpContext
  215. )
  216. /*++
  217. Routine Description:
  218. This routine handles State Change IRPs.
  219. Arguments:
  220. Irp - Supplies a pointer to the I/O request packet.
  221. DeviceContext - Supplies the context pointer supplied by the driver when it
  222. attached itself to the driver stack. Presumably this pointer contains
  223. driver-specific device context.
  224. IrpContext - Supplies the context pointer supplied by the driver when
  225. the IRP was created.
  226. Return Value:
  227. None.
  228. --*/
  229. {
  230. KSTATUS Status;
  231. ASSERT(Irp->MajorCode == IrpMajorStateChange);
  232. if (Irp->Direction == IrpDown) {
  233. switch (Irp->MinorCode) {
  234. case IrpMinorStartDevice:
  235. //
  236. // Publish the test information device type.
  237. //
  238. Status = IoRegisterDeviceInformation(
  239. Irp->Device,
  240. &KTestTestDeviceInformationUuid,
  241. TRUE);
  242. IoCompleteIrp(KTestDriver, Irp, Status);
  243. break;
  244. case IrpMinorRemoveDevice:
  245. Status = IoRegisterDeviceInformation(
  246. Irp->Device,
  247. &KTestTestDeviceInformationUuid,
  248. FALSE);
  249. IoCompleteIrp(KTestDriver, Irp, Status);
  250. break;
  251. case IrpMinorQueryResources:
  252. case IrpMinorQueryChildren:
  253. IoCompleteIrp(KTestDriver, Irp, STATUS_SUCCESS);
  254. break;
  255. default:
  256. break;
  257. }
  258. }
  259. return;
  260. }
  261. VOID
  262. KTestDispatchOpen (
  263. PIRP Irp,
  264. PVOID DeviceContext,
  265. PVOID IrpContext
  266. )
  267. /*++
  268. Routine Description:
  269. This routine handles Open IRPs.
  270. Arguments:
  271. Irp - Supplies a pointer to the I/O request packet.
  272. DeviceContext - Supplies the context pointer supplied by the driver when it
  273. attached itself to the driver stack. Presumably this pointer contains
  274. driver-specific device context.
  275. IrpContext - Supplies the context pointer supplied by the driver when
  276. the IRP was created.
  277. Return Value:
  278. None.
  279. --*/
  280. {
  281. IoCompleteIrp(KTestDriver, Irp, STATUS_SUCCESS);
  282. return;
  283. }
  284. VOID
  285. KTestDispatchClose (
  286. PIRP Irp,
  287. PVOID DeviceContext,
  288. PVOID IrpContext
  289. )
  290. /*++
  291. Routine Description:
  292. This routine handles Close IRPs.
  293. Arguments:
  294. Irp - Supplies a pointer to the I/O request packet.
  295. DeviceContext - Supplies the context pointer supplied by the driver when it
  296. attached itself to the driver stack. Presumably this pointer contains
  297. driver-specific device context.
  298. IrpContext - Supplies the context pointer supplied by the driver when
  299. the IRP was created.
  300. Return Value:
  301. None.
  302. --*/
  303. {
  304. IoCompleteIrp(KTestDriver, Irp, STATUS_SUCCESS);
  305. return;
  306. }
  307. VOID
  308. KTestDispatchIo (
  309. PIRP Irp,
  310. PVOID DeviceContext,
  311. PVOID IrpContext
  312. )
  313. /*++
  314. Routine Description:
  315. This routine handles I/O IRPs.
  316. Arguments:
  317. Irp - Supplies a pointer to the I/O request packet.
  318. DeviceContext - Supplies the context pointer supplied by the driver when it
  319. attached itself to the driver stack. Presumably this pointer contains
  320. driver-specific device context.
  321. IrpContext - Supplies the context pointer supplied by the driver when
  322. the IRP was created.
  323. Return Value:
  324. None.
  325. --*/
  326. {
  327. RtlDebugPrint("KTestDispatchIo\n");
  328. return;
  329. }
  330. VOID
  331. KTestDispatchSystemControl (
  332. PIRP Irp,
  333. PVOID DeviceContext,
  334. PVOID IrpContext
  335. )
  336. /*++
  337. Routine Description:
  338. This routine handles System Control IRPs.
  339. Arguments:
  340. Irp - Supplies a pointer to the I/O request packet.
  341. DeviceContext - Supplies the context pointer supplied by the driver when it
  342. attached itself to the driver stack. Presumably this pointer contains
  343. driver-specific device context.
  344. IrpContext - Supplies the context pointer supplied by the driver when
  345. the IRP was created.
  346. Return Value:
  347. None.
  348. --*/
  349. {
  350. PVOID Context;
  351. PSYSTEM_CONTROL_LOOKUP Lookup;
  352. PFILE_PROPERTIES Properties;
  353. KSTATUS Status;
  354. Context = Irp->U.SystemControl.SystemContext;
  355. switch (Irp->MinorCode) {
  356. case IrpMinorSystemControlLookup:
  357. Lookup = (PSYSTEM_CONTROL_LOOKUP)Context;
  358. Status = STATUS_PATH_NOT_FOUND;
  359. if (Lookup->Root != FALSE) {
  360. //
  361. // Enable opening of the root as a single file.
  362. //
  363. Properties = Lookup->Properties;
  364. Properties->FileId = 0;
  365. Properties->Type = IoObjectCharacterDevice;
  366. Properties->HardLinkCount = 1;
  367. Properties->BlockSize = 1;
  368. Properties->BlockCount = 1;
  369. Properties->Size = 0;
  370. Status = STATUS_SUCCESS;
  371. }
  372. IoCompleteIrp(KTestDriver, Irp, Status);
  373. break;
  374. case IrpMinorSystemControlWriteFileProperties:
  375. IoCompleteIrp(KTestDriver, Irp, STATUS_SUCCESS);
  376. break;
  377. case IrpMinorSystemControlTruncate:
  378. IoCompleteIrp(KTestDriver, Irp, STATUS_NOT_SUPPORTED);
  379. break;
  380. case IrpMinorSystemControlDeviceInformation:
  381. KTestpHandleDeviceInformationRequest(Irp, DeviceContext);
  382. break;
  383. //
  384. // Ignore everything unrecognized.
  385. //
  386. default:
  387. ASSERT(FALSE);
  388. break;
  389. }
  390. return;
  391. }
  392. VOID
  393. KTestDispatchUserControl (
  394. PIRP Irp,
  395. PVOID DeviceContext,
  396. PVOID IrpContext
  397. )
  398. /*++
  399. Routine Description:
  400. This routine handles User Control IRPs.
  401. Arguments:
  402. Irp - Supplies a pointer to the I/O request packet.
  403. DeviceContext - Supplies the context pointer supplied by the driver when it
  404. attached itself to the driver stack. Presumably this pointer contains
  405. driver-specific device context.
  406. IrpContext - Supplies the context pointer supplied by the driver when
  407. the IRP was created.
  408. Return Value:
  409. None.
  410. --*/
  411. {
  412. KSTATUS Status;
  413. PVOID UserBuffer;
  414. UINTN UserBufferSize;
  415. UserBuffer = Irp->U.UserControl.UserBuffer;
  416. UserBufferSize = Irp->U.UserControl.UserBufferSize;
  417. if (KTestDeviceUnloaded != FALSE) {
  418. ASSERT(FALSE);
  419. Status = STATUS_TOO_LATE;
  420. goto DispatchUserControlEnd;
  421. }
  422. switch ((KTEST_REQUEST)Irp->MinorCode) {
  423. case KTestRequestUnload:
  424. KTestDeviceUnloaded = TRUE;
  425. KTestFlushAllTests();
  426. Status = IoRemoveUnreportedDevice(Irp->Device);
  427. break;
  428. case KTestRequestStartTest:
  429. Status = KTestStartTest(UserBuffer, UserBufferSize);
  430. break;
  431. case KTestRequestCancelTest:
  432. Status = KTestRequestCancellation(UserBuffer, UserBufferSize);
  433. break;
  434. case KTestRequestPoll:
  435. Status = KTestPoll(UserBuffer, UserBufferSize);
  436. break;
  437. //
  438. // Ignore everything unrecognized.
  439. //
  440. default:
  441. ASSERT(FALSE);
  442. Status = STATUS_NOT_IMPLEMENTED;
  443. break;
  444. }
  445. DispatchUserControlEnd:
  446. IoCompleteIrp(KTestDriver, Irp, Status);
  447. return;
  448. }
  449. //
  450. // --------------------------------------------------------- Internal Functions
  451. //
  452. VOID
  453. KTestpHandleDeviceInformationRequest (
  454. PIRP Irp,
  455. PVOID DeviceContext
  456. )
  457. /*++
  458. Routine Description:
  459. This routine handles requests to get and set device information for the
  460. kernel test device.
  461. Arguments:
  462. Irp - Supplies a pointer to the IRP making the request.
  463. DeviceContext - Supplies a pointer to the device context create for this
  464. kernel test device.
  465. Return Value:
  466. None. Any completion status is set in the IRP.
  467. --*/
  468. {
  469. PTEST_DEVICE_INFORMATION Information;
  470. BOOL Match;
  471. PSYSTEM_CONTROL_DEVICE_INFORMATION Request;
  472. KSTATUS Status;
  473. Request = Irp->U.SystemControl.SystemContext;
  474. //
  475. // If this is not a request for the partition device information, ignore it.
  476. //
  477. Match = RtlAreUuidsEqual(&(Request->Uuid), &KTestTestDeviceInformationUuid);
  478. if (Match == FALSE) {
  479. return;
  480. }
  481. //
  482. // Setting test device information is not supported.
  483. //
  484. if (Request->Set != FALSE) {
  485. Status = STATUS_ACCESS_DENIED;
  486. goto HandleDeviceInformationRequestEnd;
  487. }
  488. //
  489. // Make sure the size is large enough.
  490. //
  491. if (Request->DataSize < sizeof(TEST_DEVICE_INFORMATION)) {
  492. Request->DataSize = sizeof(TEST_DEVICE_INFORMATION);
  493. Status = STATUS_BUFFER_TOO_SMALL;
  494. goto HandleDeviceInformationRequestEnd;
  495. }
  496. Request->DataSize = sizeof(TEST_DEVICE_INFORMATION);
  497. Information = Request->Data;
  498. RtlZeroMemory(Information, sizeof(TEST_DEVICE_INFORMATION));
  499. Information->Version = TEST_DEVICE_INFORMATION_VERSION;
  500. Information->DeviceType = TestDeviceKernel;
  501. Status = STATUS_SUCCESS;
  502. HandleDeviceInformationRequestEnd:
  503. IoCompleteIrp(KTestDriver, Irp, Status);
  504. return;
  505. }