none
Help: Issue on WEC7: CreateFile returns as if the target file does not exist, even there is the file. RRS feed

  • Question

  • I have a troule in the use of CreateFile on WEC7, intermittently it seems the API could not find a file actually exsisting.
    I write from its background. I had once wrote an application program runs for Windows CE.NET4.2, which used a memory mapped file. In the program it opens a file using CreateFile with dwCreationDisposition parameter as OPEN_ALWAYS.
    I've believed that under the spec of API, if the target file is there, the Createfile always returned as non 0 (Zero) and the GetLastError returns  ERROR_ALREADY_EXISTS.
    And now, I am running the same program on WEC7 based hardware, rebuilding the program with VC++ 2008 version 91605-130-2205775-60632.
    In the program, sometimes CreateFile returns as 0 (Zero: success) and naturally GetLastError returns also 0.
    As I wrote 'sometimes', the issue happens intermittently, usually it works as correct. Sometimes it does not.
    The program is starting just after rebooting OS (WEC7), the system might be tentative? It should not be like that...
    The file is in SRAM drive, does it effects the API result?
    Does anyone have similar experience? How could I solve this?
    Please help me.

    Friday, February 23, 2018 5:28 AM

Answers

  • GetLastError returns "The calling thread's last-error code" and thus is thread safe, so no matter what other threads do in the meantime, GetLastError will return the error status of the last API called on that thread.

    If what you say is really true, and the file really exists (as indicated by FindFirstFile), then there is really no reason GetLastError should not return ERROR_ALREADY_EXISTS directly after CreateFile with OPEN_ALWAYS has been called.

    If it really doesn't then the only conclusion can be that there is some bug in the CreateFile implementation.

    If you can prove this is all happening, without any doubt, and it is reproducable, then you should really open a support incident with Microsoft, If it really turns out to be a bug, you won't be charged for the support request. Before you do, make sure you can reproduce the issue on Compact 7 or 2013, as those OS versions are still in full support cycle (category is an example, pick something more suitable for this request):

    Go here, start typing "compact 2013" in the box, click on the Windows Embedded Compact 2013 link, and follow the steps to create a support request:

    Create an incident

    First, tell us about the Windows Embedded Compact 2013 problem so that we can direct your issue to the right support engineer:

    Problem type: Device Driver Development

    Developing a device driver for Windows Mobile, Windows Embedded Handheld, or Windows CE.

    Category: Wi-Fi

    Wi-Fi driver issues on Windows CE or Windows Mobile.

    Contact Microsoft

    Have a technical support representative contact you.
    Start request 


    Good luck,

    Michel Verhagen, eMVP
    Check out my blog: https://guruce.com/blog

    GuruCE
    Microsoft Embedded Partner
    NXP Proven Partner
    https://guruce.com
    Consultancy, training and development services.

    Interested in WEC on i.MX6?
    Get the only 100% stable and best performing i.MX6 BSP for WEC7 and WEC2013 here: https://guruce.com/imx6

    Tuesday, February 27, 2018 10:21 AM
    Moderator

All replies

  • Are you sure the SRAM is mounted as filesystem already at the time you call CreateFile with OPEN_ALWAYS? If the SRAM filesystem is not mounted yet you are creating the file in the RAM filesystem as new (thus explaining exactly what you see).

    So, if you run your program at boot, you first need to make sure the SRAM filesystem is mounted and ready for use. 

    Register for device notifications (see RequestDeviceNotifications), and wait for the SRAM filesystem mount notification. As soon as you get that notification try to open the store using OpenStore. If that fails, wait a bit and try again. It may take a little while for the filesystem to be fully operational, even after receiving the device notification. Don't forget to close the store handle if your call to OpenStore was successful. Also stop device notifications and close the message queue. Now you can open the file from the SRAM filesystem.


    Good luck,

    Michel Verhagen, eMVP
    Check out my blog: https://guruce.com/blog

    GuruCE
    Microsoft Embedded Partner
    NXP Proven Partner
    https://guruce.com
    Consultancy, training and development services.

    Interested in WEC on i.MX6?
    Get the only 100% stable and best performing i.MX6 BSP for WEC7 and WEC2013 here: https://guruce.com/imx6

    Friday, February 23, 2018 9:47 AM
    Moderator
  • An example  of waiting for the disk to mount using RequestDeviceNotifications can be found at:  http://geekswithblogs.net/BruceEitman/archive/2008/06/13/windows-ce-monitoring-for-disk-insertion-to-add-support-for.aspx

    Bruce Eitman
    Senior Engineer
    Bruce.Eitman AT Synopsys DOT com
    My BLOG http://geekswithblogs.net/bruceeitman
    I work for Synopsys


    Friday, February 23, 2018 2:41 PM
    Moderator
  • Hi,

    Thank you for telling me about the above API.

    I tried that, but it was ineffective.

    Is there something wrong with the source code below?

    ///////////////////////////////////////////////////////////////////////////////
    // MODULE : BOOL bHandleNewDisk
    ///////////////////////////////////////////////////////////////////////////////
    
    BOOL bHandleNewDisk( TCHAR *DiskName, DWORD dwTimeOutSec)
    {
        HANDLE hStore;
        BOOL success = FALSE;
        DWORD Count = dwTimeOutSec*10;
    
        RETAILMSG(1,(TEXT(" bHandleNewDisk(%s)\r\n"),DiskName));
    
        do{
            hStore = OpenStore( DiskName );
            if( INVALID_HANDLE_VALUE != hStore ){
                RETAILMSG(1,(TEXT(" OpenStore success!!!\r\n")));
                success = bCheckMountFolders( hStore, dwTimeOutSec );
                CloseHandle( hStore );
                break;
            }else{
               // When the disk first shows up, it may not be ready
               // for us to OpenStore(), so wait a bit then retry
               Sleep( 10 );
            }
        }while( !success && Count--);
    
        return success;
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    // MODULE : BOOL bCheckMountFolders
    ///////////////////////////////////////////////////////////////////////////////
    BOOL bCheckMountFolders( HANDLE hStore, DWORD dwTimeOutSec )
    {
        BOOL bRet = FALSE;
        HANDLE hFind = INVALID_HANDLE_VALUE;
        HANDLE hPartition = INVALID_HANDLE_VALUE;
        PARTINFO partInfo = {0};
    
        RETAILMSG(1,(TEXT(" bCheckMountFolders(%x)\r\n"),hStore));
    
        do{
            Sleep( 10 );
            memset( &partInfo, 0, sizeof( partInfo ));
            partInfo.cbSize = sizeof(PARTINFO);
            hFind = FindFirstPartition(hStore, &partInfo);
            if( INVALID_HANDLE_VALUE != hFind ){
                RETAILMSG(1,(TEXT(" FindFirstPartition success!! \r\n")));
                if(PARTITION_ATTRIBUTE_MOUNTED & partInfo.dwAttributes){
                    RETAILMSG(1,(TEXT("Mounted!!!!\r\n")));
                    bRet = TRUE;
                    break;
                }else{
                    RETAILMSG(1,(TEXT("No Mounted!!!! -> Next !!!!\r\n")));
                    FindClosePartition(hFind);
                }
            }
        } while( dwTimeOutSec-- );
    
        if(INVALID_HANDLE_VALUE != hFind){
            do{
                if(PARTITION_ATTRIBUTE_MOUNTED & partInfo.dwAttributes){
                    RETAILMSG(1,(TEXT("----------- partInfo ------------ \r\n")));
                    RETAILMSG(1,(TEXT("szPartitionName : %s \r\n"), partInfo.szPartitionName));
                    RETAILMSG(1,(TEXT("szFileSys : %s \r\n"), partInfo.szFileSys));
                    RETAILMSG(1,(TEXT("szVolumeName : %s \r\n"), partInfo.szVolumeName));
                }
            }while(FindNextPartition(hFind, &partInfo));
            FindClosePartition(hFind);
        }
    
        return bRet;
    
    }
    
    void test()
    
    {
    
        BOOL bret = FALSE;
    
        bret = bHandleNewDisk(_T("DSK1:"), dwTimeOutSec ));
    
        CreateFile();  <= OPEN_ALWAYS
    
        …
    
    }


    Regards,

    Saitou.


    Monday, February 26, 2018 10:32 AM
  • Hi,

    I add the fact I found.

    When I use CreateFile (OPEN_EXISTING), CreateFile will succeed. (open success)

    When I use FindFirstFile , FindFirstFile will succeed (find file)

    When I use CreateFile (OPEN_ALWAYS) , CreateFile will return 0 and getlasterror is 0(Zero), this means file is not exist. but file size is not 0 (Zero).

    I can only think that CreateFile is wrong.

    Regards,

    Saitou.

    Monday, February 26, 2018 10:50 AM
  • Is there something wrong with that code?  Yes, yes there is.  You left out all of the code that waits for a disk to mount.  Why didn't you use the code that calls RequestDeviceNotifications?

    Bruce Eitman
    Senior Engineer
    Bruce.Eitman AT Synopsys DOT com
    My BLOG http://geekswithblogs.net/bruceeitman
    I work for Synopsys

    Monday, February 26, 2018 1:50 PM
    Moderator
  • Thank you  for your reply.

    Sorry, I assumed that there would be no problem if OpenStore was normal.

    I will try to call RequestDeviceNotifications.

    Regards,

    Saitou.

    Tuesday, February 27, 2018 12:12 AM
  • Hi,

    I tried RequestDeviceNotifications, but it was still ineffective.

    Added code are as below.

    ///////////////////////////////////////////////////////////////////////////////
    // MODULE : BOOL bMonitorForDisks
    ///////////////////////////////////////////////////////////////////////////////
    
    BOOL bMonitorForDisks(void)
    {
        BOOL bRet = FALSE;
        HANDLE hNotify;
        HANDLE qStore;
        DWORD flags;
        DWORD size;
        BYTE DevDetail[sizeof(DEVDETAIL)+(MAX_PATH*sizeof(TCHAR))];
        DEVDETAIL *pDetail = (DEVDETAIL *)DevDetail;
        MSGQUEUEOPTIONS msgopts;
        DWORD sram[2] = {0,0};
    
        msgopts.dwSize = sizeof(MSGQUEUEOPTIONS);
        msgopts.dwFlags = 0;
        msgopts.dwMaxMessages = 0;
        msgopts.cbMaxMessage = sizeof(DevDetail);
        msgopts.bReadAccess = TRUE;
    
        qStore = CreateMsgQueue( NULL, &msgopts );
        hNotify = RequestDeviceNotifications( &BLOCK_DRIVER_GUID, qStore, TRUE );
    
        RETAILMSG(1,(TEXT(" bMonitorForDisks ----------------->>\r\n")));
    
        do{
            if( WaitForSingleObject( qStore, 1000 ) == WAIT_OBJECT_0 ){
                while( ReadMsgQueue( qStore, pDetail, sizeof(DevDetail), &size, 1, &flags )){
                    if( pDetail->fAttached ){
                        RETAILMSG(1,(TEXT("----------- pDetail start ------------ \r\n")));
                        RETAILMSG(1,(TEXT("fAttached : %d \r\n"), pDetail->fAttached));
                        RETAILMSG(1,(TEXT("szName : %s \r\n"), pDetail->szName));
                        RETAILMSG(1,(TEXT("----------- pDetail end   ------------ \r\n")));
                        bRet = bHandleNewDisk( pDetail->szName, 1000 );
                    }
                }
            }
        }while( DiskInfo[0] == FALSE );
    
        StopDeviceNotifications(hNotify);
    
        RETAILMSG(1,(TEXT(" bMonitorForDisks -----------------<<\r\n")));
    
        return bRet;
    
    }
    
    //////////////////////////////////////////////////////////////////////////////
    // MODULE : BOOL bCheckMountFolders
    ///////////////////////////////////////////////////////////////////////////////
    BOOL bCheckMountFolders( HANDLE hStore, DWORD dwTimeOutSec )
    {
        BOOL bRet = FALSE;
        HANDLE hFind = INVALID_HANDLE_VALUE;
        HANDLE hPartition = INVALID_HANDLE_VALUE;
        PARTINFO partInfo = {0};
    
        RETAILMSG(1,(TEXT(" bCheckMountFolders(%x)\r\n"),hStore));
    
        do{
            Sleep( 10 );
            memset( &partInfo, 0, sizeof( partInfo ));
            partInfo.cbSize = sizeof(PARTINFO);
            hFind = FindFirstPartition(hStore, &partInfo);
            if( INVALID_HANDLE_VALUE != hFind ){
                RETAILMSG(1,(TEXT(" FindFirstPartition success!! \r\n")));
                if(PARTITION_ATTRIBUTE_MOUNTED & partInfo.dwAttributes){
                    RETAILMSG(1,(TEXT("Mounted!!!!\r\n")));
                    bRet = TRUE;
                    break;
                }else{
                    RETAILMSG(1,(TEXT("No Mounted!!!! -> Next !!!!\r\n")));
                    FindClosePartition(hFind);
                }
            }
        } while( dwTimeOutSec-- );
    
        if(INVALID_HANDLE_VALUE != hFind){
            do{
                if(PARTITION_ATTRIBUTE_MOUNTED & partInfo.dwAttributes){
                    RETAILMSG(1,(TEXT("----------- partInfo ------------ \r\n")));
                    RETAILMSG(1,(TEXT("szPartitionName : %s \r\n"), partInfo.szPartitionName));
                    RETAILMSG(1,(TEXT("szFileSys : %s \r\n"), partInfo.szFileSys));
                    RETAILMSG(1,(TEXT("szVolumeName : %s \r\n"), partInfo.szVolumeName));
    
                    // add
    
                    if( wcscmp( partInfo.szVolumeName, _T("Sram")) == 0 ){
    
                         DiskInfo = TRUE;
    
                    }
    
                }
            }while(FindNextPartition(hFind, &partInfo));
            FindClosePartition(hFind);
        }
    
        return bRet;
    
    }


    Regards,

    Saitou.


    Tuesday, February 27, 2018 1:23 AM
  • I think your assumptions about CreateFile with OPEN_ALWAYS are wrong.

    You state:

    In the program it opens a file using CreateFile with dwCreationDisposition parameter as OPEN_ALWAYS. I've believed that under the spec of API, if the target file is there, the Createfile always returned as non 0 (Zero) and the GetLastError returns ERROR_ALREADY_EXISTS.

    The MSDN page states:

    OPEN_ALWAYS - Opens the file, if it exists. If the file does not exist, the function creates the file as if dwCreationDisposition were CREATE_NEW.
    ...
    If the specified file exists before the function call and dwCreationDisposition is CREATE_ALWAYS or OPEN_ALWAYS, a call to GetLastError returns ERROR_ALREADY_EXISTS, even though the function has succeeded. If the file does not exist before the call, GetLastError returns zero.

    So, what exactly do you see?

    if the file exists, I would expect CreateFile with OPEN_ALWAYS to return ERROR_SUCCESS (0), GetLastError() to return ERROR_ALREADY_EXISTS (183) and the file contents can be read with ReadFile.

    If the file does NOT exist, I would expect CreateFile with OPEN_ALWAYS to return ERROR_SUCCESS (0), GetLastError() to return ERROR_SUCCESS (0) and no file contents can be read (because the file is newly created and 0 bytes).

    Note that in BOTH cases, CreateFile will return 0 (ERROR_SUCCESS). The only difference is what GetLastError() returns!

    Which of the above is not behaving as per documentation?


    Good luck,

    Michel Verhagen, eMVP
    Check out my blog: https://guruce.com/blog

    GuruCE
    Microsoft Embedded Partner
    NXP Proven Partner
    https://guruce.com
    Consultancy, training and development services.

    Interested in WEC on i.MX6?
    Get the only 100% stable and best performing i.MX6 BSP for WEC7 and WEC2013 here: https://guruce.com/imx6


    Tuesday, February 27, 2018 1:44 AM
    Moderator
  • Hi,

    I'm sorry, it was a typo.

    I expect that Createfile returned as 0 (Zero) and the GetLastError returns ERROR_ALREADY_EXISTS.

    The file actually exists, but returns as 0(Zero) and getlasterror also returns 0(Zero).
    I am implementing the above for 8 files, but for some reason only one file will have a phenomenon.

    The only difference is file name.

    Regards,

    Saitou.

    Tuesday, February 27, 2018 2:29 AM
  • So, you are saying that FindFirstFile actually FINDS the file, but when you then call CreateFile with OPEN_ALWAYS it returns ERROR_SUCCESS and GetLastError() returns ERROR_SUCCESS as well?

    Are you ABSOLUTELY sure you don't call any other function in between CreateFile and GetLastError()?

    What is the name of the file?


    Good luck,

    Michel Verhagen, eMVP
    Check out my blog: https://guruce.com/blog

    GuruCE
    Microsoft Embedded Partner
    NXP Proven Partner
    https://guruce.com
    Consultancy, training and development services.

    Interested in WEC on i.MX6?
    Get the only 100% stable and best performing i.MX6 BSP for WEC7 and WEC2013 here: https://guruce.com/imx6

    Tuesday, February 27, 2018 6:19 AM
    Moderator
  • >So, you are saying that FindFirstFile actually FINDS the file, but when you then call CreateFile with OPEN_ALWAYS >it returns ERROR_SUCCESS and GetLastError() returns ERROR_SUCCESS as well?

    ⇒Yes.

    I call GetLastError immediately after CreateFile.

    But, It can not be said that absolutely calling other API between CreateFile and GetLastError. Because in the current project another DLL is also working. And I do not know how to check whether API calls by another DLL are between CreateFile and GetLastError.

    The file I want to open is the original file, named ”SRamTFile.bin”.

    I am also worried that something unexpected processing is being done between CreateFile and GetLastError.
    But I do not know how to look it up.
    ActiveSync can not be connected due to processing immediately after turning on the power.

    Regards,

    Saitou.

    Tuesday, February 27, 2018 7:25 AM
  • GetLastError returns "The calling thread's last-error code" and thus is thread safe, so no matter what other threads do in the meantime, GetLastError will return the error status of the last API called on that thread.

    If what you say is really true, and the file really exists (as indicated by FindFirstFile), then there is really no reason GetLastError should not return ERROR_ALREADY_EXISTS directly after CreateFile with OPEN_ALWAYS has been called.

    If it really doesn't then the only conclusion can be that there is some bug in the CreateFile implementation.

    If you can prove this is all happening, without any doubt, and it is reproducable, then you should really open a support incident with Microsoft, If it really turns out to be a bug, you won't be charged for the support request. Before you do, make sure you can reproduce the issue on Compact 7 or 2013, as those OS versions are still in full support cycle (category is an example, pick something more suitable for this request):

    Go here, start typing "compact 2013" in the box, click on the Windows Embedded Compact 2013 link, and follow the steps to create a support request:

    Create an incident

    First, tell us about the Windows Embedded Compact 2013 problem so that we can direct your issue to the right support engineer:

    Problem type: Device Driver Development

    Developing a device driver for Windows Mobile, Windows Embedded Handheld, or Windows CE.

    Category: Wi-Fi

    Wi-Fi driver issues on Windows CE or Windows Mobile.

    Contact Microsoft

    Have a technical support representative contact you.
    Start request 


    Good luck,

    Michel Verhagen, eMVP
    Check out my blog: https://guruce.com/blog

    GuruCE
    Microsoft Embedded Partner
    NXP Proven Partner
    https://guruce.com
    Consultancy, training and development services.

    Interested in WEC on i.MX6?
    Get the only 100% stable and best performing i.MX6 BSP for WEC7 and WEC2013 here: https://guruce.com/imx6

    Tuesday, February 27, 2018 10:21 AM
    Moderator
  • Hi,

    Thank you for everything.

    I will think about above support.

    Regards,

    Saitou.

    Tuesday, February 27, 2018 10:45 AM