mirror of
https://github.com/veracrypt/VeraCrypt
synced 2024-11-24 20:13:33 +01:00
Windows: fix SetupAPI issue on some machines where it fails to handle properly AddReg/DelReg operations during System encryption/decryption wizard.
This commit is contained in:
parent
a7056a6ac3
commit
1bf219b0dc
@ -3424,6 +3424,87 @@ namespace VeraCrypt
|
|||||||
|
|
||||||
#endif // SETUP
|
#endif // SETUP
|
||||||
|
|
||||||
|
static bool CompareMultiString (const char* str1, const char* str2)
|
||||||
|
{
|
||||||
|
size_t l1, l2;
|
||||||
|
if (!str1 || !str2)
|
||||||
|
return false;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
l1 = strlen (str1);
|
||||||
|
l2 = strlen (str2);
|
||||||
|
if (l1 == l2)
|
||||||
|
{
|
||||||
|
if (l1 == 0)
|
||||||
|
break; // we reached the end
|
||||||
|
if (_stricmp (str1, str2) == 0)
|
||||||
|
{
|
||||||
|
str1 += l1 + 1;
|
||||||
|
str2 += l2 + 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void AppendToMultiString (char* mszDest, DWORD dwMaxDesSize, DWORD& dwDestSize, const char* input)
|
||||||
|
{
|
||||||
|
// find the index of the end of the last string
|
||||||
|
DWORD dwInputSize = (DWORD) strlen (input) + 1;
|
||||||
|
DWORD index = dwDestSize;
|
||||||
|
while (index > 0 && mszDest[index - 1] == 0)
|
||||||
|
index--;
|
||||||
|
|
||||||
|
if (dwMaxDesSize > (index + 1 + dwInputSize + 1))
|
||||||
|
{
|
||||||
|
if (index == 0)
|
||||||
|
{
|
||||||
|
StringCchCopyA ((char *) mszDest, dwMaxDesSize, input);
|
||||||
|
mszDest [dwInputSize] = 0;
|
||||||
|
dwDestSize = dwInputSize + 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mszDest[index] = 0;
|
||||||
|
StringCchCopyA ((char *) &mszDest[index + 1], dwMaxDesSize - index - 1, input);
|
||||||
|
mszDest [index + 1 + dwInputSize] = 0;
|
||||||
|
dwDestSize = index + 1 + dwInputSize + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// mszDest is guaranteed to be double zero terminated
|
||||||
|
static bool RemoveFromMultiString (char* mszDest, DWORD& dwDestSize, const char* input)
|
||||||
|
{
|
||||||
|
bool bRet = false;
|
||||||
|
if (mszDest && input)
|
||||||
|
{
|
||||||
|
DWORD offset, remainingSize = dwDestSize;
|
||||||
|
while (*mszDest)
|
||||||
|
{
|
||||||
|
if (_stricmp (mszDest, input) == 0)
|
||||||
|
{
|
||||||
|
offset = (DWORD) strlen (input) + 1;
|
||||||
|
memmove (mszDest, mszDest + offset, remainingSize - offset);
|
||||||
|
dwDestSize -= offset;
|
||||||
|
bRet = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
offset = (DWORD) strlen (mszDest) + 1;
|
||||||
|
mszDest += offset;
|
||||||
|
remainingSize -= offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bRet;
|
||||||
|
}
|
||||||
|
|
||||||
void BootEncryption::RegisterFilter (bool registerFilter, FilterType filterType, const GUID *deviceClassGuid)
|
void BootEncryption::RegisterFilter (bool registerFilter, FilterType filterType, const GUID *deviceClassGuid)
|
||||||
{
|
{
|
||||||
string filter;
|
string filter;
|
||||||
@ -3458,7 +3539,9 @@ namespace VeraCrypt
|
|||||||
|
|
||||||
finally_do_arg (HKEY, regKey, { RegCloseKey (finally_arg); });
|
finally_do_arg (HKEY, regKey, { RegCloseKey (finally_arg); });
|
||||||
|
|
||||||
if (registerFilter && filterType != DumpFilter)
|
if (registerFilter)
|
||||||
|
{
|
||||||
|
if (filterType != DumpFilter)
|
||||||
{
|
{
|
||||||
// Register class filter below all other filters in the stack
|
// Register class filter below all other filters in the stack
|
||||||
|
|
||||||
@ -3477,7 +3560,91 @@ namespace VeraCrypt
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// workaround rare SetupInstallFromInfSection which overwrite value instead of appending new value
|
||||||
|
// read initial value
|
||||||
|
DWORD strSize = (DWORD) filter.size() + 1, expectedSize;
|
||||||
|
Buffer expectedRegKeyBuf(65536), outputRegKeyBuf(65536);
|
||||||
|
byte* pbExpectedRegKeyBuf = expectedRegKeyBuf.Ptr ();
|
||||||
|
byte* pbOutputRegKeyBuf = outputRegKeyBuf.Ptr ();
|
||||||
|
DWORD initialSize = (DWORD) (expectedRegKeyBuf.Size() - strSize - 2);
|
||||||
|
|
||||||
|
if (RegQueryValueExA (regKey, filterReg.c_str(), NULL, NULL, pbExpectedRegKeyBuf, &initialSize) != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
StringCchCopyA ((char *) pbExpectedRegKeyBuf, expectedRegKeyBuf.Size(), filter.c_str());
|
||||||
|
pbExpectedRegKeyBuf [strSize] = 0;
|
||||||
|
expectedSize = strSize + 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
expectedSize = initialSize;
|
||||||
|
AppendToMultiString ((char *) pbExpectedRegKeyBuf, (DWORD) expectedRegKeyBuf.Size(), expectedSize, filter.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
RegisterDriverInf (registerFilter, filter, filterReg, ParentWindow, regKey);
|
RegisterDriverInf (registerFilter, filter, filterReg, ParentWindow, regKey);
|
||||||
|
|
||||||
|
// check if operation successful
|
||||||
|
initialSize = (DWORD) outputRegKeyBuf.Size() - 2;
|
||||||
|
if (RegQueryValueExA (regKey, filterReg.c_str(), NULL, NULL, pbOutputRegKeyBuf, &initialSize) != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
pbOutputRegKeyBuf [0] = 0;
|
||||||
|
pbOutputRegKeyBuf [1] = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// append two \0 at the end if they are missing
|
||||||
|
if (pbOutputRegKeyBuf [initialSize - 1] != 0)
|
||||||
|
{
|
||||||
|
pbOutputRegKeyBuf [initialSize] = 0;
|
||||||
|
pbOutputRegKeyBuf [initialSize + 1] = 0;
|
||||||
|
}
|
||||||
|
else if (pbOutputRegKeyBuf [initialSize - 2] != 0)
|
||||||
|
{
|
||||||
|
pbOutputRegKeyBuf [initialSize] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CompareMultiString ((char *) pbExpectedRegKeyBuf, (char *) pbOutputRegKeyBuf))
|
||||||
|
{
|
||||||
|
// Set value manually
|
||||||
|
SetLastError (RegSetValueExA (regKey, filterReg.c_str(), 0, REG_MULTI_SZ, pbExpectedRegKeyBuf, expectedSize));
|
||||||
|
throw_sys_if (GetLastError() != ERROR_SUCCESS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RegisterDriverInf (registerFilter, filter, filterReg, ParentWindow, regKey);
|
||||||
|
|
||||||
|
// remove value in case it was not done properly
|
||||||
|
Buffer regKeyBuf(65536);
|
||||||
|
byte* pbRegKeyBuf = regKeyBuf.Ptr ();
|
||||||
|
|
||||||
|
DWORD initialSize = (DWORD) regKeyBuf.Size() - 2;
|
||||||
|
|
||||||
|
if ( (RegQueryValueExA (regKey, filterReg.c_str(), NULL, NULL, pbRegKeyBuf, &initialSize) == ERROR_SUCCESS)
|
||||||
|
&& (initialSize >= ((DWORD) filter.size()))
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// append two \0 at the end if they are missing
|
||||||
|
if (pbRegKeyBuf [initialSize - 1] != 0)
|
||||||
|
{
|
||||||
|
pbRegKeyBuf [initialSize] = 0;
|
||||||
|
pbRegKeyBuf [initialSize + 1] = 0;
|
||||||
|
initialSize += 2;
|
||||||
|
}
|
||||||
|
else if (pbRegKeyBuf [initialSize - 2] != 0)
|
||||||
|
{
|
||||||
|
pbRegKeyBuf [initialSize] = 0;
|
||||||
|
initialSize ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RemoveFromMultiString ((char*) pbRegKeyBuf, initialSize, filter.c_str()))
|
||||||
|
{
|
||||||
|
// Set value manually
|
||||||
|
SetLastError (RegSetValueExA (regKey, filterReg.c_str(), 0, REG_MULTI_SZ, pbRegKeyBuf, initialSize));
|
||||||
|
throw_sys_if (GetLastError() != ERROR_SUCCESS);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user