Я потратил несколько дней, гоняясь за сбоем, который проявляется как структурированное исключение 0xC0000374
(повреждение кучи) ... Конечно, воспроизводимый только в среде клиента.
Сузил до этого (очень упрощенного) кода:
DWORD cchName = 0, cchDomain = 0;
SID_NAME_USE type;
if (!LookupAccountSidW(NULL, pSid, NULL, &cchName, NULL, &cchDomain, &type))
{
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
<bail via exception or return>;
}
cout << cchName << ":" << cchDomain << " -> ";
DWORD cchName1 = (cchName + 1), cchDomain1 = (cchDomain + 1);
LPWSTR pName = ... allocate cchName1 WCHARs ...;
LPWSTR pDomain = ... allocate cchDomain1 WCHARs ...;
if (!LookupAccountSidW(NULL, pSid, pName, &cchName1, pDomain, &cchDomain1, &type))
<bail via exception or return>;
cout << cchName1 << ":" << cchDomain1 << endl;
... deallocate pDomain; // <- here Application Verifier detects corrupted block
... deallocate pName;
Пожалуйста, игнорируйте возможность утечки памяти (код упрощен).Также обратите внимание, что в соответствии с MSDN перераспределение на 1 символ не требуется.Но позвольте мне описать то, что я вижу в отладчике ...
Для всех (кроме одного) идентификаторов SID, которые он обнаружил, выводятся такие вещи, как 16:7 -> 15:6
или 6:7 -> 5:6
, и все это прекрасно.По сути, первый вызов возвращает требуемые размеры буфера (включая завершающий NUL
), второй возвращает количество записанных символов (исключая NUL
) в предоставленные буферы (которые перераспределены на 1, между прочим).
Теперь один конкретный SID приводит к выводу 6:3 -> 5:2
.Но когда я смотрю на буфер pDomain
(длина которого составляет 4 символа), я вижу усеченное имя домена ABCD
(фактическое имя домена составляет 6 символов), за которым следует NUL
(что повреждает структуры управления кучей).Так что LookupAccountSidW
утверждает, что он записал только 2 (+1) символа, в то время как в действительности он записал 4 (+1) символа в буфер длиной 4 символа.
С моей точки зрения это ясноошибка в LookupAccountSidW
, но мне бы очень хотелось выяснить, чем этот SID отличается от других.Может быть, он был перенесен из другого (более короткого) домена?
PS Это Windows 10 (10.0.14393.2969)
PPS SID равен S-1-5-21-<3-part domain id>-<user id>