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.

307 lines
7.0 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. smbnotfy.c
  5. Abstract:
  6. This module contains routine for processing the following SMBs:
  7. NT Notify Change.
  8. Author:
  9. Manny Weiser (mannyw) 29-Oct-1991
  10. Revision History:
  11. --*/
  12. #include "precomp.h"
  13. #include "smbnotfy.tmh"
  14. #pragma hdrstop
  15. //
  16. // Forward declarations
  17. //
  18. VOID SRVFASTCALL
  19. RestartNtNotifyChange (
  20. PWORK_CONTEXT WorkContext
  21. );
  22. #ifdef ALLOC_PRAGMA
  23. #pragma alloc_text( PAGE, SrvSmbNtNotifyChange )
  24. #pragma alloc_text( PAGE, RestartNtNotifyChange )
  25. #pragma alloc_text( PAGE, SrvSmbFindNotify )
  26. #pragma alloc_text( PAGE, SrvSmbFindNotifyClose )
  27. #endif
  28. SMB_TRANS_STATUS
  29. SrvSmbNtNotifyChange (
  30. IN OUT PWORK_CONTEXT WorkContext
  31. )
  32. /*++
  33. Routine Description:
  34. Processes an NT notify change SMB. This request arrives in an
  35. NT Transaction SMB.
  36. Arguments:
  37. WorkContext - Supplies the address of a Work Context Block
  38. describing the current request. See smbtypes.h for a more
  39. complete description of the valid fields.
  40. Return Value:
  41. BOOLEAN - Indicates whether an error occurred. See smbtypes.h for a
  42. more complete description.
  43. --*/
  44. {
  45. PREQ_NOTIFY_CHANGE request;
  46. NTSTATUS status;
  47. PTRANSACTION transaction;
  48. PRFCB rfcb;
  49. USHORT fid;
  50. PAGED_CODE( );
  51. transaction = WorkContext->Parameters.Transaction;
  52. request = (PREQ_NOTIFY_CHANGE)transaction->InSetup;
  53. if( transaction->SetupCount * sizeof( USHORT ) < sizeof( REQ_NOTIFY_CHANGE ) ) {
  54. SrvSetSmbError( WorkContext, STATUS_INVALID_PARAMETER );
  55. return SmbTransStatusErrorWithoutData;
  56. }
  57. fid = SmbGetUshort( &request->Fid );
  58. //
  59. // Verify the FID. If verified, the RFCB block is referenced
  60. // and its addresses is stored in the WorkContext block, and the
  61. // RFCB address is returned.
  62. //
  63. rfcb = SrvVerifyFid(
  64. WorkContext,
  65. fid,
  66. TRUE,
  67. NULL, // don't serialize with raw write
  68. &status
  69. );
  70. if ( rfcb == SRV_INVALID_RFCB_POINTER ) {
  71. //
  72. // Invalid file ID or write behind error. Reject the request.
  73. //
  74. IF_DEBUG(ERRORS) {
  75. KdPrint((
  76. "SrvSmbNtIoctl: Status %X on FID: 0x%lx\n",
  77. status,
  78. fid
  79. ));
  80. }
  81. SrvSetSmbError( WorkContext, status );
  82. return SmbTransStatusErrorWithoutData;
  83. }
  84. CHECK_FUNCTION_ACCESS(
  85. rfcb->GrantedAccess,
  86. IRP_MJ_DIRECTORY_CONTROL,
  87. IRP_MN_NOTIFY_CHANGE_DIRECTORY,
  88. 0,
  89. &status
  90. );
  91. if ( !NT_SUCCESS( status ) ) {
  92. SrvStatistics.GrantedAccessErrors++;
  93. SrvSetSmbError( WorkContext, status );
  94. return SmbTransStatusErrorWithoutData;
  95. }
  96. //
  97. // Set the Restart Routine addresses in the work context block.
  98. //
  99. WorkContext->FsdRestartRoutine = SrvQueueWorkToFspAtDpcLevel;
  100. WorkContext->FspRestartRoutine = RestartNtNotifyChange;
  101. //
  102. // Build the IRP to start a the I/O control.
  103. // Pass this request to the filesystem.
  104. //
  105. SrvBuildNotifyChangeRequest(
  106. WorkContext->Irp,
  107. rfcb->Lfcb->FileObject,
  108. WorkContext,
  109. SmbGetUlong( &request->CompletionFilter ),
  110. transaction->OutParameters,
  111. transaction->MaxParameterCount,
  112. request->WatchTree
  113. );
  114. #if DBG_STUCK
  115. //
  116. // Since change notify can take an arbitrary amount of time, do
  117. // not include it in the "stuck detection & printout" code in the
  118. // scavenger
  119. //
  120. WorkContext->IsNotStuck = TRUE;
  121. #endif
  122. (VOID)IoCallDriver(
  123. IoGetRelatedDeviceObject( rfcb->Lfcb->FileObject ),
  124. WorkContext->Irp
  125. );
  126. //
  127. // The call was successfully started, return InProgress to the caller
  128. //
  129. return SmbTransStatusInProgress;
  130. }
  131. VOID SRVFASTCALL
  132. RestartNtNotifyChange (
  133. PWORK_CONTEXT WorkContext
  134. )
  135. /*++
  136. Routine Description:
  137. Completes processing of an NT Notify Change SMB.
  138. Arguments:
  139. WorkContext - Work context block for the operation.
  140. Return Value:
  141. None.
  142. --*/
  143. {
  144. NTSTATUS status;
  145. PTRANSACTION transaction;
  146. PIRP irp;
  147. ULONG length;
  148. PAGED_CODE( );
  149. //
  150. // If we built an MDL for this IRP, free it now.
  151. //
  152. irp = WorkContext->Irp;
  153. if ( irp->MdlAddress != NULL ) {
  154. MmUnlockPages( irp->MdlAddress );
  155. IoFreeMdl( irp->MdlAddress );
  156. irp->MdlAddress = NULL;
  157. }
  158. status = irp->IoStatus.Status;
  159. if ( !NT_SUCCESS( status ) ) {
  160. SrvSetSmbError( WorkContext, status );
  161. SrvCompleteExecuteTransaction(
  162. WorkContext,
  163. SmbTransStatusErrorWithoutData
  164. );
  165. return;
  166. }
  167. //
  168. // The Notify change request has completed successfully. Send the
  169. // response.
  170. //
  171. length = (ULONG)irp->IoStatus.Information;
  172. transaction = WorkContext->Parameters.Transaction;
  173. ASSERT( length <= transaction->MaxParameterCount );
  174. if ( irp->UserBuffer != NULL ) {
  175. //
  176. // The file system wanted "neither" I/O for this request. This
  177. // means that the file system will have allocated a system
  178. // buffer for the returned data. Normally this would be copied
  179. // back to our user buffer during I/O completion, but we
  180. // short-circuit I/O completion before the copy happens. So we
  181. // have to copy the data ourselves.
  182. //
  183. if ( irp->AssociatedIrp.SystemBuffer != NULL ) {
  184. ASSERT( irp->UserBuffer == transaction->OutParameters );
  185. RtlCopyMemory( irp->UserBuffer, irp->AssociatedIrp.SystemBuffer, length );
  186. }
  187. }
  188. transaction->SetupCount = 0;
  189. transaction->ParameterCount = length;
  190. transaction->DataCount = 0;
  191. //
  192. // !!! Mask a base notify bug, remove when the bug is fixed.
  193. //
  194. if ( status == STATUS_NOTIFY_CLEANUP ) {
  195. transaction->ParameterCount = 0;
  196. }
  197. SrvCompleteExecuteTransaction( WorkContext, SmbTransStatusSuccess );
  198. return;
  199. } // RestartNtNotifyChange
  200. //
  201. // Since OS/2 chose not to expose the DosFindNotifyFirst/Next/Close APIs,
  202. // OS/2 LAN Man does not officially support these SMBs. This is true,
  203. // even though the Find Notify SMB is documented as a LAN Man 2.0 SMB
  204. // there is code in both the LM2.0 server and redir to support it.
  205. //
  206. // Therefore the NT server will also not support these SMBs.
  207. //
  208. SMB_TRANS_STATUS
  209. SrvSmbFindNotify (
  210. IN OUT PWORK_CONTEXT WorkContext
  211. )
  212. {
  213. PAGED_CODE( );
  214. return SrvTransactionNotImplemented( WorkContext );
  215. }
  216. SMB_PROCESSOR_RETURN_TYPE
  217. SrvSmbFindNotifyClose (
  218. SMB_PROCESSOR_PARAMETERS
  219. )
  220. {
  221. PAGED_CODE( );
  222. return SrvSmbNotImplemented( SMB_PROCESSOR_ARGUMENTS );
  223. }