2011-02-08 46 views
0

私はC++開発者ではないので、自分のプログラムがうまくいかないという私のせいです。 WindowsグループのSIDを検索して、読み取り可能な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ではなく、奇妙な文字だけを返すことです。なぜですか?

+0

どのようにして印刷をしているの? - 関数は文字列へのポインタを返しますが、print文は見えませんか? – Tom

+0

私はメッセージボックスでそれをテストしましたが、今はコードにはありません。 – Taram777

+0

本当に、PowerShellや.netやPythonのような、あなたのために包まれた場所では、これは簡単ではありません。このようなツールをC++でハッキングするのは苦痛です。特にC++にうまく対応していない場合は特にそうです。とにかくあなたのためにこれを行うresキットコンソールアプリケーションさえあるでしょう! –

答えて

1

あなたのコードが間違って明白な物事のカップル...

1)ConvertSidToStringSid()のプロトタイプがBOOL ConvertSidToStringSid(PSID Sid, LPTSTR *StringSid)であります。これは、あなたのtypedefがなければならないことを意味しますが、ANSIバージョンを検索し、wchar_t型を渡しているtypedef BOOL (WINAPI *tConvertSidToStringSid)(PSID,LPTSTR *);

2)* ...あなたはどちらかConvertSidToStringSidを検索、ワイド文字バージョンConvertSidToStringSid()や、よりよい解決策、私見を調べる必要がありますwchar_t *ではなくTCHAR *を使用してください。これは、Unicodeのコンパイル設定が何であっても機能し、typedefと一致するためです。

3)最後に、typedefが壊れているため、間違ったデータ型を関数に渡すことができます。それはLPTSTR *を望んでおり、それはLPTSTRを渡しています(実際には、wchar_t *を渡しています...)は実際にはワイド文字を使用している場合は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の呼び出し(への変更#は関数名(Unicode設定に応じてConvertSidToStringSidAまたはConvertSidToStringSidWのい​​ずれかになります)とpasへの変更を文字列化しますポインタ自体ではなくpszのアドレスです。

そして今あなたの唯一の問題は、あなたがLocalFree()への呼び出しで発信者からメッセージを解放することを確認しない限り、そのpszを潜在的に漏らしているということです。

呼び出しコードによっては、LPTSTR *ではなくtypedefをwchar_t **に変換し、ConvertSidToStringSidWバージョンを使用して結果を常にワイド文字列にすることをお勧めします。

+0

私はそれをやってみましたが、今私はこれらの2つのメッセージを受け取ります: "stray 'プログラムで"と "ConvertSidToStringSid'はこのスコープで宣言されていません"。 – Taram777

+0

私は決してそれを編集したことはありませんし、テキストフォームでその名前の別のマクロを上に上げるのに気を使うことはできませんでした。 wchar_tバージョンとConvertSidToStringSidWを使用してください。ただし、typedefと関数呼び出しを修正してください。 –

+0

ありがとう – Taram777

0

pConvertSidToStringSid(Sid, psz)呼び出しが成功しない可能性があり、何も返さないためSpcLookupName()戻り値は未定義です。

なぜ、ConvertSidToStringSidAとwchar_tを混ぜているのですか?

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

また、あなたはあなたがwchar_t*を期待していると同時に、ANSI文字列を返しますどのConvertSidToStringSidAを使うwchar_t *

+0

pConvertSidToStringSid(Sid、psz)が成功しました。私はメッセージボックスでそれをテストしましたが、ここに貼り付けたコードにはありません。 – Taram777

0

あなたの関数からLPTSTRを返す代わりにすべきである:直接Sddl.hからConvertSidToStringSidを使用する方が良いだろう。代わりにConvertSidToStringSidWを使用してください。または、Sddl.hを含めて、ConvertSidToStringSidを使用してください。

+0

前にConvertSidToStringSidWで試してみましたが、うまくいきませんでした。だからConvertSidToStringSidAはちょうど別の試みでした、ここでそれを混在させて申し訳ありません。 私はssdl.hをインクルードしましたが、 "ConvertSidToStringSid"を呼び出すと、コンパイラは "'ConvertSidToStringSid'がこのスコープで宣言されていないと言います。 – Taram777

0

Unicodeバージョン"ConvertSidToStringSidW"を使用する場合は、ANSIバージョンの関数を呼び出しています。

いつもSidを解放していないので、メモリリークが小さいです。