2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998 - 2005 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS kernel
22 * PURPOSE: shared sections support
23 * FILE: subsys/win32k/misc/ssec.c
24 * PROGRAMER: Thomas Weidenmueller <w3seek@reactos.com>
33 * FIXME - instead of mapping the memory into system space using
34 * MmMapViewInSystemSpace() we should rather use
35 * MmMapViewInSessionSpace() to map it into session space!
38 NTSTATUS INTERNAL_CALL
39 IntUserCreateSharedSectionPool(IN ULONG MaximumPoolSize
,
40 IN PSHARED_SECTION_POOL
*SharedSectionPool
)
42 PSHARED_SECTION_POOL Pool
;
45 ASSERT(SharedSectionPool
);
47 PoolStructSize
= ROUND_UP(sizeof(SHARED_SECTION_POOL
), PAGE_SIZE
);
48 Pool
= ExAllocatePoolWithTag(NonPagedPool
,
53 RtlZeroMemory(Pool
, PoolStructSize
);
55 /* initialize the session heap */
56 ExInitializeFastMutex(&Pool
->Lock
);
57 Pool
->PoolSize
= ROUND_UP(MaximumPoolSize
, PAGE_SIZE
);
58 Pool
->PoolFree
= Pool
->PoolSize
;
59 Pool
->SharedSectionCount
= 0;
60 Pool
->SectionsArray
.Next
= NULL
;
61 Pool
->SectionsArray
.nEntries
= ((PoolStructSize
- sizeof(SHARED_SECTION_POOL
)) /
62 sizeof(SHARED_SECTION
)) - 1;
64 ASSERT(Pool
->SectionsArray
.nEntries
> 0);
66 *SharedSectionPool
= Pool
;
68 return STATUS_SUCCESS
;
71 return STATUS_INSUFFICIENT_RESOURCES
;
76 IntUserFreeSharedSectionPool(IN PSHARED_SECTION_POOL SharedSectionPool
)
78 PSHARED_SECTIONS_ARRAY Array
, OldArray
;
79 PSHARED_SECTION SharedSection
, LastSharedSection
;
81 ASSERT(SharedSectionPool
);
83 Array
= &SharedSectionPool
->SectionsArray
;
85 ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&SharedSectionPool
->Lock
);
86 while(SharedSectionPool
->SharedSectionCount
> 0 && Array
!= NULL
)
88 for(SharedSection
= Array
->SharedSection
, LastSharedSection
= SharedSection
+ Array
->nEntries
;
89 SharedSection
!= LastSharedSection
&& SharedSectionPool
->SharedSectionCount
> 0;
92 if(SharedSection
->SectionObject
!= NULL
)
94 ASSERT(SharedSection
->SystemMappedBase
);
96 /* FIXME - use MmUnmapViewInSessionSpace() once implemented! */
97 MmUnmapViewInSystemSpace(SharedSection
->SystemMappedBase
);
98 /* dereference the keep-alive reference so the section get's deleted */
99 ObDereferenceObject(SharedSection
->SectionObject
);
101 SharedSectionPool
->SharedSectionCount
--;
108 /* all shared sections in this array were freed, link the following array to
109 the main session heap and free this array */
110 SharedSectionPool
->SectionsArray
.Next
= Array
;
111 ExFreePool(OldArray
);
114 ASSERT(SharedSectionPool
->SectionsArray
.Next
== NULL
);
115 ASSERT(SharedSectionPool
->SharedSectionCount
== 0);
117 ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&SharedSectionPool
->Lock
);
121 NTSTATUS INTERNAL_CALL
122 IntUserCreateSharedSection(IN PSHARED_SECTION_POOL SharedSectionPool
,
123 IN OUT PVOID
*SystemMappedBase
,
124 IN OUT ULONG
*SharedSectionSize
)
126 PSHARED_SECTIONS_ARRAY Array
, LastArray
;
127 PSHARED_SECTION FreeSharedSection
, SharedSection
, LastSharedSection
;
128 LARGE_INTEGER SectionSize
;
132 ASSERT(SharedSectionPool
&& SharedSectionSize
&& (*SharedSectionSize
) > 0 && SystemMappedBase
);
134 FreeSharedSection
= NULL
;
136 Size
= ROUND_UP(*SharedSectionSize
, PAGE_SIZE
);
138 ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&SharedSectionPool
->Lock
);
140 if(Size
> SharedSectionPool
->PoolFree
)
142 ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&SharedSectionPool
->Lock
);
143 DPRINT1("Shared Section Pool limit (0x%x KB) reached, attempted to allocate a 0x%x KB shared section!\n",
144 SharedSectionPool
->PoolSize
/ 1024, (*SharedSectionSize
) / 1024);
145 return STATUS_INSUFFICIENT_RESOURCES
;
148 /* walk the array to find a free entry */
149 for(Array
= &SharedSectionPool
->SectionsArray
, LastArray
= Array
;
150 Array
!= NULL
&& FreeSharedSection
== NULL
;
155 for(SharedSection
= Array
->SharedSection
, LastSharedSection
= SharedSection
+ Array
->nEntries
;
156 SharedSection
!= LastSharedSection
;
159 if(SharedSection
->SectionObject
== NULL
)
161 FreeSharedSection
= SharedSection
;
166 if(Array
->Next
!= NULL
)
174 if(FreeSharedSection
== NULL
)
177 PSHARED_SECTIONS_ARRAY NewArray
;
179 ASSERT(LastArray
->Next
== NULL
);
181 /* couldn't find a free entry in the array, extend the array */
183 nNewEntries
= ((PAGE_SIZE
- sizeof(SHARED_SECTIONS_ARRAY
)) / sizeof(SHARED_SECTION
)) + 1;
184 NewArray
= ExAllocatePoolWithTag(NonPagedPool
,
185 sizeof(SHARED_SECTIONS_ARRAY
) + ((nNewEntries
- 1) *
186 sizeof(SHARED_SECTION
)),
190 ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&SharedSectionPool
->Lock
);
191 DPRINT1("Failed to allocate new array for shared sections!\n");
192 return STATUS_INSUFFICIENT_RESOURCES
;
195 NewArray
->nEntries
= nNewEntries
;
196 NewArray
->Next
= NULL
;
197 LastArray
->Next
= NewArray
;
200 FreeSharedSection
= &Array
->SharedSection
[0];
203 ASSERT(FreeSharedSection
);
205 /* now allocate a real section */
207 SectionSize
.QuadPart
= Size
;
208 Status
= MmCreateSection(&FreeSharedSection
->SectionObject
,
212 PAGE_EXECUTE_READWRITE
,
216 if(NT_SUCCESS(Status
))
218 Status
= MmMapViewInSystemSpace(FreeSharedSection
->SectionObject
,
219 &FreeSharedSection
->SystemMappedBase
,
220 &FreeSharedSection
->ViewSize
);
221 if(NT_SUCCESS(Status
))
223 (*SharedSectionSize
) -= Size
;
224 SharedSectionPool
->SharedSectionCount
++;
226 *SystemMappedBase
= FreeSharedSection
->SystemMappedBase
;
227 *SharedSectionSize
= FreeSharedSection
->ViewSize
;
231 ObDereferenceObject(FreeSharedSection
->SectionObject
);
232 FreeSharedSection
->SectionObject
= NULL
;
233 DPRINT1("Failed to map the shared section into system space! Status 0x%x\n", Status
);
237 ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&SharedSectionPool
->Lock
);
243 NTSTATUS INTERNAL_CALL
244 InUserDeleteSharedSection(PSHARED_SECTION_POOL SharedSectionPool
,
245 PVOID SystemMappedBase
)
247 PSHARED_SECTIONS_ARRAY Array
;
248 PSECTION_OBJECT SectionObject
;
249 PSHARED_SECTION SharedSection
, LastSharedSection
;
252 ASSERT(SharedSectionPool
&& SystemMappedBase
);
254 SectionObject
= NULL
;
256 ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&SharedSectionPool
->Lock
);
258 for(Array
= &SharedSectionPool
->SectionsArray
;
259 Array
!= NULL
&& SectionObject
== NULL
;
262 for(SharedSection
= Array
->SharedSection
, LastSharedSection
= SharedSection
+ Array
->nEntries
;
263 SharedSection
!= LastSharedSection
;
266 if(SharedSection
->SystemMappedBase
== SystemMappedBase
)
268 SectionObject
= SharedSection
->SectionObject
;
269 SharedSection
->SectionObject
= NULL
;
270 SharedSection
->SystemMappedBase
= NULL
;
272 ASSERT(SharedSectionPool
->SharedSectionCount
> 0);
273 SharedSectionPool
->SharedSectionCount
--;
279 ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&SharedSectionPool
->Lock
);
281 if(SectionObject
!= NULL
)
283 Status
= MmUnmapViewInSystemSpace(SystemMappedBase
);
284 ObDereferenceObject(SectionObject
);
288 DPRINT1("Couldn't find and delete a shared section with SystemMappedBase=0x%x!\n", SystemMappedBase
);
289 Status
= STATUS_UNSUCCESSFUL
;
296 NTSTATUS INTERNAL_CALL
297 IntUserMapSharedSection(IN PSHARED_SECTION_POOL SharedSectionPool
,
298 IN PEPROCESS Process
,
299 IN PVOID SystemMappedBase
,
300 IN PLARGE_INTEGER SectionOffset OPTIONAL
,
301 IN OUT PVOID
*UserMappedBase
,
302 IN PULONG ViewSize OPTIONAL
,
305 PSHARED_SECTIONS_ARRAY Array
;
306 PSECTION_OBJECT SectionObject
;
307 PSHARED_SECTION SharedSection
, LastSharedSection
;
310 ASSERT(SharedSectionPool
&& Process
&& SystemMappedBase
&& UserMappedBase
);
312 SectionObject
= NULL
;
313 SharedSection
= NULL
;
315 ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&SharedSectionPool
->Lock
);
317 for(Array
= &SharedSectionPool
->SectionsArray
;
318 Array
!= NULL
&& SectionObject
== NULL
;
321 for(SharedSection
= Array
->SharedSection
, LastSharedSection
= SharedSection
+ Array
->nEntries
;
322 SharedSection
!= LastSharedSection
;
325 if(SharedSection
->SystemMappedBase
== SystemMappedBase
)
327 SectionObject
= SharedSection
->SectionObject
;
333 if(SectionObject
!= NULL
)
335 ULONG RealViewSize
= (ViewSize
? min(*ViewSize
, SharedSection
->ViewSize
) : SharedSection
->ViewSize
);
337 ObReferenceObjectByPointer(SectionObject
,
338 (ReadOnly
? SECTION_MAP_READ
: SECTION_MAP_READ
| SECTION_MAP_WRITE
),
342 Status
= MmMapViewOfSection(SectionObject
,
349 ViewUnmap
, /* not sure if we should inherit it... */
351 (ReadOnly
? PAGE_READONLY
: PAGE_READWRITE
));
352 if(!NT_SUCCESS(Status
))
354 DPRINT1("Failed to map shared section (readonly=%d) into user memory! Status: 0x%x\n", ReadOnly
, Status
);
359 DPRINT1("Couldn't find and map a shared section with SystemMappedBase=0x%x!\n", SystemMappedBase
);
360 Status
= STATUS_UNSUCCESSFUL
;
363 ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&SharedSectionPool
->Lock
);
369 NTSTATUS INTERNAL_CALL
370 IntUserUnMapSharedSection(IN PSHARED_SECTION_POOL SharedSectionPool
,
371 IN PEPROCESS Process
,
372 IN PVOID SystemMappedBase
,
373 IN PVOID UserMappedBase
)
375 PSHARED_SECTIONS_ARRAY Array
;
376 PSECTION_OBJECT SectionObject
;
377 PSHARED_SECTION SharedSection
, LastSharedSection
;
380 ASSERT(SharedSectionPool
&& Process
&& SystemMappedBase
&& UserMappedBase
);
382 SectionObject
= NULL
;
384 ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&SharedSectionPool
->Lock
);
386 for(Array
= &SharedSectionPool
->SectionsArray
;
387 Array
!= NULL
&& SectionObject
== NULL
;
390 for(SharedSection
= Array
->SharedSection
, LastSharedSection
= SharedSection
+ Array
->nEntries
;
391 SharedSection
!= LastSharedSection
;
394 if(SharedSection
->SystemMappedBase
== SystemMappedBase
)
396 SectionObject
= SharedSection
->SectionObject
;
402 ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&SharedSectionPool
->Lock
);
404 if(SectionObject
!= NULL
)
406 Status
= MmUnmapViewOfSection(Process
,
408 ObDereferenceObject(SectionObject
);
409 if(!NT_SUCCESS(Status
))
411 DPRINT1("Failed to unmap shared section UserMappedBase=0x%x! Status: 0x%x\n", UserMappedBase
, Status
);
416 DPRINT1("Couldn't find and unmap a shared section with SystemMappedBase=0x%x!\n", SystemMappedBase
);
417 Status
= STATUS_UNSUCCESSFUL
;