[ros-kernel] Bug in NtAllocateVirtualMemory
Filip Navara
xnavara at volny.cz
Sun Feb 1 00:04:09 CET 2004
Hi,
I need help some help from educated kernel person again. I found that
the attached code from ATL doesn't work under ReactOS. The cause is that
in ReactOS it's not possible to call NtAllocateVirtualMemory on
MEMORY_AREA_SECTION_VIEW memory area with specified prefered base
address and MEM_COMMIT flag. I have no idea how this situation should be
handled correctly, so I'm using this hack right now:
MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace,
BaseAddress);
+ if (MemoryArea != NULL &&
+ MemoryArea->Type == MEMORY_AREA_SECTION_VIEW &&
+ MemoryArea->Length >= RegionSize)
+ {
+ MmUnlockAddressSpace(AddressSpace);
+ ObDereferenceObject(Process);
+ return STATUS_SUCCESS;
+ }
else if (MemoryArea != NULL &&
MemoryArea->Type == MEMORY_AREA_VIRTUAL_MEMORY &&
MemoryArea->Length >= RegionSize)
Regards,
Filip
-------------- next part --------------
bool CAtlAllocator::Init(const CHAR *pszFileName, DWORD dwMaxSize)
{
// We're relying on syncronization provided by the startup code (CRT DllMain/WinMain)
Close();
ATLASSERT(!m_hMap && !m_pBufferStart);
HANDLE hThreadToken = NULL;
__try
{
if( !(GetVersion()&0x80000000) )
{
// If we're being loaded while impersonating a different client,
// we need to revert to self before we open the shared memory section
OpenThreadToken(GetCurrentThread(), TOKEN_IMPERSONATE|TOKEN_DUPLICATE, FALSE, &hThreadToken);
if( hThreadToken != NULL )
{
if( !RevertToSelf() )
{
CloseHandle(hThreadToken);
hThreadToken = NULL;
__leave;
}
}
}
// Use a NULL SECURITY_ATTRIBUTES structure to get the default DACL.
m_hMap = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL,
PAGE_READWRITE | SEC_RESERVE, 0, dwMaxSize, pszFileName);
if(!m_hMap)
__leave;
DWORD dwErr = ::GetLastError();
m_pBufferStart = (BYTE *)
MapViewOfFile(m_hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
if(!m_pBufferStart)
__leave;
SYSTEM_INFO si;
GetSystemInfo(&si);
if(dwErr == ERROR_ALREADY_EXISTS)
{
m_pProcess = reinterpret_cast<CAtlTraceProcess *>(m_pBufferStart);
// Looks like it's already mapped into this process space.
// Let's do some checking...
if(IsBadReadPtr(m_pProcess, sizeof(CAtlTraceProcess)) ||
IsBadReadPtr(m_pProcess->Base(), sizeof(CAtlTraceProcess)) ||
0 != memcmp(m_pBufferStart, m_pProcess->Base(), m_pProcess->m_dwFrontAlloc))
{
// something's not right
__leave;
}
// sure looks valid
m_pProcess->IncRef();
m_pProcess = static_cast<CAtlTraceProcess *>(m_pProcess->Base());
UnmapViewOfFile(m_pBufferStart);
m_pBufferStart = reinterpret_cast<BYTE *>(m_pProcess);
}
else
{
// This is just in case sizeof(CAtlTraceProcess) is
// ever > dwPageSize (doubtful that could ever
// happen, but it's easy enough to avoid here)
DWORD dwCurrAlloc = si.dwPageSize;
while(dwCurrAlloc < sizeof(CAtlTraceProcess))
dwCurrAlloc += si.dwPageSize;
if(!VirtualAlloc(m_pBufferStart, dwCurrAlloc, MEM_COMMIT, PAGE_READWRITE))
__leave;
m_pProcess = new(m_pBufferStart) CAtlTraceProcess(dwMaxSize);
m_pProcess->m_dwFrontAlloc = dwCurrAlloc;
m_pProcess->m_dwCurrFront = sizeof(CAtlTraceProcess);
}
m_dwPageSize = si.dwPageSize;
m_bValid = true;
}
__finally
{
if( hThreadToken != NULL )
{
// Go back to impersonating whomever we were impersonating
BOOL bSuccess;
bSuccess = SetThreadToken(NULL, hThreadToken);
ATLASSERT( bSuccess );
CloseHandle( hThreadToken );
}
if(!m_bValid)
{
if(m_pBufferStart)
{
UnmapViewOfFile(m_pBufferStart);
m_pBufferStart = NULL;
}
if(m_hMap)
{
CloseHandle(m_hMap);
m_hMap = NULL;
}
}
}
return m_bValid;
}
More information about the Ros-kernel
mailing list