Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1148 lines
28 KiB

  1. /*++
  2. Copyright (c) 1991 - 2001 Microsoft Corporation
  3. Module Name:
  4. ## ## ###### #### ## #### ##### #####
  5. ## ## ## ## ## ## # ## ## ## ##
  6. ## ## ## ## ## ## ## ## ## ##
  7. ## ## ## ## ## ## ## ## ## ##
  8. ## ## ## ## ## ## ##### #####
  9. ## ## ## ## ## ## ## # ## ##
  10. #### ## #### ##### ## #### ## ##
  11. Abstract:
  12. Utility driver functions.
  13. Author:
  14. Wesley Witt (wesw) 1-Oct-2001
  15. Environment:
  16. Kernel mode only.
  17. Notes:
  18. --*/
  19. #include "internal.h"
  20. #include <ntimage.h>
  21. #include <stdarg.h>
  22. #if DBG
  23. ULONG SaPortDebugLevel[5];
  24. #endif
  25. NTSTATUS
  26. CompleteRequest(
  27. PIRP Irp,
  28. NTSTATUS Status,
  29. ULONG_PTR Information
  30. )
  31. /*++
  32. Routine Description:
  33. This routine completes as outstanding I/O request.
  34. Arguments:
  35. Irp - Pointer to an IRP structure that describes the requested I/O operation.
  36. Status - NT status value
  37. Information - Informational, request specific data
  38. Return Value:
  39. NT status code.
  40. --*/
  41. {
  42. PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
  43. KIRQL CancelIrql;
  44. if (IrpSp && (IrpSp->MajorFunction == IRP_MJ_READ || IrpSp->MajorFunction == IRP_MJ_WRITE)) {
  45. IoAcquireCancelSpinLock( &CancelIrql );
  46. IoSetCancelRoutine( Irp, NULL );
  47. IoReleaseCancelSpinLock( CancelIrql );
  48. }
  49. Irp->IoStatus.Information = Information;
  50. Irp->IoStatus.Status = Status;
  51. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  52. return Status;
  53. }
  54. NTSTATUS
  55. ForwardRequest(
  56. IN PIRP Irp,
  57. IN PDEVICE_OBJECT TargetObject
  58. )
  59. /*++
  60. Routine Description:
  61. This routine forwards the IRP to another driver.
  62. Arguments:
  63. Irp - Pointer to an IRP structure that describes the requested I/O operation.
  64. TargetObject - Target device object to receive the request packet
  65. Return Value:
  66. NT status code.
  67. --*/
  68. {
  69. IoSkipCurrentIrpStackLocation( Irp );
  70. return IoCallDriver( TargetObject, Irp );
  71. }
  72. NTSTATUS
  73. CallMiniPortDriverReadWrite(
  74. IN PDEVICE_EXTENSION DeviceExtension,
  75. IN PDEVICE_OBJECT DeviceObject,
  76. IN BOOLEAN WriteIo,
  77. IN PVOID Buffer,
  78. IN ULONG Length,
  79. IN ULONG Offset
  80. )
  81. /*++
  82. Routine Description:
  83. This routine creates an IRP for a read/write I/O and
  84. then passes the IRP to the driver. This call is
  85. synchronous, control returns only when the driver has
  86. completed the IRP.
  87. Arguments:
  88. DeviceExtension - Port driver device extension pointer
  89. WriteIo - TRUE for a write, FALSE for a read
  90. Buffer - Pointer to the I/O buffer
  91. Length - Length in bytes of the I/O buffer
  92. Offset - Starting offset of the I/O
  93. Return Value:
  94. NT status code.
  95. --*/
  96. {
  97. NTSTATUS Status;
  98. PIRP Irp;
  99. KEVENT Event;
  100. IO_STATUS_BLOCK IoStatus;
  101. LARGE_INTEGER StartingOffset;
  102. KeInitializeEvent( &Event, NotificationEvent, FALSE );
  103. StartingOffset.QuadPart = Offset;
  104. Irp = IoBuildSynchronousFsdRequest(
  105. WriteIo ? IRP_MJ_WRITE : IRP_MJ_READ,
  106. DeviceObject,
  107. Buffer,
  108. Length,
  109. &StartingOffset,
  110. &Event,
  111. &IoStatus
  112. );
  113. if (!Irp) {
  114. REPORT_ERROR( DeviceExtension->DeviceType, "IoBuildSynchronousFsdRequest failed", STATUS_INSUFFICIENT_RESOURCES );
  115. return STATUS_INSUFFICIENT_RESOURCES;
  116. }
  117. MARK_IRP_INTERNAL( Irp );
  118. Status = IoCallDriver( DeviceObject, Irp );
  119. if (Status == STATUS_PENDING) {
  120. KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE, NULL );
  121. Status = IoStatus.Status;
  122. }
  123. if (!NT_SUCCESS(Status)) {
  124. REPORT_ERROR( DeviceExtension->DeviceType, "Miniport I/O request failed", Status );
  125. }
  126. return Status;
  127. }
  128. NTSTATUS
  129. CallMiniPortDriverDeviceControl(
  130. IN PDEVICE_EXTENSION DeviceExtension,
  131. IN PDEVICE_OBJECT DeviceObject,
  132. IN ULONG IoControlCode,
  133. IN PVOID InputBuffer,
  134. IN ULONG InputBufferLength,
  135. OUT PVOID OutputBuffer,
  136. IN ULONG OutputBufferLength
  137. )
  138. /*++
  139. Routine Description:
  140. This routine creates an IRP for a device control I/O and
  141. then passes the IRP to the driver. This call is
  142. synchronous, control returns only when the driver has
  143. completed the IRP.
  144. Arguments:
  145. DeviceExtension - Port driver device extension pointer
  146. IoControlCode - Device I/O control code
  147. InputBuffer - Input buffer pointer
  148. InputBufferLength - Length in bytes of the input buffer
  149. OutputBuffer - Output buffer pointer
  150. OutputBufferLength - Length in bytes of output buffer
  151. Return Value:
  152. NT status code.
  153. --*/
  154. {
  155. NTSTATUS Status;
  156. PIRP Irp;
  157. KEVENT Event;
  158. IO_STATUS_BLOCK IoStatus;
  159. KeInitializeEvent( &Event, NotificationEvent, FALSE );
  160. Irp = IoBuildDeviceIoControlRequest(
  161. IoControlCode,
  162. DeviceObject,
  163. InputBuffer,
  164. InputBufferLength,
  165. OutputBuffer,
  166. OutputBufferLength,
  167. FALSE,
  168. &Event,
  169. &IoStatus
  170. );
  171. if (!Irp) {
  172. REPORT_ERROR( DeviceExtension->DeviceType, "IoBuildDeviceIoControlRequest failed", STATUS_INSUFFICIENT_RESOURCES );
  173. return STATUS_INSUFFICIENT_RESOURCES;
  174. }
  175. MARK_IRP_INTERNAL( Irp );
  176. Status = IoCallDriver( DeviceObject, Irp );
  177. if (Status == STATUS_PENDING) {
  178. KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE, NULL );
  179. Status = IoStatus.Status;
  180. }
  181. if (!NT_SUCCESS(Status)) {
  182. REPORT_ERROR( DeviceExtension->DeviceType, "Miniport device control request failed", Status );
  183. }
  184. return Status;
  185. }
  186. VOID
  187. SaPortDebugPrint(
  188. IN ULONG DeviceType,
  189. IN ULONG DebugLevel,
  190. IN PSTR DebugMessage,
  191. IN ...
  192. )
  193. /*++
  194. Routine Description:
  195. This routine prints a formatted string to the debugger.
  196. Arguments:
  197. DebugLevel - Debug level that controls when a message is printed
  198. DebugMessage - String that is printed
  199. ... - Arguments that are used by the DebugMessage
  200. Return Value:
  201. None.
  202. --*/
  203. {
  204. static char *DeviceName[] = {"SAPORT", "DISPLAY","KEYPAD","NVRAM","WATCHDOG"};
  205. va_list arg_ptr;
  206. char buf[512];
  207. char *s = buf;
  208. #if DBG
  209. if ((SaPortDebugLevel[DeviceType] == 0) || ((SaPortDebugLevel[DeviceType] & DebugLevel) == 0)) {
  210. return;
  211. }
  212. #endif
  213. va_start( arg_ptr, DebugMessage );
  214. sprintf( s, "%s: ", DeviceName[DeviceType] );
  215. s += strlen(s);
  216. _vsnprintf( s, sizeof(buf)-strlen(s), DebugMessage, arg_ptr );
  217. DbgPrint( buf );
  218. }
  219. VOID
  220. GetOsVersion(
  221. VOID
  222. )
  223. {
  224. #if (WINVER >= 0x0501)
  225. RTL_OSVERSIONINFOW VersionInformation;
  226. VersionInformation.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOW);
  227. RtlGetVersion( &VersionInformation );
  228. OsMajorVersion = VersionInformation.dwMajorVersion;
  229. OsMinorVersion = VersionInformation.dwMinorVersion;
  230. #else
  231. OsMajorVersion = 0;
  232. OsMinorVersion = 0;
  233. //PsGetVersion( &OsMajorVersion, &OsMinorVersion, NULL, NULL );
  234. #endif
  235. }
  236. #if DBG
  237. VOID
  238. FormatTime(
  239. ULONG TimeStamp,
  240. PSTR TimeBuf
  241. )
  242. /*++
  243. Routine Description:
  244. This routine formats a timestamp word into a string.
  245. Arguments:
  246. TimeStamp - Timestamp word
  247. TimeBuf - Buffer to place the resulting string
  248. Return Value:
  249. None.
  250. --*/
  251. {
  252. static char mnames[] = { "JanFebMarAprMayJunJulAugSepOctNovDec" };
  253. LARGE_INTEGER MyTime;
  254. TIME_FIELDS TimeFields;
  255. RtlSecondsSince1970ToTime( TimeStamp, &MyTime );
  256. ExSystemTimeToLocalTime( &MyTime, &MyTime );
  257. RtlTimeToTimeFields( &MyTime, &TimeFields );
  258. strncpy( TimeBuf, &mnames[(TimeFields.Month - 1) * 3], 3 );
  259. sprintf(
  260. &TimeBuf[3],
  261. " %02d, %04d @ %02d:%02d:%02d",
  262. TimeFields.Day,
  263. TimeFields.Year,
  264. TimeFields.Hour,
  265. TimeFields.Minute,
  266. TimeFields.Second
  267. );
  268. }
  269. VOID
  270. PrintDriverVersion(
  271. IN ULONG DeviceType,
  272. IN PDRIVER_OBJECT DriverObject
  273. )
  274. /*++
  275. Routine Description:
  276. This routine locates the NT image headers from the
  277. base of a loaded driver.
  278. Arguments:
  279. DeviceType - Miniport device type (see saio.h for the enumeration)
  280. DriverObject - Pointer to the DRIVER_OBJECT structure
  281. Return Value:
  282. None.
  283. --*/
  284. {
  285. PIMAGE_NT_HEADERS NtHeaders;
  286. ULONG TimeStamp;
  287. CHAR buf[32];
  288. PSTR DriverId;
  289. NtHeaders = RtlpImageNtHeader( DriverObject->DriverStart );
  290. if (NtHeaders) {
  291. TimeStamp = NtHeaders->FileHeader.TimeDateStamp;
  292. FormatTime( TimeStamp, buf );
  293. DebugPrint(( DeviceType, SAPORT_DEBUG_INFO_LEVEL, "***********************************************\n" ));
  294. switch (DeviceType) {
  295. case 0:
  296. DriverId = "Server Appliance Port";
  297. break;
  298. case SA_DEVICE_DISPLAY:
  299. DriverId = "Local Display";
  300. break;
  301. case SA_DEVICE_KEYPAD:
  302. DriverId = "Keypad";
  303. break;
  304. case SA_DEVICE_NVRAM:
  305. DriverId = "NVRAM";
  306. break;
  307. case SA_DEVICE_WATCHDOG:
  308. DriverId = "Watchdog Timer";
  309. break;
  310. default:
  311. DriverId = "Unknown";
  312. break;
  313. }
  314. DebugPrint(( DeviceType, SAPORT_DEBUG_INFO_LEVEL, "%s Driver Built: %s\n", DriverId, buf ));
  315. if (RunningOnWin2k) {
  316. DebugPrint(( DeviceType, SAPORT_DEBUG_INFO_LEVEL, "Running on Windows 2000\n" ));
  317. } else if (RunningOnWinXp) {
  318. DebugPrint(( DeviceType, SAPORT_DEBUG_INFO_LEVEL, "Running on Windows XP\n" ));
  319. } else {
  320. DebugPrint(( DeviceType, SAPORT_DEBUG_INFO_LEVEL, "Running on *UNKNOWN*\n" ));
  321. }
  322. DebugPrint(( DeviceType, SAPORT_DEBUG_INFO_LEVEL, "***********************************************\n" ));
  323. }
  324. }
  325. #endif
  326. NTSTATUS
  327. SaSignalCompletion(
  328. IN PDEVICE_OBJECT DeviceObject,
  329. IN PIRP Irp,
  330. IN PVOID Event
  331. )
  332. /*++
  333. Routine Description:
  334. This routine is used to signal the completion of an
  335. I/O request and is used ONLY by CallLowerDriverAndWait.
  336. Arguments:
  337. DeviceObject - Pointer to the miniport's device object
  338. Irp - I/O request packet
  339. Event - Event to be signaled when the I/O is completed
  340. Return Value:
  341. NT status code
  342. --*/
  343. {
  344. KeSetEvent( (PKEVENT)Event, IO_NO_INCREMENT, FALSE );
  345. return STATUS_MORE_PROCESSING_REQUIRED;
  346. }
  347. NTSTATUS
  348. CallLowerDriverAndWait(
  349. IN PIRP Irp,
  350. IN PDEVICE_OBJECT TargetObject
  351. )
  352. /*++
  353. Routine Description:
  354. This routine calls a lower driver and waits for the I/O to complete.
  355. Arguments:
  356. Irp - I/O request packet
  357. TargetObject - Pointer to the target device object
  358. Return Value:
  359. NT status code
  360. --*/
  361. {
  362. KEVENT event;
  363. KeInitializeEvent( &event, NotificationEvent, FALSE );
  364. IoCopyCurrentIrpStackLocationToNext( Irp );
  365. IoSetCompletionRoutine( Irp, SaSignalCompletion, &event, TRUE, TRUE, TRUE );
  366. IoCallDriver( TargetObject, Irp );
  367. KeWaitForSingleObject( &event, Executive, KernelMode, FALSE, NULL );
  368. return Irp->IoStatus.Status;
  369. }
  370. NTSTATUS
  371. OpenParametersRegistryKey(
  372. IN PSAPORT_DRIVER_EXTENSION DriverExtension,
  373. IN PUNICODE_STRING RegistryPath,
  374. IN ULONG AccessMode,
  375. OUT PHANDLE RegistryHandle
  376. )
  377. {
  378. NTSTATUS status;
  379. OBJECT_ATTRIBUTES objectAttributes;
  380. UNICODE_STRING unicodeString;
  381. HANDLE serviceKey = NULL;
  382. __try {
  383. InitializeObjectAttributes(
  384. &objectAttributes,
  385. RegistryPath,
  386. OBJ_CASE_INSENSITIVE,
  387. NULL,
  388. NULL
  389. );
  390. status = ZwOpenKey(
  391. &serviceKey,
  392. AccessMode,
  393. &objectAttributes
  394. );
  395. if (!NT_SUCCESS(status)) {
  396. ERROR_RETURN( DriverExtension->InitData.DeviceType, "ZwOpenKey failed", status );
  397. }
  398. RtlInitUnicodeString( &unicodeString, L"Parameters" );
  399. InitializeObjectAttributes(
  400. &objectAttributes,
  401. &unicodeString,
  402. OBJ_CASE_INSENSITIVE,
  403. serviceKey,
  404. NULL
  405. );
  406. status = ZwOpenKey(
  407. RegistryHandle,
  408. AccessMode,
  409. &objectAttributes
  410. );
  411. if (!NT_SUCCESS(status)) {
  412. ERROR_RETURN( DriverExtension->InitData.DeviceType, "ZwOpenKey failed", status );
  413. }
  414. status = STATUS_SUCCESS;
  415. } __finally {
  416. if (serviceKey) {
  417. ZwClose( serviceKey );
  418. }
  419. if (!NT_SUCCESS(status)) {
  420. if (*RegistryHandle) {
  421. ZwClose( *RegistryHandle );
  422. }
  423. }
  424. }
  425. return status;
  426. }
  427. NTSTATUS
  428. CreateParametersRegistryKey(
  429. IN PSAPORT_DRIVER_EXTENSION DriverExtension,
  430. IN PUNICODE_STRING RegistryPath,
  431. OUT PHANDLE parametersKey
  432. )
  433. {
  434. NTSTATUS status;
  435. OBJECT_ATTRIBUTES objectAttributes;
  436. UNICODE_STRING unicodeString;
  437. HANDLE serviceKey = NULL;
  438. ULONG Disposition;
  439. __try {
  440. parametersKey = NULL;
  441. InitializeObjectAttributes(
  442. &objectAttributes,
  443. RegistryPath,
  444. OBJ_CASE_INSENSITIVE,
  445. NULL,
  446. NULL
  447. );
  448. status = ZwOpenKey(
  449. &serviceKey,
  450. KEY_READ | KEY_WRITE,
  451. &objectAttributes
  452. );
  453. if (!NT_SUCCESS(status)) {
  454. ERROR_RETURN( DriverExtension->InitData.DeviceType, "ZwOpenKey failed", status );
  455. }
  456. RtlInitUnicodeString( &unicodeString, L"Parameters" );
  457. InitializeObjectAttributes(
  458. &objectAttributes,
  459. &unicodeString,
  460. OBJ_CASE_INSENSITIVE,
  461. serviceKey,
  462. NULL
  463. );
  464. status = ZwCreateKey(
  465. parametersKey,
  466. KEY_READ | KEY_WRITE,
  467. &objectAttributes,
  468. 0,
  469. NULL,
  470. REG_OPTION_NON_VOLATILE,
  471. &Disposition
  472. );
  473. if (!NT_SUCCESS(status)) {
  474. ERROR_RETURN( DriverExtension->InitData.DeviceType, "ZwCreateKey failed", status );
  475. }
  476. status = STATUS_SUCCESS;
  477. } __finally {
  478. if (serviceKey) {
  479. ZwClose( serviceKey );
  480. }
  481. if (!NT_SUCCESS(status)) {
  482. if (parametersKey) {
  483. ZwClose( parametersKey );
  484. }
  485. }
  486. }
  487. return status;
  488. }
  489. NTSTATUS
  490. ReadRegistryValue(
  491. IN PSAPORT_DRIVER_EXTENSION DriverExtension,
  492. IN PUNICODE_STRING RegistryPath,
  493. IN PWSTR ValueName,
  494. OUT PKEY_VALUE_FULL_INFORMATION *KeyInformation
  495. )
  496. /*++
  497. Routine Description:
  498. This routine reads a registry arbitrary value from the
  499. device's parameter registry data. The necessary memory
  500. is allocated by this function and must be freed by the caller.
  501. Arguments:
  502. RegistryPath - String containing the path to the driver's registry data
  503. ValueName - Value name in the registry
  504. KeyInformation - Pointer to a PKEY_VALUE_FULL_INFORMATION pointer that is allocated by this function
  505. Return Value:
  506. NT status code
  507. --*/
  508. {
  509. NTSTATUS status;
  510. UNICODE_STRING unicodeString;
  511. HANDLE parametersKey = NULL;
  512. ULONG keyValueLength;
  513. __try {
  514. status = OpenParametersRegistryKey(
  515. DriverExtension,
  516. RegistryPath,
  517. KEY_READ,
  518. &parametersKey
  519. );
  520. if (!NT_SUCCESS(status)) {
  521. ERROR_RETURN( DriverExtension->InitData.DeviceType, "OpenParametersRegistryKey failed", status );
  522. }
  523. RtlInitUnicodeString( &unicodeString, ValueName );
  524. status = ZwQueryValueKey(
  525. parametersKey,
  526. &unicodeString,
  527. KeyValueFullInformation,
  528. NULL,
  529. 0,
  530. &keyValueLength
  531. );
  532. if (status != STATUS_BUFFER_OVERFLOW && status != STATUS_BUFFER_TOO_SMALL) {
  533. ERROR_RETURN( DriverExtension->InitData.DeviceType, "ZwQueryValueKey failed", status );
  534. }
  535. *KeyInformation = (PKEY_VALUE_FULL_INFORMATION) ExAllocatePool( NonPagedPool, keyValueLength );
  536. if (*KeyInformation == NULL) {
  537. status = STATUS_INSUFFICIENT_RESOURCES;
  538. ERROR_RETURN( DriverExtension->InitData.DeviceType, "Failed to allocate pool for registry data", status );
  539. }
  540. status = ZwQueryValueKey(
  541. parametersKey,
  542. &unicodeString,
  543. KeyValueFullInformation,
  544. *KeyInformation,
  545. keyValueLength,
  546. &keyValueLength
  547. );
  548. if (!NT_SUCCESS(status)) {
  549. ERROR_RETURN( DriverExtension->InitData.DeviceType, "ZwQueryValueKey failed", status );
  550. }
  551. status = STATUS_SUCCESS;
  552. } __finally {
  553. if (parametersKey) {
  554. ZwClose( parametersKey );
  555. }
  556. if (!NT_SUCCESS(status)) {
  557. if (*KeyInformation) {
  558. ExFreePool( *KeyInformation );
  559. }
  560. *KeyInformation = NULL;
  561. }
  562. }
  563. return status;
  564. }
  565. NTSTATUS
  566. WriteRegistryValue(
  567. IN PSAPORT_DRIVER_EXTENSION DriverExtension,
  568. IN PUNICODE_STRING RegistryPath,
  569. IN PWSTR ValueName,
  570. IN ULONG RegistryType,
  571. IN PVOID RegistryValue,
  572. IN ULONG RegistryValueLength
  573. )
  574. /*++
  575. Routine Description:
  576. This routine reads a registry arbitrary value from the
  577. device's parameter registry data. The necessary memory
  578. is allocated by this function and must be freed by the caller.
  579. Arguments:
  580. RegistryPath - String containing the path to the driver's registry data
  581. ValueName - Value name in the registry
  582. KeyInformation - Pointer to a PKEY_VALUE_FULL_INFORMATION pointer that is allocated by this function
  583. Return Value:
  584. NT status code
  585. --*/
  586. {
  587. NTSTATUS status;
  588. UNICODE_STRING unicodeString;
  589. HANDLE parametersKey = NULL;
  590. __try {
  591. status = OpenParametersRegistryKey(
  592. DriverExtension,
  593. RegistryPath,
  594. KEY_READ | KEY_WRITE,
  595. &parametersKey
  596. );
  597. if (!NT_SUCCESS(status)) {
  598. status = CreateParametersRegistryKey(
  599. DriverExtension,
  600. RegistryPath,
  601. &parametersKey
  602. );
  603. if (!NT_SUCCESS(status)) {
  604. ERROR_RETURN( DriverExtension->InitData.DeviceType, "CreateParametersRegistryKey failed", status );
  605. }
  606. }
  607. RtlInitUnicodeString( &unicodeString, ValueName );
  608. status = ZwSetValueKey(
  609. parametersKey,
  610. &unicodeString,
  611. 0,
  612. RegistryType,
  613. RegistryValue,
  614. RegistryValueLength
  615. );
  616. if (!NT_SUCCESS(status)) {
  617. ERROR_RETURN( DriverExtension->InitData.DeviceType, "ZwQueryValueKey failed", status );
  618. }
  619. status = STATUS_SUCCESS;
  620. } __finally {
  621. if (parametersKey) {
  622. ZwClose( parametersKey );
  623. }
  624. }
  625. return status;
  626. }
  627. //------------------------------------------------------------------------
  628. // debugging stuff
  629. //------------------------------------------------------------------------
  630. #if DBG
  631. PCHAR
  632. PnPMinorFunctionString(
  633. UCHAR MinorFunction
  634. )
  635. /*++
  636. Routine Description:
  637. This routine translates a minor function code into a string.
  638. Arguments:
  639. MinorFunction - Minor function code
  640. Return Value:
  641. Pointer to a string representation of the MinorFunction code.
  642. --*/
  643. {
  644. switch (MinorFunction) {
  645. case IRP_MN_START_DEVICE:
  646. return "IRP_MN_START_DEVICE";
  647. case IRP_MN_QUERY_REMOVE_DEVICE:
  648. return "IRP_MN_QUERY_REMOVE_DEVICE";
  649. case IRP_MN_REMOVE_DEVICE:
  650. return "IRP_MN_REMOVE_DEVICE";
  651. case IRP_MN_CANCEL_REMOVE_DEVICE:
  652. return "IRP_MN_CANCEL_REMOVE_DEVICE";
  653. case IRP_MN_STOP_DEVICE:
  654. return "IRP_MN_STOP_DEVICE";
  655. case IRP_MN_QUERY_STOP_DEVICE:
  656. return "IRP_MN_QUERY_STOP_DEVICE";
  657. case IRP_MN_CANCEL_STOP_DEVICE:
  658. return "IRP_MN_CANCEL_STOP_DEVICE";
  659. case IRP_MN_QUERY_DEVICE_RELATIONS:
  660. return "IRP_MN_QUERY_DEVICE_RELATIONS";
  661. case IRP_MN_QUERY_INTERFACE:
  662. return "IRP_MN_QUERY_INTERFACE";
  663. case IRP_MN_QUERY_CAPABILITIES:
  664. return "IRP_MN_QUERY_CAPABILITIES";
  665. case IRP_MN_QUERY_RESOURCES:
  666. return "IRP_MN_QUERY_RESOURCES";
  667. case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
  668. return "IRP_MN_QUERY_RESOURCE_REQUIREMENTS";
  669. case IRP_MN_QUERY_DEVICE_TEXT:
  670. return "IRP_MN_QUERY_DEVICE_TEXT";
  671. case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
  672. return "IRP_MN_FILTER_RESOURCE_REQUIREMENTS";
  673. case IRP_MN_READ_CONFIG:
  674. return "IRP_MN_READ_CONFIG";
  675. case IRP_MN_WRITE_CONFIG:
  676. return "IRP_MN_WRITE_CONFIG";
  677. case IRP_MN_EJECT:
  678. return "IRP_MN_EJECT";
  679. case IRP_MN_SET_LOCK:
  680. return "IRP_MN_SET_LOCK";
  681. case IRP_MN_QUERY_ID:
  682. return "IRP_MN_QUERY_ID";
  683. case IRP_MN_QUERY_PNP_DEVICE_STATE:
  684. return "IRP_MN_QUERY_PNP_DEVICE_STATE";
  685. case IRP_MN_QUERY_BUS_INFORMATION:
  686. return "IRP_MN_QUERY_BUS_INFORMATION";
  687. case IRP_MN_DEVICE_USAGE_NOTIFICATION:
  688. return "IRP_MN_DEVICE_USAGE_NOTIFICATION";
  689. case IRP_MN_SURPRISE_REMOVAL:
  690. return "IRP_MN_SURPRISE_REMOVAL";
  691. case IRP_MN_QUERY_LEGACY_BUS_INFORMATION:
  692. return "IRP_MN_QUERY_LEGACY_BUS_INFORMATION";
  693. default:
  694. return "IRP_MN_?????";
  695. }
  696. }
  697. PCHAR
  698. PowerMinorFunctionString(
  699. UCHAR MinorFunction
  700. )
  701. /*++
  702. Routine Description:
  703. This routine translates a minor power function code into a string.
  704. Arguments:
  705. MinorFunction - Minor function code
  706. Return Value:
  707. Pointer to a string representation of the MinorFunction code.
  708. --*/
  709. {
  710. switch (MinorFunction) {
  711. case IRP_MN_WAIT_WAKE:
  712. return "IRP_MN_WAIT_WAKE";
  713. case IRP_MN_POWER_SEQUENCE:
  714. return "IRP_MN_POWER_SEQUENCE";
  715. case IRP_MN_SET_POWER:
  716. return "IRP_MN_SET_POWER";
  717. case IRP_MN_QUERY_POWER:
  718. return "IRP_MN_QUERY_POWER";
  719. default:
  720. return "IRP_MN_?????";
  721. }
  722. }
  723. PCHAR
  724. PowerDeviceStateString(
  725. DEVICE_POWER_STATE State
  726. )
  727. /*++
  728. Routine Description:
  729. This routine translates a power state code into a string.
  730. Arguments:
  731. State - State code
  732. Return Value:
  733. Pointer to a string representation of the state code.
  734. --*/
  735. {
  736. switch (State) {
  737. case PowerDeviceUnspecified:
  738. return "PowerDeviceUnspecified";
  739. case PowerDeviceD0:
  740. return "PowerDeviceD0";
  741. case PowerDeviceD1:
  742. return "PowerDeviceD1";
  743. case PowerDeviceD2:
  744. return "PowerDeviceD2";
  745. case PowerDeviceD3:
  746. return "PowerDeviceD3";
  747. case PowerDeviceMaximum:
  748. return "PowerDeviceMaximum";
  749. default:
  750. return "PowerDevice?????";
  751. }
  752. }
  753. PCHAR
  754. PowerSystemStateString(
  755. SYSTEM_POWER_STATE State
  756. )
  757. /*++
  758. Routine Description:
  759. This routine translates a power system state code into a string.
  760. Arguments:
  761. State - State code
  762. Return Value:
  763. Pointer to a string representation of the state code.
  764. --*/
  765. {
  766. switch (State) {
  767. case PowerSystemUnspecified:
  768. return "PowerSystemUnspecified";
  769. case PowerSystemWorking:
  770. return "PowerSystemWorking";
  771. case PowerSystemSleeping1:
  772. return "PowerSystemSleeping1";
  773. case PowerSystemSleeping2:
  774. return "PowerSystemSleeping2";
  775. case PowerSystemSleeping3:
  776. return "PowerSystemSleeping3";
  777. case PowerSystemHibernate:
  778. return "PowerSystemHibernate";
  779. case PowerSystemShutdown:
  780. return "PowerSystemShutdown";
  781. case PowerSystemMaximum:
  782. return "PowerSystemMaximum";
  783. default:
  784. return "PowerSystem?????";
  785. }
  786. }
  787. PCHAR
  788. IoctlString(
  789. ULONG IoControlCode
  790. )
  791. /*++
  792. Routine Description:
  793. This routine translates an IOCTL code into a string.
  794. Arguments:
  795. IoControlCode - I/O control code
  796. Return Value:
  797. Pointer to a string representation of the I/O control code.
  798. --*/
  799. {
  800. switch (IoControlCode) {
  801. case IOCTL_MOUNTDEV_QUERY_DEVICE_NAME:
  802. return "IOCTL_MOUNTDEV_QUERY_DEVICE_NAME";
  803. case IOCTL_MOUNTDEV_QUERY_UNIQUE_ID:
  804. return "IOCTL_MOUNTDEV_QUERY_UNIQUE_ID";
  805. case IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME:
  806. return "IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME";
  807. case IOCTL_STORAGE_GET_MEDIA_TYPES:
  808. return "IOCTL_STORAGE_GET_MEDIA_TYPES";
  809. case IOCTL_DISK_GET_MEDIA_TYPES:
  810. return "IOCTL_DISK_GET_MEDIA_TYPES";
  811. case IOCTL_DISK_CHECK_VERIFY:
  812. return "IOCTL_DISK_CHECK_VERIFY";
  813. case IOCTL_DISK_GET_DRIVE_GEOMETRY:
  814. return "IOCTL_DISK_GET_DRIVE_GEOMETRY";
  815. case IOCTL_DISK_IS_WRITABLE:
  816. return "IOCTL_DISK_IS_WRITABLE";
  817. case IOCTL_DISK_VERIFY:
  818. return "IOCTL_DISK_VERIFY";
  819. case IOCTL_DISK_GET_DRIVE_LAYOUT:
  820. return "IOCTL_DISK_GET_DRIVE_LAYOUT";
  821. case IOCTL_DISK_GET_PARTITION_INFO:
  822. return "IOCTL_DISK_GET_PARTITION_INFO";
  823. case IOCTL_DISK_GET_PARTITION_INFO_EX:
  824. return "IOCTL_DISK_GET_PARTITION_INFO_EX";
  825. case IOCTL_DISK_GET_LENGTH_INFO:
  826. return "IOCTL_DISK_GET_LENGTH_INFO";
  827. case IOCTL_DISK_MEDIA_REMOVAL:
  828. return "IOCTL_DISK_MEDIA_REMOVAL";
  829. case IOCTL_SA_GET_VERSION:
  830. return "IOCTL_SA_GET_VERSION";
  831. case IOCTL_SA_GET_CAPABILITIES:
  832. return "IOCTL_SA_GET_CAPABILITIES";
  833. case IOCTL_SAWD_DISABLE:
  834. return "IOCTL_SAWD_DISABLE";
  835. case IOCTL_SAWD_QUERY_EXPIRE_BEHAVIOR:
  836. return "IOCTL_SAWD_QUERY_EXPIRE_BEHAVIOR";
  837. case IOCTL_SAWD_SET_EXPIRE_BEHAVIOR:
  838. return "IOCTL_SAWD_SET_EXPIRE_BEHAVIOR";
  839. case IOCTL_SAWD_PING:
  840. return "IOCTL_SAWD_PING";
  841. case IOCTL_SAWD_QUERY_TIMER:
  842. return "IOCTL_SAWD_QUERY_TIMER";
  843. case IOCTL_SAWD_SET_TIMER:
  844. return "IOCTL_SAWD_SET_TIMER";
  845. case IOCTL_NVRAM_WRITE_BOOT_COUNTER:
  846. return "IOCTL_NVRAM_WRITE_BOOT_COUNTER";
  847. case IOCTL_NVRAM_READ_BOOT_COUNTER:
  848. return "IOCTL_NVRAM_READ_BOOT_COUNTER";
  849. case IOCTL_SADISPLAY_LOCK:
  850. return "IOCTL_SADISPLAY_LOCK";
  851. case IOCTL_SADISPLAY_UNLOCK:
  852. return "IOCTL_SADISPLAY_UNLOCK";
  853. case IOCTL_SADISPLAY_BUSY_MESSAGE:
  854. return "IOCTL_SADISPLAY_BUSY_MESSAGE";
  855. case IOCTL_SADISPLAY_SHUTDOWN_MESSAGE:
  856. return "IOCTL_SADISPLAY_SHUTDOWN_MESSAGE";
  857. case IOCTL_SADISPLAY_CHANGE_LANGUAGE:
  858. return "IOCTL_SADISPLAY_CHANGE_LANGUAGE";
  859. default:
  860. return "IOCTL_?????";
  861. }
  862. }
  863. #endif