source: trunk/Utilities/VirtualHeapPtr/VirtualHeapPtr.cpp @ 33

Last change on this file since 33 was 33, checked in by roman, 12 years ago
  • Property svn:keywords set to Id
File size: 4.7 KB
Line 
1////////////////////////////////////////////////////////////
2// Copyright (C) Roman Ryltsov, 2008-2011
3// Created by Roman Ryltsov roman@alax.info
4//
5// $Id: VirtualHeapPtr.cpp 33 2011-11-04 09:50:08Z roman $
6
7#include "stdafx.h"
8#include <psapi.h>
9
10#pragma comment(lib, "psapi.lib")
11
12////////////////////////////////////////////////////////////
13// CGlobalVirtualAllocator
14
15class CGlobalVirtualAllocator
16{
17private:
18        SIZE_T m_nGranularity;
19
20public:
21// CGlobalVirtualAllocator
22        CGlobalVirtualAllocator() throw() :
23                m_nGranularity(4 << 10) // 4L
24        {
25                PERFORMANCE_INFORMATION Information;
26                ZeroMemory(&Information, sizeof Information);
27                ATLVERIFY(GetPerformanceInfo(&Information, sizeof Information));
28                m_nGranularity = Information.PageSize;
29                ATLASSERT(m_nGranularity);
30                ATLASSERT(!(m_nGranularity & (m_nGranularity - 1)));
31        }
32        SIZE_T GetGranularity() const throw()
33        {
34                return m_nGranularity;
35        }
36};
37
38CGlobalVirtualAllocator g_GlobalVirtualAllocator;
39
40////////////////////////////////////////////////////////////
41// CVirtualAllocator
42
43class CVirtualAllocator
44{
45public:
46// CVirtualAllocator
47        static SIZE_T Align(SIZE_T nDataSize) throw()
48        {
49                const SIZE_T nGranularity = g_GlobalVirtualAllocator.GetGranularity();
50                ATLASSERT(nGranularity);
51                ATLASSERT(!(nGranularity & (nGranularity - 1)));
52                return (nDataSize + nGranularity - 1) & ~(nGranularity - 1);
53        }
54        static VOID* Reallocate(_In_opt_ VOID* pvData, _In_ SIZE_T nDataSize)
55        {
56                MEMORY_BASIC_INFORMATION DataInformation;
57                if(pvData)
58                {
59                        ATLVERIFY(VirtualQuery(pvData, &DataInformation, sizeof DataInformation));
60                        if(nDataSize <= DataInformation.RegionSize)
61                                return pvData;
62                }
63                VOID* pvNewData = NULL;
64                if(nDataSize)
65                {
66                        pvNewData = VirtualAlloc(NULL, Align(nDataSize), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
67                        ATLENSURE_THROW(pvNewData, AtlHresultFromLastError());
68                        _ATLTRY
69                        {
70                                ATLENSURE_THROW(VirtualLock(pvNewData, nDataSize), AtlHresultFromLastError());
71                                if(pvNewData && pvData)
72                                {
73                                        ATLASSERT(DataInformation.AllocationProtect == PAGE_READWRITE);
74                                        SIZE_T nCopyDataSize = nDataSize;
75                                        if(nCopyDataSize > DataInformation.RegionSize)
76                                                nCopyDataSize = DataInformation.RegionSize;
77                                        Checked::memcpy_s(pvNewData, nDataSize, pvData, nCopyDataSize);
78                                }
79                        }
80                        _ATLCATCHALL()
81                        {
82                                Free(pvData);
83                                _ATLRETHROW;
84                        }
85                }
86                if(pvData)
87                        Free(pvData);
88                return pvNewData;
89        }
90        static VOID* Allocate(_In_ SIZE_T nDataSize)
91        {
92                if(!nDataSize)
93                        return NULL;
94                VOID* pvData = VirtualAlloc(NULL, Align(nDataSize), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
95                ATLENSURE_THROW(pvData, AtlHresultFromLastError());
96                _ATLTRY
97                {
98                        ATLENSURE_THROW(VirtualLock(pvData, nDataSize), AtlHresultFromLastError());
99                }
100                _ATLCATCHALL()
101                {
102                        Free(pvData);
103                        _ATLRETHROW;
104                }
105                return pvData;
106        }
107        static VOID Free(_In_opt_ VOID* pvData) throw()
108        {
109                if(!pvData)
110                        return;
111                //VirtualUnlock(pvData,
112                ATLVERIFY(VirtualFree(pvData, 0, MEM_RELEASE));
113        }
114};
115
116////////////////////////////////////////////////////////////
117// CVirtualHeapPtr
118
119template <typename T>
120class CVirtualHeapPtr :
121        public CHeapPtr<T, CVirtualAllocator>
122{
123public:
124// CVirtualHeapPtr
125        CVirtualHeapPtr() throw()
126        {
127        }
128        explicit CVirtualHeapPtr(_In_ T* pData) throw() :
129                CHeapPtr<T, CVirtualAllocator>(pData)
130        {
131        }
132        VOID SetProtection(DWORD nProtection)
133        {
134                if(!m_pData)
135                        return;
136                MEMORY_BASIC_INFORMATION DataInformation;
137                ATLENSURE_THROW(VirtualQuery(m_pData, &DataInformation, sizeof DataInformation), AtlHresultFromLastError());
138                DWORD nCurrentProtection;
139                ATLENSURE_THROW(VirtualProtect(m_pData, DataInformation.RegionSize, nProtection, &nCurrentProtection), AtlHresultFromLastError());
140        }
141};
142
143////////////////////////////////////////////////////////////
144// Main
145
146int _tmain(int argc, _TCHAR* argv[])
147{
148        CVirtualHeapPtr<BYTE> p;
149        p.Allocate(1);
150        p[0] = 0x01;
151        _tprintf(_T("p[0] 0x%02X\n"), p[0]);
152        ATLVERIFY(p.Reallocate(2));
153        p[1] = 0x02;
154        _tprintf(_T("p[0] 0x%02X, p[1] 0x%02X\n"), p[0], p[1]);
155        p[0] = 0x03;
156        _tprintf(_T("p[0] 0x%02X, p[1] 0x%02X\n"), p[0], p[1]);
157        if(FALSE)
158        {
159                p.SetProtection(PAGE_READONLY);
160                _ATLTRY
161                {
162                        p[1] = 0x04;
163                        _tprintf(_T("p[0] 0x%02X, p[1] 0x%02X\n"), p[0], p[1]);
164                }
165                _ATLCATCHALL()
166                {
167                        _tprintf(_T("Oopsie in line %d\n"), __LINE__);
168                }
169                p.SetProtection(PAGE_READWRITE);
170                p[1] = 0x05;
171                _tprintf(_T("p[0] 0x%02X, p[1] 0x%02X\n"), p[0], p[1]);
172        }
173        p.SetProtection(PAGE_READWRITE | PAGE_GUARD);
174        volatile BYTE n;
175        _ATLTRY
176        {
177                n = p[0];
178        }
179        _ATLCATCHALL()
180        {
181                _tprintf(_T("Oopsie in line %d\n"), __LINE__);
182        }
183        _ATLTRY
184        {
185                n = p[1];
186        }
187        _ATLCATCHALL()
188        {
189                _tprintf(_T("Oopsie in line %d\n"), __LINE__);
190        }
191        return 0;
192}
193
Note: See TracBrowser for help on using the repository browser.