0

我想查询在 C++ 中定义在以太网卡上的 Wake On Lan 模式(稍后我想上传这样的模式,但一步一步。:))。据我了解,我必须将OID_PM_WOL_PATTERN_LIST请求从用户空间发送到内核空间。我发现在 Windows 上可以调用DeviceIoControl发送这种请求。我使用 > this < 示例代码作为起点。我有设备的 GUID,我可以发出一些基本的 IOCTL_* 命令。

如果我理解得很好,我必须发出一个特定的 IOCTL_* 命令,其中 InBuffer 指向一些结构(可能是 NDIS_OID_REQUEST),其中填充了 OID_PM_WOL_PATTERN_LIST 命令。

我试图找到一些应该如何做到这一点的例子,但我找不到合适的例子。有人可以帮助如何做到这一点吗?或者一个示例来源会有所帮助。

4

1 回答 1

0

最后我找到了解决方案...

#include <iostream>
#include <winsock2.h> /* Prevent inclusion of winsock.h in windows.h */
#include <iphlpapi.h>
#include <Windows.h>
#include <IPTypes.h>
#include <WinIoCtl.h>
#define UM_NDIS650
#include <NtDDNdis.h>
#include <strsafe.h>

#pragma comment(lib, "iphlpapi.lib")
//#pragma comment(lib, "ws2_32.lib")

using namespace std;
#define ErrorMsgPos() errorMsg(__FILE__, __LINE__, __func__)

DWORD errorMsg(const char *strFile, DWORD line, const char *strFunc) {
    // Retrieve the system error message for the last-error code

    std::wstringstream ss;
    ss << strFile << ':' << line << ' ' << strFunc << "();";
    wstring str = ss.str();
    LPVOID lpMsgBuf;
    LPVOID lpDisplayBuf;
    DWORD dwErr = GetLastError();

    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER |
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        dwErr,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR)&lpMsgBuf,
        0, NULL
    );

    // Display the error message and exit the process

    lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
        (lstrlen((LPCTSTR)lpMsgBuf) + str.length() + 40) * sizeof(TCHAR)
    );
    if (lpDisplayBuf) {
        StringCchPrintfW(
            (LPTSTR)lpDisplayBuf,
            LocalSize(lpDisplayBuf) / sizeof(TCHAR),
            TEXT("%s\nfailed with: [%d] \"%s\""),
            str.c_str(),
            dwErr,
            (LPTSTR)lpMsgBuf
        );

        wcerr << (LPCTSTR)lpDisplayBuf << endl;
        //MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
    }
    LocalFree(lpDisplayBuf);
    LocalFree(lpMsgBuf);
    //ExitProcess(dw);

    return dwErr;
} // errorMsg


void outData(DWORD dw, char *data) {
    DWORD i;
    char buf[17];
    memset(buf, 0, 17);

    char prev = cout.fill('0');
    for (i = 0; i < dw; ++i) {
        cout << hex;
        if (i % 16 == 0) {
            char prev = cout.fill('0');
            cout << "    " << setw(4) << (DWORD)i << " : ";
            cout.fill(prev);
            memset(buf, 0, 16);
        }

        cout << setw(2) << ((unsigned int)data[i] & 0xFF);
        buf[i % 16] = (unsigned int)(data[i] == 0 ? '_' 
                : data[i] < 32 || data[i] > 127 ? '.' : data[i]
        ) & 0xff;

        if (i % 16 < 15) cout << (i % 4 == 3 ? "  " : " ");
        else cout << " : " << buf << dec <<  endl;
    }

    // Final, partial row
    for (int i = dw % 16 == 0 ? 16 : dw % 16; i < 16; ++i) {
        cout << "  ";
        if (i % 16 < 15) cout << (i % 4 == 3 ? "  " : " ");
        else cout << " : " << buf << endl;
    }
    cout.fill(prev);
} // outData

#define ShowGlobalStat(h, cd, buf,size, rv_sz)  \
    showGlobalStat(h, cd, #cd, buf, size, rv_sz, __FILE__, __LINE__, __func__)

DWORD showGlobalStat(HANDLE hDevice, unsigned int cd, const char* name
    , char *outBuf, size_t size, size_t *rv_size
    , const char* file, unsigned int line, const char* func
) {
    unsigned int code = cd;
    DWORD dwBytesReturned;
    BOOL res = DeviceIoControl(
        hDevice, IOCTL_NDIS_QUERY_GLOBAL_STATS,
        &code, sizeof(code),
        outBuf, size,
        &dwBytesReturned, NULL
    );
    char prev = cout.fill('0');
    cout << "\n*** cmd: " << name << ", code: " << hex << setw(8) << cd;
    DWORD dw = 0;
    *rv_size = dwBytesReturned;
    if (res) {
        cout << " bytes(" << dwBytesReturned << ")" << dec << endl;
        cout.fill(prev);
        outData(dwBytesReturned, outBuf);
    } else {
        cout << endl;
        dw = errorMsg(file, line, func);
    }

    return dw;
} // showGlobalStat


int main() {
    char buf[2048];
    size_t sz = sizeof(buf), rw;

    ShowGlobalStat(hDevice, OID_PM_WOL_PATTERN_LIST, buf, sz, &rw);
    if (rw) {
        ULONG offset = 0;
        do {
            NDIS_PM_WOL_PATTERN* pBuf =
               (NDIS_PM_WOL_PATTERN*)(buf + offset);
            cout << "Offset: << offset << endl;
            offset = pBuf->NextWoLPatternOffset;
        } while (offset > 0);
    } else
        cout << "... No items. Size of NDIS_PM_WOL_PATTERN " 
            << sizeof(NDIS_PM_WOL_PATTERN) << endl;
} // main
于 2019-12-31T17:41:18.360 回答