Search code examples
winapiadaraw-input

GetRawInputDeviceList fails with error 87 (Incorrect parameters)


I am having a problem calling Raw Input functions for my 64 bit application that worked fine before I switched from 32 bit. I have no idea what the sizes of the parameters need to be or why they changed when I switched the bit size. Specifically the first call I make to the API is GetRawInputDeviceList which fails with error code 87. I would like to get this working in 64 bit but I have tried everything (type casting pointers etc) without success.

It is very similar to this problem:

http://social.msdn.microsoft.com/Forums/en-US/23414edf-0288-4148-98ef-1a03742a6ef8/raw-input-x64-api-question-getrawinputdevicelist-call-fails-in-windows-7-x64?forum=libraryfeedback

EDIT: Code from my project

function Get_Device_List(
  List  : in Address; -- Assume 8 byte pointer
  Count : in Address; -- Assume 8 byte pointer
  Size  : in Integer_4_Unsigned_C) -- Assume 4 byte integer
  return Integer_4_Unsigned_C;
pragma Import(Stdcall, Get_Device_List, "GetRawInputDeviceList");
Assert(Get_Device_List( -- works for 32 bit applications
  List  => NULL_ADDRESS,
  Count => Number_Of_X'address,
  Size  => Record_Device_List_Element'size / Byte'size) /= -1);

Solution

  • Here's an extremely simple working example, which shows the size and layout of the structure on x64 Windows.

    C:\Users\Ben\Documents\SO>type rawinputdevicelist.cpp
    #include <windows.h>
    #include <stdio.h>
    
    int main(void)
    {
        UINT nDevices;
        PRAWINPUTDEVICELIST pRawInputDeviceList;
        auto retval = GetRawInputDeviceList(NULL, &nDevices, sizeof(RAWINPUTDEVICELIST));
        auto errval = GetLastError();
        printf("sizeof (RAWINPUTDEVICELIST) is %d\n", (int)sizeof(RAWINPUTDEVICELIST));
        printf("offsetof (RAWINPUTDEVICELIST::hDevice) is %d\n", (char*)(&pRawInputDeviceList->hDevice) - (char*)pRawInputDeviceList);
        printf("sizeof (RAWINPUTDEVICELIST::hDevice) is %d\n", (int)(sizeof pRawInputDeviceList->hDevice));
        printf("offsetof (RAWINPUTDEVICELIST::dwType) is %d\n", (char*)(&pRawInputDeviceList->dwType) - (char*)pRawInputDeviceList);
        printf("sizeof (RAWINPUTDEVICELIST::dwType) is %d\n", (int)(sizeof pRawInputDeviceList->dwType));
        printf("\nGetRawInputDeviceList() returned %d\n", (int)retval);
        printf("GetLastError() returned %d\n", (int)errval);
        printf("nDevices = %u\n", (unsigned int)nDevices);
        return 0;
    }
    
    C:\Users\Ben\Documents\SO>cl rawinputdevicelist.cpp user32.lib
    Microsoft (R) C/C++ Optimizing Compiler Version 18.00.30501 for x64
    Copyright (C) Microsoft Corporation.  All rights reserved.
    
    rawinputdevicelist.cpp
    Microsoft (R) Incremental Linker Version 12.00.30501.0
    Copyright (C) Microsoft Corporation.  All rights reserved.
    
    /out:rawinputdevicelist.exe
    rawinputdevicelist.obj
    user32.lib
    
    C:\Users\Ben\Documents\SO>rawinputdevicelist
    sizeof (RAWINPUTDEVICELIST) is 16
    offsetof (RAWINPUTDEVICELIST::hDevice) is 0
    sizeof (RAWINPUTDEVICELIST::hDevice) is 8
    offsetof (RAWINPUTDEVICELIST::dwType) is 8
    sizeof (RAWINPUTDEVICELIST::dwType) is 4
    
    GetRawInputDeviceList() returned 0
    GetLastError() returned 0
    nDevices = 9