-
Notifications
You must be signed in to change notification settings - Fork 0
/
LogObject.cpp
160 lines (144 loc) · 5.49 KB
/
LogObject.cpp
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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#include "stdafx.h"
#include "LogObject.h"
#include "HookImplementObject.h"
namespace cchips {
int CLogObject::m_reference_count = 0;
std::unique_ptr<CLogObject> g_log_object(CLogObject::GetInstance());
/* Generate a temporary file name based on TMPL. TMPL must match the
rules for mk[s]temp (i.e. end in "XXXXXX"). The name constructed
does not exist at the time of the call to mkstemp. TMPL is
overwritten with the result. */
FILE* CLpcLocalObject::mkstemp(char *tmpl)
{
int len;
char *XXXXXX;
static unsigned long long value;
unsigned long long random_time_bits;
unsigned int count;
FILE* fd = nullptr;
int save_errno = errno;
char tmpl_name[MAX_PATH] = { };
static const char letters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
/* A lower bound on the number of temporary files to attempt to
generate. The maximum total number of temporary file names that
can exist for a given template is 62**6. It should never be
necessary to try all these combinations. Instead if a reasonable
number of names is tried (we define reasonable as 62**3) fail to
give the system administrator the chance to remove the problems. */
#define ATTEMPTS_MIN (62 * 62 * 62)
/* The number of times to attempt to generate a temporary file. To
conform to POSIX, this must be no smaller than TMP_MAX. */
#if ATTEMPTS_MIN < TMP_MAX
unsigned int attempts = TMP_MAX;
#else
unsigned int attempts = ATTEMPTS_MIN;
#endif
int dwRetVal = GetTempPath(MAX_PATH, // length of the buffer
tmpl_name); // buffer for path
if (dwRetVal > MAX_PATH || (dwRetVal == 0))
{
errno = EINVAL;
return nullptr;
}
len = (int)strlen(tmpl);
if (len < 6 || len >= (MAX_PATH - dwRetVal) || strcmp(&tmpl[len - 6], "XXXXXX"))
{
errno = EINVAL;
return nullptr;
}
if (!strcat(tmpl_name, tmpl)) return nullptr;
/* This is where the Xs start. */
len += dwRetVal;
XXXXXX = &tmpl_name[len - 6];
/* Get some more or less random data. */
{
SYSTEMTIME stNow;
FILETIME ftNow;
// get system time
GetSystemTime(&stNow);
stNow.wMilliseconds = 500;
if (!SystemTimeToFileTime(&stNow, &ftNow))
{
errno = -1;
return nullptr;
}
random_time_bits = (((unsigned long long)ftNow.dwHighDateTime << 32)
| (unsigned long long)ftNow.dwLowDateTime);
}
value += random_time_bits ^ (unsigned long long)GetCurrentThreadId();
for (count = 0; count < attempts; value += 7777, ++count)
{
unsigned long long v = value;
/* Fill in the random bits. */
XXXXXX[0] = letters[v % 62];
v /= 62;
XXXXXX[1] = letters[v % 62];
v /= 62;
XXXXXX[2] = letters[v % 62];
v /= 62;
XXXXXX[3] = letters[v % 62];
v /= 62;
XXXXXX[4] = letters[v % 62];
v /= 62;
XXXXXX[5] = letters[v % 62];
fd = fopen(tmpl_name, "w+x");
if (fd >= 0)
{
errno = save_errno;
return fd;
}
else if (errno != EEXIST)
return nullptr;
}
/* We got out of the loop because we ran out of combinations to try. */
errno = EEXIST;
return nullptr;
}
bool CLogObject::Initialize(const int mode)
{
std::function<RAPID_DOC_PAIR()> getdata(std::bind(&CLogObject::GetData, this));
#ifdef USING_PIPE_MESSAGE
std::wstring pipe_name;
if (mode == output_pipe) {
pipe_name = L"\\\\.\\pipe\\hips_hook";
}
else if (mode == output_local) {
wchar_t tmp_buffer[MAX_PATH] = {};
GetCurrentDirectoryW(MAX_PATH, tmp_buffer);
pipe_name = std::wstring(L"LocalFile\\") + std::wstring(tmp_buffer) + L"hipshook.log";
}
if (!pipe_name.length()) return false;
std::unique_ptr<PipeJSONClient> pipe_ptr = std::make_unique<PipeJSONClient>(pipe_name, PipeJSONClient::cfg_serial);
if (pipe_ptr && pipe_ptr->Start())
m_pipe_client = std::move(pipe_ptr);
if (m_pipe_client)
return true;
#else
std::unique_ptr<CLpcPipeObject> pipe_ptr = std::make_unique<CLpcPipeObject>();
if (pipe_ptr->Connect(getdata))
m_socket_object = std::move(pipe_ptr);
else
{
std::unique_ptr<CLpcLocalObject> local_ptr = std::make_unique<CLpcLocalObject>();
if (local_ptr->Connect(getdata))
m_socket_object = std::move(local_ptr);
}
if(m_socket_object)
return true;
#endif
return false;
}
RAPID_DOC_PAIR CLogObject::GetData() {
static std::once_flag log_flag;
std::shared_ptr<CLogEntry> log = nullptr;
do {
std::lock_guard<std::recursive_mutex> lockGuard(m_recursive_mutex);
if (m_cache_logs.empty()) break;
log = m_cache_logs.front();
m_cache_logs.pop_front();
} while (0);
if (log)
return log->Serialize();
return RAPID_DOC_PAIR(nullptr,nullptr);
}
} // namespace cchips