Java中如何从com.sun.jna.ptr.PointerByReference提取字符串值?
从JNA的PointerByReference提取令牌相关字符串
首先明确:你通过LogonUserW得到的phToken是指向**Windows登录令牌句柄(HANDLE)**的指针,并非直接存储字符串的容器。要获取令牌对应的用户信息字符串,需要调用Windows API查询令牌详情,具体步骤如下:
步骤1:获取令牌句柄指针
从PointerByReference中取出指向令牌句柄的指针:
Pointer tokenHandle = phToken.getValue();
步骤2:查询令牌用户信息的内存大小
先调用GetTokenInformation获取存储用户信息所需的内存大小:
IntByReference infoSize = new IntByReference(0); // 首次调用仅获取所需内存大小,返回值为false属于正常情况 advapi32.GetTokenInformation(tokenHandle, TOKEN_INFORMATION_CLASS.TokenUser, null, 0, infoSize);
步骤3:获取令牌用户信息
分配对应内存后,再次调用GetTokenInformation获取实际的用户信息:
Pointer userInfoBuffer = new Memory(infoSize.getValue()); if (!advapi32.GetTokenInformation(tokenHandle, TOKEN_INFORMATION_CLASS.TokenUser, userInfoBuffer, infoSize.getValue(), infoSize)) { // 处理错误,可调用kernel32.GetLastError()获取错误码 return; }
步骤4:解析SID并转换为用户名
用户信息中包含用户SID,通过LookupAccountSidW将SID转换为可读的用户名和域名:
// 从TOKEN_USER结构体中取出SID指针 Pointer sid = userInfoBuffer.getPointer(0); // 先获取用户名、域名的内存大小 IntByReference userNameSize = new IntByReference(0); IntByReference domainNameSize = new IntByReference(0); advapi32.LookupAccountSidW(null, sid, null, userNameSize, null, domainNameSize, new IntByReference(0)); // 分配内存存储用户名和域名 char[] userNameChars = new char[userNameSize.getValue()]; char[] domainNameChars = new char[domainNameSize.getValue()]; // 调用API获取实际的用户名和域名 if (advapi32.LookupAccountSidW(null, sid, userNameChars, userNameSize, domainNameChars, domainNameSize, new IntByReference(0))) { String fullUserName = new String(domainNameChars) + "\\" + new String(userNameChars); // 这里得到的就是你需要的字符串值 System.out.println(fullUserName); }
步骤5:释放资源
使用完令牌句柄后必须关闭,避免资源泄漏:
kernel32.CloseHandle(tokenHandle);
关键说明
- 确保你的JNA接口定义中包含以下内容:
TOKEN_INFORMATION_CLASS枚举(需包含TokenUser枚举值)GetTokenInformation、LookupAccountSidW、CloseHandle的正确映射
- 所有API调用后都应检查返回值,通过
kernel32.GetLastError()排查错误。
内容的提问来源于stack exchange,提问作者Ravi Soni
相关产品推荐
相关产品推荐

