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.

543 lines
9.4 KiB

  1. /*++
  2. Copyright (C) 1991-5 Microsoft Corporation
  3. Module Name:
  4. packet.cxx
  5. Abstract:
  6. This module contains the code specific to all types of TRANSFER_PACKETS
  7. objects.
  8. Author:
  9. Norbert Kusters 2-Feb-1995
  10. Environment:
  11. kernel mode only
  12. Notes:
  13. Revision History:
  14. --*/
  15. extern "C" {
  16. #include <ntddk.h>
  17. }
  18. #include <ftdisk.h>
  19. static PNPAGED_LOOKASIDE_LIST StripeLookasidePackets = NULL;
  20. static PNPAGED_LOOKASIDE_LIST MirrorLookasidePackets = NULL;
  21. #ifdef ALLOC_PRAGMA
  22. #pragma code_seg("PAGELK")
  23. #endif
  24. PVOID
  25. TRANSFER_PACKET::operator new(
  26. IN size_t Size
  27. )
  28. /*++
  29. Routine Description:
  30. This routine is the memory allocator for all classes derived from
  31. FT_VOLUME.
  32. Arguments:
  33. Size - Supplies the number of bytes to allocate.
  34. Return Value:
  35. A pointer to Size bytes of non-paged pool.
  36. --*/
  37. {
  38. PTRANSFER_PACKET p;
  39. if (Size <= sizeof(STRIPE_TP)) {
  40. if (!StripeLookasidePackets) {
  41. StripeLookasidePackets = (PNPAGED_LOOKASIDE_LIST)
  42. ExAllocatePool(NonPagedPool,
  43. sizeof(NPAGED_LOOKASIDE_LIST));
  44. if (!StripeLookasidePackets) {
  45. return NULL;
  46. }
  47. ExInitializeNPagedLookasideList(StripeLookasidePackets, NULL, NULL,
  48. 0, sizeof(STRIPE_TP), 'sFcS', 32);
  49. }
  50. p = (PTRANSFER_PACKET)
  51. ExAllocateFromNPagedLookasideList(StripeLookasidePackets);
  52. if (p) {
  53. p->_allocationType = TP_ALLOCATION_STRIPE_POOL;
  54. }
  55. return p;
  56. }
  57. if (Size <= sizeof(MIRROR_TP)) {
  58. if (!MirrorLookasidePackets) {
  59. MirrorLookasidePackets = (PNPAGED_LOOKASIDE_LIST)
  60. ExAllocatePool(NonPagedPool,
  61. sizeof(NPAGED_LOOKASIDE_LIST));
  62. if (!MirrorLookasidePackets) {
  63. return NULL;
  64. }
  65. ExInitializeNPagedLookasideList(MirrorLookasidePackets, NULL, NULL,
  66. 0, sizeof(MIRROR_TP), 'mFcS', 32);
  67. }
  68. p = (PTRANSFER_PACKET)
  69. ExAllocateFromNPagedLookasideList(MirrorLookasidePackets);
  70. if (p) {
  71. p->_allocationType = TP_ALLOCATION_MIRROR_POOL;
  72. }
  73. return p;
  74. }
  75. p = (PTRANSFER_PACKET) ExAllocatePool(NonPagedPool, Size);
  76. if (p) {
  77. p->_allocationType = 0;
  78. }
  79. return p;
  80. }
  81. VOID
  82. TRANSFER_PACKET::operator delete(
  83. IN PVOID MemPtr
  84. )
  85. /*++
  86. Routine Description:
  87. This routine frees memory allocated for all classes derived from
  88. FT_VOLUME.
  89. Arguments:
  90. MemPtr - Supplies a pointer to the memory to free.
  91. Return Value:
  92. None.
  93. --*/
  94. {
  95. PTRANSFER_PACKET p = (PTRANSFER_PACKET) MemPtr;
  96. if (!p) {
  97. return;
  98. }
  99. if (p->_allocationType == TP_ALLOCATION_STRIPE_POOL) {
  100. ExFreeToNPagedLookasideList(StripeLookasidePackets, MemPtr);
  101. } else if (p->_allocationType == TP_ALLOCATION_MIRROR_POOL) {
  102. ExFreeToNPagedLookasideList(MirrorLookasidePackets, MemPtr);
  103. } else {
  104. ExFreePool(MemPtr);
  105. }
  106. }
  107. TRANSFER_PACKET::~TRANSFER_PACKET(
  108. )
  109. /*++
  110. Routine Description:
  111. This is the destructor for a transfer packet. It frees up any allocated
  112. MDL and buffer.
  113. Arguments:
  114. None.
  115. Return Value:
  116. None.
  117. --*/
  118. {
  119. FreeMdl();
  120. }
  121. BOOLEAN
  122. TRANSFER_PACKET::AllocateMdl(
  123. IN PVOID Buffer,
  124. IN ULONG Length
  125. )
  126. /*++
  127. Routine Description:
  128. This routine allocates an MDL and for this transfer packet.
  129. Arguments:
  130. Buffer - Supplies the buffer.
  131. Length - Supplies the buffer length.
  132. Return Value:
  133. FALSE - Insufficient resources.
  134. TRUE - Success.
  135. --*/
  136. {
  137. FreeMdl();
  138. Mdl = IoAllocateMdl(Buffer, Length, FALSE, FALSE, NULL);
  139. if (!Mdl) {
  140. return FALSE;
  141. }
  142. _freeMdl = TRUE;
  143. return TRUE;
  144. }
  145. BOOLEAN
  146. TRANSFER_PACKET::AllocateMdl(
  147. IN ULONG Length
  148. )
  149. /*++
  150. Routine Description:
  151. This routine allocates an MDL and buffer for this transfer packet.
  152. Arguments:
  153. Length - Supplies the buffer length.
  154. Return Value:
  155. FALSE - Insufficient resources.
  156. TRUE - Success.
  157. --*/
  158. {
  159. PVOID buffer;
  160. FreeMdl();
  161. buffer = ExAllocatePool(NonPagedPoolCacheAligned,
  162. Length < PAGE_SIZE ? PAGE_SIZE : Length);
  163. if (!buffer) {
  164. return FALSE;
  165. }
  166. _freeBuffer = TRUE;
  167. Mdl = IoAllocateMdl(buffer, Length, FALSE, FALSE, NULL);
  168. if (!Mdl) {
  169. ExFreePool(buffer);
  170. _freeBuffer = FALSE;
  171. return FALSE;
  172. }
  173. _freeMdl = TRUE;
  174. MmBuildMdlForNonPagedPool(Mdl);
  175. return TRUE;
  176. }
  177. VOID
  178. TRANSFER_PACKET::FreeMdl(
  179. )
  180. /*++
  181. Routine Description:
  182. It frees up any allocated MDL and buffer.
  183. Arguments:
  184. None.
  185. Return Value:
  186. None.
  187. --*/
  188. {
  189. if (_freeBuffer) {
  190. ExFreePool(MmGetMdlVirtualAddress(Mdl));
  191. _freeBuffer = FALSE;
  192. }
  193. if (_freeMdl) {
  194. IoFreeMdl(Mdl);
  195. _freeMdl = FALSE;
  196. }
  197. }
  198. OVERLAP_TP::~OVERLAP_TP(
  199. )
  200. {
  201. if (InQueue) {
  202. OverlappedIoManager->ReleaseIoRegion(this);
  203. }
  204. }
  205. MIRROR_RECOVER_TP::~MIRROR_RECOVER_TP(
  206. )
  207. {
  208. FreeMdls();
  209. }
  210. BOOLEAN
  211. MIRROR_RECOVER_TP::AllocateMdls(
  212. IN ULONG Length
  213. )
  214. {
  215. PVOID buffer;
  216. FreeMdls();
  217. PartialMdl = IoAllocateMdl((PVOID) (PAGE_SIZE - 1), Length,
  218. FALSE, FALSE, NULL);
  219. if (!PartialMdl) {
  220. FreeMdls();
  221. return FALSE;
  222. }
  223. buffer = ExAllocatePool(NonPagedPoolCacheAligned,
  224. Length < PAGE_SIZE ? PAGE_SIZE : Length);
  225. if (!buffer) {
  226. FreeMdls();
  227. return FALSE;
  228. }
  229. VerifyMdl = IoAllocateMdl(buffer, Length, FALSE, FALSE, NULL);
  230. if (!VerifyMdl) {
  231. ExFreePool(buffer);
  232. FreeMdls();
  233. return FALSE;
  234. }
  235. MmBuildMdlForNonPagedPool(VerifyMdl);
  236. return TRUE;
  237. }
  238. VOID
  239. MIRROR_RECOVER_TP::FreeMdls(
  240. )
  241. {
  242. if (PartialMdl) {
  243. IoFreeMdl(PartialMdl);
  244. PartialMdl = NULL;
  245. }
  246. if (VerifyMdl) {
  247. ExFreePool(MmGetMdlVirtualAddress(VerifyMdl));
  248. IoFreeMdl(VerifyMdl);
  249. VerifyMdl = NULL;
  250. }
  251. }
  252. SWP_RECOVER_TP::~SWP_RECOVER_TP(
  253. )
  254. {
  255. FreeMdls();
  256. }
  257. BOOLEAN
  258. SWP_RECOVER_TP::AllocateMdls(
  259. IN ULONG Length
  260. )
  261. {
  262. PVOID buffer;
  263. FreeMdls();
  264. PartialMdl = IoAllocateMdl((PVOID) (PAGE_SIZE - 1), Length,
  265. FALSE, FALSE, NULL);
  266. if (!PartialMdl) {
  267. FreeMdls();
  268. return FALSE;
  269. }
  270. buffer = ExAllocatePool(NonPagedPoolCacheAligned,
  271. Length < PAGE_SIZE ? PAGE_SIZE : Length);
  272. if (!buffer) {
  273. FreeMdls();
  274. return FALSE;
  275. }
  276. VerifyMdl = IoAllocateMdl(buffer, Length, FALSE, FALSE, NULL);
  277. if (!VerifyMdl) {
  278. ExFreePool(buffer);
  279. FreeMdls();
  280. return FALSE;
  281. }
  282. MmBuildMdlForNonPagedPool(VerifyMdl);
  283. return TRUE;
  284. }
  285. VOID
  286. SWP_RECOVER_TP::FreeMdls(
  287. )
  288. {
  289. if (PartialMdl) {
  290. IoFreeMdl(PartialMdl);
  291. PartialMdl = NULL;
  292. }
  293. if (VerifyMdl) {
  294. ExFreePool(MmGetMdlVirtualAddress(VerifyMdl));
  295. IoFreeMdl(VerifyMdl);
  296. VerifyMdl = NULL;
  297. }
  298. }
  299. SWP_WRITE_TP::~SWP_WRITE_TP(
  300. )
  301. {
  302. FreeMdls();
  303. }
  304. BOOLEAN
  305. SWP_WRITE_TP::AllocateMdls(
  306. IN ULONG Length
  307. )
  308. {
  309. PVOID buffer;
  310. FreeMdls();
  311. buffer = ExAllocatePool(NonPagedPoolCacheAligned,
  312. Length < PAGE_SIZE ? PAGE_SIZE : Length);
  313. if (!buffer) {
  314. return FALSE;
  315. }
  316. ReadAndParityMdl = IoAllocateMdl(buffer, Length, FALSE, FALSE, NULL);
  317. if (!ReadAndParityMdl) {
  318. ExFreePool(buffer);
  319. return FALSE;
  320. }
  321. MmBuildMdlForNonPagedPool(ReadAndParityMdl);
  322. buffer = ExAllocatePool(NonPagedPoolCacheAligned,
  323. Length < PAGE_SIZE ? PAGE_SIZE : Length);
  324. if (!buffer) {
  325. FreeMdls();
  326. return FALSE;
  327. }
  328. WriteMdl = IoAllocateMdl(buffer, Length, FALSE, FALSE, NULL);
  329. if (!WriteMdl) {
  330. ExFreePool(buffer);
  331. FreeMdls();
  332. return FALSE;
  333. }
  334. MmBuildMdlForNonPagedPool(WriteMdl);
  335. return TRUE;
  336. }
  337. VOID
  338. SWP_WRITE_TP::FreeMdls(
  339. )
  340. {
  341. if (ReadAndParityMdl) {
  342. ExFreePool(MmGetMdlVirtualAddress(ReadAndParityMdl));
  343. IoFreeMdl(ReadAndParityMdl);
  344. ReadAndParityMdl = NULL;
  345. }
  346. if (WriteMdl) {
  347. ExFreePool(MmGetMdlVirtualAddress(WriteMdl));
  348. IoFreeMdl(WriteMdl);
  349. WriteMdl = NULL;
  350. }
  351. }
  352. REDISTRIBUTION_CW_TP::~REDISTRIBUTION_CW_TP(
  353. )
  354. {
  355. FreeMdls();
  356. }
  357. BOOLEAN
  358. REDISTRIBUTION_CW_TP::AllocateMdls(
  359. IN ULONG Length
  360. )
  361. {
  362. PVOID buffer;
  363. FreeMdls();
  364. PartialMdl = IoAllocateMdl((PVOID) (PAGE_SIZE - 1), Length,
  365. FALSE, FALSE, NULL);
  366. if (!PartialMdl) {
  367. FreeMdls();
  368. return FALSE;
  369. }
  370. buffer = ExAllocatePool(NonPagedPoolCacheAligned,
  371. Length < PAGE_SIZE ? PAGE_SIZE : Length);
  372. if (!buffer) {
  373. FreeMdls();
  374. return FALSE;
  375. }
  376. VerifyMdl = IoAllocateMdl(buffer, Length, FALSE, FALSE, NULL);
  377. if (!VerifyMdl) {
  378. ExFreePool(buffer);
  379. FreeMdls();
  380. return FALSE;
  381. }
  382. MmBuildMdlForNonPagedPool(VerifyMdl);
  383. return TRUE;
  384. }
  385. VOID
  386. REDISTRIBUTION_CW_TP::FreeMdls(
  387. )
  388. {
  389. if (PartialMdl) {
  390. IoFreeMdl(PartialMdl);
  391. PartialMdl = NULL;
  392. }
  393. if (VerifyMdl) {
  394. ExFreePool(MmGetMdlVirtualAddress(VerifyMdl));
  395. IoFreeMdl(VerifyMdl);
  396. VerifyMdl = NULL;
  397. }
  398. }