private struct TOKEN_USER
{
internal SID_AND_ATTRIBUTES User; //Compiler warning comes from here.
}
[StructLayout(LayoutKind.Sequential)]
private struct SID_AND_ATTRIBUTES
{
internal IntPtr Sid;
private int Attributes;
}
기본값으로 구조를 초기화를해야합니다 :필드 '필드'에 할당되지 않습니다, 항상 기본값
다음 구조에 포인터를 검색하기 위해 두 개의 필수 호출을TOKEN_USER tokenUser = default(TOKEN_USER);
: (질문과 관련 없음)을 사용하여 다음을 사용합니다.
GetTokenInformation(tokenhandle, TokenInformationClass.TokenUser, sid, sidlength, ref sidlength);
그런 다음 다시 구조로 정렬합니다.
tokenUser = (TOKEN_USER)Marshal.PtrToStructure(sid, tokenUser.GetType());
작동하지만 컴파일러에서 TOKEN_USER의 'User'필드가 할당 취소되었다고 경고합니다.
public TOKEN_USER(SID_AND_ATTRIBUTES user) : this(user)
{
}
그러나,이 컴파일되지 않는 오류 "생성자는 자신을 호출 할 수 없습니다"로 :
R 번호 나 생성자에서 초기화 제안합니다. 제 질문은 컴파일러의 요구 사항을 충족 시키거나 무시할 수 있도록 SID_AND_ATTRIBUTES (기본값)에 할당해야합니까?
테스트 프로그램은 :
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr OpenProcess(
int dwDesiredAccess,
[MarshalAs(UnmanagedType.Bool)] bool bInheritHandle,
int dwProcessId);
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool OpenProcessToken(
IntPtr processHandle,
int desiredAccess,
ref IntPtr TokenHandle);
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool GetTokenInformation(
IntPtr tokenHandle,
TokenInformationClass tokenInformationClass,
IntPtr tokenInformation,
int TokenInformationLength,
ref int ReturnLength);
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool IsValidSid(
IntPtr SID);
private enum TokenInformationClass
{
TokenUser = 1,
}
private const int QueryInformation = 0x400;
private const int TokenRead = 0x20008;
private struct TOKEN_USER
{
internal SID_AND_ATTRIBUTES User; //Compiler warning comes from here.
}
[StructLayout(LayoutKind.Sequential)]
private struct SID_AND_ATTRIBUTES
{
internal IntPtr Sid;
private int Attributes;
}
internal static IntPtr GetProcessHandle()
{
foreach (Process p in Process.GetProcesses())
{
using (p)
{
if (p.ProcessName == "explorer")
{
return OpenProcess(QueryInformation, false, p.Id);
}
}
}
return IntPtr.Zero;
}
public void Test()
{
IntPtr pHandle = GetProcessHandle();
IntPtr tokenHandle = IntPtr.Zero;
OpenProcessToken(pHandle, TokenRead, ref tokenHandle);
int sidlength = 0;
GetTokenInformation(tokenHandle, TokenInformationClass.TokenUser, IntPtr.Zero,
0, ref sidlength);
TOKEN_USER tokenUser = default(TOKEN_USER);
IntPtr sid = Marshal.AllocHGlobal(sidlength);
GetTokenInformation(tokenHandle, TokenInformationClass.TokenUser,sid,
sidlength, ref sidlength);
tokenUser = (TOKEN_USER)Marshal.PtrToStructure(sid, tokenUser.GetType());
if (IsValidSid(tokenUser.User.Sid))
{
Debug.WriteLine("Valid!");
}
}
전체 프로그램을 표시 할 수 있습니까? –
@DavidHeffernan 전체 프로그램이 너무 축소되어 문제를 시연 할 수있는 테스트 프로그램을 만들었습니다. 프로세스 토큰을 사용하고 있으므로 반환 할 도우미 함수를 만들었습니다. 데모 용 "탐색기"프로세스 토큰. – SomeNickName
'tokenUser = default (TOKEN_USER)'의 요점은 무엇입니까? 나중에'tokenUser'에 지정합니다. 컴파일러는 어떤 코드 행을 처리합니까? –