CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 12 of 12

Thread: ReadFile

  1. #1
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    ReadFile

    I'm trying to build LibTIFF with VC++ (using the supplied vcproj file). The library builds okay but hangs (on Windows 7) whenever I try to read any TIFF image file. I've discovered that the file gets opened using fopen(). But instead of passing te returned FILE* to fread(), a convoluted sequence occurs whereby the FILE* gets passed to _fileno() whose return value is then passed to the Windows function ReadFile(). ReadFile() hangs every time.

    Is it safe to be doing this? I've always tended to avoid mixing and matching DOS file functions with Windows file functions.
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  2. #2
    Join Date
    Oct 2009
    Posts
    577

    Smile Re: ReadFile

    the _fileno gets a FILE pointer and returns a handle to the file. That seems ok beside that the fileno has no error return and the return value is undefined in case the FILE pointer wasn't associated with an open file stream.

    You should post the full code so that we could find out why it hangs.

  3. #3
    Join Date
    Oct 2009
    Posts
    577

    Smile Re: ReadFile

    Quote Originally Posted by John E View Post
    I've always tended to avoid mixing and matching DOS file functions with Windows file functions.
    BTW, the fopen isn't a DOS function but a C runtime function.

  4. #4
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    Re: ReadFile

    Changing the function to use _read() instead of ReadFile() does seem to have solved the problem.
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  5. #5
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: ReadFile

    _read uses C runtime handle (file number), while ReadFile needs real OS handle.
    Best regards,
    Igor

  6. #6
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    Re: ReadFile

    Thanks Igor.
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  7. #7
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: ReadFile

    A bit more about the general thing:

    Code:
    FILE* -> HANDLE
    
    #include <windows.h>
    #include <stdio.h>
    #include <io.h>
    
    FILE*  f      = fopen(path, szMode);
    int    handle = f->_file; // or handle = _fileno(f);
    HANDLE hFile  = (HANDLE) _get_osfhandle(handle);
    
    HANDLE -> FILE*
    
    #include <windows.h>
    #include <stdio.h>
    #include <io.h>
    
    HANDLE hFile  = CreateFile(...);
    int    handle = _open_osfhandle((LONG)hFile, _mode);
    FILE*  f      = fdopen(handle, szMode);
    Best regards,
    Igor

  8. #8
    Join Date
    Oct 2009
    Posts
    577

    Smile Re: ReadFile

    Quote Originally Posted by John E View Post
    Changing the function to use _read() instead of ReadFile() does seem to have solved the problem.
    _read isn't the approbiate function that belongs to fopen but fread.

    If you would post your code where it hangs we probably could show you where the issue is. In the momemnt it seems to me that you were fighting on the wrong places.

  9. #9
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    Re: ReadFile

    itsmeandnobodyelse - I do appreciate you trying to help but I already know where the problem lies. Please go back and read my original post, then read Igor's response, a few posts further down. My problem is occurring because the wrong type of handle is being passed to ReadFile().

    I'm just about to try Igor's suggestion of converting the handle type using _get_osfhandle()
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  10. #10
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    Re: ReadFile

    Igor, I tried your suggestion and it works fine - as long as 'handle' is within the range of low-level (POSIX style) handle numbers. Here's the code from libTIFF:-

    Code:
    static tsize_t
    _tiffReadProc(thandle_t fd, tdata_t buf, tsize_t size)
    {
    	DWORD dwSizeRead;
    
    	if (!ReadFile(fd, buf, size, &dwSizeRead, NULL))
    		return(0);
    	return ((tsize_t) dwSizeRead);
    }
    If the file was opened by libTIFF itself, 'fd' will already be a valid WinOS file handle (a long). In my case however, it can also be opened by libgdk_pixbuf in which case, it'll be a low-level, POSIX style handle (an int). For obvious reasons, the above function can't tell one from the other.

    Assuming that the values would never overlap (which may or may not be a safe assumption) I could get around this problem by testing to see if 'fd' was already within the range of known WinOS values or alternatively, if it was in the range of low-level values.

    At first, I hoped that a simple numerical test would suffice. But when I tried your code this morning, the value returned by _get_osfhandle() was worryingly close the the value I passed in. Can you think of any other way I could test the validity of 'fd'?
    Last edited by John E; December 1st, 2010 at 05:10 AM.
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  11. #11
    Join Date
    Oct 2009
    Posts
    577

    Smile Re: ReadFile

    Quote Originally Posted by John E View Post
    itsmeandnobodyelse - I do appreciate you trying to help but I already know where the problem lies. Please go back and read my original post, then read Igor's response, a few posts further down. My problem is occurring because the wrong type of handle is being passed to ReadFile().

    I'm just about to try Igor's suggestion of converting the handle type using _get_osfhandle()
    Yes, I did understand that. But you are solving issues that only happened because you were mixing libraries without need (as far as I could see it). So if you would use OpenFile/ReadFile or fopen/fread or _open/_read it just had worked without any extra code and extra handling.

  12. #12
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    Re: ReadFile

    Okay, I understand.... My problem is that libTIFF can be used two ways.... you can open TIFF image files the recommended way - using TIFFOpen() - or you can open them with open() / fopen() etc and then manipulate the files by supplying the relevant file handle. The *nix and Apple interfaces utilise POSIX style file handles but for some bizarre reason, the Win32 interface uses WinOS handles - even though POSIX style handles would have worked perfectly well..! I've raised the issue with the libTIFF maintainers but it would be nice to find some elegant solution in the meantime.
    "A problem well stated is a problem half solved.” - Charles F. Kettering

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured