mmapdatf.cpp
Upload User: zhongxx05
Upload Date: 2007-06-06
Package Size: 33641k
Code Size: 17k
Category:

Symbian

Development Platform:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. #include "hxcom.h"
  36. #include "hxresult.h"
  37. #include "hxtypes.h"
  38. #include "hlxclib/sys/stat.h"
  39. #include "hlxclib/sys/types.h"
  40. #include "hlxclib/io.h"
  41. #include "hlxclib/fcntl.h"
  42. #include "hlxclib/windows.h"
  43. #include "hxbuffer.h"
  44. #include "mmapdatf.h"
  45. #include "mmapmgr.h"
  46. #include "hxfiles.h"
  47. #include "hxprefs.h"
  48. #include "filespec.h"
  49. #include "filespecutils.h"
  50. #include "platform/win/filetimeutil.h"
  51. #include "hxcore.h"
  52. MemoryMapManager* MemoryMapDataFile::m_zpMMM = NULL;
  53. BOOL MemoryMapDataFile::g_NT = FALSE;
  54. MemoryMapDataFile::MemoryMapDataFile(IUnknown* pContext,
  55.     REF(IUnknown*) pPersistantObject, BOOL bDisableMemoryMappedIO,
  56.     UINT32 ulChunkSize, BOOL bEnableFileLocking)
  57.     : m_lRefCount(0)
  58.     , m_hFile(INVALID_HANDLE_VALUE)
  59.     , m_pFilename(0)
  60.     , m_ulPos(-1)
  61.     , MmapHandle(0)
  62.     , m_ulChunkSize(ulChunkSize)
  63.     , m_ulLastError(HXR_OK)
  64. {
  65.     m_pContext = pContext;
  66.     m_pContext->AddRef();
  67.     if (m_zpMMM == NULL)
  68.     {
  69. m_zpMMM = new MemoryMapManager(pContext, bDisableMemoryMappedIO,
  70. m_ulChunkSize);
  71. OSVERSIONINFO vinfo;
  72. vinfo.dwOSVersionInfoSize = sizeof(vinfo);
  73. if (GetVersionEx(&vinfo))
  74. {
  75.     if (vinfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
  76.     {
  77. g_NT = TRUE;
  78.     }
  79. }
  80.     }
  81.     if (!pPersistantObject)
  82.     {
  83. pPersistantObject = m_zpMMM;
  84. pPersistantObject->AddRef();
  85.     }
  86. }
  87. MemoryMapDataFile::~MemoryMapDataFile()
  88. {
  89.     if (m_hFile != INVALID_HANDLE_VALUE)
  90.     {
  91. CloseHandle(m_hFile);
  92. m_hFile = INVALID_HANDLE_VALUE;
  93.     }
  94.     if (m_pFilename)
  95.     {
  96. delete[] m_pFilename;
  97. m_pFilename = 0;
  98.     }
  99.     HX_RELEASE(m_pContext);
  100. }
  101. /*
  102.  *  IUnknown methods
  103.  */
  104. STDMETHODIMP
  105. MemoryMapDataFile::QueryInterface(REFIID riid,
  106. void** ppvObj)
  107. {
  108.     if (IsEqualIID(IID_IUnknown, riid))
  109.     {
  110. AddRef();
  111. *ppvObj = this;
  112. return HXR_OK;
  113.     }
  114.     else if(IsEqualIID(IID_IHXDataFile, riid))
  115.     {
  116. AddRef();
  117. *ppvObj = (IHXDataFile*)this;
  118. return HXR_OK;
  119.     }
  120.     *ppvObj = 0;
  121.     return HXR_NOINTERFACE;
  122. }
  123. STDMETHODIMP_(ULONG32)
  124. MemoryMapDataFile::AddRef()
  125. {
  126.     return InterlockedIncrement(&m_lRefCount);
  127. }
  128. STDMETHODIMP_(ULONG32)
  129. MemoryMapDataFile::Release()
  130. {
  131.     if (InterlockedDecrement(&m_lRefCount) > 0)
  132.     {
  133. return m_lRefCount;
  134.     }
  135.     delete this;
  136.     return 0;
  137. }
  138.     
  139. /*
  140.  *  IHXDataFile methods
  141.  */
  142. /* Bind DataFile Object with FileName */
  143. STDMETHODIMP_(void)
  144. MemoryMapDataFile::Bind(const char* FileName)
  145. {
  146.     /* XXXPM
  147.     if (m_hFile != INVALID_HANDLE_VALUE)
  148.     {
  149. CloseHandle(m_hFile);
  150. m_hFile = INVALID_HANDLE_VALUE;
  151.     }*/
  152.     if (m_pFilename)
  153.     {
  154. delete[] m_pFilename;
  155. m_pFilename = 0;
  156.     }
  157.     m_pFilename = new char[strlen(FileName) + 1];
  158.     strcpy(m_pFilename, FileName); /* Flawfinder: ignore */
  159. }
  160. /* Creates a datafile using the specified mode
  161.  * uOpenMode --- File Open mode - HX_FILE_READ/HX_FILE_WRITE/HX_FILE_BINARY
  162.  */
  163. STDMETHODIMP
  164. MemoryMapDataFile::Create(UINT16 uOpenMode)
  165. {
  166.     return HXR_NOTIMPL;
  167. }
  168. /*
  169.  *  Open will open a file with the specified mode
  170.  */
  171. STDMETHODIMP
  172. MemoryMapDataFile::Open(UINT16 uOpenMode)
  173. {
  174.     m_ulLastError = HXR_OK;
  175.     if (m_hFile != INVALID_HANDLE_VALUE)
  176.     {
  177. CloseHandle(m_hFile);
  178. m_hFile = INVALID_HANDLE_VALUE;
  179.     }
  180.     
  181.     DWORD dwAccess = 0;
  182.     DWORD dwShare = 0;
  183.     DWORD dwCreate = 0;
  184.     DWORD dwFlags = FILE_ATTRIBUTE_NORMAL;
  185.     m_uOpenMode = uOpenMode;
  186.     if (uOpenMode & HX_FILE_WRITE)
  187.     {
  188.         // Set read access so file can be opened read-only simultaneously
  189.         uOpenMode |= HX_FILE_READ;
  190. dwAccess |= GENERIC_WRITE;
  191. dwShare |= FILE_SHARE_WRITE;
  192. if (g_NT)
  193. {
  194.     dwShare |= FILE_SHARE_DELETE;
  195. }
  196. if (uOpenMode & HX_FILE_NOTRUNC)
  197. {
  198.     dwCreate = OPEN_ALWAYS;
  199. }
  200. else
  201. {
  202.     dwCreate = CREATE_ALWAYS;
  203. }
  204.     }
  205.     if (uOpenMode & HX_FILE_READ)
  206.     {
  207. dwAccess |= GENERIC_READ;
  208. dwShare |= FILE_SHARE_READ;
  209. if (!(uOpenMode & HX_FILE_WRITE))
  210. {
  211.     dwCreate = OPEN_EXISTING;
  212. }
  213. IHXPreferences* pPref = NULL;
  214. if (m_pContext && 
  215.     (m_pContext->QueryInterface(IID_IHXPreferences, (void**) &pPref) == HXR_OK) &&
  216.     pPref)
  217. {
  218.     IHXBuffer* pBuffer = NULL;
  219.     if (pPref->ReadPref("FileReadWriteAccess", pBuffer) == HXR_OK &&
  220. pBuffer &&
  221. (::atoi((char*) pBuffer->GetBuffer()) == 1))
  222.     {
  223. dwShare |= FILE_SHARE_WRITE;
  224. if (g_NT)
  225. {
  226.     dwShare |= FILE_SHARE_DELETE;
  227. }
  228.     }
  229.     HX_RELEASE(pBuffer);
  230.     HX_RELEASE(pPref);
  231. }
  232.     }
  233.     /*
  234.      * Nothing to be done for HX_FILE_BINARY
  235.      */
  236.     m_hFile = CreateFile(OS_STRING(m_pFilename), dwAccess, dwShare, NULL,
  237.     dwCreate, dwFlags, NULL);
  238.     
  239.     if (m_hFile == INVALID_HANDLE_VALUE)
  240.     {
  241.         if (::GetLastError() == ERROR_FILE_NOT_FOUND)
  242. {
  243.             m_ulLastError = HXR_FAIL;
  244.     return HXR_FILE_NOT_FOUND;
  245. }
  246. /*
  247.  * Check if we are trying to truncate.  If this is the
  248.  * case the file is probably mapped and we have to unmap
  249.  * it.
  250.  */
  251. BOOL bReopen = FALSE;
  252. if ((uOpenMode & (HX_FILE_WRITE|HX_FILE_NOTRUNC)) == HX_FILE_WRITE)
  253. {
  254.     _AttemptUnmap();
  255.     bReopen = TRUE;
  256. }
  257. /*
  258.  * Check if we tried to do read only.  Perhaps the file
  259.  * is mapped read/write.  We'll have to open it like that too.
  260.  */
  261. if (!(uOpenMode & HX_FILE_WRITE))
  262. {
  263.     dwAccess |= GENERIC_WRITE;
  264.     dwShare |= FILE_SHARE_WRITE;
  265.     if (g_NT)
  266.     {
  267. dwShare |= FILE_SHARE_DELETE;
  268.     }
  269.     dwCreate = OPEN_ALWAYS;
  270.     bReopen = TRUE;
  271. }
  272. if (!bReopen)
  273. {
  274.             m_ulLastError = HXR_FAIL;
  275.     return HXR_FAIL;
  276. }
  277. m_hFile = CreateFile(OS_STRING(m_pFilename), dwAccess, dwShare, NULL,
  278. dwCreate, dwFlags, NULL);
  279. if (m_hFile == INVALID_HANDLE_VALUE)
  280. {
  281.             m_ulLastError = HXR_FAIL;
  282.     return HXR_FAIL;
  283. }
  284.     }
  285.     m_ulPos = 0;
  286. //  On windows we do now want to use memory mapped IO if we are going across
  287. //  a network share. And we only want to disable this for clients, not servers.
  288.     //check to see if we are within the player...
  289.     IHXClientEngine* pEngine = NULL;
  290.     if (HXR_OK == m_pContext->QueryInterface(IID_IHXClientEngine, (void**)&pEngine))
  291.     {
  292.         HX_RELEASE(pEngine);
  293.         CHXDirSpecifier  dirspec(m_pFilename);
  294.         if (!CHXFileSpecUtils::IsDiskLocal( dirspec) || CHXFileSpecUtils::IsDiskEjectable(dirspec) )
  295.         {
  296.             if (MmapHandle)
  297.             {
  298.         m_zpMMM->CloseMap(MmapHandle);
  299.         MmapHandle = 0;
  300.             }
  301.             return HXR_OK;
  302.         }
  303.     }
  304.     
  305.     if (MmapHandle)
  306.     {
  307. m_zpMMM->CloseMap(MmapHandle);
  308. MmapHandle = 0;
  309.     }
  310.     MmapHandle = m_zpMMM->OpenMap(m_hFile, m_pContext);
  311.     
  312.     return HXR_OK;
  313. }
  314. /*
  315.  * Original Version
  316.  */
  317.     
  318. /*
  319.     if (m_hFile != INVALID_HANDLE_VALUE)
  320.     {
  321. CloseHandle(m_hFile);
  322. m_hFile = INVALID_HANDLE_VALUE;
  323.     }
  324.     DWORD dwPlatformSpecific = 0;
  325.     if (g_NT)
  326.     {
  327. dwPlatformSpecific = FILE_SHARE_DELETE;
  328.     }
  329.     DWORD dwFlags = 0;
  330.     DWORD dwShare = dwPlatformSpecific;
  331.     DWORD dwCreate = 0;
  332.     m_uOpenMode = uOpenMode;
  333.     if (uOpenMode & HX_FILE_WRITE)
  334.     {
  335. dwShare |= FILE_SHARE_WRITE;
  336. dwFlags |= GENERIC_WRITE;
  337. if (uOpenMode & HX_FILE_NOTRUNC)
  338. {
  339.     dwCreate |= OPEN_ALWAYS;
  340. }
  341. else
  342. {
  343.     dwCreate |= CREATE_ALWAYS;
  344. }
  345.     }
  346.     if (uOpenMode & HX_FILE_READ)
  347.     {
  348. dwShare |= FILE_SHARE_READ;
  349. dwFlags |= GENERIC_READ;
  350.   if (!(uOpenMode & HX_FILE_WRITE))
  351. {
  352.     dwCreate |= OPEN_EXISTING;
  353. }
  354.     }
  355.     if (uOpenMode & HX_FILE_BINARY)
  356.     {
  357.     }
  358.     m_hFile = CreateFile(m_pFilename,
  359.     GENERIC_READ | GENERIC_WRITE,
  360.     FILE_SHARE_READ | FILE_SHARE_WRITE | dwPlatformSpecific,
  361.     NULL,
  362.     dwCreate,
  363.     FILE_ATTRIBUTE_NORMAL,
  364.     NULL);
  365.     if (m_hFile == INVALID_HANDLE_VALUE)
  366.     {
  367. if (::GetLastError() == ERROR_FILE_NOT_FOUND)
  368. {
  369.     return HXR_FAIL;
  370. }
  371. /*
  372.  * File may be mapped and we are trying to truncate it.
  373.  * It will only let us do that if we unmap the file NOW.
  374.  *
  375. if (uOpenMode & HX_FILE_WRITE && dwCreate == CREATE_ALWAYS)
  376. {
  377.     _AttemptUnmap();
  378.     /*
  379.      * We are now going to open the file, so make
  380.      * sure there is always a read mixed this this write.
  381.      *
  382.     dwFlags |= GENERIC_READ;
  383.     dwShare |= FILE_SHARE_READ;
  384. }
  385. /*
  386.  * Try and re-open the file.  This will either be read only
  387.  * if we failed reading, in case it is a readonly file,
  388.  * of it could be another attempt at "w" after unampping
  389.  * the file.  All vars are set up for either case.
  390.  *
  391. m_hFile = CreateFile(m_pFilename,
  392.     dwFlags,
  393.     dwShare,
  394.     NULL,
  395.     dwCreate,
  396.     FILE_ATTRIBUTE_NORMAL,
  397.     NULL);
  398. if (m_hFile == INVALID_HANDLE_VALUE)
  399. {
  400.     return HXR_FAIL;
  401. }
  402.     }
  403.     m_ulPos = 0;
  404.     if (MmapHandle)
  405.     {
  406. m_zpMMM->CloseMap(MmapHandle);
  407. MmapHandle = 0;
  408.     }
  409.     MmapHandle = m_zpMMM->OpenMap(m_hFile, m_pContext);
  410.     return HXR_OK;
  411. }
  412. */
  413. /* Delete File */
  414. STDMETHODIMP
  415. MemoryMapDataFile::Delete()
  416. {
  417.     Close();
  418.     if (!m_pFilename)
  419.     {
  420. return HXR_UNEXPECTED;
  421.     }
  422.     if (DeleteFile(OS_STRING(m_pFilename)))
  423.     {
  424. return HXR_OK;
  425.     }
  426.     else if (_AttemptUnmap())
  427.     {
  428.         if (DeleteFile(OS_STRING(m_pFilename)))
  429. {
  430.     return HXR_OK;
  431. }
  432.     }
  433.     return HXR_FAIL;
  434. }
  435. /* Close closes a file 
  436.  * If the reference count on the IHXDataFile object is greater than 1, 
  437.  * then the underlying file cannot be safely closed, so Close() becomes 
  438.  * a noop in that case. Close it only when the object is destroyed. 
  439.  * This would be safe, but could lead to a file descriptor leak.
  440.  */
  441. STDMETHODIMP
  442. MemoryMapDataFile::Close()
  443. {
  444.     m_ulLastError = HXR_OK;
  445.     if (m_hFile != INVALID_HANDLE_VALUE)
  446.     {
  447. CloseHandle(m_hFile);
  448. m_hFile = INVALID_HANDLE_VALUE;
  449.     }
  450.     m_ulPos = -1;
  451.     if (MmapHandle)
  452.     {
  453. m_zpMMM->CloseMap(MmapHandle);
  454. MmapHandle = 0;
  455.     }
  456.     return HXR_OK;
  457. }
  458. /* Name returns the currently bound file name in FileName.
  459.  * and returns TRUE, if the a name has been bound.  Otherwise
  460.  * FALSE is returned.
  461.  */
  462. STDMETHODIMP_(BOOL)
  463. MemoryMapDataFile::Name(REF(IHXBuffer*) pFileName)
  464. {
  465.     if (!m_pFilename)
  466.     {
  467. return FALSE;
  468.     }
  469.     pFileName = new CHXBuffer();
  470.     pFileName->AddRef();
  471.     pFileName->Set((const unsigned char*)m_pFilename,
  472. strlen(m_pFilename) + 1);
  473.     return TRUE;
  474. }
  475. /*
  476.  * IsOpen returns TRUE if file is open.  Otherwise FALSE.
  477.  */
  478. STDMETHODIMP_(BOOL)
  479. MemoryMapDataFile::IsOpen()
  480. {
  481.     if (m_hFile != INVALID_HANDLE_VALUE)
  482.     {
  483. return TRUE;
  484.     }
  485.     return FALSE;
  486. }
  487. /* Seek moves the current file position to the offset from the
  488.  * fromWhere specifier returns current position of file or -1 on
  489.  * error.
  490.  */
  491. STDMETHODIMP
  492. MemoryMapDataFile::Seek(ULONG32 offset, UINT16 fromWhere)
  493. {
  494.     LONG32 lHighOffset = 0;
  495.     m_ulLastError = HXR_OK;
  496.     DWORD fw = 0;
  497.     switch (fromWhere)
  498.     {
  499. case SEEK_CUR:
  500.     fw = FILE_CURRENT;
  501.     m_ulPos += offset;
  502.     if (((LONG32) offset) < 0)
  503.     {
  504. lHighOffset = -1;
  505.     }
  506.     break;
  507. case SEEK_END:
  508.     fw = FILE_END;
  509.     if (offset > m_ulPos)
  510.     {
  511. m_ulPos = 0;
  512.     }
  513.     else
  514.     {
  515. m_ulPos -= offset;
  516.     }
  517.     break;
  518. case SEEK_SET:
  519.     fw = FILE_BEGIN;
  520.     m_ulPos = offset;
  521.     break;
  522.     }
  523.     DWORD dwRet = SetFilePointer(m_hFile, offset, &lHighOffset, fw);
  524.     if (dwRet == -1)
  525.     {
  526. if (GetLastError() != NO_ERROR)
  527. {
  528.     m_ulPos = -1;
  529.     m_ulLastError = HXR_FAIL;
  530.     return HXR_FAIL;
  531. }
  532.     }
  533.     
  534.     return 0;
  535. }
  536. /* Tell returns the current file position in the file */
  537. STDMETHODIMP_(ULONG32)
  538. MemoryMapDataFile::Tell()
  539. {
  540.     m_ulLastError = HXR_OK;
  541.     return m_ulPos;
  542. }
  543. void MemoryMapDataFile::StopMmap()
  544. {
  545.     if (MmapHandle == NULL)
  546. return;
  547.     m_zpMMM->CloseMap(MmapHandle);
  548.     MmapHandle = 0;
  549.     Seek(m_ulPos, SEEK_SET);
  550. }
  551. /* Read reads up to count bytes of data into buf.
  552.  * returns the number of bytes read, EOF, or -1 if the read failed 
  553.  */
  554. STDMETHODIMP_(ULONG32)
  555. MemoryMapDataFile::Read(REF(IHXBuffer*) pBuf, 
  556. ULONG32 count)
  557. {
  558.     m_ulLastError = HXR_OK;
  559.     if (!(m_uOpenMode & HX_FILE_READ))
  560.     {
  561. return 0;
  562.     }
  563.     UINT32 ulRead = 0;
  564.     if (MmapHandle)
  565.     {
  566. ulRead = m_zpMMM->GetBlock(pBuf, MmapHandle, m_ulPos, count);
  567. if (ulRead >= MMAP_EXCEPTION)
  568. {
  569.     if (ulRead != MMAP_EOF_EXCEPTION)
  570.     {
  571. StopMmap();
  572.     }
  573.     else
  574.     {
  575. Seek(m_ulPos, SEEK_SET);
  576.     }
  577.     goto normal_read;
  578. }
  579. if (ulRead > 0)
  580. {
  581.     m_ulPos += ulRead;
  582. }
  583. return ulRead;
  584.     }
  585. normal_read:
  586.     if (m_hFile == INVALID_HANDLE_VALUE)
  587.     {
  588. pBuf = NULL;
  589. return 0;
  590.     }
  591.     pBuf = new CHXBuffer;
  592.     pBuf->AddRef();
  593.     pBuf->SetSize(count);
  594.     if (!ReadFile(m_hFile, (void*)pBuf->GetBuffer(), count, &ulRead, NULL))
  595.     {
  596.         m_ulLastError = HXR_FAIL;
  597.     }
  598.     m_ulPos += ulRead;
  599.     if (ulRead < count)
  600.     {
  601.         pBuf->SetSize(ulRead);
  602.     }
  603.     return ulRead;
  604. }
  605. /* Write writes up to count bytes of data from buf.
  606.  * returns the number of bytes written, or -1 if the write failed 
  607.  */
  608. STDMETHODIMP_(ULONG32)
  609. MemoryMapDataFile::Write(REF(IHXBuffer*) pBuf)
  610. {
  611.     m_ulLastError = HXR_OK;
  612.     if (!(m_uOpenMode & HX_FILE_WRITE))
  613.     {
  614. return 0;
  615.     }
  616.     StopMmap();
  617.     UINT32 ulWritten = 0;
  618.     if (m_hFile == INVALID_HANDLE_VALUE)
  619.     {
  620. return 0;
  621.     }
  622.     if (!WriteFile(m_hFile, (void*)pBuf->GetBuffer(), pBuf->GetSize(),
  623.                    &ulWritten, NULL))
  624.     {
  625.         m_ulLastError = HXR_FAIL;
  626.     }
  627.     return ulWritten;
  628. }
  629. /* Flush out the data in case of unbuffered I/O
  630.  */
  631. STDMETHODIMP
  632. MemoryMapDataFile::Flush()
  633. {
  634.     StopMmap();
  635.     return HXR_NOTIMPL;
  636. }
  637. /*
  638.  * Return info about the data file such as permissions, time of creation
  639.  * size in bytes, etc.
  640.  */
  641. STDMETHODIMP
  642. MemoryMapDataFile::Stat(struct stat* buffer)
  643. {
  644.     if (!m_pFilename)
  645.     {
  646. return HXR_UNEXPECTED;
  647.     }
  648.     BOOL bClose = FALSE;
  649.     HANDLE hUse = m_hFile;
  650.     if (hUse == INVALID_HANDLE_VALUE)
  651.     {
  652. bClose = TRUE;
  653. hUse = CreateFile(OS_STRING(m_pFilename),
  654. 0, //query
  655. FILE_SHARE_READ,
  656. NULL,
  657. OPEN_EXISTING,
  658. FILE_ATTRIBUTE_NORMAL,
  659. NULL);
  660.     }
  661.     if (hUse == INVALID_HANDLE_VALUE)
  662.     {
  663. return HXR_FAIL;
  664.     }
  665.     BY_HANDLE_FILE_INFORMATION mss;
  666.     memset(buffer, 0, sizeof(*buffer));
  667.     buffer->st_nlink = 1;
  668.     
  669.     HX_RESULT res;
  670.     if (GetFileInformationByHandle(hUse,
  671.     &mss))
  672.     {
  673. buffer->st_atime = FileTimeTotime_t(&mss.ftLastAccessTime);
  674. buffer->st_ctime = FileTimeTotime_t(&mss.ftCreationTime);
  675. buffer->st_mtime = FileTimeTotime_t(&mss.ftLastWriteTime);
  676. buffer->st_size  = mss.nFileSizeLow;
  677. res = HXR_OK;
  678.     }
  679.     else
  680.     {
  681. res = HXR_FAIL;
  682.     }
  683.     if (bClose)
  684.     {
  685. CloseHandle(hUse);
  686.     }
  687.     return res;
  688. }
  689. /* Return the file descriptor */
  690. STDMETHODIMP_(INT16)
  691. MemoryMapDataFile::GetFd()
  692. {
  693.     if (m_hFile != INVALID_HANDLE_VALUE)
  694.     {
  695. return 1;
  696.     }
  697.     return -1;
  698. }
  699. /* GetLastError returns the platform specific file error */
  700. STDMETHODIMP
  701. MemoryMapDataFile::GetLastError()
  702. {
  703.     return m_ulLastError;
  704. }
  705. /* GetLastError returns the platform specific file error in
  706.  * string form.
  707.  */
  708. STDMETHODIMP_(void)
  709. MemoryMapDataFile::GetLastError(REF(IHXBuffer*) err)
  710. {
  711.     err = 0;
  712.     return;
  713. }
  714. BOOL
  715. MemoryMapDataFile::_AttemptUnmap()
  716. {
  717.     HANDLE hFile;
  718.     hFile = CreateFile(OS_STRING(m_pFilename),
  719.     GENERIC_READ,
  720.     FILE_SHARE_READ |
  721. (g_NT ? FILE_SHARE_DELETE : 0),
  722.     NULL,
  723.     OPEN_EXISTING,
  724.     FILE_ATTRIBUTE_NORMAL,
  725.     NULL);
  726.     if (hFile == INVALID_HANDLE_VALUE)
  727.     {
  728. return FALSE;
  729.     }
  730.     void* pHandle = m_zpMMM->GetMMHandle(hFile);
  731.     CloseHandle(hFile);
  732.     if (!pHandle)
  733.     {
  734. return FALSE;
  735.     }
  736.     m_zpMMM->AttemptCloseMapNow(pHandle);
  737.     return TRUE;
  738. }