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.

1254 lines
27 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) 23-Jan-2002
  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 WdDebugLevel;
  24. #endif
  25. ULONG OsMajorVersion;
  26. ULONG OsMinorVersion;
  27. NTSTATUS
  28. CompleteRequest(
  29. PIRP Irp,
  30. NTSTATUS Status,
  31. ULONG_PTR Information
  32. )
  33. /*++
  34. Routine Description:
  35. This routine completes as outstanding I/O request.
  36. Arguments:
  37. Irp - Pointer to an IRP structure that describes the requested I/O operation.
  38. Status - NT status value
  39. Information - Informational, request specific data
  40. Return Value:
  41. NT status code.
  42. --*/
  43. {
  44. PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
  45. KIRQL CancelIrql;
  46. if (IrpSp->MajorFunction == IRP_MJ_READ || IrpSp->MajorFunction == IRP_MJ_WRITE) {
  47. IoAcquireCancelSpinLock( &CancelIrql );
  48. IoSetCancelRoutine( Irp, NULL );
  49. IoReleaseCancelSpinLock( CancelIrql );
  50. }
  51. Irp->IoStatus.Information = Information;
  52. Irp->IoStatus.Status = Status;
  53. IoCompleteRequest( Irp, IO_NO_INCREMENT );
  54. return Status;
  55. }
  56. NTSTATUS
  57. ForwardRequest(
  58. IN PIRP Irp,
  59. IN PDEVICE_OBJECT TargetObject
  60. )
  61. /*++
  62. Routine Description:
  63. This routine forwards the IRP to another driver.
  64. Arguments:
  65. Irp - Pointer to an IRP structure that describes the requested I/O operation.
  66. TargetObject - Target device object to receive the request packet
  67. Return Value:
  68. NT status code.
  69. --*/
  70. {
  71. IoSkipCurrentIrpStackLocation( Irp );
  72. return IoCallDriver( TargetObject, Irp );
  73. }
  74. VOID
  75. WdDebugPrint(
  76. IN ULONG DebugLevel,
  77. IN PSTR DebugMessage,
  78. IN ...
  79. )
  80. /*++
  81. Routine Description:
  82. This routine prints a formatted string to the debugger.
  83. Arguments:
  84. DebugLevel - Debug level that controls when a message is printed
  85. DebugMessage - String that is printed
  86. ... - Arguments that are used by the DebugMessage
  87. Return Value:
  88. None.
  89. --*/
  90. {
  91. va_list arg_ptr;
  92. char buf[512];
  93. char *s = buf;
  94. #if DBG
  95. if ((DebugLevel != 0xffffffff) && ((WdDebugLevel == 0) || ((WdDebugLevel & DebugLevel) == 0))) {
  96. return;
  97. }
  98. #endif
  99. va_start( arg_ptr, DebugMessage );
  100. strcpy( s, "WD: " );
  101. s += strlen(s);
  102. _vsnprintf( s, sizeof(buf)-1-strlen(s), DebugMessage, arg_ptr );
  103. DbgPrint( buf );
  104. }
  105. #if DBG
  106. VOID
  107. GetOsVersion(
  108. VOID
  109. )
  110. /*++
  111. Routine Description:
  112. This routine gets the current OS version information
  113. Arguments:
  114. None.
  115. Return Value:
  116. None.
  117. --*/
  118. {
  119. RTL_OSVERSIONINFOW VersionInformation;
  120. VersionInformation.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOW);
  121. RtlGetVersion( &VersionInformation );
  122. OsMajorVersion = VersionInformation.dwMajorVersion;
  123. OsMinorVersion = VersionInformation.dwMinorVersion;
  124. }
  125. VOID
  126. FormatTime(
  127. ULONG TimeStamp,
  128. PSTR TimeBuf
  129. )
  130. /*++
  131. Routine Description:
  132. This routine formats a timestamp word into a string.
  133. Arguments:
  134. TimeStamp - Timestamp word
  135. TimeBuf - Buffer to place the resulting string
  136. Return Value:
  137. None.
  138. --*/
  139. {
  140. static char mnames[] = { "JanFebMarAprMayJunJulAugSepOctNovDec" };
  141. LARGE_INTEGER MyTime;
  142. TIME_FIELDS TimeFields;
  143. RtlSecondsSince1970ToTime( TimeStamp, &MyTime );
  144. ExSystemTimeToLocalTime( &MyTime, &MyTime );
  145. RtlTimeToTimeFields( &MyTime, &TimeFields );
  146. strncpy( TimeBuf, &mnames[(TimeFields.Month - 1) * 3], 3 );
  147. sprintf(
  148. &TimeBuf[3],
  149. " %02d, %04d @ %02d:%02d:%02d",
  150. TimeFields.Day,
  151. TimeFields.Year,
  152. TimeFields.Hour,
  153. TimeFields.Minute,
  154. TimeFields.Second
  155. );
  156. }
  157. VOID
  158. PrintDriverVersion(
  159. IN PDRIVER_OBJECT DriverObject
  160. )
  161. /*++
  162. Routine Description:
  163. This routine locates the NT image headers from the
  164. base of a loaded driver.
  165. Arguments:
  166. DeviceType - Miniport device type (see saio.h for the enumeration)
  167. DriverObject - Pointer to the DRIVER_OBJECT structure
  168. Return Value:
  169. None.
  170. --*/
  171. {
  172. PIMAGE_NT_HEADERS NtHeaders;
  173. ULONG TimeStamp;
  174. CHAR buf[32];
  175. NtHeaders = RtlpImageNtHeader( DriverObject->DriverStart );
  176. if (NtHeaders) {
  177. TimeStamp = NtHeaders->FileHeader.TimeDateStamp;
  178. FormatTime( TimeStamp, buf );
  179. }
  180. }
  181. #endif
  182. NTSTATUS
  183. WdSignalCompletion(
  184. IN PDEVICE_OBJECT DeviceObject,
  185. IN PIRP Irp,
  186. IN PVOID Event
  187. )
  188. /*++
  189. Routine Description:
  190. This routine is used to signal the completion of an
  191. I/O request and is used ONLY by CallLowerDriverAndWait.
  192. Arguments:
  193. DeviceObject - Pointer to the miniport's device object
  194. Irp - I/O request packet
  195. Event - Event to be signaled when the I/O is completed
  196. Return Value:
  197. NT status code
  198. --*/
  199. {
  200. KeSetEvent( (PKEVENT)Event, IO_NO_INCREMENT, FALSE );
  201. return STATUS_MORE_PROCESSING_REQUIRED;
  202. }
  203. NTSTATUS
  204. CallLowerDriverAndWait(
  205. IN PIRP Irp,
  206. IN PDEVICE_OBJECT TargetObject
  207. )
  208. /*++
  209. Routine Description:
  210. This routine calls a lower driver and waits for the I/O to complete.
  211. Arguments:
  212. Irp - I/O request packet
  213. TargetObject - Pointer to the target device object
  214. Return Value:
  215. NT status code
  216. --*/
  217. {
  218. KEVENT event;
  219. KeInitializeEvent( &event, NotificationEvent, FALSE );
  220. IoCopyCurrentIrpStackLocationToNext( Irp );
  221. IoSetCompletionRoutine( Irp, WdSignalCompletion, &event, TRUE, TRUE, TRUE );
  222. IoCallDriver( TargetObject, Irp );
  223. KeWaitForSingleObject( &event, Executive, KernelMode, FALSE, NULL );
  224. return Irp->IoStatus.Status;
  225. }
  226. NTSTATUS
  227. OpenParametersRegistryKey(
  228. IN PUNICODE_STRING RegistryPath,
  229. IN ULONG AccessMode,
  230. OUT PHANDLE RegistryHandle
  231. )
  232. /*++
  233. Routine Description:
  234. This routine opens the driver's paramaters
  235. registry key for I/O.
  236. Arguments:
  237. RegistryPath - Full path to the root of the driver's
  238. registry tree.
  239. AccessMode - Specifies how the handle is to be opened (READ/WRITE/etc).
  240. RegistryHandle - Output parameter that receives the registry handle.
  241. Return Value:
  242. NT status code
  243. --*/
  244. {
  245. NTSTATUS status;
  246. OBJECT_ATTRIBUTES objectAttributes;
  247. UNICODE_STRING unicodeString;
  248. HANDLE serviceKey = NULL;
  249. __try {
  250. InitializeObjectAttributes(
  251. &objectAttributes,
  252. RegistryPath,
  253. OBJ_CASE_INSENSITIVE,
  254. NULL,
  255. NULL
  256. );
  257. status = ZwOpenKey(
  258. &serviceKey,
  259. AccessMode,
  260. &objectAttributes
  261. );
  262. if (!NT_SUCCESS(status)) {
  263. ERROR_RETURN( "ZwOpenKey failed", status );
  264. }
  265. RtlInitUnicodeString( &unicodeString, L"Parameters" );
  266. InitializeObjectAttributes(
  267. &objectAttributes,
  268. &unicodeString,
  269. OBJ_CASE_INSENSITIVE,
  270. serviceKey,
  271. NULL
  272. );
  273. status = ZwOpenKey(
  274. RegistryHandle,
  275. AccessMode,
  276. &objectAttributes
  277. );
  278. if (!NT_SUCCESS(status)) {
  279. ERROR_RETURN( "ZwOpenKey failed", status );
  280. }
  281. status = STATUS_SUCCESS;
  282. } __finally {
  283. if (serviceKey) {
  284. ZwClose( serviceKey );
  285. }
  286. if (!NT_SUCCESS(status)) {
  287. if (*RegistryHandle) {
  288. ZwClose( *RegistryHandle );
  289. }
  290. }
  291. }
  292. return status;
  293. }
  294. NTSTATUS
  295. CreateParametersRegistryKey(
  296. IN PUNICODE_STRING RegistryPath,
  297. OUT PHANDLE parametersKey
  298. )
  299. /*++
  300. Routine Description:
  301. This routine creates the driver's paramaters
  302. registry key for I/O.
  303. Arguments:
  304. RegistryPath - Full path to the root of the driver's
  305. registry tree.
  306. RegistryHandle - Output parameter that receives the registry handle.
  307. Return Value:
  308. NT status code
  309. --*/
  310. {
  311. NTSTATUS status;
  312. OBJECT_ATTRIBUTES objectAttributes;
  313. UNICODE_STRING unicodeString;
  314. HANDLE serviceKey = NULL;
  315. ULONG Disposition;
  316. __try {
  317. parametersKey = NULL;
  318. InitializeObjectAttributes(
  319. &objectAttributes,
  320. RegistryPath,
  321. OBJ_CASE_INSENSITIVE,
  322. NULL,
  323. NULL
  324. );
  325. status = ZwOpenKey(
  326. &serviceKey,
  327. KEY_READ | KEY_WRITE,
  328. &objectAttributes
  329. );
  330. if (!NT_SUCCESS(status)) {
  331. ERROR_RETURN( "ZwOpenKey failed", status );
  332. }
  333. RtlInitUnicodeString( &unicodeString, L"Parameters" );
  334. InitializeObjectAttributes(
  335. &objectAttributes,
  336. &unicodeString,
  337. OBJ_CASE_INSENSITIVE,
  338. serviceKey,
  339. NULL
  340. );
  341. status = ZwCreateKey(
  342. parametersKey,
  343. KEY_READ | KEY_WRITE,
  344. &objectAttributes,
  345. 0,
  346. NULL,
  347. REG_OPTION_NON_VOLATILE,
  348. &Disposition
  349. );
  350. if (!NT_SUCCESS(status)) {
  351. ERROR_RETURN( "ZwCreateKey failed", status );
  352. }
  353. status = STATUS_SUCCESS;
  354. } __finally {
  355. if (serviceKey) {
  356. ZwClose( serviceKey );
  357. }
  358. if (!NT_SUCCESS(status)) {
  359. if (parametersKey) {
  360. ZwClose( parametersKey );
  361. }
  362. }
  363. }
  364. return status;
  365. }
  366. NTSTATUS
  367. ReadRegistryValue(
  368. IN PUNICODE_STRING RegistryPath,
  369. IN PWSTR ValueName,
  370. OUT PKEY_VALUE_FULL_INFORMATION *KeyInformation
  371. )
  372. /*++
  373. Routine Description:
  374. This routine reads a registry arbitrary value from the
  375. device's parameter registry data. The necessary memory
  376. is allocated by this function and must be freed by the caller.
  377. Arguments:
  378. RegistryPath - String containing the path to the driver's registry data
  379. ValueName - Value name in the registry
  380. KeyInformation - Pointer to a PKEY_VALUE_FULL_INFORMATION pointer that is allocated by this function
  381. Return Value:
  382. NT status code
  383. --*/
  384. {
  385. NTSTATUS status;
  386. UNICODE_STRING unicodeString;
  387. HANDLE parametersKey = NULL;
  388. ULONG keyValueLength;
  389. __try {
  390. *KeyInformation = NULL;
  391. status = OpenParametersRegistryKey(
  392. RegistryPath,
  393. KEY_READ,
  394. &parametersKey
  395. );
  396. if (!NT_SUCCESS(status)) {
  397. ERROR_RETURN( "OpenParametersRegistryKey failed", status );
  398. }
  399. RtlInitUnicodeString( &unicodeString, ValueName );
  400. status = ZwQueryValueKey(
  401. parametersKey,
  402. &unicodeString,
  403. KeyValueFullInformation,
  404. NULL,
  405. 0,
  406. &keyValueLength
  407. );
  408. if (status != STATUS_BUFFER_OVERFLOW && status != STATUS_BUFFER_TOO_SMALL) {
  409. ERROR_RETURN( "ZwQueryValueKey failed", status );
  410. }
  411. *KeyInformation = (PKEY_VALUE_FULL_INFORMATION) ExAllocatePool( NonPagedPool, keyValueLength );
  412. if (*KeyInformation == NULL) {
  413. status = STATUS_INSUFFICIENT_RESOURCES;
  414. ERROR_RETURN( "Failed to allocate pool for registry data", status );
  415. }
  416. status = ZwQueryValueKey(
  417. parametersKey,
  418. &unicodeString,
  419. KeyValueFullInformation,
  420. *KeyInformation,
  421. keyValueLength,
  422. &keyValueLength
  423. );
  424. if (!NT_SUCCESS(status)) {
  425. ERROR_RETURN( "ZwQueryValueKey failed", status );
  426. }
  427. status = STATUS_SUCCESS;
  428. } __finally {
  429. if (parametersKey) {
  430. ZwClose( parametersKey );
  431. }
  432. if (!NT_SUCCESS(status)) {
  433. if (*KeyInformation) {
  434. ExFreePool( *KeyInformation );
  435. }
  436. *KeyInformation = NULL;
  437. }
  438. }
  439. return status;
  440. }
  441. NTSTATUS
  442. WriteRegistryValue(
  443. IN PUNICODE_STRING RegistryPath,
  444. IN PWSTR ValueName,
  445. IN ULONG RegistryType,
  446. IN PVOID RegistryValue,
  447. IN ULONG RegistryValueLength
  448. )
  449. /*++
  450. Routine Description:
  451. This routine reads a registry arbitrary value from the
  452. device's parameter registry data. The necessary memory
  453. is allocated by this function and must be freed by the caller.
  454. Arguments:
  455. RegistryPath - String containing the path to the driver's registry data
  456. ValueName - Value name in the registry
  457. KeyInformation - Pointer to a PKEY_VALUE_FULL_INFORMATION pointer that is allocated by this function
  458. Return Value:
  459. NT status code
  460. --*/
  461. {
  462. NTSTATUS status;
  463. UNICODE_STRING unicodeString;
  464. HANDLE parametersKey = NULL;
  465. __try {
  466. status = OpenParametersRegistryKey(
  467. RegistryPath,
  468. KEY_READ | KEY_WRITE,
  469. &parametersKey
  470. );
  471. if (!NT_SUCCESS(status)) {
  472. status = CreateParametersRegistryKey(
  473. RegistryPath,
  474. &parametersKey
  475. );
  476. if (!NT_SUCCESS(status)) {
  477. ERROR_RETURN( "CreateParametersRegistryKey failed", status );
  478. }
  479. }
  480. RtlInitUnicodeString( &unicodeString, ValueName );
  481. status = ZwSetValueKey(
  482. parametersKey,
  483. &unicodeString,
  484. 0,
  485. RegistryType,
  486. RegistryValue,
  487. RegistryValueLength
  488. );
  489. if (!NT_SUCCESS(status)) {
  490. ERROR_RETURN( "ZwQueryValueKey failed", status );
  491. }
  492. status = STATUS_SUCCESS;
  493. } __finally {
  494. if (parametersKey) {
  495. ZwClose( parametersKey );
  496. }
  497. }
  498. return status;
  499. }
  500. NTSTATUS
  501. WriteEventLogEntry (
  502. IN PDEVICE_EXTENSION DeviceExtension,
  503. IN ULONG ErrorCode,
  504. IN PVOID InsertionStrings, OPTIONAL
  505. IN ULONG StringCount, OPTIONAL
  506. IN PVOID DumpData, OPTIONAL
  507. IN ULONG DataSize OPTIONAL
  508. )
  509. /*++
  510. Routine Description:
  511. Writes an entry into the system eventlog.
  512. Arguments:
  513. DeviceExtension - Pointer to a device extension object
  514. ErrorCode - Eventlog errorcode as specified in eventmsg.mc
  515. InsertionStrings - String to insert into the eventlog message
  516. StringCount - Number of InsertionStrings
  517. DumpData - Additional data to be include in the message
  518. DataSize - Size of the DumpData
  519. Return Value:
  520. NT status code
  521. --*/
  522. {
  523. #define ERROR_PACKET_SIZE sizeof(IO_ERROR_LOG_PACKET)
  524. NTSTATUS status = STATUS_SUCCESS;
  525. ULONG totalPacketSize;
  526. ULONG i, stringSize = 0;
  527. PWCHAR *strings, temp;
  528. PIO_ERROR_LOG_PACKET logEntry;
  529. UNICODE_STRING unicodeString;
  530. __try {
  531. //
  532. // Calculate total string length, including NULL.
  533. //
  534. strings = (PWCHAR *) InsertionStrings;
  535. for (i=0; i<StringCount; i++) {
  536. RtlInitUnicodeString(&unicodeString, strings[i]);
  537. stringSize += unicodeString.Length + sizeof(UNICODE_NULL);
  538. }
  539. //
  540. // Calculate total packet size to allocate. The packet must be
  541. // at least sizeof(IO_ERROR_LOG_PACKET) and not larger than
  542. // ERROR_LOG_MAXIMUM_SIZE or the IoAllocateErrorLogEntry call will fail.
  543. //
  544. totalPacketSize = ERROR_PACKET_SIZE + DataSize + stringSize;
  545. if (totalPacketSize >= ERROR_LOG_MAXIMUM_SIZE) {
  546. ERROR_RETURN( "WriteEventLogEntry: Error Log Entry too large", STATUS_UNSUCCESSFUL );
  547. }
  548. //
  549. // Allocate the error log packet
  550. //
  551. logEntry = (PIO_ERROR_LOG_PACKET) IoAllocateErrorLogEntry( DeviceExtension->DeviceObject, (UCHAR)totalPacketSize );
  552. if (!logEntry) {
  553. ERROR_RETURN( "IoAllocateErrorLogEntry failed", STATUS_INSUFFICIENT_RESOURCES );
  554. }
  555. RtlZeroMemory( logEntry, totalPacketSize );
  556. //
  557. // Fill out the packet
  558. //
  559. //logEntry->MajorFunctionCode = 0;
  560. //logEntry->RetryCount = 0;
  561. //logEntry->UniqueErrorValue = 0;
  562. //logEntry->FinalStatus = 0;
  563. //logEntry->SequenceNumber = ErrorLogCount++;
  564. //logEntry->IoControlCode = 0;
  565. //logEntry->DeviceOffset.QuadPart = 0;
  566. logEntry->DumpDataSize = (USHORT) DataSize;
  567. logEntry->NumberOfStrings = (USHORT) StringCount;
  568. logEntry->EventCategory = 0x1;
  569. logEntry->ErrorCode = ErrorCode;
  570. if (StringCount) {
  571. logEntry->StringOffset = (USHORT) (ERROR_PACKET_SIZE + DataSize);
  572. }
  573. //
  574. // Copy Dump Data
  575. //
  576. if (DataSize) {
  577. RtlCopyMemory( (PVOID)logEntry->DumpData, DumpData, DataSize );
  578. }
  579. //
  580. // Copy String Data
  581. //
  582. temp = (PWCHAR)((PUCHAR)logEntry + logEntry->StringOffset);
  583. for (i=0; i<StringCount; i++) {
  584. PWCHAR ptr = strings[i];
  585. //
  586. // This routine will copy the null terminator on the string
  587. //
  588. while ((*temp++ = *ptr++) != UNICODE_NULL);
  589. }
  590. //
  591. // Submit error log packet
  592. //
  593. IoWriteErrorLogEntry(logEntry);
  594. } __finally {
  595. }
  596. return status;
  597. }
  598. ULONG
  599. ConvertTimeoutToMilliseconds(
  600. IN ULONG Units,
  601. IN ULONG NativeTimeout
  602. )
  603. /*++
  604. Routine Description:
  605. Converts a time value that is represented in the native
  606. format that is specified by the hardware watchdog timer's
  607. ACPI table entry into a millisecond based value.
  608. Arguments:
  609. DeviceExtension - Pointer to a device extension object
  610. NativeTimeout - Native timeout value
  611. Return Value:
  612. Converted value or zero.
  613. --*/
  614. {
  615. ULONG Timeout = 0;
  616. switch (Units) {
  617. case 0:
  618. //
  619. // 1 seconds
  620. //
  621. Timeout = NativeTimeout * 1000;
  622. break;
  623. case 1:
  624. //
  625. // 100 miliseconds
  626. //
  627. Timeout = NativeTimeout / 100;
  628. break;
  629. case 2:
  630. //
  631. // 10 milliseconds
  632. //
  633. Timeout = NativeTimeout / 10;
  634. break;
  635. case 3:
  636. //
  637. // 1 miliseconds
  638. //
  639. Timeout = NativeTimeout;
  640. break;
  641. default:
  642. Timeout = 0;
  643. break;
  644. }
  645. return Timeout;
  646. }
  647. ULONG
  648. ConvertTimeoutFromMilliseconds(
  649. IN ULONG Units,
  650. IN ULONG UserTimeout
  651. )
  652. /*++
  653. Routine Description:
  654. Converts a time value that is represented in milliseconds
  655. to the native format that is specified by the hardware
  656. watchdog timer's ACPI table entry.
  657. Arguments:
  658. DeviceExtension - Pointer to a device extension object
  659. UserTimeout - Millisecond timeout value.
  660. Return Value:
  661. Converted value or zero.
  662. --*/
  663. {
  664. ULONG Timeout = 0;
  665. switch (Units) {
  666. case 0:
  667. //
  668. // 1 seconds
  669. //
  670. Timeout = UserTimeout / 1000;
  671. break;
  672. case 1:
  673. //
  674. // 100 miliseconds
  675. //
  676. Timeout = UserTimeout * 100;
  677. break;
  678. case 2:
  679. //
  680. // 10 milliseconds
  681. //
  682. Timeout = UserTimeout * 10;
  683. break;
  684. case 3:
  685. //
  686. // 1 miliseconds
  687. //
  688. Timeout = UserTimeout;
  689. break;
  690. default:
  691. Timeout = 0;
  692. break;
  693. }
  694. return Timeout;
  695. }
  696. //------------------------------------------------------------------------
  697. // debugging stuff
  698. //------------------------------------------------------------------------
  699. #if DBG
  700. PCHAR
  701. PnPMinorFunctionString(
  702. UCHAR MinorFunction
  703. )
  704. /*++
  705. Routine Description:
  706. This routine translates a minor function code into a string.
  707. Arguments:
  708. MinorFunction - Minor function code
  709. Return Value:
  710. Pointer to a string representation of the MinorFunction code.
  711. --*/
  712. {
  713. switch (MinorFunction) {
  714. case IRP_MN_START_DEVICE:
  715. return "IRP_MN_START_DEVICE";
  716. case IRP_MN_QUERY_REMOVE_DEVICE:
  717. return "IRP_MN_QUERY_REMOVE_DEVICE";
  718. case IRP_MN_REMOVE_DEVICE:
  719. return "IRP_MN_REMOVE_DEVICE";
  720. case IRP_MN_CANCEL_REMOVE_DEVICE:
  721. return "IRP_MN_CANCEL_REMOVE_DEVICE";
  722. case IRP_MN_STOP_DEVICE:
  723. return "IRP_MN_STOP_DEVICE";
  724. case IRP_MN_QUERY_STOP_DEVICE:
  725. return "IRP_MN_QUERY_STOP_DEVICE";
  726. case IRP_MN_CANCEL_STOP_DEVICE:
  727. return "IRP_MN_CANCEL_STOP_DEVICE";
  728. case IRP_MN_QUERY_DEVICE_RELATIONS:
  729. return "IRP_MN_QUERY_DEVICE_RELATIONS";
  730. case IRP_MN_QUERY_INTERFACE:
  731. return "IRP_MN_QUERY_INTERFACE";
  732. case IRP_MN_QUERY_CAPABILITIES:
  733. return "IRP_MN_QUERY_CAPABILITIES";
  734. case IRP_MN_QUERY_RESOURCES:
  735. return "IRP_MN_QUERY_RESOURCES";
  736. case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
  737. return "IRP_MN_QUERY_RESOURCE_REQUIREMENTS";
  738. case IRP_MN_QUERY_DEVICE_TEXT:
  739. return "IRP_MN_QUERY_DEVICE_TEXT";
  740. case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
  741. return "IRP_MN_FILTER_RESOURCE_REQUIREMENTS";
  742. case IRP_MN_READ_CONFIG:
  743. return "IRP_MN_READ_CONFIG";
  744. case IRP_MN_WRITE_CONFIG:
  745. return "IRP_MN_WRITE_CONFIG";
  746. case IRP_MN_EJECT:
  747. return "IRP_MN_EJECT";
  748. case IRP_MN_SET_LOCK:
  749. return "IRP_MN_SET_LOCK";
  750. case IRP_MN_QUERY_ID:
  751. return "IRP_MN_QUERY_ID";
  752. case IRP_MN_QUERY_PNP_DEVICE_STATE:
  753. return "IRP_MN_QUERY_PNP_DEVICE_STATE";
  754. case IRP_MN_QUERY_BUS_INFORMATION:
  755. return "IRP_MN_QUERY_BUS_INFORMATION";
  756. case IRP_MN_DEVICE_USAGE_NOTIFICATION:
  757. return "IRP_MN_DEVICE_USAGE_NOTIFICATION";
  758. case IRP_MN_SURPRISE_REMOVAL:
  759. return "IRP_MN_SURPRISE_REMOVAL";
  760. case IRP_MN_QUERY_LEGACY_BUS_INFORMATION:
  761. return "IRP_MN_QUERY_LEGACY_BUS_INFORMATION";
  762. default:
  763. return "IRP_MN_?????";
  764. }
  765. }
  766. PCHAR
  767. PowerMinorFunctionString(
  768. UCHAR MinorFunction
  769. )
  770. /*++
  771. Routine Description:
  772. This routine translates a minor power function code into a string.
  773. Arguments:
  774. MinorFunction - Minor function code
  775. Return Value:
  776. Pointer to a string representation of the MinorFunction code.
  777. --*/
  778. {
  779. switch (MinorFunction) {
  780. case IRP_MN_WAIT_WAKE:
  781. return "IRP_MN_WAIT_WAKE";
  782. case IRP_MN_POWER_SEQUENCE:
  783. return "IRP_MN_POWER_SEQUENCE";
  784. case IRP_MN_SET_POWER:
  785. return "IRP_MN_SET_POWER";
  786. case IRP_MN_QUERY_POWER:
  787. return "IRP_MN_QUERY_POWER";
  788. default:
  789. return "IRP_MN_?????";
  790. }
  791. }
  792. PCHAR
  793. PowerDeviceStateString(
  794. DEVICE_POWER_STATE State
  795. )
  796. /*++
  797. Routine Description:
  798. This routine translates a power state code into a string.
  799. Arguments:
  800. State - State code
  801. Return Value:
  802. Pointer to a string representation of the state code.
  803. --*/
  804. {
  805. switch (State) {
  806. case PowerDeviceUnspecified:
  807. return "PowerDeviceUnspecified";
  808. case PowerDeviceD0:
  809. return "PowerDeviceD0";
  810. case PowerDeviceD1:
  811. return "PowerDeviceD1";
  812. case PowerDeviceD2:
  813. return "PowerDeviceD2";
  814. case PowerDeviceD3:
  815. return "PowerDeviceD3";
  816. case PowerDeviceMaximum:
  817. return "PowerDeviceMaximum";
  818. default:
  819. return "PowerDevice?????";
  820. }
  821. }
  822. PCHAR
  823. PowerSystemStateString(
  824. SYSTEM_POWER_STATE State
  825. )
  826. /*++
  827. Routine Description:
  828. This routine translates a power system state code into a string.
  829. Arguments:
  830. State - State code
  831. Return Value:
  832. Pointer to a string representation of the state code.
  833. --*/
  834. {
  835. switch (State) {
  836. case PowerSystemUnspecified:
  837. return "PowerSystemUnspecified";
  838. case PowerSystemWorking:
  839. return "PowerSystemWorking";
  840. case PowerSystemSleeping1:
  841. return "PowerSystemSleeping1";
  842. case PowerSystemSleeping2:
  843. return "PowerSystemSleeping2";
  844. case PowerSystemSleeping3:
  845. return "PowerSystemSleeping3";
  846. case PowerSystemHibernate:
  847. return "PowerSystemHibernate";
  848. case PowerSystemShutdown:
  849. return "PowerSystemShutdown";
  850. case PowerSystemMaximum:
  851. return "PowerSystemMaximum";
  852. default:
  853. return "PowerSystem?????";
  854. }
  855. }
  856. PCHAR
  857. IoctlString(
  858. ULONG IoControlCode
  859. )
  860. /*++
  861. Routine Description:
  862. This routine translates an IOCTL code into a string.
  863. Arguments:
  864. IoControlCode - I/O control code
  865. Return Value:
  866. Pointer to a string representation of the I/O control code.
  867. --*/
  868. {
  869. switch (IoControlCode) {
  870. case IOCTL_MOUNTDEV_QUERY_DEVICE_NAME:
  871. return "IOCTL_MOUNTDEV_QUERY_DEVICE_NAME";
  872. case IOCTL_MOUNTDEV_QUERY_UNIQUE_ID:
  873. return "IOCTL_MOUNTDEV_QUERY_UNIQUE_ID";
  874. case IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME:
  875. return "IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME";
  876. case IOCTL_STORAGE_GET_MEDIA_TYPES:
  877. return "IOCTL_STORAGE_GET_MEDIA_TYPES";
  878. case IOCTL_DISK_GET_MEDIA_TYPES:
  879. return "IOCTL_DISK_GET_MEDIA_TYPES";
  880. case IOCTL_DISK_CHECK_VERIFY:
  881. return "IOCTL_DISK_CHECK_VERIFY";
  882. case IOCTL_DISK_GET_DRIVE_GEOMETRY:
  883. return "IOCTL_DISK_GET_DRIVE_GEOMETRY";
  884. case IOCTL_DISK_IS_WRITABLE:
  885. return "IOCTL_DISK_IS_WRITABLE";
  886. case IOCTL_DISK_VERIFY:
  887. return "IOCTL_DISK_VERIFY";
  888. case IOCTL_DISK_GET_DRIVE_LAYOUT:
  889. return "IOCTL_DISK_GET_DRIVE_LAYOUT";
  890. case IOCTL_DISK_GET_PARTITION_INFO:
  891. return "IOCTL_DISK_GET_PARTITION_INFO";
  892. case IOCTL_DISK_GET_PARTITION_INFO_EX:
  893. return "IOCTL_DISK_GET_PARTITION_INFO_EX";
  894. case IOCTL_DISK_GET_LENGTH_INFO:
  895. return "IOCTL_DISK_GET_LENGTH_INFO";
  896. case IOCTL_DISK_MEDIA_REMOVAL:
  897. return "IOCTL_DISK_MEDIA_REMOVAL";
  898. default:
  899. return "IOCTL_?????";
  900. }
  901. }
  902. #endif