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

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: hxdir.cpp,v 1.5.8.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 "hxtypes.h"
  50. #include <stdio.h>
  51. #include <stdlib.h>
  52. #include <string.h>
  53. #include "hlxclib/errno.h"
  54. #include "hlxclib/io.h"
  55. #include "hlxclib/sys/stat.h"
  56. #include "hxstrutl.h"
  57. #include "hxdir.h"
  58. #include "dbcs.h"
  59. #if _WIN16
  60. #include <direct.h>
  61. #endif
  62. #include "hxheap.h"
  63. #ifdef _DEBUG
  64. #undef HX_THIS_FILE
  65. static const char HX_THIS_FILE[] = __FILE__;
  66. #endif
  67. CHXDirectory::CHXDirectory()
  68. #ifdef _WIN32
  69.             : m_hFindFile(INVALID_HANDLE_VALUE)
  70. #endif
  71. {
  72. }
  73. CHXDirectory::~CHXDirectory()
  74. {
  75. #ifdef _WIN32
  76.     if(m_hFindFile != INVALID_HANDLE_VALUE)
  77.     {
  78.         FindClose(m_hFindFile);
  79.         m_hFindFile = INVALID_HANDLE_VALUE;
  80.     }
  81. #endif
  82. }
  83. void 
  84. CHXDirectory::SetPath(const char* szPath)
  85. {
  86.     XHXDirectory::SetPath(szPath);
  87.     if(m_strPath.GetLength() == 2 && m_strPath.GetAt(1) == ':')
  88. m_strPath += "\";
  89.     // Remove ending ''.
  90.     const char* pLastChar = HXGetPrevChar(szPath, szPath + strlen(szPath));
  91.     if(m_strPath.GetLength() > 3 && pLastChar + 1 == szPath + strlen(szPath) && *pLastChar == '\')
  92. m_strPath = m_strPath.Left(m_strPath.GetLength() - 1);
  93. }
  94. static BOOL HasDiskSpaceFree(const char* pPath)
  95. {
  96.     BOOL bRet = FALSE;
  97. #if defined(WIN32_PLATFORM_PSPC)
  98.     ULARGE_INTEGER   lpFreeBytesAvailableToCaller;
  99.     ULARGE_INTEGER   lpTotalNumberOfBytes;
  100.     ULARGE_INTEGER   lpTotalNumberOfFreeBytes;
  101.     GetDiskFreeSpaceEx(OS_STRING(pPath), &lpFreeBytesAvailableToCaller,
  102.        &lpTotalNumberOfBytes,
  103.        &lpTotalNumberOfFreeBytes);
  104.     if (lpFreeBytesAvailableToCaller.LowPart ||
  105. lpFreeBytesAvailableToCaller.HighPart)
  106. bRet = TRUE;
  107. #else /* defined(WIN32_PLATFORM_PSPC) */
  108.     DWORD nSectorsPerCluster = 0;
  109.     DWORD nBytesPerSector = 0; 
  110.     DWORD nNumberOfFreeClusters = 0;
  111.     DWORD TotalNumberOfClusters = 0;
  112.     GetDiskFreeSpace(OS_STRING(pPath), 
  113.      &nSectorsPerCluster, 
  114.      &nBytesPerSector, 
  115.      &nNumberOfFreeClusters, 
  116.      &TotalNumberOfClusters);
  117.     
  118.     if (nNumberOfFreeClusters)
  119. bRet = TRUE;
  120. #endif /* defined(WIN32_PLATFORM_PSPC) */
  121.     return bRet;
  122. }
  123. BOOL
  124. CHXDirectory::IsWritable()
  125. {
  126.     if(!IsValid())
  127. return FALSE;
  128.     int nIndex = m_strPath.Find(":\");
  129.     if(nIndex != -1)
  130.     {
  131. CHXString strDiskRootDir = m_strPath.Left(nIndex + 2);
  132. if(HasDiskSpaceFree(strDiskRootDir))
  133.     return TRUE;
  134.     }
  135.     return FALSE;
  136. }
  137.  
  138. BOOL
  139. CHXDirectory::SetTempPath(HXXHANDLE hpsHandle, const char* szRelPath)
  140. {
  141.     BOOL bTempDirSet = FALSE;
  142.     /* First try to use TEMP environment variable as extraction path. */
  143.     char * pTEMPValue = 0;
  144. #if !defined(WIN32_PLATFORM_PSPC)
  145.     pTEMPValue = getenv("TEMP");
  146. #endif /* !defined(WIN32_PLATFORM_PSPC) */
  147.     if(pTEMPValue)
  148.     {
  149.         m_strPath = pTEMPValue;
  150. if(IsWritable())
  151. {
  152.     bTempDirSet = TRUE;
  153. }
  154. else
  155. {
  156.     m_strPath.Empty();
  157. }
  158.     }
  159.     /* If we don't have suitable path 
  160.        we will try to use application directory. */
  161.     if(!bTempDirSet && hpsHandle)
  162.     {
  163.         GetModuleFileName((HINSTANCE)hpsHandle, 
  164.   OS_STRING2(m_strPath.GetBuffer(_MAX_PATH + 1), 
  165.      _MAX_PATH),
  166.    _MAX_PATH);
  167.         m_strPath.ReleaseBuffer();
  168.         int nIndex = m_strPath.ReverseFind('\');
  169.         if(nIndex == -1)
  170.         {
  171.             m_strPath.Empty();
  172.         }
  173.         else
  174.         {
  175.             m_strPath = m_strPath.Left(nIndex);
  176.         }
  177. if(IsWritable())
  178. {
  179.     bTempDirSet = TRUE;
  180. }
  181. else
  182. {
  183.     m_strPath.Empty();
  184. }
  185.     }
  186.     /* If we don't have suitable path 
  187.        we will try to use Windows directory. */
  188.     if(!bTempDirSet)
  189.     {
  190. #if defined(WIN32_PLATFORM_PSPC)
  191. // WinCE does not have the GetWindowsDirectory() call,
  192. // so the path is hard coded here
  193. m_strPath = "\Windows";
  194. #else /* defined(WIN32_PLATFORM_PSPC) */
  195.         GetWindowsDirectory(m_strPath.GetBuffer(_MAX_PATH + 1), _MAX_PATH);
  196. m_strPath.ReleaseBuffer();
  197. #endif /* defined(WIN32_PLATFORM_PSPC) */
  198. if(IsWritable())
  199. {
  200.     bTempDirSet = TRUE;
  201. }
  202. else
  203. {
  204.     m_strPath.Empty();
  205. }
  206.     }
  207.     if(bTempDirSet && szRelPath && szRelPath[0])
  208.     {
  209. const char* pLastChar = HXGetPrevChar(m_strPath, (const char*)m_strPath + m_strPath.GetLength());
  210. if(pLastChar + 1 != (const char*)m_strPath + m_strPath.GetLength() || *pLastChar != '\')
  211.     m_strPath += "\";
  212.         m_strPath += szRelPath;
  213.     }
  214.     return bTempDirSet;
  215. }
  216. /* Creates directory. */
  217. BOOL 
  218. CHXDirectory::Create()
  219. {
  220.     CreateDirectory(OS_STRING(m_strPath), 0);
  221.     return IsValid();
  222. }
  223. /* Checks if directory exists. */    
  224. BOOL 
  225. CHXDirectory::IsValid()
  226. {
  227.     if(m_strPath.IsEmpty() || m_strPath.GetAt(0) == '.')
  228.         return FALSE;
  229.     if(m_strPath.GetLength() == 3 && m_strPath.GetAt(1) == ':' &&
  230.        m_strPath.GetAt(2) == '\')
  231.     {
  232. #if defined(WIN32_PLATFORM_PSPC)
  233. return TRUE;
  234. #else /* defined(WIN32_PLATFORM_PSPC) */
  235. UINT nDriveType = 0;
  236. #ifdef _WIN32
  237. nDriveType = GetDriveType(m_strPath);
  238. #else
  239.         nDriveType = GetDriveType(toupper(m_strPath.GetAt(0)) - 'A');
  240. #endif
  241. if(nDriveType == DRIVE_FIXED || nDriveType == DRIVE_REMOTE ||
  242.    nDriveType == DRIVE_REMOVABLE || nDriveType == DRIVE_RAMDISK)
  243.    return TRUE;
  244. #endif /* defined(WIN32_PLATFORM_PSPC) */
  245.     }
  246.     else
  247.     {
  248. #ifdef _WIN32
  249. WIN32_FIND_DATA findData;
  250. HANDLE hFindFile =  FindFirstFile(OS_STRING(m_strPath), &findData);
  251. if(hFindFile != INVALID_HANDLE_VALUE)
  252. {
  253.     FindClose(hFindFile);
  254.     if ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)
  255. return TRUE;
  256. }
  257. #else
  258. struct _find_t fileinfo;
  259. if(!_dos_findfirst(m_strPath, _A_SUBDIR | _A_HIDDEN, &fileinfo ))
  260. {   
  261.     if (fileinfo.attrib & _A_SUBDIR)
  262. return TRUE;
  263. }
  264. #endif
  265.     }
  266.     return FALSE;
  267. }
  268. /* Checks if directory is on CD or removable drive. */    
  269. BOOL 
  270. CHXDirectory::IsRemovable()
  271. {
  272.     if(m_strPath.GetLength() < 2 || m_strPath.GetAt(1) != ':')
  273.         return FALSE;
  274. #if !defined(WIN32_PLATFORM_PSPC)
  275.     UINT nDriveType = 0;
  276. #ifdef _WIN32
  277.     nDriveType = GetDriveType(m_strPath);
  278.     if(nDriveType == DRIVE_CDROM)
  279.        return TRUE;
  280. #else
  281.     nDriveType = GetDriveType(toupper(m_strPath.GetAt(0)) - 'A');
  282. #endif
  283.     if(nDriveType == DRIVE_REMOVABLE)
  284.        return TRUE;
  285. #endif /* defined(WIN32_PLATFORM_PSPC) */
  286.     return FALSE;
  287. }
  288. /* Deletes empty directory. */
  289. BOOL 
  290. CHXDirectory::DeleteDirectory()
  291. {
  292. #ifdef _WIN32
  293.     if(m_hFindFile != INVALID_HANDLE_VALUE)
  294.     {
  295.         FindClose(m_hFindFile);
  296.         m_hFindFile = INVALID_HANDLE_VALUE;
  297.     }
  298. #endif
  299.     if(RemoveDirectory(OS_STRING(m_strPath)))
  300.         return TRUE;
  301.     return FALSE;
  302. }
  303. /* Starts enumeration process. */
  304. CHXDirectory::FSOBJ 
  305. CHXDirectory::FindFirst(const char* szPattern, char* szPath, UINT16 nSize)
  306. {
  307.     FSOBJ RetVal = FSOBJ_NOTVALID;
  308.     CHXString strMask = m_strPath;
  309.     const char* pLastChar = HXGetPrevChar(m_strPath, (const char*)m_strPath + m_strPath.GetLength());
  310.     if(pLastChar + 1 != (const char*)m_strPath + m_strPath.GetLength() || *pLastChar != '\')
  311. strMask += "\";
  312.     strMask += szPattern;
  313. #ifdef _WIN32
  314.     if(m_hFindFile != INVALID_HANDLE_VALUE)
  315.     {
  316.         FindClose(m_hFindFile);
  317.         m_hFindFile = INVALID_HANDLE_VALUE;
  318.     }
  319.     WIN32_FIND_DATA findData;
  320.     m_hFindFile =  FindFirstFile(OS_STRING(strMask), &findData);
  321.     if(m_hFindFile != INVALID_HANDLE_VALUE)
  322.     {
  323.         if(m_strPath.GetLength() + 1 + strlen(OS_STRING(findData.cFileName)) < nSize)
  324. {
  325.     SafeStrCpy(szPath, (const char*)m_strPath, nSize);
  326.     pLastChar = HXGetPrevChar(szPath, szPath + strlen(szPath));
  327.     if(pLastChar + 1 < szPath + strlen(szPath) || *pLastChar != '\')
  328. SafeStrCat(szPath,  "\", nSize);
  329.             SafeStrCat(szPath,  OS_STRING(findData.cFileName), nSize);
  330. }
  331. if ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)
  332.     RetVal = FSOBJ_DIRECTORY;
  333.         else
  334.             RetVal = FSOBJ_FILE;
  335.     }
  336. #else
  337.     if(!_dos_findfirst(strMask, _A_SUBDIR | _A_HIDDEN, &m_FindFileInfo))
  338.     {   
  339.         if(m_strPath.GetLength() + 1 + strlen(m_FindFileInfo.name) < nSize)
  340. {
  341.     SafeStrCpy(szPath, (const char*)m_strPath, nSize);
  342.     if(m_strPath.GetLength() && m_strPath.GetAt(m_strPath.GetLength() - 1) != '\')
  343. SafeStrCat(szPath,  "\", nSize);
  344.             SafeStrCat(szPath,  m_FindFileInfo.name, nSize);
  345. }
  346. if (m_FindFileInfo.attrib & _A_SUBDIR)
  347.             RetVal = FSOBJ_DIRECTORY;
  348.         else
  349.             RetVal = FSOBJ_FILE;
  350.     }
  351. #endif
  352.     while(RetVal != FSOBJ_NOTVALID &&
  353.           !IsValidFileDirName(szPath))
  354.         RetVal = FindNext(szPath, nSize);
  355.     return RetVal;
  356. }
  357. /* Continues enumeration process. */
  358. CHXDirectory::FSOBJ 
  359. CHXDirectory::FindNext(char* szPath, UINT16 nSize)
  360. {
  361.     FSOBJ RetVal = FSOBJ_NOTVALID;
  362. #ifdef _WIN32
  363.     if(m_hFindFile != INVALID_HANDLE_VALUE)
  364.     {
  365.         WIN32_FIND_DATA findData;
  366.         if(FindNextFile(m_hFindFile, &findData))
  367.         {
  368.             if(m_strPath.GetLength() + 1 + strlen(OS_STRING(findData.cFileName)) < nSize)
  369.     {
  370. SafeStrCpy(szPath, (const char*)m_strPath, nSize);
  371. const char* pLastChar = HXGetPrevChar(szPath, szPath + strlen(szPath));
  372. if(pLastChar + 1 < szPath + strlen(szPath) || *pLastChar != '\')
  373.     SafeStrCat(szPath,  "\", nSize);
  374. SafeStrCat(szPath,  OS_STRING(findData.cFileName), nSize);
  375.     }
  376.     if ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)
  377.         RetVal = FSOBJ_DIRECTORY;
  378.             else
  379.                 RetVal = FSOBJ_FILE;
  380.         }
  381.     }
  382. #else
  383.     if(!_dos_findnext(&m_FindFileInfo))
  384.     {   
  385.         if(m_strPath.GetLength() + 1 + strlen(m_FindFileInfo.name) < nSize)
  386. {
  387.     SafeStrCpy(szPath, (const char*)m_strPath, nSize);
  388.     if(m_strPath.GetLength() && m_strPath.GetAt(m_strPath.GetLength() - 1) != '\')
  389. SafeStrCat(szPath,  "\", nSize);
  390.             SafeStrCat(szPath,  m_FindFileInfo.name, nSize);
  391. }
  392. if (m_FindFileInfo.attrib & _A_SUBDIR)
  393.             RetVal = FSOBJ_DIRECTORY;
  394.         else
  395.             RetVal = FSOBJ_FILE;
  396.     }
  397. #endif
  398.     while(RetVal != FSOBJ_NOTVALID &&
  399.           !IsValidFileDirName(szPath))
  400.         RetVal = FindNext(szPath, nSize);
  401.     return RetVal;
  402. }
  403. BOOL 
  404. CHXDirectory::IsValidFileDirName(const char* szPath)
  405. {
  406.     const char* pSlash = HXReverseFindChar(szPath, '\');
  407.     if(!pSlash)
  408.         return FALSE;
  409.     CHXString strEnding = pSlash + 1;
  410.     if(!strEnding.Compare(".") || !strEnding.Compare(".."))
  411.         return FALSE;
  412.     return TRUE;
  413. }
  414. BOOL 
  415. CHXDirectory::DeleteFile(const char* szRelPath)
  416. {
  417.     if(!szRelPath)
  418.         return FALSE;
  419.     CHXString strPath;
  420.     if(strlen(szRelPath) > 1 && szRelPath[1] == ':')
  421.     {
  422.         strPath = szRelPath;
  423.     }
  424.     else
  425.     {
  426. strPath = m_strPath;
  427. const char* pLastChar = HXGetPrevChar(m_strPath, (const char*)m_strPath + m_strPath.GetLength());
  428. if(pLastChar + 1 < (const char*)m_strPath + m_strPath.GetLength() || *pLastChar != '\')
  429.     strPath += "\";
  430. strPath += szRelPath;
  431.     }
  432.     BOOL RetVal = FALSE;
  433.     //_chmod(strPath, S_IREAD | S_IWRITE);
  434.     DWORD attrib = GetFileAttributes(OS_STRING(strPath)); 
  435.     attrib &= ~FILE_ATTRIBUTE_READONLY;
  436.     SetFileAttributes(OS_STRING(strPath), attrib); 
  437.     //if(!unlink(strPath) || errno != EACCES)
  438.     if (::DeleteFile(OS_STRING(strPath)))
  439.         RetVal = TRUE;
  440.     return RetVal;
  441. }
  442. /* Sets itself to current directory. */
  443. BOOL 
  444. CHXDirectory::SetCurrentDir()
  445. {
  446.     BOOL bRetVal = TRUE;
  447. #if defined(WIN32_PLATFORM_PSPC)
  448.     // WinCE doesn't have a concept of a working directory.
  449.     // Assert here and look at the calling code to see
  450.     // if we really need to worry about this
  451.     HX_ASSERT(!"CHXDirectory::SetCurrentDir()");
  452. #else /* defined(WIN32_PLATFORM_PSPC) */
  453.     if(!getcwd(m_strPath.GetBuffer(_MAX_PATH + 1), _MAX_PATH))
  454. bRetVal = FALSE;
  455.     m_strPath.ReleaseBuffer();
  456. #endif /* defined(WIN32_PLATFORM_PSPC) */
  457.     return bRetVal;
  458. }
  459. /* Makes itself a current directory. */
  460. BOOL 
  461. CHXDirectory::MakeCurrentDir()
  462. {
  463. #ifdef _WIN16
  464.     // In win16, you have to change the current drive seperately from changing
  465.     // to the new directory, if the new directory is on a different drive than
  466.     // the current drive.
  467.     int retval = 0;
  468.     int curdrive = _getdrive();
  469.     int drive = (toupper(m_strPath.GetAt(0)) - 'A') + 1;
  470.     if (curdrive != drive)
  471. if ((retval = _chdrive(drive)) != 0)
  472.     return FALSE;
  473. #endif
  474. #if defined(WIN32_PLATFORM_PSPC)
  475.     // WinCE does not have the concept of a current directory.
  476.     // Assert here and look at the calling code to see if
  477.     // we need to worry about it
  478.     HX_ASSERT(!"CHXDirectory::MakeCurrentDir()");
  479. #else /* defined(WIN32_PLATFORM_PSPC) */
  480.     if(!chdir(m_strPath))
  481.         return TRUE;
  482. #endif /* defined(WIN32_PLATFORM_PSPC) */
  483.     return FALSE;
  484. }
  485. UINT32 
  486. CHXDirectory::Rename(const char* szOldName, const char* szNewName)
  487. {
  488.     if ((szOldName == NULL) || (szNewName == NULL))
  489.     {
  490.         HX_ASSERT(FALSE);
  491. return HXR_FAIL;
  492.     }
  493.     UINT32 theError = HXR_FAIL;
  494.     CHXDirectory DestinationDir;
  495.     DestinationDir.SetPath( szNewName );
  496.     if ( DestinationDir.IsValid() )
  497.     {
  498.         //Destination directory exist.
  499. if(!::RemoveDirectory(OS_STRING(szNewName)) )
  500. {
  501.     //Failed to delete destination directory.
  502.     //Check if read only attribute is set.
  503.     DWORD attrib = GetFileAttributes(OS_STRING(szNewName));
  504.     if ( attrib & FILE_ATTRIBUTE_READONLY )
  505.     {
  506. //Directory is read only.
  507. //Remove read only attribute.
  508. attrib &= ~FILE_ATTRIBUTE_READONLY;
  509. SetFileAttributes(OS_STRING(szNewName), attrib); 
  510. if(!::RemoveDirectory(OS_STRING(szNewName)))
  511. {
  512.     //Still failed to delete.
  513.     //So put the read only attribute back.
  514.          attrib |= FILE_ATTRIBUTE_READONLY;
  515.     SetFileAttributes(OS_STRING(szNewName), attrib); 
  516.     return HXR_FAIL;
  517. }
  518.     }
  519.     else
  520.     {
  521. //Failed to delete & directory is not readonly.
  522. return HXR_FAIL;
  523.     }
  524. }
  525.     }
  526.     if(MoveFile(OS_STRING(szOldName), OS_STRING(szNewName)))
  527. theError = HXR_OK;
  528.     return theError;
  529. }