You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C语言中枚举Boot Entries且避免程序崩溃?

问题分析与解决

你的代码存在两个核心问题,直接导致程序崩溃:

1. 缓冲区类型错误

你声明了PBOOT_ENTRY_LIST* BootEntries(二级指针),但NtEnumerateBootEntries要求的第一个参数是PBOOT_ENTRY_LIST(一级指针,指向BOOT_ENTRY_LIST结构体的缓冲区)。错误的指针类型会让函数写入错误的内存地址,后续访问时触发非法内存访问。

2. 启动项数量计算错误

sizeof(BootEntries) / sizeof(PBOOT_ENTRY_LIST*)计算的是指针本身的大小除以指针类型的大小,在32/64位系统中结果都是1,完全无法得到真实的启动项数量。正确做法是读取BOOT_ENTRY_LIST结构体自带的Count字段,该字段由NtEnumerateBootEntries填充,记录了实际启动项总数。


修正后的代码

ULONG BufferLength;
NTSTATUS NtStatus = NtEnumerateBootEntries(NULL, &BufferLength);
if (NtStatus != STATUS_BUFFER_TOO_SMALL) { NtStatusErrorExit("NtEnumerateBootEntries", NtStatus); }

// 修正:使用一级指针匹配函数参数要求
PBOOT_ENTRY_LIST BootEntries = (PBOOT_ENTRY_LIST)malloc(BufferLength);
if (!BootEntries) { /* 处理内存分配失败逻辑 */ }

NtStatus = NtEnumerateBootEntries(BootEntries, &BufferLength);
if (NT_ERROR(NtStatus)) { 
    free(BootEntries); // 分配成功后需释放内存
    NtStatusErrorExit("NtEnumerateBootEntries", NtStatus); 
}

// 修正:从结构体Count字段获取真实启动项数量
int NumBootEntries = BootEntries->Count;
printf("Number of Boot Entries: %i\n", NumBootEntries);

// 修正:访问结构体中的BootEntry数组
for (int i = 0; i < NumBootEntries; i++) {
    BOOT_ENTRY BootEntry = BootEntries->BootEntry[i];
    printf("Boot Entry ID: %lu\n", BootEntry.Id);
}

// 释放分配的缓冲区,避免内存泄漏
free(BootEntries);

额外注意事项

  • 内存分配后必须检查是否成功,防止空指针访问。
  • NtEnumerateBootEntries是未公开系统函数,不同Windows版本的结构体定义可能存在差异,需确保BOOT_ENTRY_LIST和BOOT_ENTRY的定义与目标系统匹配,示例定义如下:
    typedef struct _BOOT_ENTRY {
        ULONG Id;
        WCHAR Name[256];
        // 其他字段根据系统版本补充
    } BOOT_ENTRY, *PBOOT_ENTRY;
    
    typedef struct _BOOT_ENTRY_LIST {
        ULONG Count;
        BOOT_ENTRY BootEntry[ANYSIZE_ARRAY];
    } BOOT_ENTRY_LIST, *PBOOT_ENTRY_LIST;
    

内容的提问来源于stack exchange,提问作者Hantalyte

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 12:15:29