1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2016-2017 - TortoiseGit
4 // Copyright (C) 2003-2006, 2008, 2013-2015 - TortoiseSVN
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software Foundation,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include "../version.h"
26 #pragma comment(lib, "Version.lib")
29 : m_hInstance(nullptr)
37 HINSTANCE
CLangDll::Init(LPCTSTR appname
, unsigned long langID
)
39 TCHAR langpath
[MAX_PATH
] = {0};
40 TCHAR langdllpath
[MAX_PATH
] = {0};
41 TCHAR sVer
[MAX_PATH
] = {0};
42 wcscpy_s(sVer
, _T(STRPRODUCTVER
));
43 GetModuleFileName(nullptr, langpath
, _countof(langpath
));
44 TCHAR
* pSlash
= wcsrchr(langpath
, L
'\\');
49 pSlash
= wcsrchr(langpath
, L
'\\');
54 wcscat_s(langpath
, L
"\\Languages\\");
55 assert(m_hInstance
== nullptr);
58 swprintf_s(langdllpath
, L
"%s%s%lu.dll", langpath
, appname
, langID
);
60 m_hInstance
= LoadLibrary(langdllpath
);
62 if (!DoVersionStringsMatch(sVer
, langdllpath
))
65 FreeLibrary(m_hInstance
);
66 m_hInstance
= nullptr;
70 DWORD lid
= SUBLANGID(langID
);
73 langID
= MAKELANGID(PRIMARYLANGID(langID
), lid
);
77 } while (!m_hInstance
&& (langID
!= 0));
82 void CLangDll::Close()
87 FreeLibrary(m_hInstance
);
88 m_hInstance
= nullptr;
91 bool CLangDll::DoVersionStringsMatch(LPCTSTR sVer
, LPCTSTR langDll
) const
100 DWORD dwBufferSize
= GetFileVersionInfoSize((LPTSTR
)langDll
,&dwReserved
);
102 if (dwBufferSize
== 0)
105 auto pBuffer
= std::make_unique
<BYTE
[]>(dwBufferSize
);
110 UINT nInfoSize
= 0, nFixedLength
= 0;
111 LPSTR lpVersion
= nullptr;
112 VOID
* lpFixedPointer
;
113 TRANSARRAY
* lpTransArray
;
114 TCHAR strLangProductVersion
[MAX_PATH
] = { 0 };
116 if (!GetFileVersionInfo((LPTSTR
)langDll
, dwReserved
, dwBufferSize
, pBuffer
.get()))
119 VerQueryValue(pBuffer
.get(), L
"\\VarFileInfo\\Translation", &lpFixedPointer
, &nFixedLength
);
120 lpTransArray
= (TRANSARRAY
*)lpFixedPointer
;
122 swprintf_s(strLangProductVersion
, L
"\\StringFileInfo\\%04x%04x\\ProductVersion", lpTransArray
[0].wLanguageID
, lpTransArray
[0].wCharacterSet
);
124 VerQueryValue(pBuffer
.get(), (LPTSTR
)strLangProductVersion
, (LPVOID
*)&lpVersion
, &nInfoSize
);
125 if (lpVersion
&& nInfoSize
)
126 return (wcscmp(sVer
, (LPCTSTR
)lpVersion
) == 0);