Windows NT 4.0 source code leak
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.

298 lines
7.8 KiB

4 years ago
  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. dispatch.c
  5. Abstract:
  6. This module contains code for opening a handle to AFD.
  7. Author:
  8. David Treadwell (davidtr) 21-Feb-1992
  9. Revision History:
  10. --*/
  11. #include "afdp.h"
  12. #ifdef ALLOC_PRAGMA
  13. #pragma alloc_text( PAGE, AfdCreate )
  14. #endif
  15. extern PSECURITY_DESCRIPTOR AfdRawSecurityDescriptor;
  16. NTSTATUS
  17. AfdCreate (
  18. IN PIRP Irp,
  19. IN PIO_STACK_LOCATION IrpSp
  20. )
  21. /*++
  22. Routine Description:
  23. This is the routine that handles Create IRPs in AFD. If creates an
  24. AFD_ENDPOINT structure and fills it in with the information
  25. specified in the open packet.
  26. Arguments:
  27. Irp - Pointer to I/O request packet.
  28. IrpSp - pointer to the IO stack location to use for this request.
  29. Return Value:
  30. NTSTATUS -- Indicates whether the request was successfully queued.
  31. --*/
  32. {
  33. PAFD_OPEN_PACKET openPacket;
  34. PAFD_ENDPOINT endpoint;
  35. PFILE_FULL_EA_INFORMATION eaBuffer;
  36. UNICODE_STRING transportDeviceName;
  37. NTSTATUS status;
  38. PAGED_CODE( );
  39. DEBUG endpoint = NULL;
  40. //
  41. // Find the open packet from the EA buffer in the system buffer of
  42. // the associated IRP. Fail the request if there was no EA
  43. // buffer specified.
  44. //
  45. eaBuffer = Irp->AssociatedIrp.SystemBuffer;
  46. if ( eaBuffer == NULL ) {
  47. //
  48. // Allocate an AFD "helper" endpoint.
  49. //
  50. status = AfdAllocateEndpoint(
  51. &endpoint,
  52. NULL,
  53. 0
  54. );
  55. if( !NT_SUCCESS(status) ) {
  56. return status;
  57. }
  58. } else {
  59. openPacket = (PAFD_OPEN_PACKET)(eaBuffer->EaName +
  60. eaBuffer->EaNameLength + 1);
  61. //
  62. // Validate parameters in the open packet.
  63. //
  64. if ( openPacket->EndpointType < MIN_AFD_ENDPOINT_TYPE ||
  65. openPacket->EndpointType > MAX_AFD_ENDPOINT_TYPE ) {
  66. return STATUS_INVALID_PARAMETER;
  67. }
  68. //
  69. // Make sure that the transport address fits within the specified
  70. // EA buffer.
  71. //
  72. if ( eaBuffer->EaValueLength <
  73. sizeof(AFD_OPEN_PACKET) + openPacket->TransportDeviceNameLength ) {
  74. return STATUS_ACCESS_VIOLATION;
  75. }
  76. //
  77. // Set up a string that describes the transport device name.
  78. //
  79. transportDeviceName.Buffer = openPacket->TransportDeviceName;
  80. transportDeviceName.Length = (USHORT)openPacket->TransportDeviceNameLength;
  81. transportDeviceName.MaximumLength =
  82. transportDeviceName.Length + sizeof(WCHAR);
  83. //
  84. // If this is an open of a raw endpoint, perform an access check.
  85. //
  86. if ( ( openPacket->EndpointType == AfdEndpointTypeRaw ) &&
  87. !AfdDisableRawSecurity
  88. )
  89. {
  90. BOOLEAN accessGranted;
  91. PACCESS_STATE accessState;
  92. PIO_SECURITY_CONTEXT securityContext;
  93. NTSTATUS status;
  94. PPRIVILEGE_SET privileges = NULL;
  95. ACCESS_MASK grantedAccess;
  96. securityContext = IrpSp->Parameters.Create.SecurityContext;
  97. accessState = securityContext->AccessState;
  98. SeLockSubjectContext(&accessState->SubjectSecurityContext);
  99. accessGranted = SeAccessCheck(
  100. AfdRawSecurityDescriptor,
  101. &accessState->SubjectSecurityContext,
  102. TRUE,
  103. IrpSp->Parameters.Create.SecurityContext->DesiredAccess,
  104. 0,
  105. &privileges,
  106. IoGetFileObjectGenericMapping(),
  107. UserMode,
  108. &grantedAccess,
  109. &status
  110. );
  111. if (privileges) {
  112. (VOID) SeAppendPrivileges(
  113. accessState,
  114. privileges
  115. );
  116. SeFreePrivileges(privileges);
  117. }
  118. if (accessGranted) {
  119. accessState->PreviouslyGrantedAccess |= grantedAccess;
  120. accessState->RemainingDesiredAccess &= ~( grantedAccess | MAXIMUM_ALLOWED );
  121. }
  122. SeUnlockSubjectContext(&accessState->SubjectSecurityContext);
  123. if (!accessGranted) {
  124. return STATUS_ACCESS_DENIED;
  125. }
  126. }
  127. //
  128. // Allocate an AFD endpoint.
  129. //
  130. status = AfdAllocateEndpoint(
  131. &endpoint,
  132. &transportDeviceName,
  133. openPacket->GroupID
  134. );
  135. if( !NT_SUCCESS(status) ) {
  136. return status;
  137. }
  138. }
  139. ASSERT( endpoint != NULL );
  140. //
  141. // Set up a pointer to the endpoint in the file object so that we
  142. // can find the endpoint in future calls.
  143. //
  144. IrpSp->FileObject->FsContext = endpoint;
  145. IF_DEBUG(OPEN_CLOSE) {
  146. KdPrint(( "AfdCreate: opened file object = %lx, endpoint = %lx\n",
  147. IrpSp->FileObject, endpoint ));
  148. }
  149. //
  150. // Remember the type of endpoint that this is. If this is a datagram
  151. // endpoint, change the block type to reflect this.
  152. //
  153. if ( eaBuffer != NULL ) {
  154. if (openPacket->EndpointType == AfdEndpointTypeRaw) {
  155. //
  156. // There is no other distinction between a raw endpoint and
  157. // a datagram endpoint, so we mark them all as datagram.
  158. //
  159. endpoint->EndpointType = AfdEndpointTypeDatagram;
  160. }
  161. else {
  162. endpoint->EndpointType = openPacket->EndpointType;
  163. }
  164. }
  165. if ( IS_DGRAM_ENDPOINT(endpoint) ) {
  166. if ( eaBuffer == NULL ) {
  167. DEREFERENCE_ENDPOINT( endpoint );
  168. AfdCloseEndpoint( endpoint );
  169. return STATUS_INVALID_PARAMETER;
  170. }
  171. endpoint->Type = AfdBlockTypeDatagram;
  172. //
  173. // Initialize lists which exist only in datagram endpoints.
  174. //
  175. InitializeListHead( &endpoint->ReceiveDatagramIrpListHead );
  176. InitializeListHead( &endpoint->PeekDatagramIrpListHead );
  177. InitializeListHead( &endpoint->ReceiveDatagramBufferListHead );
  178. //
  179. // Charge quota for the endpoint to account for the data
  180. // bufferring we'll do on behalf of the process.
  181. //
  182. try {
  183. PsChargePoolQuota(
  184. endpoint->OwningProcess,
  185. NonPagedPool,
  186. AfdReceiveWindowSize + AfdSendWindowSize
  187. );
  188. AfdRecordQuotaHistory(
  189. endpoint->OwningProcess,
  190. (LONG)(AfdReceiveWindowSize + AfdSendWindowSize),
  191. "Create dgram",
  192. endpoint
  193. );
  194. AfdRecordPoolQuotaCharged(
  195. AfdReceiveWindowSize + AfdSendWindowSize
  196. );
  197. } except ( EXCEPTION_EXECUTE_HANDLER ) {
  198. #if DBG
  199. DbgPrint( "AfdCreate: PsChargePoolQuota failed.\n" );
  200. #endif
  201. DEREFERENCE_ENDPOINT( endpoint );
  202. AfdCloseEndpoint( endpoint );
  203. return STATUS_QUOTA_EXCEEDED;
  204. }
  205. endpoint->Common.Datagram.MaxBufferredReceiveBytes = AfdReceiveWindowSize;
  206. endpoint->Common.Datagram.MaxBufferredReceiveCount =
  207. (CSHORT)(AfdReceiveWindowSize / AfdBufferMultiplier);
  208. endpoint->Common.Datagram.MaxBufferredSendBytes = AfdSendWindowSize;
  209. endpoint->Common.Datagram.MaxBufferredSendCount =
  210. (CSHORT)(AfdSendWindowSize / AfdBufferMultiplier);
  211. }
  212. //
  213. // The open worked. Dereference the endpoint and return success.
  214. //
  215. DEREFERENCE_ENDPOINT( endpoint );
  216. return STATUS_SUCCESS;
  217. } // AfdCreate