Source code of Windows XP (NT5)
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.

221 lines
4.9 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name:
  4. PpPathPath.c
  5. Abstract:
  6. The file implements support for managing devices on the paging path.
  7. Author:
  8. Adrian J. Oney (AdriaO) February 3rd, 2001
  9. Revision History:
  10. Originally taken from ChuckL's implementation in mm\modwrite.c.
  11. --*/
  12. #include "pnpmgrp.h"
  13. #include "pipagepath.h"
  14. #ifdef ALLOC_PRAGMA
  15. #pragma alloc_text(PAGE, PpPagePathAssign)
  16. #pragma alloc_text(PAGE, PpPagePathRelease)
  17. #pragma alloc_text(PAGE, PiPagePathSetState)
  18. #endif
  19. NTSTATUS
  20. PpPagePathAssign(
  21. IN PFILE_OBJECT FileObject
  22. )
  23. /*++
  24. Routine Description:
  25. This routine informs driver stacks that they are now on the paging path.
  26. Drivers need to take appropriate actions when on the path, such as failing
  27. IRP_MN_QUERY_STOP and IRP_MN_QUERY_REMOVE, locking their code and clearing
  28. the DO_POWER_PAGABLE bit, etc.
  29. Arguments:
  30. FileObject - File object for the paging file itself.
  31. Return Value:
  32. NTSTATUS.
  33. --*/
  34. {
  35. PAGED_CODE();
  36. return PiPagePathSetState(FileObject, TRUE);
  37. }
  38. NTSTATUS
  39. PpPagePathRelease(
  40. IN PFILE_OBJECT FileObject
  41. )
  42. /*++
  43. Routine Description:
  44. This routine informs driver stacks that the passed in file is no longer a
  45. paging file. Each driver stack notified may still be on the paging path
  46. however if their hardware supports a different paging file on another drive.
  47. Arguments:
  48. FileObject - File object for the paging file itself.
  49. Return Value:
  50. NTSTATUS.
  51. --*/
  52. {
  53. PAGED_CODE();
  54. return PiPagePathSetState(FileObject, FALSE);
  55. }
  56. NTSTATUS
  57. PiPagePathSetState(
  58. IN PFILE_OBJECT FileObject,
  59. IN BOOLEAN InPath
  60. )
  61. /*++
  62. Routine Description:
  63. This routine notifies driver stacks when a paging file is shut down on their
  64. device, or if a paging file is being started up on their device. If a paging
  65. file is being started up, this request is also a query as the stack may not
  66. be able to support a pagefile.
  67. Arguments:
  68. FileObject - File object for the paging file itself.
  69. InPath - Whether the page file is being started or shut down.
  70. Return Value:
  71. NTSTATUS.
  72. --*/
  73. {
  74. PIRP irp;
  75. NTSTATUS status;
  76. PDEVICE_OBJECT deviceObject;
  77. KEVENT event;
  78. PIO_STACK_LOCATION irpSp;
  79. IO_STATUS_BLOCK localIoStatus;
  80. PAGED_CODE();
  81. //
  82. // Reference the file object here so that no special checks need be made
  83. // in I/O completion to determine whether or not to dereference the file
  84. // object.
  85. //
  86. ObReferenceObject(FileObject);
  87. //
  88. // Initialize the local event.
  89. //
  90. KeInitializeEvent(&event, NotificationEvent, FALSE);
  91. //
  92. // Get the address of the target device object.
  93. //
  94. deviceObject = IoGetRelatedDeviceObject(FileObject);
  95. //
  96. // Allocate and initialize the irp for this operation.
  97. //
  98. irp = IoAllocateIrp(deviceObject->StackSize, FALSE);
  99. if (irp == NULL) {
  100. //
  101. // Don't dereference the file object, our caller will take care of that.
  102. //
  103. return STATUS_NO_MEMORY;
  104. }
  105. irp->Tail.Overlay.OriginalFileObject = FileObject;
  106. irp->Tail.Overlay.Thread = PsGetCurrentThread();
  107. irp->RequestorMode = KernelMode;
  108. //
  109. // Fill in the service independent parameters in the IRP.
  110. //
  111. irp->UserEvent = &event;
  112. irp->Flags = IRP_SYNCHRONOUS_API;
  113. irp->UserIosb = &localIoStatus;
  114. irp->Overlay.AsynchronousParameters.UserApcRoutine = (PIO_APC_ROUTINE) NULL;
  115. //
  116. // Get a pointer to the stack location for the first driver. This will be
  117. // used to pass the original function codes and parameters.
  118. //
  119. irpSp = IoGetNextIrpStackLocation(irp);
  120. irpSp->MajorFunction = IRP_MJ_PNP;
  121. irpSp->MinorFunction = IRP_MN_DEVICE_USAGE_NOTIFICATION;
  122. irpSp->FileObject = FileObject;
  123. irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
  124. irp->AssociatedIrp.SystemBuffer = NULL;
  125. // irp->Flags = 0;
  126. irpSp->Parameters.UsageNotification.InPath = InPath;
  127. irpSp->Parameters.UsageNotification.Type = DeviceUsageTypePaging;
  128. //
  129. // Insert the packet at the head of the IRP list for the thread.
  130. //
  131. IoQueueThreadIrp(irp);
  132. //
  133. // Acquire the engine lock to ensure no rebalances, removes, or power
  134. // operations are in progress during this notification.
  135. //
  136. PpDevNodeLockTree(PPL_TREEOP_ALLOW_READS);
  137. //
  138. // Now simply invoke the driver at its dispatch entry with the IRP.
  139. //
  140. status = IoCallDriver(deviceObject, irp);
  141. //
  142. // Wait for the local event and copy the final status information
  143. // back to the caller.
  144. //
  145. if (status == STATUS_PENDING) {
  146. (VOID) KeWaitForSingleObject(&event,
  147. Executive,
  148. KernelMode,
  149. FALSE,
  150. NULL);
  151. status = localIoStatus.Status;
  152. }
  153. //
  154. // Unlock the tree.
  155. //
  156. PpDevNodeUnlockTree(PPL_TREEOP_ALLOW_READS);
  157. return status;
  158. }