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.

405 lines
7.5 KiB

  1. //
  2. // Template Driver
  3. // Copyright (c) Microsoft Corporation, 2000.
  4. //
  5. // Module: ResrvMap.c
  6. // Author: Daniel Mihai (DMihai)
  7. // Created: 10/18/2000
  8. //
  9. // This module contains tests for Mm APIs for reserved mapping addresses
  10. //
  11. // MmAllocateMappingAddress
  12. // MmFreeMappingAddress
  13. // MmMapLockedPagesWithReservedMapping
  14. // MmUnmapReservedMapping
  15. //
  16. // --- History ---
  17. //
  18. // 10/18/2000 (DMihai): initial version.
  19. //
  20. #include <ntddk.h>
  21. #include <wchar.h>
  22. #include "active.h"
  23. #include "tdriver.h"
  24. #include "ResrvMap.h"
  25. #if !RESRVMAP_ACTIVE
  26. //
  27. // Dummy stubs in case this module is disabled
  28. //
  29. VOID
  30. TdReservedMappingSetSize(
  31. IN PVOID Irp
  32. )
  33. {
  34. DbgPrint( "Buggy: ReservedMapping module is disabled (check \\driver\\active.h header)\n");
  35. }
  36. #else //#if !RESRVMAP_ACTIVE
  37. //
  38. // This is the real stuff
  39. //
  40. //////////////////////////////////////////////////////////
  41. //
  42. // Global data
  43. //
  44. //
  45. // Size of the current reserved mapping address
  46. //
  47. SIZE_T CrtReservedSize;
  48. //
  49. // Current reserved mapping address
  50. //
  51. PVOID CrtReservedAddress;
  52. /////////////////////////////////////////////////////////////////////
  53. //
  54. // Clean-up a possible currently reserved buffer
  55. // Called for IRP_MJ_CLEANUP
  56. //
  57. VOID
  58. TdReservedMappingCleanup(
  59. VOID
  60. )
  61. {
  62. if( NULL != CrtReservedAddress )
  63. {
  64. DbgPrint( "Buggy: TdReservedMappingCleanup: free reserved mapping address %p\n",
  65. CrtReservedAddress );
  66. MmFreeMappingAddress(
  67. CrtReservedAddress,
  68. TD_POOL_TAG );
  69. }
  70. else
  71. {
  72. ASSERT( 0 == CrtReservedSize );
  73. }
  74. }
  75. /////////////////////////////////////////////////////////////////////
  76. //
  77. // Set the current reserved size and address as asked by the user
  78. //
  79. VOID
  80. TdReservedMappingSetSize(
  81. IN PVOID Irp
  82. )
  83. {
  84. PIO_STACK_LOCATION IrpStack;
  85. ULONG InputBufferLength;
  86. SIZE_T NewReservedSize;
  87. PVOID NewReservedAddress;
  88. IrpStack = IoGetCurrentIrpStackLocation ( (PIRP)Irp);
  89. InputBufferLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
  90. if( InputBufferLength != sizeof( SIZE_T ) )
  91. {
  92. //
  93. // The user should send us the new size of the buffer
  94. //
  95. DbgPrint( "Buggy: TdReservedMappingSetSize: invalid buffer length %p\n",
  96. InputBufferLength );
  97. DbgBreakPoint();
  98. return;
  99. }
  100. //
  101. // This will be our new reserved mapping address size
  102. //
  103. NewReservedSize = *(PSIZE_T) ( (PIRP) Irp )->AssociatedIrp.SystemBuffer;
  104. if( NewReservedSize < PAGE_SIZE )
  105. {
  106. NewReservedSize = PAGE_SIZE;
  107. }
  108. else
  109. {
  110. NewReservedSize = ROUND_TO_PAGES( NewReservedSize );
  111. }
  112. //DbgPrint( "Buggy: TdReservedMappingSetSize: new reserved mapping address size %p\n",
  113. // NewReservedSize );
  114. if( 0 != NewReservedSize )
  115. {
  116. //
  117. // Try to reserve NewReservedSize bytes
  118. //
  119. NewReservedAddress = MmAllocateMappingAddress(
  120. NewReservedSize,
  121. TD_POOL_TAG );
  122. if( NULL == NewReservedAddress )
  123. {
  124. DbgPrint(
  125. "Buggy: TdReservedMappingSetSize: MmAllocateMappingAddress returned NULL, keeping old reserved address %p, size = %p\n",
  126. CrtReservedAddress,
  127. CrtReservedSize );
  128. return;
  129. }
  130. }
  131. else
  132. {
  133. //
  134. // Just release the old reserved address and set the size to 0
  135. //
  136. NewReservedAddress = NULL;
  137. }
  138. //
  139. // We have a new buffer, release the old one
  140. //
  141. TdReservedMappingCleanup();
  142. CrtReservedSize = NewReservedSize;
  143. CrtReservedAddress = NewReservedAddress;
  144. /*
  145. DbgPrint(
  146. "Buggy: TdReservedMappingSetSize: new reserved address %p, size = %p\n",
  147. CrtReservedAddress,
  148. CrtReservedSize );
  149. */
  150. }
  151. ////////////////////////////////////////////////////////////////////////
  152. //
  153. // Simulate a "read" operation in a user-supplied buffer
  154. //
  155. VOID
  156. TdReservedMappingDoRead(
  157. IN PVOID Irp
  158. )
  159. {
  160. PVOID UserBuffer;
  161. PVOID MappedAddress;
  162. PSIZE_T CrtPageAdddress;
  163. SIZE_T UserBufferSize;
  164. SIZE_T CrtPageIndex;
  165. SIZE_T CrtCycleSize;
  166. SIZE_T CrtCyclePages;
  167. PMDL Mdl;
  168. PIO_STACK_LOCATION IrpStack;
  169. ULONG InputBufferLength;
  170. PUSER_READ_BUFFER UserReadBufferStruct;
  171. BOOLEAN Locked;
  172. //
  173. // If we don't have a reserved address for mapping currently we cannot
  174. // execute the operation
  175. //
  176. if( NULL == CrtReservedAddress )
  177. {
  178. ASSERT( 0 == CrtReservedSize );
  179. DbgPrint( "Buggy: TdReservedMappingDoRead: no buffer available - rejecting request\n" );
  180. return;
  181. }
  182. //
  183. // Make a copy of the user-supplied buffer address and size
  184. //
  185. IrpStack = IoGetCurrentIrpStackLocation ( (PIRP)Irp);
  186. InputBufferLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
  187. if( InputBufferLength != sizeof( USER_READ_BUFFER ) )
  188. {
  189. //
  190. // The user should have sent us a USER_READ_BUFFER
  191. //
  192. DbgPrint( "Buggy: TdReservedMappingDoRead: invalid user buffer length %p, expected %p\n",
  193. InputBufferLength,
  194. (SIZE_T)sizeof( USER_READ_BUFFER ) );
  195. DbgBreakPoint();
  196. return;
  197. }
  198. UserReadBufferStruct = (PUSER_READ_BUFFER) ( (PIRP) Irp )->AssociatedIrp.SystemBuffer ;
  199. UserBuffer = UserReadBufferStruct->UserBuffer;
  200. UserBufferSize = UserReadBufferStruct->UserBufferSize;
  201. //
  202. // Map CrtReservedSize bytes at most
  203. //
  204. CrtPageIndex = 1;
  205. while( UserBufferSize >= PAGE_SIZE )
  206. {
  207. //DbgPrint( "Buggy: TdReservedMappingDoRead: %p bytes left to be read at adddress %p\n",
  208. // UserBufferSize,
  209. // UserBuffer );
  210. if( UserBufferSize > CrtReservedSize )
  211. {
  212. CrtCycleSize = CrtReservedSize;
  213. }
  214. else
  215. {
  216. CrtCycleSize = UserBufferSize;
  217. }
  218. //DbgPrint( "Buggy: TdReservedMappingDoRead: reading %p bytes this cycle\n",
  219. // CrtCycleSize );
  220. //
  221. // Allocate an MDL
  222. //
  223. Mdl = IoAllocateMdl(
  224. UserBuffer,
  225. (ULONG)CrtCycleSize,
  226. FALSE, // not secondary buffer
  227. FALSE, // do not charge quota
  228. NULL); // no irp
  229. if( NULL != Mdl )
  230. {
  231. //
  232. // Try to lock the pages
  233. //
  234. Locked = FALSE;
  235. try
  236. {
  237. MmProbeAndLockPages(
  238. Mdl,
  239. KernelMode,
  240. IoWriteAccess);
  241. //DbgPrint(
  242. // "Buggy: locked pages in MDL %p\n",
  243. // Mdl);
  244. Locked = TRUE;
  245. }
  246. except (EXCEPTION_EXECUTE_HANDLER)
  247. {
  248. DbgPrint(
  249. "Buggy: MmProbeAndLockPages( %p ) raised exception %X\n",
  250. Mdl,
  251. GetExceptionCode() );
  252. DbgBreakPoint();
  253. }
  254. if( TRUE == Locked )
  255. {
  256. //
  257. // Map them to our reserved address
  258. //
  259. MappedAddress = MmMapLockedPagesWithReservedMapping(
  260. CrtReservedAddress,
  261. TD_POOL_TAG,
  262. Mdl,
  263. MmCached );
  264. if( NULL == MappedAddress )
  265. {
  266. DbgPrint(
  267. "Buggy: MmProbeAndLockPages( %p, MDL %p ) returned NULL. This API is almost guaranteed to succeed\n",
  268. CrtReservedAddress,
  269. Mdl );
  270. DbgBreakPoint();
  271. }
  272. else
  273. {
  274. //
  275. // Mapped successfully - execute the "read"
  276. //
  277. CrtCyclePages = CrtCycleSize / PAGE_SIZE;
  278. CrtPageAdddress = (PSIZE_T)MappedAddress;
  279. //
  280. // Stamp all the pages with their index, starting from 1
  281. //
  282. while( CrtCyclePages > 0 )
  283. {
  284. *CrtPageAdddress = CrtPageIndex;
  285. CrtPageIndex += 1;
  286. CrtCyclePages -= 1;
  287. CrtPageAdddress = (PSIZE_T)( (PCHAR)CrtPageAdddress + PAGE_SIZE );
  288. }
  289. //
  290. // Unmap
  291. //
  292. MmUnmapReservedMapping(
  293. MappedAddress,
  294. TD_POOL_TAG,
  295. Mdl );
  296. }
  297. //
  298. // Unlock
  299. //
  300. MmUnlockPages (Mdl);
  301. }
  302. //
  303. // Free MDL
  304. //
  305. IoFreeMdl (Mdl);
  306. }
  307. else
  308. {
  309. //
  310. // Bad luck - couldn't allocate the MDL
  311. //
  312. DbgPrint( "Buggy: TdReservedMappingDoRead: IoAllocateMdl( %p, %p ) returned NULL\n",
  313. UserBuffer,
  314. UserBufferSize );
  315. }
  316. //
  317. // How many bytes left to be read and to what address?
  318. //
  319. UserBufferSize -= CrtCycleSize;
  320. UserBuffer = (PVOID)( (PCHAR)UserBuffer + CrtCycleSize );
  321. }
  322. }
  323. #endif //#if !RESRVMAP_ACTIVE