捕获加密的 USB 解密事件?

Capture encrypted USB decryption event?

您好,我使用的是受密码保护的金士顿 DT4000 G2 USB 驱动器。

我可以通过调用 RegisterDeviceNotification() 在 windows 下跟踪磁盘插入和拔出事件, 并通过 WM_DEVICECHANGE;

接收通知

虽然问题是在我输入密码之前媒体不可用。 在解密之前我可以看到设备和系统将显示“请将磁盘插入 USB 驱动器 (E:)”。

但是当数据被解密并且我确实可以使用媒体时,我无法捕获事件。 是否可以使用 win32 捕获此类事件?

您可以将以下示例与 Win32_EncryptableVolume

GetLockStatus 方法一起使用
#include <windows.h> 
#include <dbt.h> 
#include <string>
#include <initguid.h>
#include <IoEvent.h>
#include <iostream>
#include <comdef.h>
#include <Wbemidl.h>
using namespace std;

#pragma comment(lib, "wbemuuid.lib")
#pragma warning(disable : 4996)


// Function prototype 
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
std::string DrivesFromMask(ULONG unitmask);
UINT32 GetLockStatus();

int main(int argc, char** argv)
{
    MSG         msg;        // MSG structure to store messages 
    HWND        hwndMain;   // Main window handle 
    WNDCLASSEX  wcx;        // WINDOW class information  
    HDEVNOTIFY  hDevnotify;
    DWORD       len;

    DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;

    // 53F56307-B6BF-11D0-94F2-00A0C91EFB8B 
    GUID FilterGUID = { 0x53F56307,0x0B6BF,0x11D0,{0x94,0xF2,0x00,0xA0,0xC9,0x1E,0xFB,0x8B} };


    // Initialize the struct to zero 
    ZeroMemory(&wcx, sizeof(WNDCLASSEX));

    wcx.cbSize = sizeof(WNDCLASSEX);        // Window size. Must always be sizeof(WNDCLASSEX) 
    wcx.style = 0;                          // Class styles 
    wcx.lpfnWndProc = (WNDPROC)MainWndProc; // Pointer to the callback procedure 
    wcx.cbClsExtra = 0;                     // Extra byte to allocate following the wndclassex structure 
    wcx.cbWndExtra = 0;                     // Extra byte to allocate following an instance of the structure 
    wcx.hInstance = GetModuleHandle(NULL);              // Instance of the application 
    wcx.hIcon = NULL;                       // Class Icon 
    wcx.hCursor = NULL;                     // Class Cursor 
    wcx.hbrBackground = NULL;               // Background brush 
    wcx.lpszMenuName = NULL;                // Menu resource 
    wcx.lpszClassName = "USB";              // Name of this class 
    wcx.hIconSm = NULL;                     // Small icon for this class 

    // Register this window class with MS-Windows 
    if (!RegisterClassEx(&wcx))
        return 0;

    // Create the window 
    hwndMain = CreateWindowEx(0,// Extended window style 
        "USB",          // Window class name 
        "",             // Window title 
        WS_POPUP,       // Window style 
        0, 0,           // (x,y) pos of the window 
        0, 0,           // Width and height of the window 
        NULL,           // HWND of the parent window (can be null also) 
        NULL,           // Handle to menu 
        GetModuleHandle(NULL),      // Handle to application instance 
        NULL);          // Pointer to window creation data 

// Check if window creation was successful 
    if (!hwndMain)
        return 0;

    // Make the window invisible 
    ShowWindow(hwndMain, SW_HIDE);

    // Initialize device class structure  
    len = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
    memset(&NotificationFilter, 0, len);

    NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
    NotificationFilter.dbcc_devicetype = 5;         // DBT_DEVTYP_DEVICEINTERFACE; 
    NotificationFilter.dbcc_classguid = FilterGUID;

    // Register 
    hDevnotify = RegisterDeviceNotification(hwndMain, &NotificationFilter, DEVICE_NOTIFY_WINDOW_HANDLE);

    if (hDevnotify == NULL)
        return 0;

    // Process messages coming to this window 
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    // return value to the system 
    return msg.wParam;
}

HDEVNOTIFY RegisterDevice(HWND hWnd, PDEV_BROADCAST_DEVICEINTERFACE PdevDEVICEINTERFACE)
{
    DEV_BROADCAST_HANDLE broadcast = { 0 };
    broadcast.dbch_size = sizeof(DEV_BROADCAST_HANDLE);
    broadcast.dbch_devicetype = DBT_DEVTYP_HANDLE;
    broadcast.dbch_handle = CreateFile(PdevDEVICEINTERFACE->dbcc_name, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
    return RegisterDeviceNotification(hWnd, &broadcast, DEVICE_NOTIFY_WINDOW_HANDLE);
}
HDEVNOTIFY hDevNotify = NULL;
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    PDEV_BROADCAST_VOLUME PdevVolume;
    PDEV_BROADCAST_DEVICEINTERFACE PdevDEVICEINTERFACE;
    std::string drvs;
    static UINT32 g_LockedDrivesMask;
    switch (msg)
    {
    case WM_DEVICECHANGE:
        switch (wParam)
        {
            // A device or piece of media has been inserted and is now available 
        case DBT_CUSTOMEVENT:
        {
            DEV_BROADCAST_HDR* hdr = (DEV_BROADCAST_HDR*)lParam;
            switch (hdr->dbch_devicetype)
            {
            case DBT_DEVTYP_HANDLE:
                UINT32 LockedDrivesMask = GetLockStatus();
                UINT32 result = LockedDrivesMask ^ g_LockedDrivesMask;
                if (result)
                {
                    for (int i = 0; i < 26 && result; ++i)
                    {
                        if (result & 0x1)
                        {
                            if (0 == (LockedDrivesMask & (0x1 << i)))
                                printf("%c: unlock!\n", i + 'A');
                        }
                        result = result >> 1;
                    }
                }
                g_LockedDrivesMask = LockedDrivesMask;
                break;
            }
        }
        break;
        case DBT_DEVICEARRIVAL:
            PdevDEVICEINTERFACE = (PDEV_BROADCAST_DEVICEINTERFACE)lParam;

            switch (PdevDEVICEINTERFACE->dbcc_devicetype)
            {
                // Class of devices 
            case DBT_DEVTYP_DEVICEINTERFACE:
                g_LockedDrivesMask = GetLockStatus();
                hDevNotify = RegisterDevice(hwnd, PdevDEVICEINTERFACE);
                break;
                // Logical volume 
            case DBT_DEVTYP_VOLUME:
                PdevVolume = (PDEV_BROADCAST_VOLUME)lParam;
                drvs = DrivesFromMask(PdevVolume->dbcv_unitmask);
                for (UINT i = 0; i < drvs.length(); i++)
                    printf("Drive %c:\ connected\n", drvs[i]);
            }
            break;
        case DBT_DEVICEREMOVEPENDING:
            PdevDEVICEINTERFACE = (PDEV_BROADCAST_DEVICEINTERFACE)lParam;
            UnregisterDeviceNotification(hDevNotify);
        }
        break;

    default:
        // Call the default window handler 
        return DefWindowProc(hwnd, msg, wParam, lParam);
    }

    return 0;
}

std::string DrivesFromMask(ULONG unitmask)
{
    char i;
    std::string drv = "";
    for (i = 0; i < 26 && unitmask; ++i)
    {
        if (unitmask & 0x1)
        {
            drv += i + 'A';
        }
        unitmask = unitmask >> 1;
    }
    return drv;
}


UINT32 GetLockStatus()
{
    HRESULT hres;
    hres = CoInitializeEx(0, COINIT_MULTITHREADED);
    hres = CoInitializeSecurity(
        NULL,
        -1,
        NULL,
        NULL,
        RPC_C_AUTHN_LEVEL_DEFAULT,
        RPC_C_IMP_LEVEL_IMPERSONATE,
        NULL,
        EOAC_NONE,
        NULL
    );

    IWbemLocator* pLoc = NULL;
    hres = CoCreateInstance(
        CLSID_WbemLocator,
        0,
        CLSCTX_INPROC_SERVER,
        IID_IWbemLocator, (LPVOID*)&pLoc);

    IWbemServices* pSvc = NULL;
    hres = pLoc->ConnectServer(
        _bstr_t(L"Root\CIMV2\Security\MicrosoftVolumeEncryption"), // Object path of WMI namespace
        NULL,
        NULL,
        0,
        NULL,
        0,
        0,
        &pSvc
    );

    hres = CoSetProxyBlanket(
        pSvc,
        RPC_C_AUTHN_WINNT,
        RPC_C_AUTHZ_NONE,
        NULL,
        RPC_C_AUTHN_LEVEL_CALL,
        RPC_C_IMP_LEVEL_IMPERSONATE,
        NULL,
        EOAC_NONE
    );

    IEnumWbemClassObject* pEnumerator = NULL;
    wstring strQuery = L"SELECT * FROM Win32_EncryptableVolume";
    hres = pSvc->ExecQuery(BSTR(L"WQL"), BSTR(strQuery.c_str()),
        WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator);

    IWbemClassObject* pclsObj = NULL;
    IWbemClassObject* pOutParams = NULL;
    ULONG uReturn = 0;
    UINT32 mask = 0;
    while (pEnumerator)
    {
        UINT32 bit = 0;
        hres = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);

        if (0 == uReturn || FAILED(hres))
            break;

        IWbemClassObject* pClass = NULL;
        hres = pSvc->GetObject(BSTR(L"Win32_EncryptableVolume"), 0, NULL, &pClass, NULL);

        VARIANT val;
        hres = pclsObj->Get(L"DriveLetter", 0, &val, 0, NULL);
        bit = val.bstrVal[0] - 'A';
        

        IWbemClassObject* pInParamsDefinition = NULL;
        hres = pClass->GetMethod(L"GetLockStatus", 0, NULL, NULL);

        VARIANT var;
        pclsObj->Get(L"__PATH", 0, &var, NULL, NULL);

        hres = pSvc->ExecMethod(var.bstrVal, _bstr_t(L"GetLockStatus"), 0,
            NULL, NULL, &pOutParams, NULL);
        VARIANT varReturnValue;
        hres = pOutParams->Get(_bstr_t(L"LockStatus"), 0,
            &varReturnValue, NULL, 0);
        if (varReturnValue.iVal)
        {
            mask |= 0x1 << bit;
        }
        VariantClear(&val);
        VariantClear(&var);
        VariantClear(&varReturnValue);

        pclsObj->Release();
        pClass->Release();
        pOutParams->Release();
        pOutParams = NULL;
    }
    pEnumerator->Release();
    pLoc->Release();
    pSvc->Release();
    CoUninitialize();
    return mask;
}

但请注意,由于 Security Considerations,此示例必须 运行 作为管理员。

或者没有管理员权限,您可以使用本例中的轮询方法:

https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/e0585eca-31fa-4fe4-873d-d87934cbbf9d/thread-not-working-if-winmain-arg-is-2?forum=windowssdk