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.

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