Results 1 to 2 of 2

Thread: WriteFile in QT... Too many bytes to write?

  1. #1
    Join Date
    Aug 2008
    Posts
    38
    Thanks
    15
    Qt products
    Qt4
    Platforms
    Windows

    Question WriteFile in QT... Too many bytes to write?

    Hello all,
    Currently I am working on creating an HID device User Application using QT4. I am using QTCreator 1.2 on Windows Vista (32bit) Business. Here is the rundown...

    Firstly, I open a file and create a buffer filled with x bytes of data from the file, then I call writefile on the buffer with the number of bytes passed as a DWORD (code below). Since the HID device has a packet size of 64 bytes, the internal USB engine parses out the data in 64 byte blocks to the device. (WORKS)
    Next, once the writefile() completes, it returns to the caller and if the file was not completely read, it grabs the next set of x bytes and repeats. (WORKS SOMETIMES)

    If I set the x bytes to something <=256, the transfers work exactly as described above. Once I exceed 256, the QT App crashes during the WriteFile() call. I have qDebug statements running to see when it gets to certain areas of theprogram, and I see it enter the WriteFile() but never returns before it crashes. The device however gets the complete transmission of x bytes even though the crash happens long before the device would get all the data. i.e. If I set the x bytes to 1024, the device sees all 1024 passed bytes, even though the app crashed on the WriteFile() call. My total file size right now is ~ 2048 bytes. (This could grow to < 8kB). So I set the x bytes = 4096, and fixed the descriptors in the device, also under my control, to take in 4k report size. I can break in the device code and see that it receives the entire file, but the QT App still crashes almost immediately after the writefile() has been called.

    If anyone can offer some assistance it would be greatly appreciated... If I need to submit more/less code, just say the word!
    Thanks to all,
    AlphaWolfXV

    Here is the calling code snippet:
    Qt Code:
    1. void USBProgrammer::cmdProgNew()
    2. {
    3. unsigned int patSz = 4096;
    4. unsigned char outputBuffer[patSz+1];
    5. unsigned char* pOutBuf;
    6. BYTE n;
    7. gblHold = "";
    8. // teBottom->clear();
    9. totalECHCount = 0; //clear before we start
    10. for(unsigned int i = 0; i < (patSz + 1); i++)
    11. outputBuffer[i] = 0;
    12. //we need to get what file we will be programming from the user. (if there is not one already
    13. //selected)
    14. if(!(lblProgramFile->text().contains(".ech")))
    15. //we do not have avalid file selected, lets get one...
    16. cmdBrowse();
    17. if (!(blnAlreadyActive))
    18. Activate(); //need this running first...
    19. if (!(blnAlreadyActive))
    20. {
    21. //this kicks us out if the board still isn't connected after
    22. //trying again to activate!
    23. sbarStatus->showMessage(msgProgError, 2000);
    24. return;
    25. }
    26.  
    27. lblProgress->setText(progBarDownload);
    28. pbarProgress->reset(); //put the progress bar back to 0
    29.  
    30. //now we need to stuff the output buffer.
    31. QFile fIn(lblProgramFile->text()), fOut();
    32. QDataStream dsIn(&fIn); //data stream input from file.
    33. unsigned int totCode, progBarVal;
    34.  
    35. unsigned char tmp[0], tmp2[0],block,outCount = 2, tmpi, i;
    36. if(!fIn.open(QIODevice::ReadOnly))
    37. {
    38. m.setText("Error opening ECH File!");
    39. m.exec();
    40. fIn.close(); return;
    41. }
    42. totCode = fIn.size();
    43.  
    44. unsigned int z, q;
    45. pOutBuf = outputBuffer;
    46. *pOutBuf++ = 0;//first byte always 0;
    47. *pOutBuf++ = 1; //Code Byte, first byte received at SiLabs
    48. while (!fIn.atEnd())
    49. {
    50. if (pOutBuf == outputBuffer)
    51. {
    52. *pOutBuf++ = 0;
    53. q = dsIn.readRawData((char*)pOutBuf,(patSz));
    54. }
    55. else
    56. q = dsIn.readRawData((char*)pOutBuf,(patSz - 1 ));
    57. qDebug()<< "BytesWritten:"<<q;
    58. for (unsigned int m1 = 0; m1 < (patSz+1); m1++)
    59. s.append(QString::number(outputBuffer[m1],16) + ", ");
    60. qDebug()<<s;
    61. //send it out
    62. n = hidDevice.setReport_Interrupt(outputBuffer, (patSz+1));
    63. qDebug()<<"Return Code from Interrupt Send:" << n;
    64. //ok, clear the buffer for the next round
    65. for(unsigned int m1 = 0; m1 < (patSz+1); m1++)
    66. outputBuffer[m1] = 0;
    67. pOutBuf = outputBuffer;
    68. }
    69. }
    To copy to clipboard, switch view to plain text mode 
    And the actual WriteFile() Call:
    Qt Code:
    1. BYTE HIDDevice::setReport_Interrupt(BYTE* buffer, DWORD bufferSize)
    2. {
    3. BYTE status = HID_DEVICE_SUCCESS;
    4. if(bufferSize <= (DWORD)(m_OutputReportBufferLength))
    5. {
    6. if(isOpened())
    7. {
    8. DWORD bytesWritten = 0;
    9. OVERLAPPED o = {0};
    10. o.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    11. bool a = flushBuffers();
    12. qDebug()<< "Output Buffer Length="<<QString::number(m_OutputReportBufferLength, 10);
    13. //try to write to the file...
    14. if(!::WriteFile(m_Handle, buffer, bufferSize, &bytesWritten, &o))
    15. {
    16. qDebug()<< "Errored Out!";
    17. //if write fails see if due to IO pending...
    18. if(GetLastError() == ERROR_IO_PENDING) //winerror.h
    19. {
    20. // if there is still data to be written, wait on the event
    21. // for m_SetReportTimeout
    22. DWORD waitStatus = WaitForSingleObject(o.hEvent, m_SetReportTimeout);
    23. // if the object is signaled, get the overlapped result...
    24. // the write succeeded...
    25. if(waitStatus == WAIT_OBJECT_0)
    26. {
    27. GetOverlappedResult(m_Handle, &o, &bytesWritten, FALSE);
    28. }
    29. else if (waitStatus == WAIT_TIMEOUT)
    30. {
    31. status = HID_DEVICE_TRANSFER_TIMEOUT;
    32. CancelIo(m_Handle);
    33. }
    34. else
    35. {
    36. status = HID_DEVICE_TRANSFER_FAILED;
    37. CancelIo(m_Handle);
    38. }
    39. }
    40. else
    41. status = HID_DEVICE_TRANSFER_FAILED;
    42.  
    43. }
    44. qDebug()<<"Bytes Written:"<<bytesWritten;
    45. CloseHandle(o.hEvent);
    46. }
    47. else
    48. status = HID_DEVICE_NOT_OPENED;
    49. }
    50. else
    51. status = HID_DEVICE_INVALID_BUFFER_SIZE;
    52. return status;
    53. }
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Aug 2008
    Posts
    38
    Thanks
    15
    Qt products
    Qt4
    Platforms
    Windows

    Default Error at end of ::WriteFile()

    Ok, some changes here, now I can send the data out and for a 1024 byte transfer, The first 2 transfers pass fine, then the final transfer runs and either times out or causes qt to crash. Completely changed to syncronous call now.

    The error code when the debug window appears is: -1073741819. All the data does complete writing, so it appears as though it is a crash on the last call only.


    It acts as if the file is not closing properly or something... closing prematurely, some combination. Any ideas welcomed!
    Thanks,
    AlphaWolfXV

    Here is the new Interrupt Report code:
    Qt Code:
    1. BYTE HIDDevice::setReport_Interrupt(BYTE* buffer, DWORD bufferSize)
    2. {
    3. BYTE status = HID_DEVICE_SUCCESS;
    4. if(bufferSize <= (DWORD)(m_OutputReportBufferLength))
    5. {
    6. if(isOpened())
    7. {
    8. LOCK_MUTEX();
    9. qDebug()<<"MUTEX LOCKED!";
    10. DWORD bytesWritten = 0;
    11. OVERLAPPED o = {0};
    12. o.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    13. if(o.hEvent == NULL)
    14. qDebug()<< "OVERLAPPED issue with structure.";
    15. qDebug()<< "Output Buffer Length="<<QString::number(m_OutputReportBufferLength, 10);
    16. //try to write to the file...
    17. ::WriteFile(m_Handle, buffer, bufferSize, &bytesWritten, NULL);
    18. /*{
    19.   //qDebug()<< "Errored Out!"<< GetLastError();
    20.  
    21.   //if write fails see if due to IO pending...
    22.   if(GetLastError() == ERROR_IO_PENDING) //winerror.h
    23.   {
    24.   //qDebug()<<"Begin Waiting... For IO Overlapped.";
    25.   //while(!(HasOverlappedIoCompleted(&o)));
    26.   //qDebug()<<"Done waiting for IO!";
    27.   // if there is still data to be written, wait on the event
    28.   // for m_SetReportTimeout
    29.   DWORD waitStatus = WaitForSingleObject(o.hEvent, m_SetReportTimeout);
    30.   // if the object is signaled, get the overlapped result...
    31.   // the write succeeded...
    32.   if(waitStatus == WAIT_OBJECT_0)
    33.   {
    34.   GetOverlappedResult(m_Handle, &o, &bytesWritten, FALSE);
    35.   }
    36.   else if (waitStatus == WAIT_TIMEOUT)
    37.   {
    38.   status = HID_DEVICE_TRANSFER_TIMEOUT;
    39.   CancelIo(m_Handle);
    40.   }
    41.   else
    42.   {
    43.   status = HID_DEVICE_TRANSFER_FAILED;
    44.   CancelIo(m_Handle);
    45.   }
    46.   }
    47.   else
    48.   status = HID_DEVICE_TRANSFER_FAILED;
    49.  
    50.   }*/
    51. qDebug()<<"Bytes Written:"<<bytesWritten;
    52. CloseHandle(o.hEvent);
    53. }
    54. else
    55. status = HID_DEVICE_NOT_OPENED;
    56. }
    57. else
    58. status = HID_DEVICE_INVALID_BUFFER_SIZE;
    59. UNLOCK_MUTEX();
    60. qDebug()<<"MUTEX UNLOCKED!";
    61. return status;
    62. }
    To copy to clipboard, switch view to plain text mode 

    and the new calling code is:
    Qt Code:
    1. void USBProgrammer::cmdProgNew()
    2. {
    3. DWORD patSz = 1024;
    4. unsigned char outputBuffer[patSz+1];
    5. unsigned char* pOutBuf;
    6. BYTE n;
    7. gblHold = "";
    8. // teBottom->clear();
    9. totalECHCount = 0; //clear before we start
    10. for(unsigned int i = 0; i < (patSz + 1); i++)
    11. outputBuffer[i] = 0;
    12. //we need to get what file we will be programming from the user. (if there is not one already
    13. //selected)
    14. if(!(lblProgramFile->text().contains(".ech")))
    15. //we do not have avalid file selected, lets get one...
    16. cmdBrowse();
    17. if (!(blnAlreadyActive))
    18. Activate(); //need this running first...
    19. if (!(blnAlreadyActive))
    20. {
    21. //this kicks us out if the board still isn't connected after
    22. //trying again to activate!
    23. sbarStatus->showMessage(msgProgError, 2000);
    24. return;
    25. }
    26.  
    27. lblProgress->setText(progBarDownload);
    28. pbarProgress->reset(); //put the progress bar back to 0
    29.  
    30. //now we need to stuff the output buffer.
    31. QFile fIn(lblProgramFile->text()), fOut();
    32. QDataStream dsIn(&fIn); //data stream input from file.
    33. unsigned int totCode, progBarVal;
    34.  
    35. unsigned char tmp[0], tmp2[0],block,outCount = 2, tmpi, i;
    36. if(!fIn.open(QIODevice::ReadOnly))
    37. {
    38. m.setText("Error opening ECH File!");
    39. m.exec();
    40. fIn.close(); return;
    41. }
    42. totCode = fIn.size();
    43.  
    44. unsigned int z, q;
    45. pOutBuf = outputBuffer;
    46. *pOutBuf++ = 0;//first byte always 0;
    47. *pOutBuf++ = 1; //Code Byte, first byte received at SiLabs
    48. while (!fIn.atEnd())
    49. {
    50. if (pOutBuf == outputBuffer)
    51. {
    52. *pOutBuf++ = 0;
    53. q = dsIn.readRawData((char*)pOutBuf,(patSz));
    54. }
    55. else
    56. {
    57. q = dsIn.readRawData((char*)pOutBuf,(patSz - 1 ));
    58. q++;
    59. }
    60. qDebug()<< "BytesWritten before send:"<<q+1;
    61. for (unsigned int m1 = 0; m1 < (patSz+1); m1++)
    62. s.append(QString::number(outputBuffer[m1],16) + ", ");
    63. qDebug()<<s;
    64. //send it out
    65. n = hidDevice.setReport_Interrupt(outputBuffer, (patSz+1));
    66. qDebug()<<"Return Code from Interrupt Send:" << n;
    67. //ok, clear the buffer for the next round
    68. for(unsigned int m1 = 0; m1 < (patSz+1); m1++)
    69. outputBuffer[m1] = 0;
    70. pOutBuf = outputBuffer;
    71. }
    72. fIn.close();
    73. }
    To copy to clipboard, switch view to plain text mode 

Similar Threads

  1. Phonon issues with DirectSound9
    By Zoltán in forum Qt Programming
    Replies: 2
    Last Post: 2nd February 2009, 03:48
  2. QTcpSocket exception.
    By Fastman in forum Qt Programming
    Replies: 9
    Last Post: 29th January 2008, 14:51
  3. How many bytes did i send?
    By yagabey in forum Qt Programming
    Replies: 3
    Last Post: 24th January 2008, 11:12
  4. Qwizard crashed when created in a slot
    By joshlareau in forum Qt Programming
    Replies: 9
    Last Post: 15th January 2008, 10:16
  5. How to write bytes read from serial port to a QFile
    By shamik in forum Qt Programming
    Replies: 19
    Last Post: 25th June 2007, 15:12

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.