前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >遍历 Windows 系统账户信息

遍历 Windows 系统账户信息

作者头像
我与梦想有个约会
发布2023-10-21 14:36:31
1880
发布2023-10-21 14:36:31
举报
文章被收录于专栏:jiajia_deng

最近在重构一个项目的时候需要用到遍历系统账户信息和每个账户的 SID 信息用来对比数据,所以就涉及到如何获取 Windows 的账户信息,以及每个账户所关联的 SID。学习了一些前辈的代码后自己总结了一下记录在博客里,方便以后使用。

代码效果

2016-10-08_103411
2016-10-08_103411

相关代码

代码使用 Windows API 遍历了系统账户信息,并实现了一个将 SID 转为字符串的功能函数。将账户名和 SID 分别打印了出来。

代码语言:javascript
复制
#include "stdafx.h"
#include "Ntsecapi.h"

DWORD GetStrWithPSID(PSID pSid, TCHAR* szBuffer, int nLength);

int _tmain(int argc, _TCHAR* argv[])
{
    PLUID       pSessions; 
    NTSTATUS    ntStatus;  
    ULONG       ulCount = 0;

    // 枚举所有账户信息
    ntStatus = LsaEnumerateLogonSessions(&ulCount, &pSessions);
    for (ULONG i = 0; i < ulCount; i++)
    {
        // 取出一个账户信息到 pSessionData,该函数在内部分配内存
        PSECURITY_LOGON_SESSION_DATA pSessionData = NULL;
        ntStatus = LsaGetLogonSessionData (&pSessions[i], &pSessionData);
        if (0 != ntStatus)
        {
            if (pSessionData)
            {
                LsaFreeReturnBuffer(pSessionData);
            }

            continue;
        }

        // 验证 SID 是否有效
        if (pSessionData && IsValidSid(pSessionData->Sid))
        {
            TCHAR szUserName[MAX_PATH] = {0};
            TCHAR szSID[MAX_PATH] = {0};

            // 拷贝并打印用户名信息,该结构体中有很多成员,描述了该账户的属性
            if (NULL != pSessionData->UserName.Buffer)
            {
                ZeroMemory(szUserName, MAX_PATH);
                CopyMemory(szUserName, pSessionData->UserName.Buffer, pSessionData->UserName.Length);
                wcout << szUserName << _T(" -> ");
                GetStrWithPSID(pSessionData->Sid, szSID, MAX_PATH);
                wcout << szSID << endl;
            }
        }

        // 释放资源
        if (NULL != pSessionData)
        {
            LsaFreeReturnBuffer(pSessionData);
        }
    }

    getchar();
    return 0;
}

DWORD GetStrWithPSID(PSID pSid, TCHAR* szBuffer, int nLength)
{
    // convert SID to string
    SID_IDENTIFIER_AUTHORITY *psia = ::GetSidIdentifierAuthority(pSid);
    DWORD dwTopAuthority = psia->Value[5];
    _stprintf_s(szBuffer, nLength, _T("S-1-%lu"), dwTopAuthority);

    TCHAR szTemp[32];
    int iSubAuthorityCount = *(GetSidSubAuthorityCount(pSid));
    for (int i = 0; i < iSubAuthorityCount; i++)
    {
        DWORD dwSubAuthority = *(GetSidSubAuthority(pSid, i));
        _stprintf_s(szTemp, 32, _T("%lu"), dwSubAuthority);
        _tcscat_s(szBuffer, nLength, _T("-"));
        _tcscat_s(szBuffer, nLength, szTemp);
    }

    return 0;
}

要注意的是,由于使用了 Secur32 中的函数,所以工程中要导入 Secur32.lib 才能正常编译。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016-10-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 代码效果
  • 相关代码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档