Преобразовать SID в строку - PullRequest
0 голосов
/ 08 февраля 2011

Я не разработчик C ++, поэтому я думаю, что это моя вина, что моя программа не работает.Я хочу найти SID для группы окон и вернуть читаемый SID.

wchar_t* SpcLookupName(LPCTSTR lpszSystemName, LPCTSTR lpszAccountName) {

PSID         Sid;
DWORD        cbReferencedDomainName, cbSid;
LPTSTR       ReferencedDomainName;
SID_NAME_USE eUse;

cbReferencedDomainName = cbSid = 0;
if (LookupAccountName(lpszSystemName, lpszAccountName, 0, &cbSid,
                    0, &cbReferencedDomainName, &eUse)) {
    SetLastError(ERROR_NONE_MAPPED);
    return 0;
}

if (GetLastError(  ) != ERROR_INSUFFICIENT_BUFFER) return 0;

if (!(Sid = (PSID)LocalAlloc(LMEM_FIXED, cbSid))) return 0;

ReferencedDomainName = (LPTSTR)LocalAlloc(LMEM_FIXED, cbReferencedDomainName);

if (!ReferencedDomainName) {
    LocalFree(Sid);
    return 0;
}

if (!LookupAccountName(lpszSystemName, lpszAccountName, Sid, &cbSid,
                     ReferencedDomainName, &cbReferencedDomainName, &eUse)) {
    LocalFree(ReferencedDomainName);
    LocalFree(Sid);
    return 0;
}

wchar_t* psz;

// Loading ConvertSidToStringSid
typedef BOOL (WINAPI *tConvertSidToStringSid)(PSID,wchar_t*);

tConvertSidToStringSid pConvertSidToStringSid=0;

HINSTANCE handle = ::LoadLibrary("Advapi32.dll");

pConvertSidToStringSid = (tConvertSidToStringSid) ::GetProcAddress(handle, "ConvertSidToStringSidA");

if(pConvertSidToStringSid(Sid, psz)){                               
    return psz;
}
}

Моя проблема в том, что функция возвращает только некоторые странные символы, а не SID, почему?

Ответы [ 4 ]

1 голос
/ 08 февраля 2011

Есть несколько очевидных вещей, которые не так с вашим кодом ...

1) прототип для ConvertSidToStringSid() равен BOOL ConvertSidToStringSid(PSID Sid, LPTSTR *StringSid); это означает, что ваш typedef должен быть typedef BOOL (WINAPI *tConvertSidToStringSid)(PSID,LPTSTR *);

2) вы просматриваете версию ANSI и передаете wchar_t * ... Вы должны либо найти версию широких символов ConvertSidToStringSid(), либо, лучшее решение, ИМХО, найти ConvertSidToStringSid и использовать TCHAR * вместо wchar_t *, поскольку это будет работать независимо от настроек компиляции Unicode и соответствует typedef.

3) наконец, из-за некорректного определения типа вам разрешено передавать неверный тип данных в функцию. Он хочет LPTSTR *, а вы передаете ему LPTSTR (ну, на самом деле вы передаете wchar_t * ... * LPTSTR на самом деле является типом, поддерживающим юникод, который отображается на wchar_t *, если вы используете широкие символы, но вызываемая функция хочет указатель на этот указатель, а не сам указатель.

Итак, фиксированный код:

typedef BOOL (WINAPI *tConvertSidToStringSid)(PSID,LPTSTR*);

tConvertSidToStringSid pConvertSidToStringSid=0;

HINSTANCE handle = ::LoadLibrary("Advapi32.dll");



pConvertSidToStringSid = (tConvertSidToStringSid) ::GetProcAddress(handle, #ConvertSidToStringSid);

if(pConvertSidToStringSid(Sid, &psz)){                               
    return psz;
}

Обратите внимание на изменение typedef, изменение на вызов GetProcAddress (где мы используем # для преобразования имени функции в строку (которое будет либо ConvertSidToStringSidA, либо ConvertSidToStringSidW в зависимости от настроек юникода) и изменение для передачи адреса psz а не сам указатель.

И теперь ваша единственная проблема заключается в том, что вы потенциально можете пропустить этот psz, если не будете уверены, что освободите его в вызывающем абоненте с помощью вызова LocalFree().

Обратите внимание, что в зависимости от вызывающего кода вы можете преобразовать typedef в wchar_t ** вместо LPTSTR *, а затем использовать версию ConvertSidToStringSidW, чтобы результат всегда был строкой широких символов.

0 голосов
/ 08 февраля 2011

Вы используете ConvertSidToStringSidA, который будет возвращать строку ANSI, в то время как вы ожидаете wchar_t* Попробуйте использовать ConvertSidToStringSidW вместо этого. Или просто включите Sddl.h и используйте ConvertSidToStringSid.

0 голосов
/ 08 февраля 2011

Вы вызываете версию функции ANSI, когда вам нужна версия Unicode "ConvertSidToStringSidW".

Также у вас небольшая утечка памяти, поскольку вы не всегда освобождаете Sid.

0 голосов
/ 08 февраля 2011

Возможно, ваш pConvertSidToStringSid(Sid, psz) вызов не был успешным, а SpcLookupName() возвращаемое значение не определено, потому что вы ничего не возвращаете.

А почему вы смешиваете ConvertSidToStringSidA с wchar_t?Было бы лучше использовать ConvertSidToStringSid из Sddl.h напрямую:

#define _WIN32_WINNT 0x0500
#include <Sddl.h>

Вы также должны вернуть LPTSTR из вашей функции вместо wchar_t *

...