00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
#include "exp.h"
00022
00023
VOID
00024 ExInitializeRegion(
00025 IN
PREGION_HEADER Region,
00026 IN ULONG BlockSize,
00027 IN PVOID Segment,
00028 IN ULONG SegmentSize
00029 )
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 {
00056
00057 SINGLE_LIST_ENTRY FirstEntry;
00058 PSINGLE_LIST_ENTRY LastEntry;
00059 PSINGLE_LIST_ENTRY NextEntry;
00060 ULONG TotalSize;
00061
00062
00063
00064
00065
00066
00067
if ((
MmQuerySystemSize() ==
MmSmallSystem) && (SegmentSize > (2 *
PAGE_SIZE))) {
00068
KeBugCheckEx(NO_PAGES_AVAILABLE, 0x123, SegmentSize, 0, 0);
00069 }
00070
00071
00072
00073
00074
00075
00076
00077
if ((((ULONG)Segment & 7) != 0) ||
00078 ((
BlockSize & 7) != 0) ||
00079 (
BlockSize > (SegmentSize -
sizeof(
REGION_SEGMENT_HEADER)))) {
00080
KeBugCheckEx(INVALID_REGION_OR_SEGMENT, (ULONG)Segment, SegmentSize,
BlockSize, 0);
00081 }
00082
00083
00084
00085
00086
00087
ExInitializeSListHead(&Region->ListHead);
00088 Region->FirstSegment = (
PREGION_SEGMENT_HEADER)Segment;
00089 Region->BlockSize =
BlockSize;
00090 TotalSize = ((SegmentSize -
sizeof(
REGION_SEGMENT_HEADER)) /
BlockSize) *
BlockSize;
00091 Region->TotalSize = TotalSize;
00092
00093
00094
00095
00096
00097 FirstEntry.Next =
NULL;
00098 NextEntry = (PSINGLE_LIST_ENTRY)((PCHAR)Segment +
sizeof(
REGION_SEGMENT_HEADER));
00099 LastEntry = (PSINGLE_LIST_ENTRY)((PCHAR)NextEntry + TotalSize);
00100
do {
00101 NextEntry->Next = FirstEntry.Next;
00102 FirstEntry.Next = NextEntry;
00103 NextEntry = (PSINGLE_LIST_ENTRY)((PCHAR)NextEntry +
BlockSize);
00104 }
while (NextEntry != LastEntry);
00105 Region->ListHead.Next.Next = FirstEntry.Next;
00106
return;
00107 }
00108
00109
VOID
00110 ExInterlockedExtendRegion(
00111 IN
PREGION_HEADER Region,
00112 IN PVOID Segment,
00113 IN ULONG SegmentSize,
00114 IN PKSPIN_LOCK Lock
00115 )
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140 {
00141
00142 ULONG
BlockSize;
00143 SINGLE_LIST_ENTRY FirstEntry;
00144 KIRQL OldIrql;
00145 PSINGLE_LIST_ENTRY LastEntry;
00146 PSINGLE_LIST_ENTRY NextEntry;
00147 ULONG TotalSize;
00148
00149
00150
00151
00152
00153
00154
00155
BlockSize = Region->BlockSize;
00156
if ((((ULONG)Segment & 7) != 0) ||
00157 ((
BlockSize & 7) != 0) ||
00158 (
BlockSize > (SegmentSize -
sizeof(
REGION_SEGMENT_HEADER)))) {
00159
KeBugCheckEx(INVALID_REGION_OR_SEGMENT, (ULONG)Segment, SegmentSize,
BlockSize, 0);
00160 }
00161
00162
00163
00164
00165
00166 TotalSize = ((SegmentSize -
sizeof(
REGION_SEGMENT_HEADER)) /
BlockSize) *
BlockSize;
00167 FirstEntry.Next =
NULL;
00168 NextEntry = (PSINGLE_LIST_ENTRY)((PCHAR)Segment +
sizeof(
REGION_SEGMENT_HEADER));
00169 LastEntry = (PSINGLE_LIST_ENTRY)((PCHAR)NextEntry + TotalSize);
00170
do {
00171 NextEntry->Next = FirstEntry.Next;
00172 FirstEntry.Next = NextEntry;
00173 NextEntry = (PSINGLE_LIST_ENTRY)((PCHAR)NextEntry +
BlockSize);
00174 }
while (NextEntry != LastEntry);
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185 ExAcquireSpinLock(
Lock, &OldIrql);
00186 ((
PREGION_SEGMENT_HEADER)Segment)->NextSegment = Region->FirstSegment;
00187 Region->FirstSegment = (
PREGION_SEGMENT_HEADER)Segment;
00188 Region->TotalSize += TotalSize;
00189 NextEntry = (PSINGLE_LIST_ENTRY)((PCHAR)Segment +
sizeof(
REGION_SEGMENT_HEADER));
00190 LastEntry = (PSINGLE_LIST_ENTRY)((PCHAR)LastEntry - Region->BlockSize);
00191
do {
00192
00193
00194
00195
00196
00197
00198 FirstEntry.Next = Region->ListHead.Next.Next;
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 NextEntry->Next = FirstEntry.Next;
00210 }
while (InterlockedCompareExchange((PVOID)&Region->ListHead.Next,
00211 LastEntry,
00212 FirstEntry.Next) != FirstEntry.Next);
00213
00214 ExReleaseSpinLock(
Lock, OldIrql);
00215
return;
00216 }