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.

301 lines
11 KiB

  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name:
  4. NtRxDef.h
  5. Abstract:
  6. This module defines a whole host of macros that orient the code towards NT
  7. as opposed to Win9x.
  8. Author:
  9. Joe Linn [JoeLinn] 19-aug-1994
  10. Revision History:
  11. Jim McNelis [jimmcn] 14-mar-1995 added OAL defines.
  12. Sethu [SethuR] 15-mar-1995 include OAL defines for RX_DATA_BUFFER (aka MDL )
  13. --*/
  14. #ifndef _RX_NTDEFS_DEFINED_
  15. #define _RX_NTDEFS_DEFINED_
  16. #define INLINE __inline
  17. //
  18. // from winbase.h:
  19. //
  20. #ifndef INVALID_HANDLE_VALUE
  21. #define INVALID_HANDLE_VALUE ((HANDLE)-1)
  22. #endif // ifndef INVALID_HANDLE_VALUE
  23. #define RxDeviceType(__xxx) ((DEVICE_TYPE)FILE_DEVICE_##__xxx)
  24. //
  25. // this macro is used in various places to assist in defining sets of constants
  26. // that can be used to set/clear/test specific bits in a flags-type field
  27. //
  28. #define RX_DEFINE_FLAG(a,c,d) a = ((1<<c)&d),
  29. //
  30. // we need this constant various places
  31. //
  32. #define TICKS_PER_SECOND (10 * 1000 * 1000)
  33. #define TICKS_PER_MILLESECOND (10 * 1000)
  34. int
  35. RxSprintf (
  36. char *,
  37. const char *,
  38. ...
  39. );
  40. #ifndef WRAPPER_CALLS_ONLY
  41. #define RxSprintf sprintf
  42. #endif // ifndef WRAPPER_CALLS_ONLY
  43. //
  44. // the next set of macros defines how to get things out of the RxContext; however, RxContext is not
  45. // a macro parameter; rather, the appropriate pointers are just captured from whatever RxContext happens
  46. // to be around. Q: "why would you use RxCaptureFcb and then reference thru capFcb instead of just having
  47. // a macro like RxGetFcb() === RxContext->Fcb?" A: it is done this way to help with optimization. when you make
  48. // the RxGetFcb() call, the Fcb will have to be reloaded from the RxContext if you have called any procs; however,
  49. // it will not have to be reloaded with the capture technique.
  50. //
  51. #ifndef MINIRDR__NAME
  52. #define RxCaptureFcb PFCB __C_Fcb = (PFCB)(RxContext->pFcb)
  53. #define RxCaptureFobx PFOBX __C_Fobx = (PFOBX)(RxContext->pFobx)
  54. #else
  55. #define RxCaptureFcb PMRX_FCB __C_Fcb = (RxContext->pFcb)
  56. #define RxCaptureFobx PMRX_FOBX __C_Fobx = (RxContext->pFobx)
  57. #endif
  58. #define RxCaptureRequestPacket PIRP __C_Irp = RxContext->CurrentIrp
  59. #define RxCaptureParamBlock PIO_STACK_LOCATION __C_IrpSp = RxContext->CurrentIrpSp
  60. #define RxCaptureFileObject PFILE_OBJECT __C_FileObject = __C_IrpSp-> FileObject
  61. //
  62. // the "cap" prefix means "Captured from the RxContext....."; it's ok after you get used to it
  63. //
  64. #define capFcb __C_Fcb
  65. #define capFobx __C_Fobx
  66. #define capPARAMS __C_IrpSp
  67. #define capReqPacket __C_Irp
  68. #define capFileObject __C_FileObject
  69. //
  70. // The following routines are used for pool allocation. On a checked build
  71. // additional information, we add in callsite information and go to a set of
  72. // routines that over perform various kinds of checking and guarding. On a free
  73. // build we forego this luxury and go straight for the allocation.
  74. //
  75. #ifdef RX_POOL_WRAPPER
  76. //
  77. // These routines do various debug checks on the pool and the block
  78. // being freed.
  79. //
  80. extern VOID *_RxAllocatePoolWithTag( ULONG PoolType, ULONG NumberOfBytes, ULONG Tag, PSZ File, ULONG line );
  81. extern VOID _RxFreePool( PVOID PoolBlock, PSZ File, ULONG line );
  82. extern BOOLEAN _RxCheckMemoryBlock( PVOID PoolBlock, PSZ File, ULONG line );
  83. #define RxAllocatePoolWithTag( type, size, tag ) \
  84. _RxAllocatePoolWithTag( type, size, tag, __FILE__, __LINE__ )
  85. #define RxFreePool( ptr ) \
  86. _RxFreePool( ptr, __FILE__, __LINE__ )
  87. #define RxCheckMemoryBlock( ptr ) \
  88. _RxCheckMemoryBlock( ptr, __FILE__, __LINE__ )
  89. #else // NOT RX_POOL_WRAPPER
  90. //
  91. // For retail builds, we want to go right to the regular (de)allocator
  92. //
  93. // extern VOID *RxAllocatePool( ULONG PoolType, ULONG NumberOfBytes );
  94. extern VOID *RxAllocatePoolWithTag( ULONG PoolType, ULONG NumberOfBytes, ULONG Tag );
  95. extern VOID RxFreePool( PVOID PoolBlock );
  96. // extern BOOLEAN RxCheckMemoryBlock( PVOID PoolBlock, PSZ File, ULONG line );
  97. #define RxCheckMemoryBlock( ptr ) {NOTHING;}
  98. #endif // RX_POOL_WRAPPER
  99. #define RxAllocatePool( type, size ) \
  100. RxAllocatePoolWithTag( type, size, '??xR' )
  101. #if !DBG
  102. #ifndef WRAPPER_CALLS_ONLY
  103. #ifndef RX_POOL_WRAPPER
  104. #define RxAllocatePoolWithTag ExAllocatePoolWithTag
  105. #define RxFreePool ExFreePool
  106. #endif // RX_POOL_WRAPPER
  107. #endif // WRAPPER_CALLS_ONLY
  108. #endif
  109. extern
  110. NTSTATUS
  111. RxDuplicateString(
  112. PUNICODE_STRING *Copy,
  113. PUNICODE_STRING Original,
  114. POOL_TYPE PoolType
  115. );
  116. #define RxIsResourceOwnershipStateExclusive(__r) (FlagOn((__r)->Flag, ResourceOwnedExclusive))
  117. #define RxProtectMdlFromFree( Mdl ) {NOTHING;}
  118. #define RxUnprotectMdlFromFree( Mdl ) {NOTHING;}
  119. #define RxMdlIsProtected( Mdl ) (FALSE)
  120. #define RxTakeOwnershipOfMdl( Mdl ) {NOTHING;}
  121. #define RxDisownMdl( Mdl ) {NOTHING;}
  122. #define RxMdlIsOwned( Mdl ) (TRUE)
  123. #define RxAllocateMdl( Buffer, BufferSize ) \
  124. IoAllocateMdl( Buffer, BufferSize, FALSE, FALSE, NULL )
  125. #define RxMdlIsLocked( Mdl ) ((Mdl)->MdlFlags & MDL_PAGES_LOCKED)
  126. #define RxMdlSourceIsNonPaged( Mdl ) ((Mdl)->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL)
  127. #define RxMdlIsPartial( Mdl ) ((Mdl)->MdlFlags & MDL_PARTIAL)
  128. #undef RxProbeAndLockPages
  129. #define RxProbeAndLockPages( Mdl, Mode, Access, Status ) \
  130. Status = STATUS_SUCCESS; \
  131. try { \
  132. MmProbeAndLockPages((Mdl), (Mode), (Access)); \
  133. } except (EXCEPTION_EXECUTE_HANDLER) { \
  134. Status = GetExceptionCode(); \
  135. }
  136. //
  137. // Macros for dealing with network header MDLs
  138. //
  139. //
  140. // This is the amount of space we preallocate in front of the smb header to hold
  141. // transport headers. This number came from the server. I suspect it is a worse case
  142. // value for all the transports that support MDL_NETWORK_HEADER
  143. //
  144. #define TRANSPORT_HEADER_SIZE 64 // IPX_HEADER_SIZE+MAC_HEADER_SIZE
  145. //
  146. // Mdls that are marked with the MDL_NETWORK_HEADER flag have extra space allocated before
  147. // the current start address that can be used for prepending lower-level headers. The idea
  148. // is that when we want to prepend another header, we take the current mdl and adjust it to
  149. // include this extra header at the front of the message. This is not strictly kosher and relies
  150. // on the behavior that the page the current header is on, and the page that the prepended header
  151. // is on, is the same page. The way the macros work is that if they are not on the same page,
  152. // we don't set the NETWORK_HEADER flag, and the transport will use a second Mdl for the header.
  153. //
  154. // Note that the other wierd thing about this is that we don't use the true buffer sizes. The
  155. // buffer address is really offset TRANSPORT_HEADER_SIZE into the buffer. The buffer size passed
  156. // in the buffer size without the TRANSPORT_HEADER_SIZE included. Thus if the addition of the
  157. // TRANSPORT_HEADER_SIZE would cause the Mdl to span an additonal page, this optimization won't
  158. // work.
  159. //
  160. #define RxInitializeHeaderMdl( Mdl, Va, Len ) { \
  161. MmInitializeMdl( Mdl, Va, Len ); \
  162. if (Mdl->ByteOffset >= TRANSPORT_HEADER_SIZE) { \
  163. Mdl->MdlFlags |= MDL_NETWORK_HEADER; \
  164. } \
  165. }
  166. #define RxAllocateHeaderMdl( Buffer, BufferSize, Mdl ) { \
  167. Mdl = RxAllocateMdl( Buffer, BufferSize ); \
  168. if ((Mdl) && (Mdl->ByteOffset >= TRANSPORT_HEADER_SIZE) ) { \
  169. SetFlag( Mdl->MdlFlags, MDL_NETWORK_HEADER ); \
  170. } \
  171. }
  172. #define RxMdlIsHeader( Mdl ) (FlagOn( Mdl )->MdlFlags, MDL_NETWORK_HEADER)
  173. #define RxBuildPartialHeaderMdl( SourceMdl, TargetMdl, Va, Len ) { \
  174. IoBuildPartialMdl( SourceMdl, TargetMdl, Va, Len ); \
  175. if (FlagOn(SourceMdl->MdlFlags, MDL_NETWORK_HEADER ) && \
  176. (TargetMdl->ByteOffset >= TRANSPORT_HEADER_SIZE)) { \
  177. SetFlag( TargetMdl->MdlFlags, MDL_NETWORK_HEADER ); \
  178. } \
  179. }
  180. #define RxBuildHeaderMdlForNonPagedPool( Mdl) MmBuildMdlForNonPagedPool( Mdl )
  181. #define RxProbeAndLockHeaderPages( Mdl, Mode, Access, Status ) \
  182. RxProbeAndLockPages( Mdl, Mode, Access, Status )
  183. #define RxUnlockHeaderPages( Mdl ) MmUnlockPages( Mdl )
  184. //
  185. // the next set of macros defines the prototype and the argument list for the toplevel (Common)
  186. // routines. these routines are just below the dispatch level and this is where the commonality
  187. // between win9x and NT begins. In addition, the IN PRX_CONTEXT RxContext and accompanying capture macros
  188. // could be platform specific as well. We must pass at least the RxContext; but on a RISC machine with
  189. // lots of registers we could pass a lot more. An adjustment would have to be made in the
  190. // RxFsdCommonDispatch in this case since the parameters are not yet captured at that point.
  191. //
  192. //
  193. // the reason why to say "RXSTATUS RxCommonRead (IN PRX_CONTEXT RxContext)" instead
  194. // of "RxCommon(Read)" is so that the standard tags programs will work. "RxCommon(Read):
  195. // doesn't look like a procedure definition
  196. //
  197. #define RXCOMMON_SIGNATURE \
  198. PRX_CONTEXT RxContext
  199. #define RXCOMMON_ARGUMENTS \
  200. RxContext
  201. #define RxGetRequestorProcess( RXCONTEXT ) IoGetRequestorProcess( RXCONTEXT->CurrentIrp )
  202. //
  203. // RxGetRequestorProcess() returns what IoGetRequestorProcess() returns, which
  204. // is a pointer to a process structure. Truncating this to 32 bits does
  205. // not yield a value that is unique to the process.
  206. //
  207. // When a 32 bit value that is unique to the process is desired,
  208. // RxGetRequestorProcessId() must be used instead.
  209. //
  210. #define RxGetRequestorProcessId( RXCONTEXT ) IoGetRequestorProcessId( (RXCONTEXT)->CurrentIrp )
  211. #define RxMarkContextPending( RXCONTEXT ) IoMarkIrpPending( (RXCONTEXT)->CurrentIrp )
  212. #define RxSetCancelRoutine( Irp, CancelRoutine ) IoSetCancelRoutine( Irp, CancelRoutine );
  213. //
  214. // we do this as a macro because we may want to record that we did this adjustment so that
  215. // people who QFI for standardinfo will be forced to the net to get the right answer and that would
  216. // probably be better as a routine
  217. //
  218. #define RxAdjustAllocationSizeforCC( FCB ) {\
  219. if ((FCB)->Header.FileSize.QuadPart > (FCB)->Header.AllocationSize.QuadPart) { \
  220. PMRX_NET_ROOT NetRoot = (FCB)->pNetRoot; \
  221. ULONGLONG ClusterSize = NetRoot->DiskParameters.ClusterSize; \
  222. ULONGLONG FileSize = (FCB)->Header.FileSize.QuadPart; \
  223. ASSERT(ClusterSize!=0); \
  224. (FCB)->Header.AllocationSize.QuadPart = (FileSize+ClusterSize)&~(ClusterSize-1); \
  225. } \
  226. ASSERT ( (FCB)->Header.ValidDataLength.QuadPart <= (FCB)->Header.FileSize.QuadPart ); \
  227. }
  228. #endif // _RX_NTDEFS_DEFINED_