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.

274 lines
6.7 KiB

  1. /*++
  2. Copyright (c) 1998-2001 Microsoft Corporation
  3. Module Name:
  4. create.cxx
  5. Abstract:
  6. This module contains code for opening a handle to UL.
  7. Author:
  8. Keith Moore (keithmo) 10-Jun-1998
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. #ifdef ALLOC_PRAGMA
  13. #pragma alloc_text( PAGE, UlCreate )
  14. #endif // ALLOC_PRAGMA
  15. //
  16. // Public functions.
  17. //
  18. /***************************************************************************++
  19. Routine Description:
  20. This is the routine that handles Create IRPs in UL. Create IRPs are
  21. issued when the file object is created.
  22. Arguments:
  23. pDeviceObject - Supplies a pointer to the target device object.
  24. pIrp - Supplies a pointer to IO request packet.
  25. Return Value:
  26. NTSTATUS - Completion status.
  27. --***************************************************************************/
  28. NTSTATUS
  29. UlCreate(
  30. IN PDEVICE_OBJECT pDeviceObject,
  31. IN PIRP pIrp
  32. )
  33. {
  34. NTSTATUS status;
  35. PIO_STACK_LOCATION pIrpSp;
  36. PFILE_OBJECT pFileObject;
  37. PFILE_FULL_EA_INFORMATION pEaBuffer;
  38. PHTTP_OPEN_PACKET pOpenPacket;
  39. UCHAR createDisposition;
  40. PWSTR pName;
  41. ULONG nameLength;
  42. PIO_SECURITY_CONTEXT pSecurityContext;
  43. //
  44. // Sanity check.
  45. //
  46. PAGED_CODE();
  47. UL_ENTER_DRIVER( "UlCreate", pIrp );
  48. //
  49. // Find and validate the open packet.
  50. //
  51. pEaBuffer = (PFILE_FULL_EA_INFORMATION)(pIrp->AssociatedIrp.SystemBuffer);
  52. if (pEaBuffer == NULL ||
  53. pEaBuffer->EaValueLength != sizeof(*pOpenPacket) ||
  54. pEaBuffer->EaNameLength != HTTP_OPEN_PACKET_NAME_LENGTH ||
  55. strcmp( pEaBuffer->EaName, HTTP_OPEN_PACKET_NAME ) )
  56. {
  57. status = STATUS_REVISION_MISMATCH;
  58. goto complete;
  59. }
  60. pOpenPacket =
  61. (PHTTP_OPEN_PACKET)( pEaBuffer->EaName + pEaBuffer->EaNameLength + 1 );
  62. ASSERT( (((ULONG_PTR)pOpenPacket) & 7) == 0 );
  63. //
  64. // For now, we'll fail if the incoming version doesn't EXACTLY match
  65. // the expected version. In future, we may need to be a bit more
  66. // flexible to allow down-level clients.
  67. //
  68. if (pOpenPacket->MajorVersion != HTTP_INTERFACE_VERSION_MAJOR ||
  69. pOpenPacket->MinorVersion != HTTP_INTERFACE_VERSION_MINOR)
  70. {
  71. status = STATUS_REVISION_MISMATCH;
  72. goto complete;
  73. }
  74. //
  75. // Snag the current IRP stack pointer, then extract the creation
  76. // disposition. IO stores this as the high byte of the Options field.
  77. // Also snag the file object; we'll need it often.
  78. //
  79. pIrpSp = IoGetCurrentIrpStackLocation( pIrp );
  80. createDisposition = (UCHAR)( pIrpSp->Parameters.Create.Options >> 24 );
  81. pFileObject = pIrpSp->FileObject;
  82. pSecurityContext = pIrpSp->Parameters.Create.SecurityContext;
  83. ASSERT( pSecurityContext != NULL );
  84. //
  85. // Determine if this is a request to open a control channel or
  86. // open/create an app pool.
  87. //
  88. if (pDeviceObject == g_pUlControlDeviceObject)
  89. {
  90. //
  91. // It's a control channel.
  92. //
  93. // Validate the creation disposition. We allow open only.
  94. //
  95. if (createDisposition != FILE_OPEN)
  96. {
  97. status = STATUS_INVALID_PARAMETER;
  98. goto complete;
  99. }
  100. //
  101. // Open the control channel.
  102. //
  103. status = UlOpenControlChannel(GET_PP_CONTROL_CHANNEL(pFileObject));
  104. if (NT_SUCCESS(status))
  105. {
  106. ASSERT( GET_CONTROL_CHANNEL(pFileObject) != NULL );
  107. MARK_VALID_CONTROL_CHANNEL( pFileObject );
  108. }
  109. }
  110. else if (pDeviceObject == g_pUlFilterDeviceObject)
  111. {
  112. //
  113. // It's a filter channel.
  114. //
  115. // Validate the creation disposition. We allow create and open
  116. //
  117. if (createDisposition != FILE_CREATE && createDisposition != FILE_OPEN)
  118. {
  119. status = STATUS_INVALID_PARAMETER;
  120. goto complete;
  121. }
  122. //
  123. // Make sure there's a name with a reasonable length
  124. //
  125. if (pFileObject->FileName.Buffer == NULL ||
  126. pFileObject->FileName.Length < sizeof(WCHAR) ||
  127. pFileObject->FileName.Length > UL_MAX_FILTER_NAME_LENGTH)
  128. {
  129. status = STATUS_OBJECT_NAME_INVALID;
  130. goto complete;
  131. }
  132. //
  133. // Bind to the specified filter channel.
  134. //
  135. pName = pFileObject->FileName.Buffer + 1;
  136. nameLength = pFileObject->FileName.Length - sizeof(WCHAR);
  137. status = UlAttachFilterProcess(
  138. pName,
  139. nameLength,
  140. (BOOLEAN)(createDisposition == FILE_CREATE),
  141. pSecurityContext->AccessState,
  142. pSecurityContext->DesiredAccess,
  143. pIrp->RequestorMode,
  144. GET_PP_FILTER_PROCESS(pFileObject)
  145. );
  146. if (NT_SUCCESS(status))
  147. {
  148. ASSERT( GET_FILTER_PROCESS(pFileObject) != NULL );
  149. MARK_VALID_FILTER_CHANNEL( pFileObject );
  150. }
  151. }
  152. else
  153. {
  154. ASSERT( pDeviceObject == g_pUlAppPoolDeviceObject );
  155. //
  156. // It's an app pool.
  157. //
  158. // Validate the creation disposition. We allow create and open.
  159. //
  160. if (createDisposition != FILE_CREATE && createDisposition != FILE_OPEN)
  161. {
  162. status = STATUS_INVALID_PARAMETER;
  163. goto complete;
  164. }
  165. //
  166. // Bind to the specified app pool.
  167. //
  168. if (pFileObject->FileName.Buffer == NULL ||
  169. pFileObject->FileName.Length < sizeof(WCHAR))
  170. {
  171. pName = NULL;
  172. nameLength = 0;
  173. }
  174. else
  175. {
  176. pName = pFileObject->FileName.Buffer + 1;
  177. nameLength = pFileObject->FileName.Length - sizeof(WCHAR);
  178. }
  179. status = UlAttachProcessToAppPool(
  180. pName,
  181. nameLength,
  182. (BOOLEAN)(createDisposition == FILE_CREATE),
  183. pSecurityContext->AccessState,
  184. pSecurityContext->DesiredAccess,
  185. pIrp->RequestorMode,
  186. GET_PP_APP_POOL_PROCESS(pFileObject)
  187. );
  188. if (NT_SUCCESS(status))
  189. {
  190. ASSERT( GET_APP_POOL_PROCESS(pFileObject) != NULL );
  191. MARK_VALID_APP_POOL( pFileObject );
  192. }
  193. }
  194. //
  195. // Complete the request.
  196. //
  197. complete:
  198. if (NT_SUCCESS(status))
  199. {
  200. IF_DEBUG( OPEN_CLOSE )
  201. {
  202. KdPrint((
  203. "UlCreate: opened file object = %lx\n",
  204. pFileObject
  205. ));
  206. }
  207. }
  208. pIrp->IoStatus.Status = status;
  209. UlCompleteRequest( pIrp, g_UlPriorityBoost );
  210. UL_LEAVE_DRIVER( "UlCreate" );
  211. RETURN(status);
  212. } // UlCreate