winfile.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:10k
源码类别:

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: winfile.cpp,v 1.4.42.3 2004/07/09 01:44:27 hubbe Exp $
  3.  * 
  4.  * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
  5.  * 
  6.  * The contents of this file, and the files included with this file,
  7.  * are subject to the current version of the RealNetworks Public
  8.  * Source License (the "RPSL") available at
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed
  10.  * the file under the current version of the RealNetworks Community
  11.  * Source License (the "RCSL") available at
  12.  * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
  13.  * will apply. You may also obtain the license terms directly from
  14.  * RealNetworks.  You may not use this file except in compliance with
  15.  * the RPSL or, if you have a valid RCSL with RealNetworks applicable
  16.  * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
  17.  * the rights, obligations and limitations governing use of the
  18.  * contents of the file.
  19.  * 
  20.  * Alternatively, the contents of this file may be used under the
  21.  * terms of the GNU General Public License Version 2 or later (the
  22.  * "GPL") in which case the provisions of the GPL are applicable
  23.  * instead of those above. If you wish to allow use of your version of
  24.  * this file only under the terms of the GPL, and not to allow others
  25.  * to use your version of this file under the terms of either the RPSL
  26.  * or RCSL, indicate your decision by deleting the provisions above
  27.  * and replace them with the notice and other provisions required by
  28.  * the GPL. If you do not delete the provisions above, a recipient may
  29.  * use your version of this file under the terms of any one of the
  30.  * RPSL, the RCSL or the GPL.
  31.  * 
  32.  * This file is part of the Helix DNA Technology. RealNetworks is the
  33.  * developer of the Original Code and owns the copyrights in the
  34.  * portions it created.
  35.  * 
  36.  * This file, and the files included with this file, is distributed
  37.  * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
  38.  * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
  39.  * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
  40.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
  41.  * ENJOYMENT OR NON-INFRINGEMENT.
  42.  * 
  43.  * Technology Compatibility Kit Test Suite(s) Location:
  44.  *    http://www.helixcommunity.org/content/tck
  45.  * 
  46.  * Contributor(s):
  47.  * 
  48.  * ***** END LICENSE BLOCK ***** */
  49. #include "hxcom.h"
  50. #include "hxresult.h"
  51. #include "hxtypes.h"
  52. #include "hlxclib/sys/stat.h"
  53. #include "hlxclib/sys/types.h"
  54. #include "hxbuffer.h"
  55. #include "winfile.h"
  56. #include "hxfiles.h"
  57. #include "hlxclib/io.h"
  58. #include "hlxclib/fcntl.h"
  59. WinFile::WinFile()
  60. : m_lRefCount(0)
  61. , m_hFile(INVALID_HANDLE_VALUE)
  62. , m_pFilename(0)
  63. , m_ulPos(-1)
  64. {
  65. }
  66. WinFile::~WinFile()
  67. {
  68.     if (m_hFile != INVALID_HANDLE_VALUE)
  69.     {
  70. CloseHandle(m_hFile);
  71. m_hFile = INVALID_HANDLE_VALUE;
  72.     }
  73.     if (m_pFilename)
  74.     {
  75. delete[] m_pFilename;
  76. m_pFilename = 0;
  77.     }
  78. }
  79. /*
  80.  *  IUnknown methods
  81.  */
  82. STDMETHODIMP
  83. WinFile::QueryInterface(REFIID riid,
  84. void** ppvObj)
  85. {
  86.     if (IsEqualIID(IID_IUnknown, riid))
  87.     {
  88. AddRef();
  89. *ppvObj = this;
  90. return HXR_OK;
  91.     }
  92.     else if(IsEqualIID(IID_IHXDataFile, riid))
  93.     {
  94. AddRef();
  95. *ppvObj = (IHXDataFile*)this;
  96. return HXR_OK;
  97.     }
  98.     *ppvObj = 0;
  99.     return HXR_NOINTERFACE;
  100. }
  101. STDMETHODIMP_(ULONG32)
  102. WinFile::AddRef()
  103. {
  104.     return InterlockedIncrement(&m_lRefCount);
  105. }
  106. STDMETHODIMP_(ULONG32)
  107. WinFile::Release()
  108. {
  109.     if (InterlockedDecrement(&m_lRefCount) > 0)
  110.     {
  111. return m_lRefCount;
  112.     }
  113.     delete this;
  114.     return 0;
  115. }
  116.     
  117. /*
  118.  *  IHXDataFile methods
  119.  */
  120. /* Bind DataFile Object with FileName */
  121. STDMETHODIMP_(void)
  122. WinFile::Bind(const char* FileName)
  123. {
  124.     /* XXXPM
  125.     if (m_hFile != INVALID_HANDLE_VALUE)
  126.     {
  127. CloseHandle(m_hFile);
  128. m_hFile = INVALID_HANDLE_VALUE;
  129.     }*/
  130.     if (m_pFilename)
  131.     {
  132. delete[] m_pFilename;
  133. m_pFilename = 0;
  134.     }
  135.     m_pFilename = new char[strlen(FileName) + 1];
  136.     strcpy(m_pFilename, FileName); /* Flawfinder: ignore */
  137. }
  138. /* Creates a datafile using the specified mode
  139.  * uOpenMode --- File Open mode - HX_FILE_READ/HX_FILE_WRITE/HX_FILE_BINARY
  140.  */
  141. STDMETHODIMP
  142. WinFile::Create(UINT16 uOpenMode)
  143. {
  144.     return HXR_NOTIMPL;
  145. }
  146. /* Open will open a file with the specified mode
  147.  */
  148. STDMETHODIMP
  149. WinFile::Open(UINT16 uOpenMode)
  150. {
  151.     if (m_hFile != INVALID_HANDLE_VALUE)
  152.     {
  153. CloseHandle(m_hFile);
  154. m_hFile = INVALID_HANDLE_VALUE;
  155.     }
  156.     DWORD dwFlags = 0;
  157.     DWORD dwShare = 0;
  158.     DWORD dwCreate = 0;
  159.     if (uOpenMode & HX_FILE_WRITE)
  160.     {
  161. dwShare |= FILE_SHARE_WRITE;
  162. dwFlags |= GENERIC_WRITE;
  163. if (uOpenMode & HX_FILE_NOTRUNC)
  164. {
  165.     dwCreate |= OPEN_ALWAYS;
  166. }
  167. else
  168. {
  169.     dwCreate |= CREATE_ALWAYS;
  170. }
  171.     }
  172.     if (uOpenMode & HX_FILE_READ)
  173.     {
  174. dwShare |= FILE_SHARE_READ;
  175. dwFlags |= GENERIC_READ;
  176.   if (!(uOpenMode & HX_FILE_WRITE))
  177. {
  178.     dwCreate |= OPEN_EXISTING;
  179. }
  180.     }
  181.     if (uOpenMode & HX_FILE_BINARY)
  182.     {
  183.     }
  184.     m_hFile = CreateFile(OS_STRING(m_pFilename),
  185.     dwFlags,
  186.     dwShare,
  187.     NULL,
  188.     dwCreate,
  189.     FILE_ATTRIBUTE_NORMAL,
  190.     NULL);
  191.     if (m_hFile == INVALID_HANDLE_VALUE)
  192.     {
  193. return HXR_FAIL;
  194.     }
  195.     m_ulPos = 0;
  196.     return HXR_OK;
  197. }
  198. /* Close closes a file 
  199.  * If the reference count on the IHXDataFile object is greater than 1, 
  200.  * then the underlying file cannot be safely closed, so Close() becomes 
  201.  * a noop in that case. Close it only when the object is destroyed. 
  202.  * This would be safe, but could lead to a file descriptor leak.
  203.  */
  204. STDMETHODIMP
  205. WinFile::Close()
  206. {
  207.     if (m_hFile != INVALID_HANDLE_VALUE)
  208.     {
  209. CloseHandle(m_hFile);
  210. m_hFile = INVALID_HANDLE_VALUE;
  211.     }
  212.     m_ulPos = -1;
  213.     return HXR_OK;
  214. }
  215. /* Name returns the currently bound file name in FileName.
  216.  * and returns TRUE, if the a name has been bound.  Otherwise
  217.  * FALSE is returned.
  218.  */
  219. STDMETHODIMP_(BOOL)
  220. WinFile::Name(REF(IHXBuffer*) pFileName)
  221. {
  222.     if (!m_pFilename)
  223.     {
  224. return FALSE;
  225.     }
  226.     pFileName = new CHXBuffer();
  227.     pFileName->AddRef();
  228.     pFileName->Set((const unsigned char*)m_pFilename,
  229. strlen(m_pFilename) + 1);
  230.     return TRUE;
  231. }
  232. /*
  233.  * IsOpen returns TRUE if file is open.  Otherwise FALSE.
  234.  */
  235. STDMETHODIMP_(BOOL)
  236. WinFile::IsOpen()
  237. {
  238.     if (m_hFile != INVALID_HANDLE_VALUE)
  239.     {
  240. return TRUE;
  241.     }
  242.     return FALSE;
  243. }
  244. /* Seek moves the current file position to the offset from the
  245.  * fromWhere specifier returns current position of file or -1 on
  246.  * error.
  247.  */
  248. STDMETHODIMP
  249. WinFile::Seek(ULONG32 offset, UINT16 fromWhere)
  250. {
  251.     DWORD fw = 0;
  252.     switch (fromWhere)
  253.     {
  254. case SEEK_CUR:
  255.     fw = FILE_CURRENT;
  256.     m_ulPos += offset;
  257.     break;
  258. case SEEK_END:
  259.     fw = FILE_END;
  260.     if (offset > m_ulPos)
  261.     {
  262. m_ulPos = 0;
  263.     }
  264.     else
  265.     {
  266. m_ulPos -= offset;
  267.     }
  268.     break;
  269. case SEEK_SET:
  270.     fw = FILE_BEGIN;
  271.     m_ulPos = offset;
  272.     break;
  273.     }
  274.     DWORD dwRet;
  275.     dwRet = SetFilePointer(m_hFile,
  276. offset,
  277. NULL,
  278. fw);
  279.     
  280.     if (dwRet == -1)
  281.     {
  282. m_ulPos = -1;
  283. return HXR_FAIL;
  284.     }
  285.     
  286.     return 0;
  287. }
  288. /* Tell returns the current file position in the file */
  289. STDMETHODIMP_(ULONG32)
  290. WinFile::Tell()
  291. {
  292.     return m_ulPos;
  293. }
  294. /* Read reads up to count bytes of data into buf.
  295.  * returns the number of bytes read, EOF, or -1 if the read failed 
  296.  */
  297. STDMETHODIMP_(ULONG32)
  298. WinFile::Read(REF(IHXBuffer*) pBuf, 
  299. ULONG32 count)
  300. {
  301.     if (m_hFile == INVALID_HANDLE_VALUE)
  302.     {
  303. pBuf = NULL;
  304. return 0;
  305.     }
  306.     pBuf = new CHXBuffer;
  307.     pBuf->AddRef();
  308.     pBuf->SetSize(count);
  309.     BOOL bRet;
  310.     UINT32 ulRead = 0;
  311.     bRet = ReadFile(m_hFile,
  312. (void*)pBuf->GetBuffer(),
  313. count,
  314. &ulRead,
  315. NULL);
  316.     if (ulRead < count)
  317.     {
  318.         pBuf->SetSize(ulRead);
  319.     }
  320.     return ulRead;
  321. }
  322. /* Write writes up to count bytes of data from buf.
  323.  * returns the number of bytes written, or -1 if the write failed 
  324.  */
  325. STDMETHODIMP_(ULONG32)
  326. WinFile::Write(REF(IHXBuffer*) pBuf)
  327. {
  328.     UINT32 ulWritten = 0;
  329.     if (m_hFile == INVALID_HANDLE_VALUE)
  330.     {
  331. return 0;
  332.     }
  333.     BOOL bRet;
  334.     bRet = WriteFile(m_hFile,
  335. (void*)pBuf->GetBuffer(),
  336. pBuf->GetSize(),
  337. &ulWritten,
  338. NULL);
  339.     return ulWritten;
  340. }
  341. /* Flush out the data in case of unbuffered I/O
  342.  */
  343. STDMETHODIMP
  344. WinFile::Flush()
  345. {
  346.     return HXR_NOTIMPL;
  347. }
  348. /*
  349.  * Return info about the data file such as permissions, time of creation
  350.  * size in bytes, etc.
  351.  */
  352. STDMETHODIMP
  353. WinFile::Stat(struct stat* buffer)
  354. {
  355.     if (!m_pFilename)
  356.     {
  357. return HXR_UNEXPECTED;
  358.     }
  359.     int ret = _stat(m_pFilename, (struct _stat*)buffer);
  360.     if (ret == 0)
  361.     {
  362. return HXR_OK;
  363.     }
  364.     return HXR_FAIL;
  365.     /*
  366.      * XXXPM
  367.      * This way is faster, but the times are incompatible with stat times.
  368.      * Maybe someday I will convert.
  369.      *
  370.     BOOL bClose = 0;
  371.     HANDLE hUse = m_hFile;
  372.     if (hUse == INVALID_HANDLE_VALUE)
  373.     {
  374. bClose = 1;
  375. hUse = CreateFile(m_pFilename,
  376. 0, //query
  377. FILE_SHARE_READ,
  378. NULL,
  379. OPEN_EXISTING,
  380. FILE_ATTRIBUTE_NORMAL,
  381. NULL);
  382.     }
  383.     if (hUse == INVALID_HANDLE_VALUE)
  384.     {
  385. return HXR_FAIL;
  386.     }
  387.     BY_HANDLE_FILE_INFORMATION mss;
  388.     memset(buffer, 0, sizeof(*buffer));
  389.     buffer->st_nlink = 1;
  390.     
  391.     HX_RESULT res;
  392.     if (GetFileInformationByHandle(hUse,
  393.     &mss))
  394.     {
  395. buffer->st_atime = mss.ftLastAccessTime.dwLowDateTime;
  396. buffer->st_ctime = mss.ftCreationTime.dwLowDateTime;
  397. buffer->st_mtime = mss.ftLastWriteTime.dwLowDateTime;
  398. buffer->st_size = mss.nFileSizeLow;
  399. res = HXR_OK;
  400.     }
  401.     else
  402.     {
  403. res = HXR_FAIL;
  404.     }
  405.     if (bClose)
  406.     {
  407. CloseHandle(hUse);
  408.     }
  409.     return res;
  410.     */
  411. }
  412. /* Return the file descriptor */
  413. STDMETHODIMP_(INT16)
  414. WinFile::GetFd()
  415. {
  416.     if (m_hFile != INVALID_HANDLE_VALUE)
  417.     {
  418. return 1;
  419.     }
  420.     return -1;
  421. }
  422. /* GetLastError returns the platform specific file error */
  423. STDMETHODIMP
  424. WinFile::GetLastError()
  425. {
  426.     return HXR_NOTIMPL;
  427. }
  428. /* GetLastError returns the platform specific file error in
  429.  * string form.
  430.  */
  431. STDMETHODIMP_(void)
  432. WinFile::GetLastError(REF(IHXBuffer*) err)
  433. {
  434.     err = 0;
  435.     return;
  436. }