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.

646 lines
18 KiB

  1. // Copyright (c) 1997-1999 Microsoft Corporation
  2. //
  3. // File System services.
  4. //
  5. // 8-14-97 (sburns)
  6. #ifndef FILESYS_HPP_INCLUDED
  7. #define FILESYS_HPP_INCLUDED
  8. // CODEWORK: remove exceptions in favor of an HRESULT orientation.
  9. namespace Burnslib
  10. {
  11. namespace FS
  12. {
  13. // Facilitates walking a directory tree.
  14. // CODEWORK: add methods to extract current file data beyond just the
  15. // name.
  16. class Iterator
  17. {
  18. public:
  19. enum
  20. {
  21. INCLUDE_FILES = 0x0001,
  22. INCLUDE_FOLDERS = 0x0002,
  23. INCLUDE_DOT_PATHS = 0x0004,
  24. // CODEWORK:
  25. // EXPAND_SUBDIRS = 0x0008,
  26. RETURN_FULL_PATHS = 0x0010
  27. };
  28. // Constructs a new instance of an Iterator.
  29. //
  30. // startingPathSpec - fully-qualified path specification of the
  31. // files/directories to be iterated upon. A wildcard
  32. // specification is allowed at the end of the path. E.g.
  33. // "C:\dir\*.txt"
  34. //
  35. // (Without a wildcard expression of some kind, the iteration set will
  36. // be the single file or folder that matches startingPathSpec. This set
  37. // may be further reduced to the empty set if the optionMask eliminates
  38. // the single match.)
  39. //
  40. // optionMask - Options, OR'ed together.
  41. explicit
  42. Iterator(
  43. const String& startingPathSpec,
  44. unsigned optionMask =
  45. INCLUDE_FILES
  46. | INCLUDE_FOLDERS
  47. | INCLUDE_DOT_PATHS
  48. /* | EXPAND_SUBDIRS */
  49. | RETURN_FULL_PATHS);
  50. ~Iterator();
  51. // Restores the iterator to the state that it had upon
  52. // construction.
  53. void
  54. Reset();
  55. // Retrieve the name of the file at the current iterator position. If
  56. // the iterator was constructed with the RETURN_FULL_PATHS Option, then
  57. // the returned string is a fully-qualified path, instead of a path
  58. // relative to the starting path the Iterator was constructed with.
  59. // Returns S_OK on success, S_FALSE if the iteration is empty (there are
  60. // no files), or an error code.
  61. //
  62. // If AtEnd() is true, then the empty string is returned.
  63. //
  64. // result - receives the file path at the current position of the
  65. // iterator, or the empty string if the iteration set is empty, or
  66. // an error occurred.
  67. HRESULT
  68. GetCurrent(String& result);
  69. // Move the current position to the next file, according to the
  70. // iterator filtering options. May cause the iterator to become
  71. // invalid, which can be tested with AtEnd(). Returns S_OK on success
  72. // S_FALSE when the iteration is complete, or an error code.
  73. HRESULT
  74. Increment();
  75. private:
  76. WIN32_FIND_DATA* findData;
  77. HANDLE findHandle;
  78. bool finished;
  79. unsigned options;
  80. String parentFolder;
  81. String startSearchSpec;
  82. void
  83. Finish();
  84. bool
  85. IsNotStarted();
  86. String
  87. ReturnPath();
  88. bool
  89. ShouldSkipCurrent();
  90. HRESULT
  91. Start();
  92. HRESULT
  93. SkipFilteredPaths();
  94. // copying not implemented in the interest of simplicity (could be done
  95. // in theory)
  96. Iterator(const Iterator&);
  97. const Iterator& operator=(const Iterator&);
  98. };
  99. // Simple file-to-file copy.
  100. //
  101. // sourceFile - Fully-qalified path of the file to be copied. This
  102. // path must reference an existing file.
  103. //
  104. // destinationFile - Fully-qualified path of the file to be
  105. // created. This file is always overwritten, if it exists. All
  106. // intermediate subdirectories required are created.
  107. //
  108. // progressCallback - Callback object to receive progress
  109. // notifications. The param argument to the callback's Execute
  110. // method will be an instance of CopyCallbackParam. The method
  111. // should return !0 to abort the copy.
  112. struct CopyCallbackParam
  113. {
  114. String sourceFile;
  115. String destinationFile;
  116. int percentCopied;
  117. };
  118. HRESULT
  119. CopyFile(
  120. const String& sourceFile,
  121. const String& destinationFile,
  122. Callback* progressCallback);
  123. // Creates a directory, including all intermediate subdirectories,
  124. // as necessary. Returns S_FALSE if the path already exists.
  125. //
  126. // path - Fully-qualified path to be created. It must not
  127. // already exist.
  128. HRESULT
  129. CreateFolder(const String& path);
  130. // Opens a file for shared read/write access with normal attributes,
  131. // creating it if it does not already exist.
  132. //
  133. // path - Fully-qualified path of file to open. If path doesn't
  134. // exist, it is created, including intermediate subdirectories.
  135. //
  136. // result - receives the resulting file handle, on success. On falure,
  137. // this is set to INVALID_HANDLE_VALUE
  138. //
  139. // REVIEWED-2002/02/26-sburns we require full absolute or unc file paths,
  140. // else we assert and return E_INVALIDARG.
  141. HRESULT
  142. CreateFile(
  143. const String& path,
  144. HANDLE& result,
  145. DWORD desiredAccess,
  146. DWORD shareMode = 0,
  147. // we don't require all callers to specify an SD in case the call
  148. // just to open the file.
  149. DWORD creationDisposition = OPEN_ALWAYS,
  150. DWORD flagsAndAttributes = FILE_ATTRIBUTE_NORMAL);
  151. // Deletes a file. Returns S_OK on success, or an error code on failure.
  152. //
  153. // path - Fully-qualified path of file to delete.
  154. HRESULT
  155. DeleteFile(const String& path);
  156. // Splits a fully-qualified path into its constituent parts.
  157. //
  158. // drive - receives the volume portion (in the form "X:")
  159. //
  160. // parentFolderPath - receives the path of the folder containing the leaf
  161. // file or folder.
  162. //
  163. // leafName - receives the base name of the last file or folder on the
  164. // path.
  165. //
  166. // extension - receives the extension, of the last file or folder on the
  167. // path, including the dot (".ext")
  168. void
  169. SplitPath(
  170. const String& fullpath,
  171. String& drive,
  172. String& parentFolderPath,
  173. String& leafName,
  174. String& extension);
  175. // Appends an unqualified relative path (i.e. system32\cys.exe) to the
  176. // the base path supplied and returns the full path. A '\' will be added
  177. // between the parts if needed. If the base path is not normalized the
  178. // result will not be normalized either.
  179. //
  180. // base - fully-qualified path which will be appended to
  181. //
  182. // additional - unqualified relative path which will be appended
  183. String
  184. AppendPath(
  185. const String& base,
  186. const String& additional);
  187. // Returns the leaf portion of a fully-qualified path, including the
  188. // extension. The path may refer to either a file or a folder. For
  189. // example, "x:\foo\bar.ext" returns "bar.ext"
  190. //
  191. // fullpath - fully-qualified filename.
  192. String
  193. GetPathLeafElement(const String& fullpath);
  194. // Removes the last component of a fully-qualified file name or folder
  195. // name. Includes trailing path separator only if the parent folder is the
  196. // root folder on a volume.
  197. //
  198. // e.g. "x:\foo" returns "x:\", but "x:\foo\bar" returns "x:\foo" (not
  199. // "x:\foo\")
  200. //
  201. // fullpath - fully-qualified filename.
  202. String
  203. GetParentFolder(const String& fullpath);
  204. // Returns the available space, in bytes, to the current user of the
  205. // calling thread (i.e. takes into account user quotas)
  206. //
  207. // path - Fully-qualified path of file/directory for which attributes will
  208. // be retrieved. This need not be the root directory of the volume in
  209. // question.
  210. //
  211. // result - receives the result, the available space in bytes. Set to
  212. // 0 on error.
  213. HRESULT
  214. GetAvailableSpace(const String& path, ULONGLONG& result);
  215. // Returns the root folder path of the given full path, e.g. for
  216. // "C:\foo\bar" returns "C:\"
  217. //
  218. // fullpath - Fully-qualified path of file/directory
  219. String
  220. GetRootFolder(const String& fullpath);
  221. // Reports the current position of the file read/write pointer. Returns
  222. // S_OK on success, or an error code on failure.
  223. //
  224. // handle - valid handle to an opened file
  225. //
  226. // result - receives the file position, set to 0 on error
  227. HRESULT
  228. GetFilePosition(HANDLE handle, LONGLONG& result);
  229. // Returns the total size, in bytes, of the file opened on the provided
  230. // handle.
  231. //
  232. // handle - valid handle to an opened file
  233. //
  234. // result - receives the file size, or 0 on error.
  235. HRESULT
  236. GetFileSize(HANDLE handle, LONGLONG& result);
  237. // Returns the type of the file system of the volume on which the path
  238. // refers. Non-existant paths are considered to have the FAT file system.
  239. //
  240. // path - fully-qualified path, which contains the drive letter of the
  241. // volume
  242. // CODEWORK: how does this behave in the presence of mount points? For
  243. // example, what if a FAT volume is mounted as a subdirectory of an
  244. // NTFS volume?
  245. enum FSType
  246. {
  247. FAT,
  248. CDFS,
  249. NTFS4,
  250. NTFS5
  251. };
  252. FSType
  253. GetFileSystemType(const String& path);
  254. enum PathSyntax
  255. {
  256. SYNTAX_ABSOLUTE_DRIVE, // d:\foo\bar
  257. SYNTAX_ABSOLUTE_DRIVE_WILDCARD, // d:\foo\*.*
  258. SYNTAX_ABSOLUTE_NO_DRIVE, // \foo\bar
  259. SYNTAX_ABSOLUTE_NO_DRIVE_WILDCARD, // \foo\*.*
  260. SYNTAX_RELATIVE_DRIVE, // d:foo\bar
  261. SYNTAX_RELATIVE_DRIVE_WILDCARD, // d:foo\*.*
  262. SYNTAX_RELATIVE_NO_DRIVE, // foo\bar
  263. SYNTAX_RELATIVE_NO_DRIVE_WILDCARD, // foo\*.*
  264. SYNTAX_UNC, // \\machine\share
  265. SYNTAX_UNC_WILDCARD, // \\machine\share\*.*
  266. SYNTAX_UNRECOGNIZED
  267. };
  268. // Parses the supplied string an attempts to validate its syntax. The
  269. // string need not refer to an existing file or directory.
  270. //
  271. // str - the string to be analysed.
  272. PathSyntax
  273. GetPathSyntax(const String& str);
  274. // Populates the given DriveList with elements representing the valid
  275. // drive letters on the local machine. Each element is a string of the
  276. // form "X:" where X is a drive letter.
  277. //
  278. // BackInsertableContainer - any type that supports the construction of
  279. // a back_insert_iterator on itself, and has a value type that can be
  280. // constructed from an PWSTR.
  281. //
  282. // bii - a reference to a back_insert_iterator of the
  283. // BackInsertableContainer template parameter. The simplest way to make
  284. // one of these is to use the back_inserter helper function.
  285. //
  286. // Example:
  287. //
  288. // StringList container;
  289. // hr = FS::GetValidDrives(std::back_inserter(container));
  290. //
  291. // StringVector container2;
  292. // hr = FS::GetValidDrives(std::back_inserter(container2));
  293. template <class BackInsertableContainer>
  294. HRESULT
  295. GetValidDrives(std::back_insert_iterator<BackInsertableContainer>& bii)
  296. {
  297. HRESULT hr = S_OK;
  298. WCHAR* buf = 0;
  299. do
  300. {
  301. // first call determines the size of the buffer we need.
  302. DWORD bufchars = 0;
  303. hr = Win::GetLogicalDriveStrings(0, 0, bufchars);
  304. BREAK_ON_FAILED_HRESULT(hr);
  305. // add 1 for extra-safe null terminator
  306. ++bufchars;
  307. buf = new WCHAR[bufchars];
  308. ::ZeroMemory(buf, bufchars * sizeof WCHAR);
  309. // second call actually retrieves the strings
  310. DWORD unused = 0;
  311. hr = Win::GetLogicalDriveStrings(bufchars - 1, buf, unused);
  312. BREAK_ON_FAILED_HRESULT(hr);
  313. // walk thru buf and chop it into substrings.
  314. for (
  315. // ISSUE-2002/02/22-sburns consider using safe version of wcschr, if
  316. // there is one
  317. WCHAR* sub = wcschr(buf, 0), *buf2 = buf;
  318. sub && buf2 && buf2[0];
  319. buf2 = sub + 1, sub = wcschr(buf2, 0))
  320. {
  321. *bii++ = buf2;
  322. }
  323. }
  324. while (0);
  325. delete[] buf;
  326. return hr;
  327. }
  328. // Wrapper of the Win32 API of the same name
  329. //
  330. // path - Fully-qualified path. This path need not exist.
  331. HRESULT
  332. GetVolumePathName(const String& path, String&);
  333. // Returns true if the path refers to an empty or non-existent directory.
  334. //
  335. // path - Fully-qualified path
  336. bool
  337. IsFolderEmpty(const String& path);
  338. // Returns true if parent is the name of a parent directory of the given
  339. // child directory, false if not. A parent directory is defined as one
  340. // that appears closer to the root than a child on the same branch. A
  341. // parent may be any superior directory (e.g. grandparent,
  342. // great-grandparent), not just the immediate superior.
  343. //
  344. // parent - valid, fully-qualified path of supposed parent directory. Need
  345. // not exist.
  346. //
  347. // child - valid, fully-qualified path of child directory. Need not exist.
  348. bool
  349. IsParentFolder(const String& parent, const String& child);
  350. // Checks the validity, but not the existence of, the specified
  351. // file or directory. the path must be absolute and include the
  352. // drive specifier.
  353. //
  354. // path - Fully-qualified path.
  355. bool
  356. IsValidPath(const String& path);
  357. // Moves or renames an existing file or directory.
  358. //
  359. // sourcePath - Fully-qualified path of the file/directory to be
  360. // moved/renamed. This file or directory must exist. If the path refers to
  361. // a directory, the directory and all of its children are moved.
  362. //
  363. // destinationPath - Fully-qualified path of the destination
  364. // file/directory. This path need not be on the same volume as the
  365. // sourcePath, but if it is not, the move will result in a recursive copy
  366. // of the sourcePath.
  367. //
  368. // replaceExisting - If the destinationPath refers to an existing
  369. // file/directory, and this parameter is true, the destinationPath is
  370. // overwritten. Otherwise, if the destinationPath exists, an error is
  371. // returned.
  372. HRESULT
  373. MoveFile(
  374. const String& sourcePath,
  375. const String& destinationPath);
  376. // CODEWORK:
  377. // bool replaceExisting = false);
  378. // "Normalize" a path by parsing any relative path components (like . and
  379. // ..), and return the resulting path. If there are no relative
  380. // components, or if an error occurred, return the same string as the
  381. // input.
  382. //
  383. // The result is not guaranteed to be syntactically correct, or to refer to
  384. // and existing file. For that, use IsValidPath() and PathExists()
  385. //
  386. // Example:
  387. // L"c:\\.\\.\\..\\.\\temp\\.\\foo\\bar\\..\\baz" results in
  388. // L"c:\\temp\\foo\\baz"
  389. //
  390. // abnormalPath - path to parse.
  391. String
  392. NormalizePath(const String& abnormalPath);
  393. // Returns true if the specified file or directory exists.
  394. //
  395. // path - Fully-qualified path.
  396. bool
  397. PathExists(const String& path);
  398. // Returns true if the specified file exists, i.e. the path exists and
  399. // it refers to a file (as opposed to a folder)
  400. bool
  401. FileExists(const String& filePath);
  402. // Reads bytes from the current file pointer of the handle as Unicode
  403. // text (2 bytes/character).
  404. //
  405. // handle - valid, open file handle, with read/write pointer positioned
  406. // to the first byte of the first character to be read.
  407. //
  408. // charactersToRead - number of characters to read. -1 to read all
  409. // characters up to the end of the file or the first null character
  410. // encountered. If this number would cause a read past the end of the
  411. // file, or past a null character, the read will stop at the end of the
  412. // file or null character. In the case of a null character, the file
  413. // read/write pointer will be positioned at the byte following the null
  414. // character.
  415. //
  416. // text - the characters read. A truncated read operation can be detected
  417. // by comparing the length of this string to the charactersToRead
  418. // parameter.
  419. HRESULT
  420. Read(HANDLE handle, int charactersToRead, String& text);
  421. // Reads bytes from the current file pointer of the handle as ANSI
  422. // text.
  423. //
  424. // handle - valid, open file handle, with read/write pointer positioned
  425. // to the first byte of the first character to be read.
  426. //
  427. // bytesToRead - count of the number of bytes (*NOT* characters) to read
  428. //
  429. // text - the bytes read.
  430. HRESULT
  431. Read(HANDLE handle, int bytesToRead, AnsiString& text);
  432. // Positions the file read/write pointer.
  433. //
  434. // handle - Valid, open file handle.
  435. //
  436. // position - new position of the pointer, from the beginning of the
  437. // file.
  438. HRESULT
  439. Seek(HANDLE handle, LONGLONG position);
  440. // Moves the file read/write pointer to the end of the file.
  441. //
  442. // handle - Valid, open file handle.
  443. HRESULT
  444. SeekToEnd(HANDLE handle);
  445. // Writes the supplied string as Unicode text to the file.
  446. //
  447. // handle - Valid, open file handle.
  448. //
  449. // text - the text to be written
  450. HRESULT
  451. Write(HANDLE handle, const String& text);
  452. // appends a crlf
  453. HRESULT
  454. WriteLine(HANDLE handle, const String& text);
  455. // Writes the supplied buffer to the file.
  456. //
  457. // handle - Valid, open file handle.
  458. //
  459. // buf - buffer to write. This is an instance of basic_string<char>
  460. HRESULT
  461. Write(HANDLE handle, const AnsiString& buf);
  462. // appends a crlf
  463. HRESULT
  464. WriteLine(HANDLE handle, const AnsiString& text);
  465. }
  466. }
  467. #endif // FILESYS_HPP_INCLUDED