Проблема в C++ с _tprintf печатью вопросительных знаков
У меня проблемы с C++, я не часто использую этот язык!
Я пытаюсь обработать списки ACL в каталоге NTFS, чтобы вывести полный список всех разрешенных и запрещенных разрешений, существующих в каталоге.
У меня есть списки ACL из каталога в порядке, и у меня есть имя Domain\Account для большинства записей. Однако в некоторых случаях вывод этой команды дает мне????????\????????.
Я определил 2 причины для этого.
1) учетная запись пользователя была удалена с компьютера, поэтому SID является бесхозным. Я могу определить это с GetLastError () = 1332.
2) это "общеизвестный SID", то есть какой-то встроенный SID, поэтому имя пользователя для сопоставления отсутствует - LookupAccountSid не сообщает об ошибке на этом этапе. У меня нет возможности (насколько я вижу) идентифицировать эти случаи, не отображая все известные идентификаторы безопасности в файл и не делая перекрестные ссылки (медленно). Что я хочу сделать, это просто вывести SID вместо????????. LPTSTR myTrusteeName - это строка, возвращаемая LookupAccountSid(), которая отображается как???????? Я не знаю, каково его действительное значение, если бы я знал, что мог бы легко сделать оператор IF, чтобы вместо этого напечатать SID.
//this is part of a loop.
if (IsValidSid(mySid)){
//cout << "SID supplied is valid\n";
//cout << GetLengthSid(mySid) << "\n";
LPWSTR mySidName = NULL;
ConvertSidToStringSid((PSID)mySid, &mySidName);
//Make an initial lookup to find out how big the names are
LookupAccountSid(
NULL
, (PSID) mySid
, myTrusteeName
, (LPDWORD)&myDwordNameLength
, myDomainName
, (LPDWORD)&myDwordDomLength
, &myNameUse
); //at this point error 122 is thrown as the length of myTrusteeName is too short.
//alter the size of these variables rather than just getting the 1st letter and some gibberish
myTrusteeName = (LPTSTR)GlobalAlloc(GMEM_FIXED, myDwordNameLength);
myDomainName = (LPTSTR)GlobalAlloc(GMEM_FIXED, myDwordDomLength);
//do the lookup again this time with genuine sizes
LookupAccountSid(
NULL
, (PSID)mySid
, myTrusteeName
, (LPDWORD)&myDwordNameLength
, myDomainName
, (LPDWORD)&myDwordDomLength
, &myNameUse
);
wcout << GetLastError() << "\n"; //this will output "122" even when successful because of the first attempt.
_tprintf(TEXT("%s\n"), myTrusteeName); //when there is no name this outputs ????????
wcout << myTrusteeName << "\n"; //when there is no name this completely screws myTrusteeName so that it fails to print for the rest of the loop
//if we only have ???? then it's wrong
if (myTrusteeName == NULL){ /// WHAT IN HELL DO I PUT IN THIS COMPARISON TO IDENTIFY myTrusteeName VALUES THAT PRINT ????????
wcout << "we are changing trustee because it's blank\n";
myTrusteeName = _T("");//maybe change this to the value of mySidName
wcout << "length of trustee is now " << _tcslen(myTrusteeName) << "\n";
}
wcout << "\n";
}
Теперь... пока я пишу это, я понимаю, что есть функция с именем IsWellKnownSid() facepalm
Это выводит элемент из перечисления WELL_KNOWN_SID_TYPE
Я должен быть в состоянии использовать это.... Я не уверен, как я могу получить строковое представление хорошо известного типа sid (то есть "Пользователи"), как вы уже видели в редакторе ACL.... Если У кого-нибудь есть какие-либо советы по этому поводу, я был бы очень благодарен
Я еще не закончил с этим небольшим проектом, поэтому я решил опубликовать его в любом случае, если он окажется полезным для кого-то еще в будущем!
Мне все еще любопытно - если бы не было функции IsWellKnownSid(), как бы я обнаружил строковое значение, которое отказывается печатать, ДО ТОГО, как я пытаюсь его напечатать?
Большое спасибо за чтение и наилучшие пожелания Бен
1 ответ
Вы должны проверить это ConvertSidToStringSid
а также LookupAccountSid
вернуть ИСТИНА. Если они это сделают, тогда LookupAccountSid записывает строку в myTrusteeName
, Если LookupAccountSid возвращает FALSE, тогда LookupAccountSid не изменит содержимое myTrusteeName
так что это будет так же неинициализировано, как GlobalAlloc
вернул его.