Writefile ошибка 87

Solution was here: File Buffering https://msdn.microsoft.com/en-us/library/windows/desktop/cc644950%28v=vs.85%29.aspx

Working code:

#include "stdafx.h"
#include "assert.h"
#include <iostream>
#include <Windows.h>
#include <comutil.h>

using namespace std;

namespace{

    unsigned long tempBytesWritten = 0;
    HANDLE m_fileHandle;
    char m_pszFilename[_MAX_PATH] = "";

    // Create a temporary file for benchmark
    int createFile()
    {
        WCHAR tempPath[MAX_PATH];
        GetTempPath(_countof(tempPath), tempPath);
        _bstr_t p(tempPath);
        const char* c = p;
        strcpy(m_pszFilename, c);
        strcat(m_pszFilename, "testRawFile.raw");
        cout << "Writing to " << m_pszFilename << endl;

        m_fileHandle = CreateFileA( 
            m_pszFilename,          
            GENERIC_WRITE,          
            0,                      
            NULL,                   
            CREATE_ALWAYS,          
            FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH,
            NULL);

        if (m_fileHandle == INVALID_HANDLE_VALUE) 
        {
            assert( false );
        }
        return 0;
    }
}

DWORD DetectSectorSize( WCHAR * devName, PSTORAGE_ACCESS_ALIGNMENT_DESCRIPTOR pAlignmentDescriptor)
 {
  DWORD                  Bytes   = 0;
  BOOL                   bReturn = FALSE;
  DWORD                  Error   = NO_ERROR;
  STORAGE_PROPERTY_QUERY Query;

  ZeroMemory(&Query, sizeof(Query));

  HANDLE  hFile = CreateFileW( devName,
                               STANDARD_RIGHTS_READ, 
                               FILE_SHARE_READ | FILE_SHARE_WRITE,
                               NULL, 
                               OPEN_EXISTING, 
                               FILE_ATTRIBUTE_NORMAL,
                               NULL);

  if (hFile==INVALID_HANDLE_VALUE) {
    wprintf(L"  hFile==INVALID_HANDLE_VALUE. GetLastError() returns %lu.n", Error=GetLastError());
    return Error;
   }

  Query.QueryType  = PropertyStandardQuery;
  Query.PropertyId = StorageAccessAlignmentProperty;

  bReturn = DeviceIoControl( hFile, 
                             IOCTL_STORAGE_QUERY_PROPERTY, 
                             &Query, 
                             sizeof(STORAGE_PROPERTY_QUERY), 
                             pAlignmentDescriptor,
                             sizeof(STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR), 
                             &Bytes,
                             NULL);

  if (bReturn == FALSE) {
    wprintf(L"  bReturn==FALSE. GetLastError() returns %lu.n", Error=GetLastError());
   }

  CloseHandle(hFile);
  return Error;

 }


int main()
{
    unsigned int dataSize = 2000;

    DWORD                               Error     = NO_ERROR;
    STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR Alignment = {0};
    //  WCHAR                               szDisk[]  = L"\\.\PhysicalDrive0";
    WCHAR                               szDisk[]  = L"\\.\C:";

    Error = DetectSectorSize(szDisk, &Alignment);
    if (Error) {
        wprintf(L"Error %lu encountered while querying alignment.n", Error);
        return Error;
    }

    wprintf(L"Disk %s Propertiesn", (WCHAR*) szDisk);

    if (Alignment.BytesPerLogicalSector < Alignment.BytesPerPhysicalSector) {
        wprintf(L"  Emulated sector size is %lu bytes.n", Alignment.BytesPerLogicalSector);
    }

    wprintf(L"  Physical sector size is %lu bytes.n", Alignment.BytesPerPhysicalSector);

    dataSize = ((unsigned int)(dataSize + Alignment.BytesPerPhysicalSector - 1)/Alignment.BytesPerPhysicalSector) * Alignment.BytesPerPhysicalSector;

    // Allocate buffer for file
    unsigned char *buffer = new unsigned char[dataSize];

    // Create file to write to
    if ( createFile() != 0 )
    {
        printf("There was error creating the files... press Enter to exit.");
        getchar();
        return -1;
    }

    const BOOL bSuccess  = WriteFile(m_fileHandle, buffer, dataSize, &tempBytesWritten, NULL ); 

    if (!bSuccess)
    {
        cout << "Write failed with error " << GetLastError() << endl;
    }

    // clean up and remove file
    CloseHandle(m_fileHandle);
    wchar_t wtext[_MAX_PATH];
    mbstowcs(wtext, m_pszFilename, strlen(m_pszFilename)+1);
    DeleteFile(wtext);

    return 0;
}

  • Remove From My Forums
  • Question

  • Windows XP SP3
    Visual Studio 2008
    .Net 3.5

    When accessing an HID, I am receiving the error code 87 (The parameter is incorrect) when calling WriteFile.
    I am able to successfully open a handle to the device and read from it.

    Here are the relevant portions of the code that I am using:

    IntPtr dHandle = CreateFile(DevicePath, GENERIC_READ | GENERIC_WRITE, 0, IntPtr.Zero, 
    	OPEN_EXISTING, 0, IntPtr.Zero);
    
    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern bool WriteFile(IntPtr hFile, ref byte[] lpBuffer, uint nNumberOfBytesToWrite,
    	ref uint lpNumberOfBytesWritten, IntPtr ipOverlapped);
    
    uint bytesWritten = 0;
    byte[] buffer = new byte[] { 0x5a, 0x0a };
    WriteFile(dHandle, ref buffer, outputReportLength, ref bytesWritten, IntPtr.Zero);
    

    The output report length specified by the call to HidP_GetCaps is 2.

    If I change the DevicePath specified in CreateFile to a file, the file is written to.

    This is leading me to believe that the byte array being sent in WriteFile is the parameter being rejected.
    Many of the examples I have seen online pass byte arrays to the function.

    I am unsure as to what should be passed in.

    The ddk documentation discusses using an output report, but the examples I have seen of those are byte arrays as well.

    I have tried this on two different systems with two different usb devices.

Answers

  • Ah, one of those devices.

    The arguments you pass in CreateFile seem OK, I have an application which communicates with a HID microchip programmer and I use exactly the same arguments. My WriteFile routine is no different to yours — other than mine works. I guess the only thing it
    can be is the format of the packet you are sending to the device.

    Are you certain you have a valid handle?

    K

    • Marked as answer by

      Tuesday, October 12, 2010 8:01 AM

  • Try using HHD software’s USB monitor to find out what packets are being sent/received by application. Here’s a link…

    http://www.hhdsoftware.com/usb-monitor

    K

    Thank you for supplying the link to the monitor app. I was able to determine what was being sent to the scale using it.

    It turns out that the 87 error code was resulting from an incorrect report id.

    The report id the scale expected was 4. 

    • Marked as answer by
      Guang-Ming Bian — MSFT
      Tuesday, October 12, 2010 8:01 AM

WriteFile() Win32 call with input buffer size = 512 Fails., when i try to write to the disk that has bytes per sector = 4096.[3 TB disk]. Same WriteFile with input buffer size = 4096 works fine.,

Can any body explain this behavior.

svick's user avatar

svick

235k50 gold badges384 silver badges513 bronze badges

asked Mar 5, 2013 at 5:18

Saji's user avatar

4

For low-level I/O operations, your buffer must be an integer multiple of the sector size. In your case, k*4096. Most likely your hard drive wasn’t manufactured a long time ago. They are called «Advanced Format» and have 4096 bytes per sector. Mine doesn’t mind if I set it to 512 because it’s old. Try using the GetDiskFreeSpace function to learn more about your hard-drive.

answered Mar 9, 2013 at 7:10

Valentin's user avatar

ValentinValentin

6541 gold badge7 silver badges15 bronze badges

Я работаю над программой, которая пишет на устройство HID, и получаю ошибку 87, Недопустимый параметр в функции WriteFile. Я получил функции от USB Complete Яна Аксельсона, поэтому я не уверен, почему я получаю ошибку. Я использую это, чтобы найти мое устройство:

private void USBInit()
    {
        IntPtr deviceInfoSet;
        Int32 memberIndex = 0;
        SP_DEVICE_INTERFACE_DATA MyDeviceInterfaceData = new SP_DEVICE_INTERFACE_DATA();
        Int32 bufferSize = 0;
        IntPtr detailDataBuffer;
        Boolean success = false;
        deviceFound = false;

        HidD_GetHidGuid(ref hidGuid);           // Get the GUID

        deviceInfoSet = SetupDiGetClassDevs     // Get pointer to a device info set
            (ref hidGuid,
            IntPtr.Zero,
            IntPtr.Zero,
            DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);

        do
        {
            MyDeviceInterfaceData.cbSize = Marshal.SizeOf(MyDeviceInterfaceData);   // Identify Device Interface
            success = SetupDiEnumDeviceInterfaces
                (deviceInfoSet,
                IntPtr.Zero,
                ref hidGuid,
                memberIndex,
                ref MyDeviceInterfaceData);

            success = SetupDiGetDeviceInterfaceDetail           // Request Structure with Device Path Name
                (deviceInfoSet,
                ref MyDeviceInterfaceData,
                IntPtr.Zero,
                0,
                ref bufferSize,
                IntPtr.Zero);

            detailDataBuffer = Marshal.AllocHGlobal(bufferSize);
            Marshal.WriteInt32(detailDataBuffer, (IntPtr.Size == 4) ? (4 + Marshal.SystemDefaultCharSize) : 8);

            success = SetupDiGetDeviceInterfaceDetail
                (deviceInfoSet,
                ref MyDeviceInterfaceData,
                detailDataBuffer,
                bufferSize,
                ref bufferSize,
                IntPtr.Zero);

            IntPtr pDevicePathName = new IntPtr(detailDataBuffer.ToInt32() + 4);
            devicePathName = Marshal.PtrToStringAuto(pDevicePathName);
            Marshal.FreeHGlobal(detailDataBuffer);

            /* Request Communications Handle */
            deviceHandle = CreateFile
                (devicePathName,
                (GENERIC_WRITE | GENERIC_READ),
                FILE_SHARE_READ | FILE_SHARE_WRITE,
                IntPtr.Zero,
                OPEN_EXISTING,
                FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
                0);

            /* Get Vendor ID and Product ID */
            DeviceAttributes.Size = Marshal.SizeOf(DeviceAttributes);
            success = HidD_GetAttributes(deviceHandle, ref DeviceAttributes);

            // Compare Vendor ID and Product ID.
            if ((DeviceAttributes.VendorID == myVendorID) && (DeviceAttributes.ProductID == myProductID))
            {
                MessageBoxResult res = System.Windows.MessageBox.Show("Device Found", "K-IX", MessageBoxButton.OK);
                deviceFound = true;

                /* Get pointer to capabilities */
                success = HidD_GetPreparsedData(deviceHandle, ref preparsedData);

                /* Get Device Capabilities */
                Int32 result = 0;
                result = HidP_GetCaps(preparsedData, ref Capabilities);

                return;
            }
            else
            {
                // Not my device
                memberIndex++;
                deviceHandle.Close();
                if (memberIndex == 128)
                { break; }
            }
        } while (!deviceFound);
    }

И вот код, который я использую, чтобы попытаться отправить на устройство:

private void SendUSB()
    {
        Int32 numberOfBytesWritten = 0;
        Byte[] outputReportBuffer = null;
        Boolean success;
        Boolean success2;
        // Set size of the Output report buffer.
        Array.Resize(ref outputReportBuffer, Capabilities.InputReportByteLength);

        // Store Report ID in first byte of header.
        outputReportBuffer[0] = 0;

        // Store report data following the Report ID.
        outputReportBuffer[1] = 0x01;
        //outputReportBuffer[2] = 0x02;
       // outputReportBuffer[3] = 0x03;
        // Send Report
        success = WriteFile
            (deviceHandle,
            outputReportBuffer,
            outputReportBuffer.Length,
            ref numberOfBytesWritten,
            IntPtr.Zero);

        if (!success)
        {
            Int32 lastError = Marshal.GetLastWin32Error();
        }
        success2 = HidD_FreePreparsedData(preparsedData);
    }

Я подтвердил, что ожидаемая длина моего отчета для устройства равна 2, но я не уверен, куда идти, поскольку USB и HID программирование являются новыми для меня.

Topic: Sending report to a HID-dev via WriteFile failed with 87 errorcode  (Read 19238 times)

Hi,
I’m a new to USB/HID development.
I need to interact with a HID-device.

I’ve followed the way decribed in «USB Complete» book (ch.11) for finding my device and getting a handler for him.
The handler is good as I can use it with HidP_GetCaps function.

But when I try to send some bytes with calling WriteFile to my device I get 87 error (parameter is incorrect).
Frankly I don’t fully understand all this concepts of report id/report types/pipes/collections etc. But I used a sniffer tool to get interaction log with my device (when it’s used from some proprietary software). This tool is BusDog. I also tried USB Monitor (Device Monitoring Studio) but it’s more complex.

I can see in the BusDog’s log the following bytes when the device is used from proprietary software:
0b 04… and some vendor specific payload

 Then tried to send exactly such bytes from my program:
var bytes = new byte[] { 0x0b, 0x04, 0x2f, 0x7a, 0x77, 0x0d, 0, 0 };
bool success = NativeMethods.WriteFile(m_hDevice, bytes,
                                                bytes.Length,
                                                ref numberOfBytesWritten,
                                                IntPtr.Zero);
I tried adding 0x00 byte at the begging.
I tried allocate 64-bytes array. Tried to get OutputReportByteLength from HidP_GetCaps (it equals 8).

But in all cases WriteFile fails with 87 error.

Any ideas?

update: I also tried allocate 65 byte length buffer and first zero.

« Last Edit: December 17, 2010, 12:07:00 pm by Shrike »


Logged


What is OutputReportByteLength? How about FeatureReportByteLength? (It might be a Feature report.) The WriteFile buffer definitely needs a zero or other report ID in the first byte.

Jan


Logged


FeatureReportByteLength=8
OutputReportByteLength=8
InputReportByteLength=8
Usage=1
UsagePage=64K

But inspite of GetCaps reports OutputReportByteLength=8 in sniffer I can see a report of 64 byte length.
I try both 8+1 (first zero) and 64+1 (first zero)

var data = new byte[65];
var bytes = new byte[] { 0, 0x0b, 0x04, 0x2f, 0x7a, 0x77, 0x0d, 0, 0 };
Array.Copy(bytes, data, bytes.Length);
Int32 numberOfBytesWritten = 0;
WriteFile(m_hDevice, data, data.Length, ref numberOfBytesWritten, IntPtr.Zero);

How to find out required report id for sure? I suspect BusDog tool to not show it.

UPDATE: here’s the BusDog tool — http://code.google.com/p/busdog/
UPDATE2: I’ve attached HID descriptor

[attachment deleted by admin]

« Last Edit: December 17, 2010, 02:21:36 pm by Shrike »


Logged


The report descriptor you posted shows 28 report IDs. Report ID zero is used only by devices that have at most one of each report type (Input, Output, Feature).

To send a report to your device, pick a report ID and send that report’s quantity of data. For example, Output Report ID 2 has 7 bytes, so you would send 02h followed by seven data bytes.

Make the WriteFile buffer = the largest report size + 1.

Jan


Logged


Jan, thanks for your help!

But I can’t get the point why I’m getting «parameter is incorrect» from WriteFile while I’m sending exactly the same sequence of data as I catch in the sniffer.

In BusDog tool (sniffer) I catch such report data: 0x0b, 0x04, 0x2f, 0x7a, 0x77, 0x0d. Ok, the first byte is report id = 0x0b. There’s such report type in HID descriptor I attached ealier. Then the rest bytes is payload. In the sniffer I can see sending of 64 bytes, but HID descriptor for 0x0b report type says «report size=8, report count 63».

Actualy the device I’m trying to work with is a custom solution (it’s a device with rs232 interface connected via custom controller which emulates HID interfaces to the OS), I just need to send them some commands and not very care about its descriptors (if it’s not required to work with it of cause!).

I’m calling WriteFile with the showed above sequence in the buffer of size 64 and get «parameter is incorrent» without touching the bus (there’s no any activity in the sniffer I mean).

In another sniffer (HHD Software Device Monitoring Studio) I catched more info with «Packet view» tool. The command I see in BusDog («/zw») is sending to «USB_FUNCTION_BULK_OR_INTERUPT_TRANSFER» function, but before I can see other output packets with function «USB_FUNCTION_CLASS_INTERFACE». I’ve attached log with all data.

Should I do something to reproduce these comunications with function «USB_FUNCTION_CLASS_INTERFACE» in my application (or this’s just OS HID driver’s activity)?

[attachment deleted by admin]


Logged


Ok, I’ve sorted out with «parameter is incorrect». The error was caused by the fact how I opened the handle to device. I opened it with FILE_FLAG_OVERLAPPED flag but tried to write synchronously.

So my question now is only about USB_FUNCTION_CLASS_INTERFACE: should (and how) I reproduce these kind communication in my program?
Thanks.


Logged


Hi
How exactly did you change from «write synchronously» to a synchronously?
Do you have an example of what you did wrong and then how you did it right?

Thanks
David


Logged



Logged


Понравилась статья? Поделить с друзьями:
  • Wrc 9 fia world rally championship ошибка
  • Wpt15 2 коды ошибок
  • Wow ошибка lua как убрать
  • Wow ошибка divxdecoder dll
  • Wow ошибка cdn