Fix warning
[TortoiseGit.git] / src / Utils / LangDll.cpp
blob3f1edf1690ebd4b40df74eafb781597f46cb8d11
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.
20 #include "stdafx.h"
21 #include <assert.h>
22 #include "LangDll.h"
23 #include "../version.h"
24 #include <memory>
26 #pragma comment(lib, "Version.lib")
28 CLangDll::CLangDll()
29 : m_hInstance(nullptr)
33 CLangDll::~CLangDll()
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'\\');
45 if (!pSlash)
46 return m_hInstance;
48 *pSlash = 0;
49 pSlash = wcsrchr(langpath, L'\\');
50 if (!pSlash)
51 return m_hInstance;
53 *pSlash = 0;
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))
64 if (m_hInstance)
65 FreeLibrary(m_hInstance);
66 m_hInstance = nullptr;
68 if (!m_hInstance)
70 DWORD lid = SUBLANGID(langID);
71 lid--;
72 if (lid > 0)
73 langID = MAKELANGID(PRIMARYLANGID(langID), lid);
74 else
75 langID = 0;
77 } while (!m_hInstance && (langID != 0));
79 return m_hInstance;
82 void CLangDll::Close()
84 if (!m_hInstance)
85 return;
87 FreeLibrary(m_hInstance);
88 m_hInstance = nullptr;
91 bool CLangDll::DoVersionStringsMatch(LPCTSTR sVer, LPCTSTR langDll) const
93 struct TRANSARRAY
95 WORD wLanguageID;
96 WORD wCharacterSet;
99 DWORD dwReserved = 0;
100 DWORD dwBufferSize = GetFileVersionInfoSize((LPTSTR)langDll,&dwReserved);
102 if (dwBufferSize == 0)
103 return false;
105 auto pBuffer = std::make_unique<BYTE[]>(dwBufferSize);
107 if (!pBuffer)
108 return false;
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()))
117 return false;
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);
128 return false;