#include <windows.h>
#include <setupapi.h>
#include <tchar.h>
#include <stdio.h>
#include <string>
#pragma comment(lib,"ws2_32.lib")
#pragma comment(lib,"setupapi.lib")

//wchar_t * char2wchar(const char* cchar)
//{
//    wchar_t *m_wchar;
//    int len = MultiByteToWideChar(CP_ACP, 0, cchar, strlen(cchar), NULL, 0);
//    m_wchar = new wchar_t[len + 1];
//    MultiByteToWideChar(CP_ACP, 0, cchar, strlen(cchar), m_wchar, len);
//    m_wchar[len] = '\0';
//    return m_wchar;
//}
//
//char * wchar2char(const wchar_t* wchar)
//{
//    char * m_char;
//    int len = WideCharToMultiByte(CP_ACP, 0, wchar, wcslen(wchar), NULL, 0, NULL, NULL);
//    m_char = new char[len + 1];
//    WideCharToMultiByte(CP_ACP, 0, wchar, wcslen(wchar), m_char, len, NULL, NULL);
//    m_char[len] = '\0';
//    return m_char;
//}

BOOL DisableNetInterface(const std::string& szHardWareId, bool bStatus)
{
    IN LPTSTR HardwareId;
    //硬件ComponentId,注册表地址:system\currentcontrolset\class\{4D36E972-E325-11CE-BFC1-08002BE10318}\0000
    // HardwareId = L"PCI\\VEN_8086&DEV_0085&SUBSYS_13118086&REV_34";
    HardwareId = (LPTSTR)szHardWareId.c_str();
    DWORD NewState;
    if (bStatus)
    {
        NewState = DICS_DISABLE;
        //禁用
    }
    else
    {
        NewState = DICS_ENABLE;
        //启用
    }
    //调用ddk函数,来禁用网卡
    DWORD i, err;
    BOOL Found = false;
    HDEVINFO hDevInfo;
    SP_DEVINFO_DATA spDevInfoData;
    //访问系统的硬件库
    hDevInfo = SetupDiGetClassDevs(NULL, "PCI", NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT);
    if (hDevInfo == INVALID_HANDLE_VALUE)
    {
        //printf("访问系统硬件出错!");
        return false;
    }
    //枚举硬件,获得需要的接口
    spDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
    for (i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &spDevInfoData); i++)
    {
        DWORD DataT;
        LPTSTR p, buffer = NULL;
        DWORD buffersize = 0;
        //获得硬件的属性值
        while (!SetupDiGetDeviceRegistryProperty(
            hDevInfo,
            &spDevInfoData,
            SPDRP_HARDWAREID,
            &DataT,
            (PBYTE)buffer,
            buffersize,
            &buffersize))
        {
            if (GetLastError() == ERROR_INVALID_DATA)
            {
                //不存在HardwareID. Continue.
                break;
            }
            else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
            {
                //buffer size不对.
                if (buffer)
                    LocalFree(buffer);
                buffer = (LPTSTR)LocalAlloc(LPTR, buffersize);
            }
            else
            {
                //未知错误
                goto cleanup_DeviceInfo;
            }
        }
        if (GetLastError() == ERROR_INVALID_DATA)
            continue;
        //比较,找到和网卡ID相同的项
        for (p = buffer; *p && (p < &buffer[buffersize]); p += lstrlen(p) + sizeof(TCHAR))
        {
            if (!_tcscmp(HardwareId, p))
            {
                //找到网卡
                Found = TRUE;
                break;
            }
        }
        if (buffer)
            LocalFree(buffer);
        //如果相等
        if (Found)
        {
            //禁用该设备
            SP_PROPCHANGE_PARAMS spPropChangeParams;
            spPropChangeParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
            spPropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
            spPropChangeParams.Scope = DICS_FLAG_GLOBAL;
            spPropChangeParams.StateChange = NewState;
            //禁用:DICS_DISABLE,DICS_ENABLE启用
            //
            if (!SetupDiSetClassInstallParams(hDevInfo, &spDevInfoData, (SP_CLASSINSTALL_HEADER*)&spPropChangeParams, sizeof(spPropChangeParams)))
            {
                DWORD errorcode = GetLastError();
            }
            if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, hDevInfo, &spDevInfoData))
            {
                DWORD errorcode = GetLastError();
            }
            switch (NewState)
            {
            case DICS_DISABLE:
                printf("成功禁用网络!");
                break;
            case DICS_ENABLE:
                printf("成功启用网络!");
                break;
            }
            break;
        }
    }
    //delete[] HardwareId;
    //HardwareId = nullptr;

    //退出时,清理工作环境
    cleanup_DeviceInfo:
    err = GetLastError();
    SetupDiDestroyDeviceInfoList(hDevInfo);
    SetLastError(err);
    return true;
}