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

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