winfile.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:10k
源码类别:

Symbian

开发平台:

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 "hxbuffer.h"
  41. #include "winfile.h"
  42. #include "hxfiles.h"
  43. #include "hlxclib/io.h"
  44. #include "hlxclib/fcntl.h"
  45. WinFile::WinFile()
  46. : m_lRefCount(0)
  47. , m_hFile(INVALID_HANDLE_VALUE)
  48. , m_pFilename(0)
  49. , m_ulPos(-1)
  50. {
  51. }
  52. WinFile::~WinFile()
  53. {
  54.     if (m_hFile != INVALID_HANDLE_VALUE)
  55.     {
  56. CloseHandle(m_hFile);
  57. m_hFile = INVALID_HANDLE_VALUE;
  58.     }
  59.     if (m_pFilename)
  60.     {
  61. delete[] m_pFilename;
  62. m_pFilename = 0;
  63.     }
  64. }
  65. /*
  66.  *  IUnknown methods
  67.  */
  68. STDMETHODIMP
  69. WinFile::QueryInterface(REFIID riid,
  70. void** ppvObj)
  71. {
  72.     if (IsEqualIID(IID_IUnknown, riid))
  73.     {
  74. AddRef();
  75. *ppvObj = this;
  76. return HXR_OK;
  77.     }
  78.     else if(IsEqualIID(IID_IHXDataFile, riid))
  79.     {
  80. AddRef();
  81. *ppvObj = (IHXDataFile*)this;
  82. return HXR_OK;
  83.     }
  84.     *ppvObj = 0;
  85.     return HXR_NOINTERFACE;
  86. }
  87. STDMETHODIMP_(ULONG32)
  88. WinFile::AddRef()
  89. {
  90.     return InterlockedIncrement(&m_lRefCount);
  91. }
  92. STDMETHODIMP_(ULONG32)
  93. WinFile::Release()
  94. {
  95.     if (InterlockedDecrement(&m_lRefCount) > 0)
  96.     {
  97. return m_lRefCount;
  98.     }
  99.     delete this;
  100.     return 0;
  101. }
  102.     
  103. /*
  104.  *  IHXDataFile methods
  105.  */
  106. /* Bind DataFile Object with FileName */
  107. STDMETHODIMP_(void)
  108. WinFile::Bind(const char* FileName)
  109. {
  110.     /* XXXPM
  111.     if (m_hFile != INVALID_HANDLE_VALUE)
  112.     {
  113. CloseHandle(m_hFile);
  114. m_hFile = INVALID_HANDLE_VALUE;
  115.     }*/
  116.     if (m_pFilename)
  117.     {
  118. delete[] m_pFilename;
  119. m_pFilename = 0;
  120.     }
  121.     m_pFilename = new char[strlen(FileName) + 1];
  122.     strcpy(m_pFilename, FileName); /* Flawfinder: ignore */
  123. }
  124. /* Creates a datafile using the specified mode
  125.  * uOpenMode --- File Open mode - HX_FILE_READ/HX_FILE_WRITE/HX_FILE_BINARY
  126.  */
  127. STDMETHODIMP
  128. WinFile::Create(UINT16 uOpenMode)
  129. {
  130.     return HXR_NOTIMPL;
  131. }
  132. /* Open will open a file with the specified mode
  133.  */
  134. STDMETHODIMP
  135. WinFile::Open(UINT16 uOpenMode)
  136. {
  137.     if (m_hFile != INVALID_HANDLE_VALUE)
  138.     {
  139. CloseHandle(m_hFile);
  140. m_hFile = INVALID_HANDLE_VALUE;
  141.     }
  142.     DWORD dwFlags = 0;
  143.     DWORD dwShare = 0;
  144.     DWORD dwCreate = 0;
  145.     if (uOpenMode & HX_FILE_WRITE)
  146.     {
  147. dwShare |= FILE_SHARE_WRITE;
  148. dwFlags |= GENERIC_WRITE;
  149. if (uOpenMode & HX_FILE_NOTRUNC)
  150. {
  151.     dwCreate |= OPEN_ALWAYS;
  152. }
  153. else
  154. {
  155.     dwCreate |= CREATE_ALWAYS;
  156. }
  157.     }
  158.     if (uOpenMode & HX_FILE_READ)
  159.     {
  160. dwShare |= FILE_SHARE_READ;
  161. dwFlags |= GENERIC_READ;
  162.   if (!(uOpenMode & HX_FILE_WRITE))
  163. {
  164.     dwCreate |= OPEN_EXISTING;
  165. }
  166.     }
  167.     if (uOpenMode & HX_FILE_BINARY)
  168.     {
  169.     }
  170.     m_hFile = CreateFile(OS_STRING(m_pFilename),
  171.     dwFlags,
  172.     dwShare,
  173.     NULL,
  174.     dwCreate,
  175.     FILE_ATTRIBUTE_NORMAL,
  176.     NULL);
  177.     if (m_hFile == INVALID_HANDLE_VALUE)
  178.     {
  179. return HXR_FAIL;
  180.     }
  181.     m_ulPos = 0;
  182.     return HXR_OK;
  183. }
  184. /* Close closes a file 
  185.  * If the reference count on the IHXDataFile object is greater than 1, 
  186.  * then the underlying file cannot be safely closed, so Close() becomes 
  187.  * a noop in that case. Close it only when the object is destroyed. 
  188.  * This would be safe, but could lead to a file descriptor leak.
  189.  */
  190. STDMETHODIMP
  191. WinFile::Close()
  192. {
  193.     if (m_hFile != INVALID_HANDLE_VALUE)
  194.     {
  195. CloseHandle(m_hFile);
  196. m_hFile = INVALID_HANDLE_VALUE;
  197.     }
  198.     m_ulPos = -1;
  199.     return HXR_OK;
  200. }
  201. /* Name returns the currently bound file name in FileName.
  202.  * and returns TRUE, if the a name has been bound.  Otherwise
  203.  * FALSE is returned.
  204.  */
  205. STDMETHODIMP_(BOOL)
  206. WinFile::Name(REF(IHXBuffer*) pFileName)
  207. {
  208.     if (!m_pFilename)
  209.     {
  210. return FALSE;
  211.     }
  212.     pFileName = new CHXBuffer();
  213.     pFileName->AddRef();
  214.     pFileName->Set((const unsigned char*)m_pFilename,
  215. strlen(m_pFilename) + 1);
  216.     return TRUE;
  217. }
  218. /*
  219.  * IsOpen returns TRUE if file is open.  Otherwise FALSE.
  220.  */
  221. STDMETHODIMP_(BOOL)
  222. WinFile::IsOpen()
  223. {
  224.     if (m_hFile != INVALID_HANDLE_VALUE)
  225.     {
  226. return TRUE;
  227.     }
  228.     return FALSE;
  229. }
  230. /* Seek moves the current file position to the offset from the
  231.  * fromWhere specifier returns current position of file or -1 on
  232.  * error.
  233.  */
  234. STDMETHODIMP
  235. WinFile::Seek(ULONG32 offset, UINT16 fromWhere)
  236. {
  237.     DWORD fw = 0;
  238.     switch (fromWhere)
  239.     {
  240. case SEEK_CUR:
  241.     fw = FILE_CURRENT;
  242.     m_ulPos += offset;
  243.     break;
  244. case SEEK_END:
  245.     fw = FILE_END;
  246.     if (offset > m_ulPos)
  247.     {
  248. m_ulPos = 0;
  249.     }
  250.     else
  251.     {
  252. m_ulPos -= offset;
  253.     }
  254.     break;
  255. case SEEK_SET:
  256.     fw = FILE_BEGIN;
  257.     m_ulPos = offset;
  258.     break;
  259.     }
  260.     DWORD dwRet;
  261.     dwRet = SetFilePointer(m_hFile,
  262. offset,
  263. NULL,
  264. fw);
  265.     
  266.     if (dwRet == -1)
  267.     {
  268. m_ulPos = -1;
  269. return HXR_FAIL;
  270.     }
  271.     
  272.     return 0;
  273. }
  274. /* Tell returns the current file position in the file */
  275. STDMETHODIMP_(ULONG32)
  276. WinFile::Tell()
  277. {
  278.     return m_ulPos;
  279. }
  280. /* Read reads up to count bytes of data into buf.
  281.  * returns the number of bytes read, EOF, or -1 if the read failed 
  282.  */
  283. STDMETHODIMP_(ULONG32)
  284. WinFile::Read(REF(IHXBuffer*) pBuf, 
  285. ULONG32 count)
  286. {
  287.     if (m_hFile == INVALID_HANDLE_VALUE)
  288.     {
  289. pBuf = NULL;
  290. return 0;
  291.     }
  292.     pBuf = new CHXBuffer;
  293.     pBuf->AddRef();
  294.     pBuf->SetSize(count);
  295.     BOOL bRet;
  296.     UINT32 ulRead = 0;
  297.     bRet = ReadFile(m_hFile,
  298. (void*)pBuf->GetBuffer(),
  299. count,
  300. &ulRead,
  301. NULL);
  302.     if (ulRead < count)
  303.     {
  304.         pBuf->SetSize(ulRead);
  305.     }
  306.     return ulRead;
  307. }
  308. /* Write writes up to count bytes of data from buf.
  309.  * returns the number of bytes written, or -1 if the write failed 
  310.  */
  311. STDMETHODIMP_(ULONG32)
  312. WinFile::Write(REF(IHXBuffer*) pBuf)
  313. {
  314.     UINT32 ulWritten = 0;
  315.     if (m_hFile == INVALID_HANDLE_VALUE)
  316.     {
  317. return 0;
  318.     }
  319.     BOOL bRet;
  320.     bRet = WriteFile(m_hFile,
  321. (void*)pBuf->GetBuffer(),
  322. pBuf->GetSize(),
  323. &ulWritten,
  324. NULL);
  325.     return ulWritten;
  326. }
  327. /* Flush out the data in case of unbuffered I/O
  328.  */
  329. STDMETHODIMP
  330. WinFile::Flush()
  331. {
  332.     return HXR_NOTIMPL;
  333. }
  334. /*
  335.  * Return info about the data file such as permissions, time of creation
  336.  * size in bytes, etc.
  337.  */
  338. STDMETHODIMP
  339. WinFile::Stat(struct stat* buffer)
  340. {
  341.     if (!m_pFilename)
  342.     {
  343. return HXR_UNEXPECTED;
  344.     }
  345.     int ret = _stat(m_pFilename, (struct _stat*)buffer);
  346.     if (ret == 0)
  347.     {
  348. return HXR_OK;
  349.     }
  350.     return HXR_FAIL;
  351.     /*
  352.      * XXXPM
  353.      * This way is faster, but the times are incompatible with stat times.
  354.      * Maybe someday I will convert.
  355.      *
  356.     BOOL bClose = 0;
  357.     HANDLE hUse = m_hFile;
  358.     if (hUse == INVALID_HANDLE_VALUE)
  359.     {
  360. bClose = 1;
  361. hUse = CreateFile(m_pFilename,
  362. 0, //query
  363. FILE_SHARE_READ,
  364. NULL,
  365. OPEN_EXISTING,
  366. FILE_ATTRIBUTE_NORMAL,
  367. NULL);
  368.     }
  369.     if (hUse == INVALID_HANDLE_VALUE)
  370.     {
  371. return HXR_FAIL;
  372.     }
  373.     BY_HANDLE_FILE_INFORMATION mss;
  374.     memset(buffer, 0, sizeof(*buffer));
  375.     buffer->st_nlink = 1;
  376.     
  377.     HX_RESULT res;
  378.     if (GetFileInformationByHandle(hUse,
  379.     &mss))
  380.     {
  381. buffer->st_atime = mss.ftLastAccessTime.dwLowDateTime;
  382. buffer->st_ctime = mss.ftCreationTime.dwLowDateTime;
  383. buffer->st_mtime = mss.ftLastWriteTime.dwLowDateTime;
  384. buffer->st_size = mss.nFileSizeLow;
  385. res = HXR_OK;
  386.     }
  387.     else
  388.     {
  389. res = HXR_FAIL;
  390.     }
  391.     if (bClose)
  392.     {
  393. CloseHandle(hUse);
  394.     }
  395.     return res;
  396.     */
  397. }
  398. /* Return the file descriptor */
  399. STDMETHODIMP_(INT16)
  400. WinFile::GetFd()
  401. {
  402.     if (m_hFile != INVALID_HANDLE_VALUE)
  403.     {
  404. return 1;
  405.     }
  406.     return -1;
  407. }
  408. /* GetLastError returns the platform specific file error */
  409. STDMETHODIMP
  410. WinFile::GetLastError()
  411. {
  412.     return HXR_NOTIMPL;
  413. }
  414. /* GetLastError returns the platform specific file error in
  415.  * string form.
  416.  */
  417. STDMETHODIMP_(void)
  418. WinFile::GetLastError(REF(IHXBuffer*) err)
  419. {
  420.     err = 0;
  421.     return;
  422. }