-
Notifications
You must be signed in to change notification settings - Fork 0
/
Utility.cpp
194 lines (156 loc) · 5.42 KB
/
Utility.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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
//---------------------------------------------------------------------------//
//
// Utility.cpp
// TTB Plugin Template (C++11)
//
//---------------------------------------------------------------------------//
#include <windows.h>
#include <strsafe.h>
#pragma comment(lib, "version.lib") // VerQueryValue
#include "Plugin.hpp"
#include "Utility.hpp"
//---------------------------------------------------------------------------//
//
// ユーティリティルーチン
//
//---------------------------------------------------------------------------//
// 文字列の格納領域を確保し、文字列をコピーして返す
LPTSTR CopyString(LPCTSTR Src)
{
const auto len = 1 + ::lstrlen(Src);
auto Dst = new TCHAR[len];
if ( Dst != nullptr )
{
::StringCchCopy(Dst, len, Src);
}
return Dst;
}
//---------------------------------------------------------------------------//
// 文字列を削除する
void DeleteString(LPCTSTR Str)
{
if ( Str != nullptr )
{
delete[] Str;
}
}
//---------------------------------------------------------------------------//
// プラグイン情報構造体をディープコピーして返す
PLUGIN_INFO* CopyPluginInfo(const PLUGIN_INFO* Src)
{
if ( Src == nullptr ) { return nullptr; }
const auto info = new PLUGIN_INFO;
if ( info == nullptr )
{
return nullptr;
}
// プラグイン情報のコピー
*info = *Src;
info->Name = CopyString(Src->Name);
info->Filename = CopyString(Src->Filename);
info->Commands = (Src->CommandCount == 0) ?
nullptr : new PLUGIN_COMMAND_INFO[Src->CommandCount];
// コマンド情報のコピー
if ( info->Commands != nullptr && Src->Commands != nullptr )
{
for ( size_t i = 0; i < Src->CommandCount; ++i )
{
info->Commands[i] = Src->Commands[i];
info->Commands[i].Name = CopyString(Src->Commands[i].Name);
info->Commands[i].Caption = CopyString(Src->Commands[i].Caption);
}
}
return info;
}
//---------------------------------------------------------------------------//
// プラグイン側で作成されたプラグイン情報構造体を破棄する
void FreePluginInfo(PLUGIN_INFO* PluginInfo)
{
if ( PluginInfo == nullptr ) { return; }
// コマンド情報構造体配列の破棄
if ( PluginInfo->Commands != nullptr )
{
for ( size_t i = 0; i < PluginInfo->CommandCount; ++i )
{
const auto pCI = &PluginInfo->Commands[i];
DeleteString(pCI->Name);
DeleteString(pCI->Caption);
}
delete[] PluginInfo->Commands;
}
DeleteString(PluginInfo->Filename);
DeleteString(PluginInfo->Name);
delete PluginInfo;
}
//---------------------------------------------------------------------------//
// バージョン情報を返す
void GetVersion(LPTSTR Filename, DWORD* VersionMS, DWORD* VersionLS)
{
if ( VersionMS == nullptr || VersionLS == nullptr ) { return; }
// DLL ファイルに埋め込まれたバージョンリソースのサイズを取得
DWORD VersionHandle;
const auto VersionSize = GetFileVersionInfoSize(Filename, &VersionHandle);
if ( VersionSize == 0 )
{
return;
}
// バージョンリソースを読み込む
const auto pVersionInfo = new BYTE[VersionSize];
if ( pVersionInfo == nullptr )
{
return;
}
if ( GetFileVersionInfo(Filename, VersionHandle, VersionSize, pVersionInfo) )
{
VS_FIXEDFILEINFO* FixedFileInfo;
UINT itemLen;
// バージョンリソースからファイルバージョンを取得
if ( VerQueryValue(pVersionInfo, (LPTSTR)TEXT("\\"), (void **)&FixedFileInfo, &itemLen) )
{
*VersionMS = FixedFileInfo->dwFileVersionMS;
*VersionLS = FixedFileInfo->dwFileVersionLS;
}
}
delete[] pVersionInfo;
}
//---------------------------------------------------------------------------//
// ログを出力する
void WriteLog(ERROR_LEVEL logLevel, LPCTSTR format, ...)
{
#if defined(_USRDLL)
// 本体が TTBPlugin_WriteLog をエクスポートしていない場合は何もしない
if ( TTBPlugin_WriteLog == nullptr ) { return; }
#endif
constexpr size_t BUF_SIZE { 1024 + 1 };
static TCHAR msg[BUF_SIZE];
// TODO: 排他制御
// 文字列の結合
va_list al;
va_start(al, format);
{
#if defined(_NODEFLIB)
::wvsprintf(msg, format, al);
// NOTE: If the length of msg exceeds 1024 byte,
// wvsprintf() writes NULL at msg[1024].
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms647550(v=vs.85).aspx
#else
::StringCchVPrintf(msg, BUF_SIZE, format, al);
#endif
}
va_end(al);
msg[BUF_SIZE - 1] = '\0';
// ログの出力
TTBPlugin_WriteLog(g_hPlugin, logLevel, msg);
}
//---------------------------------------------------------------------------//
// ほかのプラグインのコマンドを実行する
BOOL ExecutePluginCommand(LPCTSTR pluginName, INT32 CmdID)
{
#if defined(_USRDLL)
// 本体が TTBPlugin_ExecuteCommand をエクスポートしていない場合は何もしない
if ( TTBPlugin_ExecuteCommand == nullptr ) { return TRUE; }
#endif
return TTBPlugin_ExecuteCommand(pluginName, CmdID);
}
//---------------------------------------------------------------------------//
// Utility.cpp