Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

368 lines
7.6 KiB

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1997 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10. #ifdef _MAC
  11. #error CFindFile is not supported on the Macintosh
  12. #endif
  13. #include "stdafx.h"
  14. #include "filefind.h"
  15. ////////////////////////////////////////////////////////////////////////////
  16. // CFindFile implementation
  17. CFindFile::CFindFile()
  18. {
  19. m_pFoundInfo = NULL;
  20. m_pNextInfo = NULL;
  21. m_hContext = NULL;
  22. m_chDirSeparator = '\\';
  23. }
  24. CFindFile::~CFindFile()
  25. {
  26. Close();
  27. }
  28. void CFindFile::Close()
  29. {
  30. if (m_pFoundInfo != NULL)
  31. {
  32. delete m_pFoundInfo;
  33. m_pFoundInfo = NULL;
  34. }
  35. if (m_pNextInfo != NULL)
  36. {
  37. delete m_pNextInfo;
  38. m_pNextInfo = NULL;
  39. }
  40. if (m_hContext != NULL && m_hContext != INVALID_HANDLE_VALUE)
  41. {
  42. CloseContext();
  43. m_hContext = NULL;
  44. }
  45. }
  46. void CFindFile::CloseContext()
  47. {
  48. ::FindClose(m_hContext);
  49. return;
  50. }
  51. BOOL CFindFile::FindFile(LPCTSTR pstrName /* = NULL */,
  52. DWORD dwUnused /* = 0 */)
  53. {
  54. UNUSED_ALWAYS(dwUnused);
  55. Close();
  56. m_pNextInfo = new WIN32_FIND_DATA;
  57. m_bGotLast = FALSE;
  58. if (pstrName == NULL)
  59. pstrName = _T("*.*");
  60. _tcsncpy(((WIN32_FIND_DATA*) m_pNextInfo)->cFileName, pstrName,_tcslen(((WIN32_FIND_DATA*) m_pNextInfo)->cFileName));
  61. m_hContext = ::FindFirstFile(pstrName, (WIN32_FIND_DATA*) m_pNextInfo);
  62. if (m_hContext == INVALID_HANDLE_VALUE)
  63. {
  64. DWORD dwTemp = ::GetLastError();
  65. Close();
  66. ::SetLastError(dwTemp);
  67. return FALSE;
  68. }
  69. LPTSTR pstrRoot = m_strRoot.GetBufferSetLength(_MAX_PATH);
  70. LPCTSTR pstr = _tfullpath(pstrRoot, pstrName, _MAX_PATH);
  71. // passed name isn't a valid path but was found by the API
  72. ASSERT(pstr != NULL);
  73. if (pstr == NULL)
  74. {
  75. m_strRoot.ReleaseBuffer(-1);
  76. Close();
  77. ::SetLastError(ERROR_INVALID_NAME);
  78. return FALSE;
  79. }
  80. else
  81. {
  82. // find the last forward or backward whack
  83. LPTSTR pstrBack = _tcsrchr(pstrRoot, '\\');
  84. LPTSTR pstrFront = _tcsrchr(pstrRoot, '/');
  85. if (pstrFront != NULL || pstrBack != NULL)
  86. {
  87. if (pstrFront == NULL)
  88. pstrFront = pstrRoot;
  89. if (pstrBack == NULL)
  90. pstrBack = pstrRoot;
  91. // from the start to the last whack is the root
  92. if (pstrFront >= pstrBack)
  93. *pstrFront = '\0';
  94. else
  95. *pstrBack = '\0';
  96. }
  97. m_strRoot.ReleaseBuffer(-1);
  98. }
  99. return TRUE;
  100. }
  101. BOOL CFindFile::MatchesMask(DWORD dwMask) const
  102. {
  103. ASSERT(m_hContext != NULL);
  104. ASSERT_VALID(this);
  105. if (m_pFoundInfo != NULL)
  106. return (!!(((LPWIN32_FIND_DATA) m_pFoundInfo)->dwFileAttributes & dwMask));
  107. else
  108. return FALSE;
  109. }
  110. BOOL CFindFile::GetLastAccessTime(FILETIME* pTimeStamp) const
  111. {
  112. ASSERT(m_hContext != NULL);
  113. ASSERT(pTimeStamp != NULL);
  114. ASSERT_VALID(this);
  115. if (m_pFoundInfo != NULL && pTimeStamp != NULL)
  116. {
  117. *pTimeStamp = ((LPWIN32_FIND_DATA) m_pFoundInfo)->ftLastAccessTime;
  118. return TRUE;
  119. }
  120. else
  121. return FALSE;
  122. }
  123. BOOL CFindFile::GetLastWriteTime(FILETIME* pTimeStamp) const
  124. {
  125. ASSERT(m_hContext != NULL);
  126. ASSERT(pTimeStamp != NULL);
  127. ASSERT_VALID(this);
  128. if (m_pFoundInfo != NULL && pTimeStamp != NULL)
  129. {
  130. *pTimeStamp = ((LPWIN32_FIND_DATA) m_pFoundInfo)->ftLastWriteTime;
  131. return TRUE;
  132. }
  133. else
  134. return FALSE;
  135. }
  136. BOOL CFindFile::GetCreationTime(FILETIME* pTimeStamp) const
  137. {
  138. ASSERT(m_hContext != NULL);
  139. ASSERT_VALID(this);
  140. if (m_pFoundInfo != NULL && pTimeStamp != NULL)
  141. {
  142. *pTimeStamp = ((LPWIN32_FIND_DATA) m_pFoundInfo)->ftCreationTime;
  143. return TRUE;
  144. }
  145. else
  146. return FALSE;
  147. }
  148. BOOL CFindFile::GetLastAccessTime(CTime& refTime) const
  149. {
  150. ASSERT(m_hContext != NULL);
  151. ASSERT_VALID(this);
  152. if (m_pFoundInfo != NULL)
  153. {
  154. refTime = CTime(((LPWIN32_FIND_DATA) m_pFoundInfo)->ftLastAccessTime);
  155. return TRUE;
  156. }
  157. else
  158. return FALSE;
  159. }
  160. BOOL CFindFile::GetLastWriteTime(CTime& refTime) const
  161. {
  162. ASSERT(m_hContext != NULL);
  163. ASSERT_VALID(this);
  164. if (m_pFoundInfo != NULL)
  165. {
  166. refTime = CTime(((LPWIN32_FIND_DATA) m_pFoundInfo)->ftLastWriteTime);
  167. return TRUE;
  168. }
  169. else
  170. return FALSE;
  171. }
  172. BOOL CFindFile::GetCreationTime(CTime& refTime) const
  173. {
  174. ASSERT(m_hContext != NULL);
  175. ASSERT_VALID(this);
  176. if (m_pFoundInfo != NULL)
  177. {
  178. refTime = CTime(((LPWIN32_FIND_DATA) m_pFoundInfo)->ftCreationTime);
  179. return TRUE;
  180. }
  181. else
  182. return FALSE;
  183. }
  184. BOOL CFindFile::IsDots() const
  185. {
  186. ASSERT(m_hContext != NULL);
  187. ASSERT_VALID(this);
  188. // return TRUE if the file name is "." or ".." and
  189. // the file is a directory
  190. BOOL bResult = FALSE;
  191. if (m_pFoundInfo != NULL && IsDirectory())
  192. {
  193. LPWIN32_FIND_DATA pFindData = (LPWIN32_FIND_DATA) m_pFoundInfo;
  194. if (pFindData->cFileName[0] == '.')
  195. {
  196. if (pFindData->cFileName[1] == '\0' ||
  197. (pFindData->cFileName[1] == '.' &&
  198. pFindData->cFileName[2] == '\0'))
  199. {
  200. bResult = TRUE;
  201. }
  202. }
  203. }
  204. return bResult;
  205. }
  206. BOOL CFindFile::FindNextFile()
  207. {
  208. ASSERT(m_hContext != NULL);
  209. if (m_hContext == NULL)
  210. return FALSE;
  211. if (m_pFoundInfo == NULL)
  212. m_pFoundInfo = new WIN32_FIND_DATA;
  213. ASSERT_VALID(this);
  214. void* pTemp = m_pFoundInfo;
  215. m_pFoundInfo = m_pNextInfo;
  216. m_pNextInfo = pTemp;
  217. return ::FindNextFile(m_hContext, (LPWIN32_FIND_DATA) m_pNextInfo);
  218. }
  219. CString CFindFile::GetFileURL() const
  220. {
  221. ASSERT(m_hContext != NULL);
  222. ASSERT_VALID(this);
  223. CString strResult("file://");
  224. strResult += GetFilePath();
  225. return strResult;
  226. }
  227. CString CFindFile::GetRoot() const
  228. {
  229. ASSERT(m_hContext != NULL);
  230. ASSERT_VALID(this);
  231. return m_strRoot;
  232. }
  233. CString CFindFile::GetFilePath() const
  234. {
  235. ASSERT(m_hContext != NULL);
  236. ASSERT_VALID(this);
  237. CString strResult = m_strRoot;
  238. if (strResult[strResult.GetLength()-1] != '\\' &&
  239. strResult[strResult.GetLength()-1] != '/')
  240. strResult += m_chDirSeparator;
  241. strResult += GetFileName();
  242. return strResult;
  243. }
  244. CString CFindFile::GetFileTitle() const
  245. {
  246. ASSERT(m_hContext != NULL);
  247. ASSERT_VALID(this);
  248. CString strFullName = GetFileName();
  249. CString strResult;
  250. _tsplitpath(strFullName, NULL, NULL, strResult.GetBuffer(_MAX_PATH), NULL);
  251. strResult.ReleaseBuffer();
  252. return strResult;
  253. }
  254. CString CFindFile::GetFileName() const
  255. {
  256. ASSERT(m_hContext != NULL);
  257. ASSERT_VALID(this);
  258. CString ret;
  259. if (m_pFoundInfo != NULL)
  260. ret = ((LPWIN32_FIND_DATA) m_pFoundInfo)->cFileName;
  261. return ret;
  262. }
  263. DWORD CFindFile::GetLength() const
  264. {
  265. ASSERT(m_hContext != NULL);
  266. ASSERT_VALID(this);
  267. if (m_pFoundInfo != NULL)
  268. return ((LPWIN32_FIND_DATA) m_pFoundInfo)->nFileSizeLow;
  269. else
  270. return 0;
  271. }
  272. #if defined(_X86_) || defined(_ALPHA_)
  273. __int64 CFindFile::GetLength64() const
  274. {
  275. ASSERT(m_hContext != NULL);
  276. ASSERT_VALID(this);
  277. if (m_pFoundInfo != NULL)
  278. return ((LPWIN32_FIND_DATA) m_pFoundInfo)->nFileSizeLow +
  279. (((LPWIN32_FIND_DATA) m_pFoundInfo)->nFileSizeHigh << 32);
  280. else
  281. return 0;
  282. }
  283. #endif
  284. #ifdef _DEBUG
  285. void CFindFile::Dump(CDumpContext& dc) const
  286. {
  287. CObject::Dump(dc);
  288. dc << "\nm_hContext = " << (UINT) m_hContext;
  289. }
  290. void CFindFile::AssertValid() const
  291. {
  292. // if you trip the ASSERT in the else side, you've called
  293. // a Get() function without having done at least one
  294. // FindNext() call
  295. if (m_hContext == NULL)
  296. ASSERT(m_pFoundInfo == NULL && m_pNextInfo == NULL);
  297. else
  298. ASSERT(m_pFoundInfo != NULL && m_pNextInfo != NULL);
  299. }
  300. #endif
  301. #ifdef AFX_INIT_SEG
  302. #pragma code_seg(AFX_INIT_SEG)
  303. #endif
  304. IMPLEMENT_DYNAMIC(CFindFile, CObject)