LibreOffice Module onlineupdate (master) 1
pathhash.cxx
Go to the documentation of this file.
1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5#ifdef _WIN32
6#include <windows.h>
7#include <wincrypt.h>
8#include "pathhash.h"
9
10
19static void
20BinaryDataToHexString(const BYTE *hash, DWORD &hashSize,
21 LPWSTR hexString)
22{
23 WCHAR *p = hexString;
24 for (DWORD i = 0; i < hashSize; ++i)
25 {
26 wsprintfW(p, L"%.2x", hash[i]);
27 p += 2;
28 }
29}
30
40static BOOL
41CalculateMD5(const char *data, DWORD dataSize,
42 BYTE **hash, DWORD &hashSize)
43{
44 HCRYPTPROV hProv = 0;
45 HCRYPTHASH hHash = 0;
46
47 if (!CryptAcquireContext(&hProv, nullptr, nullptr, PROV_RSA_FULL,
48 CRYPT_VERIFYCONTEXT))
49 {
50 if (NTE_BAD_KEYSET != GetLastError())
51 {
52 return FALSE;
53 }
54
55 // Maybe it doesn't exist, try to create it.
56 if (!CryptAcquireContext(&hProv, nullptr, nullptr, PROV_RSA_FULL,
57 CRYPT_VERIFYCONTEXT | CRYPT_NEWKEYSET))
58 {
59 return FALSE;
60 }
61 }
62
63 if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash))
64 {
65 return FALSE;
66 }
67
68 if (!CryptHashData(hHash, reinterpret_cast<const BYTE*>(data),
69 dataSize, 0))
70 {
71 return FALSE;
72 }
73
74 DWORD dwCount = sizeof(DWORD);
75 if (!CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE *)&hashSize,
76 &dwCount, 0))
77 {
78 return FALSE;
79 }
80
81 *hash = new BYTE[hashSize];
82 ZeroMemory(*hash, hashSize);
83 if (!CryptGetHashParam(hHash, HP_HASHVAL, *hash, &hashSize, 0))
84 {
85 return FALSE;
86 }
87
88 if (hHash)
89 {
90 CryptDestroyHash(hHash);
91 }
92
93 if (hProv)
94 {
95 CryptReleaseContext(hProv,0);
96 }
97
98 return TRUE;
99}
100
109BOOL
110CalculateRegistryPathFromFilePath(const LPCWSTR filePath,
111 LPWSTR registryPath)
112{
113 size_t filePathLen = wcslen(filePath);
114 if (!filePathLen)
115 {
116 return FALSE;
117 }
118
119 // If the file path ends in a slash, ignore that character
120 if (filePath[filePathLen -1] == L'\\' ||
121 filePath[filePathLen - 1] == L'/')
122 {
123 filePathLen--;
124 }
125
126 // Copy in the full path into our own buffer.
127 // Copying in the extra slash is OK because we calculate the hash
128 // based on the filePathLen which excludes the slash.
129 // +2 to account for the possibly trailing slash and the null terminator.
130 WCHAR *lowercasePath = new WCHAR[filePathLen + 2];
131 memset(lowercasePath, 0, (filePathLen + 2) * sizeof(WCHAR));
132 wcsncpy(lowercasePath, filePath, filePathLen + 1);
133 _wcslwr(lowercasePath);
134
135 BYTE *hash;
136 DWORD hashSize = 0;
137 if (!CalculateMD5(reinterpret_cast<const char*>(lowercasePath),
138 filePathLen * 2,
139 &hash, hashSize))
140 {
141 delete[] lowercasePath;
142 return FALSE;
143 }
144 delete[] lowercasePath;
145
146 LPCWSTR baseRegPath = L"SOFTWARE\\LibreOffice\\MaintenanceService\\";
147 wcsncpy(registryPath, baseRegPath, MAX_PATH);
148 BinaryDataToHexString(hash, hashSize,
149 registryPath + wcslen(baseRegPath));
150 delete[] hash;
151 return TRUE;
152}
153#endif
#define TRUE
#define FALSE
void * p
int i
BOOL CalculateRegistryPathFromFilePath(const LPCWSTR filePath, LPWSTR registryPath)
Converts a file path into a unique registry location for cert storage.
const wchar_t *typedef BOOL
unsigned char BYTE