forked from microsoft/wil
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMallocSpy.h
More file actions
145 lines (118 loc) · 3.73 KB
/
Copy pathMallocSpy.h
File metadata and controls
145 lines (118 loc) · 3.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#pragma once
#include "catch.hpp"
#include <objbase.h>
#include <wil/wistd_functional.h>
#include <wrl/implements.h>
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM)
// IMallocSpy requires you to implement all methods, but we often only want one or two...
struct MallocSpy : Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>, IMallocSpy>
{
wistd::function<SIZE_T(SIZE_T)> PreAllocCallback;
virtual SIZE_T STDMETHODCALLTYPE PreAlloc(SIZE_T requestSize) override
{
if (PreAllocCallback)
{
return PreAllocCallback(requestSize);
}
return requestSize;
}
wistd::function<void*(void*)> PostAllocCallback;
virtual void* STDMETHODCALLTYPE PostAlloc(void* ptr) override
{
if (PostAllocCallback)
{
return PostAllocCallback(ptr);
}
return ptr;
}
wistd::function<void*(void*)> PreFreeCallback;
virtual void* STDMETHODCALLTYPE PreFree(void* ptr, BOOL wasSpyed) override
{
if (wasSpyed && PreFreeCallback)
{
return PreFreeCallback(ptr);
}
return ptr;
}
virtual void STDMETHODCALLTYPE PostFree(BOOL /*wasSpyed*/) override
{
}
wistd::function<SIZE_T(void*, SIZE_T, void**)> PreReallocCallback;
virtual SIZE_T STDMETHODCALLTYPE PreRealloc(void* ptr, SIZE_T requestSize, void** newPtr, BOOL wasSpyed) override
{
*newPtr = ptr;
if (wasSpyed && PreReallocCallback)
{
return PreReallocCallback(ptr, requestSize, newPtr);
}
return requestSize;
}
wistd::function<void*(void*)> PostReallocCallback;
virtual void* STDMETHODCALLTYPE PostRealloc(void* ptr, BOOL wasSpyed) override
{
if (wasSpyed && PostReallocCallback)
{
return PostReallocCallback(ptr);
}
return ptr;
}
wistd::function<void*(void*)> PreGetSizeCallback;
virtual void* STDMETHODCALLTYPE PreGetSize(void* ptr, BOOL wasSpyed) override
{
if (wasSpyed && PreGetSizeCallback)
{
return PreGetSizeCallback(ptr);
}
return ptr;
}
wistd::function<SIZE_T(SIZE_T)> PostGetSizeCallback;
virtual SIZE_T STDMETHODCALLTYPE PostGetSize(SIZE_T size, BOOL wasSpyed) override
{
if (wasSpyed && PostGetSizeCallback)
{
return PostGetSizeCallback(size);
}
return size;
}
wistd::function<void*(void*)> PreDidAllocCallback;
virtual void* STDMETHODCALLTYPE PreDidAlloc(void* ptr, BOOL wasSpyed) override
{
if (wasSpyed && PreDidAllocCallback)
{
return PreDidAllocCallback(ptr);
}
return ptr;
}
virtual int STDMETHODCALLTYPE PostDidAlloc(void* /*ptr*/, BOOL /*wasSpyed*/, int result) override
{
return result;
}
virtual void STDMETHODCALLTYPE PreHeapMinimize() override
{
}
virtual void STDMETHODCALLTYPE PostHeapMinimize() override
{
}
};
Microsoft::WRL::ComPtr<MallocSpy> MakeSecureDeleterMallocSpy()
{
using namespace Microsoft::WRL;
auto result = Make<MallocSpy>();
REQUIRE(result);
result->PreFreeCallback = [](void* ptr)
{
ComPtr<IMalloc> malloc;
if (SUCCEEDED(::CoGetMalloc(1, &malloc)))
{
auto size = malloc->GetSize(ptr);
auto buffer = static_cast<byte*>(ptr);
for (size_t i = 0; i < size; ++i)
{
REQUIRE(buffer[i] == 0);
}
}
return ptr;
};
return result;
}
#endif