MikeCheers 2023-03-12 12:53 采纳率: 50%
浏览 39

c++ 结构体指针放入map后取值错误的问题

这是一个内核驱动的一部分,碰到了一个奇怪的问题(可能是我脸太白……)

创建设备,指定IRP_MJ_DEVICE_CONTROL的处理函数为 RouterManager::IoDispatch,这里没什么问题。



NDIS_STATUS    RouterManager::CreateMyDevice(){
    NDIS_STATUS  Status;

    // Fill in the dispatch table array and register device
    static PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1];
    NdisZeroMemory(MajorFunction, sizeof(MajorFunction));
    MajorFunction[IRP_MJ_CREATE] = 
        MajorFunction[IRP_MJ_CLOSE] = 
        MajorFunction[IRP_MJ_CLEANUP] = 
        MajorFunction[IRP_MJ_READ] = 
        MajorFunction[IRP_MJ_WRITE] = 
        MajorFunction[IRP_MJ_DEVICE_CONTROL] = RouterManager::IoDispatch;

    Status = NdisMRegisterDevice(
        *KNdisMiniDriver::DriverInstance(),
        KNDIS_STRING_CONST("\\Device\\MwSysNdisRouter"),
        KNDIS_STRING_CONST("\\DosDevices\\MwSysNdisRouter"),
        MajorFunction,
        &RouterManager::m_pDeviceObject,
        &RouterManager::m_DeviceHandle);

    T.Trace(__FUNCTION__"\tCreate Device: %s\n", ((Status) ? "FAILED" : "SUCCESS"));

    return Status;
}

定义了一个结构体,简化为:

typedef struct _IO_COMMANDS_EXCHANGE_PARAMS {
    UCHAR    m_bytes[49];

    bool IsEnable(){ return m_bytes[0] ? true : false; }

        // index : 1 ~ 6 为mac地址,这里跳过。

    ULONG GetIpAddr_RS(){
        ULONG    ip = 0;
        memcpy(&ip, m_bytes + 7, sizeof(ULONG));
        return ip;
    }

    PSTR GetIpAddrStr_RS(){
        PSTR addr = new CHAR[16];
        RtlSecureZeroMemory(addr, 16);
        sprintf(addr, "%u.%u.%u.%u", m_bytes[10], m_bytes[9], m_bytes[8], m_bytes[7]);
        return addr;
    }

    USHORT GetTcpPort_RS(){
        USHORT    tcpport = 0;
        memcpy(&tcpport, m_bytes + 11, sizeof(USHORT));
        return tcpport;
    }

    VOID PrintMBytes(){
        T.Trace(__FUNCTION__"\t");
        for(int index = 0; index < sizeof(m_bytes); index++){
            T.Trace("-%02X", m_bytes[index]);
        }
        T.Trace("\n");
    }

// .... 省略若干函数

} IO_COMMANDS_EXCHANGE_PARAMS, *P_IO_COMMANDS_EXCHANGE_PARAMS; 

在RouterManager中定义了一个map


    static map<string, P_IO_COMMANDS_EXCHANGE_PARAMS>        T_MAP_EXC_EXT;

在RouterManager::IoDispatch中给这个map添加pair<string, P_IO_COMMANDS_EXCHANGE_PARAMS>


NTSTATUS    RouterManager::IoDispatch            (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
    NTSTATUS Status = STATUS_SUCCESS;
    static UCHAR response[] = {(UCHAR)4};
    KIrp I(Irp);

    // 首先要得到功能号
    ULONG code = I.IoctlCode();
    // 得到输入输出缓冲长度
    ULONG in_len = I.IoctlInputBufferSize();
    ULONG out_len = I.IoctlOutputBufferSize();
    PVOID buffer = I.IoctlType3InputBuffer();

    //ULONG_PTR informaiton = 0;

    T.Trace(__FUNCTION__"\t code: %x, in_len: %u, out_len: %u.\n", code, in_len, out_len);

    switch(code){
        case IO_COMMANDS_EXCHANGE:
            {
                P_IO_COMMANDS_EXCHANGE_PARAMS params = (P_IO_COMMANDS_EXCHANGE_PARAMS)buffer;

                //  这里各项输出正常
                T.Trace(__FUNCTION__"\t case: %s; Enable: %s; \nMacAddress: %s; IpAddress: %s; Port: %u; \nMacAddress: %s; IpAddress: %s; Port: %u.\n"
                    , "IO_COMMANDS_EXCHANGE"
                    , ((params->IsEnable()) ? "True" : "False")
                    , params->GetMacStr_RS()
                    , params->GetIpAddrStr_RS()
                    , params->GetTcpPort_RS()
                    , params->GetMacStr_RC()
                    , params->GetIpAddrStr_RC()
                    , params->GetTcpPort_RC());

                RouterManager::ExecCommandExchange(params);

                I.Information() = 0;
            }
            break;
        default:
            T.Trace(__FUNCTION__"\t case: %s;\n", "default");
            break;
    }

    return I.Complete(Status);
}

VOID        RouterManager::ExecCommandExchange(P_IO_COMMANDS_EXCHANGE_PARAMS params){
    PSTR rKey = params->GetRKey();
    PSTR lKey = params->GetLKey();

    params->PrintMBytes();

    { // 这里的输出也正常
        T.Trace(__FUNCTION__"\t r: %u:%s:%u <--> %u:%s:%u.\n"
            , params->GetIpAddr_RS()
            , params->GetIpAddrStr_RS()
            , params->GetTcpPort_RS()
            , params->GetIpAddr_RC()
            , params->GetIpAddrStr_RC()
            , params->GetTcpPort_RC());

        T.Trace(__FUNCTION__"\t l: %u:%s:%u <--> %u:%s:%u.\n"
            , params->GetIpAddr_LS()
            , params->GetIpAddrStr_LS()
            , params->GetTcpPort_LS()
            , params->GetIpAddr_LC()
            , params->GetIpAddrStr_LC()
            , params->GetTcpPort_LC());
    }

    {
        map<string, P_IO_COMMANDS_EXCHANGE_PARAMS>::iterator it = RouterManager::T_MAP_EXC_EXT.find(rKey);

        if(it == RouterManager::T_MAP_EXC_EXT.end()){
            if(params->IsEnable()){
                RouterManager::T_MAP_EXC_EXT.insert(pair<string, P_IO_COMMANDS_EXCHANGE_PARAMS>(rKey, params));
                T.Trace(__FUNCTION__"\t Exchange map '%s'-'%s'.\n", rKey, lKey);
            }
        }else{
            if(params->IsEnable())
                it->second = params;
            else
                RouterManager::T_MAP_EXC_EXT.erase(it);
        }
    }

    {
        map<string, P_IO_COMMANDS_EXCHANGE_PARAMS>::iterator it = RouterManager::T_MAP_EXC_EXT.find(lKey);

        if(it == RouterManager::T_MAP_EXC_EXT.end()){
            if(params->IsEnable()){
                RouterManager::T_MAP_EXC_EXT.insert(pair<string, P_IO_COMMANDS_EXCHANGE_PARAMS>(lKey, params));
                T.Trace(__FUNCTION__"\t Exchange map '%s'-'%s'.\n", lKey, rKey);
            }
        }else{
            if(params->IsEnable()){
                it->second = params;
            }
            else{
                RouterManager::T_MAP_EXC_EXT.erase(it);
            }
        }
    }
    
    if(0 <RouterManager::T_MAP_EXC_EXT.size()){
        for(map<string, P_IO_COMMANDS_EXCHANGE_PARAMS>::iterator it = T_MAP_EXC_EXT.begin(); it != T_MAP_EXC_EXT.end(); ++it){
            
            it->second->PrintMBytes();  // 这里的输出依旧没有问题

            // 可是这里就出问题了,我在后面副一张图阐述问题。
            T.Trace(__FUNCTION__"\t key: %s; rs: %s:%u; rc: %s:%u; ls: %s:%u; lc: %s:%u.\n"
                , it->first
                , it->second->GetIpAddrStr_RS()
                , it->second->GetTcpPort_RS()
                , it->second->GetIpAddrStr_RC()
                , it->second->GetTcpPort_RC()
                , it->second->GetIpAddrStr_LS()
                , it->second->GetTcpPort_LS()
                , it->second->GetIpAddrStr_LC()
                , it->second->GetTcpPort_LC());
        }
    }
}

img


预期的输出是从B点开始,实际却从A点开始了,导致

T.Trace(__FUNCTION__"\t key: %s; rs: %s:%u; rc: %s:%u; ls: %s:%u; lc: %s:%u.\n",.....)

中,rs:部分是一段未知的结果,rc: 中是预期的rs部分的结果,后面的依次类推。
而且我在输出之前,打印了结构体中m_bytes的数据,与之前的打印做了对比,是一致的。
搞不清为什么输出的时候就“打歪了” - -!

希望我把问题描述清楚了,请大家不吝赐教,感谢!

  • 写回答

2条回答 默认 最新

  • threenewbee 2023-03-12 14:19
    关注

    你需要调试下,看看指针是否正确调用了。

    评论

报告相同问题?

问题事件

  • 修改了问题 3月12日
  • 创建了问题 3月12日

悬赏问题

  • ¥15 用visualstudio2022创建vue项目后无法启动
  • ¥15 x趋于0时tanx-sinx极限可以拆开算吗
  • ¥500 把面具戴到人脸上,请大家贡献智慧
  • ¥15 任意一个散点图自己下载其js脚本文件并做成独立的案例页面,不要作在线的,要离线状态。
  • ¥15 各位 帮我看看如何写代码,打出来的图形要和如下图呈现的一样,急
  • ¥30 c#打开word开启修订并实时显示批注
  • ¥15 如何解决ldsc的这条报错/index error
  • ¥15 VS2022+WDK驱动开发环境
  • ¥30 关于#java#的问题,请各位专家解答!
  • ¥30 vue+element根据数据循环生成多个table,如何实现最后一列 平均分合并