none
CopyFile failing when not using FILE_SHARE_READ on the CreateFile of the source file. RRS feed

  • Question

  • I am working on CE 6.0 R3 with full QFE's updates.

    I have a memory-mapped file created by the main process of a stream driver.  I have an independent thread in the same driver that I am using for saving the memory-mapped file into separate log files each day.  The problem I am having is that I cannot copy the mapped file if I am not using FILE_SHARE_READ mode even if I am closing the file handle before the call of CopyFile().

    You will maybe say : why not use the FILE_SHARE_READ mode than? Well, I would like to keep the access on the opened file to only one at the time...  Moreover, it is supposed to work also which brings me to question myself why that doesn't work!

    I have put the my 3 functions used and the variable declarations.  The first call to OpenScratchFile() is done by XXX_Init() of my driver and the saving function is called my thread started by XXX_Init().

     

    #define SCRATCH_FILENAME _T("\\Windows\\EventManager.scratch")

    #define TEMP_SCRATCH_FILENAME _T("\\Windows\\Temp.scratch")

    #define MEMORY_MAPPED_REPORT_OBJECT L"NWC/ReportMappingObject"

    #define MAXIMUM_SCRACTH_SIZE 1048576

    #define MAX_EVENT_LOG_ENTRY_SIZE 312

     

    static HANDLE ScratchFile = INVALID_HANDLE_VALUE;

    static HANDLE MappedFile = INVALID_HANDLE_VALUE;

    static char* BasePtr = NULL;

    static char* CurrentPtr = NULL;

    static DWORD FileSize = 0x00;

    static int LogIndex = 0;


    void OpenScratchFile(void)

    {

    DWORD SizeHigh = (DWORD)((MAXIMUM_SCRACTH_SIZE & 0xFFFFFFFF00000000) >> 8);

    DWORD SizeLow = (DWORD)(MAXIMUM_SCRACTH_SIZE & 0x00000000FFFFFFFF);

     

    ScratchFile = CreateFile(SCRATCH_FILENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, 0, NULL);

     

    if(ScratchFile != INVALID_HANDLE_VALUE)

    {

    FileSize = GetFileSize(ScratchFile, NULL);

    //Create the RAM mapped file

    MappedFile = CreateFileMapping(ScratchFile, NULL, PAGE_READWRITE, SizeHigh, SizeLow, MEMORY_MAPPED_REPORT_OBJECT);

    if(MappedFile != INVALID_HANDLE_VALUE)

    {

    //Create memory region

    BasePtr = (char*) MapViewOfFile(MappedFile, FILE_MAP_ALL_ACCESS, 0, 0, 0);

    if(BasePtr == NULL)

    {

    CloseHandle(MappedFile);

    CloseHandle(ScratchFile);

    MappedFile = INVALID_HANDLE_VALUE;

    ScratchFile = INVALID_HANDLE_VALUE;

    }

    else

    {

    CurrentPtr = BasePtr;

    }

    }

    else

    {

    CloseHandle(ScratchFile);

    ScratchFile = INVALID_HANDLE_VALUE;

    }

    }

    }

    void CloseScratchFile (void)

    {

    UnmapViewOfFile(BasePtr);

    BasePtr = NULL;

     

    CloseHandle(MappedFile);

    MappedFile = INVALID_HANDLE_VALUE;

     

    SetFilePointer(ScratchFile, FileSize, NULL, FILE_BEGIN);

    SetEndOfFile(ScratchFile);

     

    if(CloseHandle(ScratchFile) == FALSE)

    {

    RETAILMSG( 1, (TEXT("Cannot Close Scratch File %d\r\n"), GetLastError()));

    }

    ScratchFile = INVALID_HANDLE_VALUE;

    }

    void SaveScratchFile (void)

    {

    HANDLE TempFile = INVALID_HANDLE_VALUE;

    HANDLE TempMappedFile = INVALID_HANDLE_VALUE;

    DWORD SizeHigh = (DWORD)((MAXIMUM_SCRACTH_SIZE & 0xFFFFFFFF00000000) >> 8);

    DWORD SizeLow = (DWORD)(MAXIMUM_SCRACTH_SIZE & 0x00000000FFFFFFFF);

    char* TempBasePtr = NULL;

    WCHAR Path[256];

    SYSTEMTIME Time;

     

    //CreateTempFile

    TempFile = CreateFile(TEMP_SCRATCH_FILENAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);

     

    if(TempFile != INVALID_HANDLE_VALUE)

    {

    //Create the RAM mapped file

    TempMappedFile = CreateFileMapping(TempFile, NULL, PAGE_READWRITE, SizeHigh, SizeLow, MEMORY_MAPPED_REPORT_OBJECT);

    if(TempMappedFile != INVALID_HANDLE_VALUE)

    {

    //Create memory region

    TempBasePtr = (char*) MapViewOfFile(TempMappedFile, FILE_MAP_ALL_ACCESS, 0, 0, 0);

     

    if(TempBasePtr == NULL)

    {

    CloseHandle(TempMappedFile);

    CloseHandle(TempFile);

    TempMappedFile = INVALID_HANDLE_VALUE;

    TempFile = INVALID_HANDLE_VALUE;

    }

    else

    {

    //Use new file pointer

    CurrentPtr = TempBasePtr;

    }

    }

    }

     

    //Close original scratch file

    CloseScratchFile();

     

    //Reset file size of temporary scratch use

    FileSize = 0;

     

    //Get system time for log filename

    GetSystemTime(&Time);

    LogIndex++;

     

    wsprintf(Path, _T("\\FlashDisk\\Reports\\%04d-%02d-%02d-%04d.log"),Time.wYear, Time.wMonth, Time.wDay, LogIndex);

     

    //RETAILMSG(1, (TEXT("SaveScratchFile - Creating log file %s\r\n"), Path));

    //***** THIS IS THE COPY THAT IS FAILING **********

    //Copy original scratch file

    if(CopyFile(SCRATCH_FILENAME, Path, FALSE) == FALSE)

    {

    RETAILMSG(1, (TEXT("Copy Scratch File Failed!!! %d\r\n"), GetLastError()));

    }

     

    //Close temp scratch file

    //RETAILMSG(1, (TEXT("SaveScratchFile - Closing temporary view and file\r\n")));

    UnmapViewOfFile(TempBasePtr);

     

    CloseHandle(TempMappedFile);

     

    SetFilePointer(TempFile, FileSize, NULL, FILE_BEGIN);

    SetEndOfFile(TempFile);

     

    CloseHandle(TempFile);

     

    //Copy temp file to scratch file

    if(DeleteAndRenameFile(SCRATCH_FILENAME, TEMP_SCRATCH_FILENAME) != TRUE)

    {

    RETAILMSG(1, (TEXT("Copy Scratch File Failed!!!\r\n")));

    }

     

    //Open scratch file

    OpenScratchFile();

     

    return;

    }

     

    Thank you!

    Tuesday, January 11, 2011 7:10 PM

Answers

  • If you take a look at how CopyFileEx is implemented in %_WINCEROOT%\PRIVATE\WINCEOS\COREOS\CORE\DLL\apis.c  (CopyFile is a wrapper for CopyFileEx) you see that the source file is opened with dwShareMode == FILE_SHARE_READ|FILE_SHARE_WRITE. According to CreateFile docs "If dwShareMode is set to zero [as when you create the file], the object cannot be shared. Subsequent open operations on the object fail until the handle is closed".
    Luca Calligaris lucaDOTcalligarisATeurotechDOTcom www.eurotech.com Check my blog: http://lcalligaris.wordpress.com
    • Marked as answer by Keaven Wednesday, May 28, 2014 3:45 PM
    Wednesday, January 12, 2011 8:08 AM

All replies

  • What does GetLastError() return when DeleteAndRenameFile fails?


    Good luck,

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

    GuruCE
    Microsoft Embedded Partner
    http://guruce.com
    Consultancy, training and development services.
    Wednesday, January 12, 2011 1:33 AM
    Moderator
  • If you take a look at how CopyFileEx is implemented in %_WINCEROOT%\PRIVATE\WINCEOS\COREOS\CORE\DLL\apis.c  (CopyFile is a wrapper for CopyFileEx) you see that the source file is opened with dwShareMode == FILE_SHARE_READ|FILE_SHARE_WRITE. According to CreateFile docs "If dwShareMode is set to zero [as when you create the file], the object cannot be shared. Subsequent open operations on the object fail until the handle is closed".
    Luca Calligaris lucaDOTcalligarisATeurotechDOTcom www.eurotech.com Check my blog: http://lcalligaris.wordpress.com
    • Marked as answer by Keaven Wednesday, May 28, 2014 3:45 PM
    Wednesday, January 12, 2011 8:08 AM