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.

734 lines
26 KiB

  1. //////////////////////////////////////////////////////////////////////
  2. // PATH.H
  3. //
  4. // Definition of CPath and CDir objects.
  5. //
  6. // History
  7. // =======
  8. // Date Who What
  9. // ---- --- ----
  10. // 07-May-93 mattg Created
  11. // 12-May-93 danw Add operator = and GetDisplayName
  12. // 20-May-93 mattg Added CDir object
  13. // 22-May-93 danw Added ConstructObject and DestructObject
  14. // for collections.
  15. // 11-Jul-93 mattg Added many new methods to CPath and CDir
  16. // Also "TCHAR'ified"
  17. // 20-Jul-93 danw Added relativization functions.
  18. //////////////////////////////////////////////////////////////////////
  19. #ifndef __PATH_H__
  20. #define __PATH_H__
  21. #ifndef _INC_DIRECT
  22. #include <direct.h>
  23. #endif
  24. #ifndef _INC_IO
  25. #include <io.h>
  26. #endif
  27. #ifndef _INC_TCHAR
  28. #include <tchar.h>
  29. #endif
  30. #ifndef _WIN32
  31. #include <ctype.h>
  32. #endif
  33. #ifndef _INC_STAT
  34. #include <sys\stat.h>
  35. #endif
  36. #pragma warning(disable : 4275 4251)
  37. size_t RemoveNewlines(_TCHAR *);
  38. //
  39. // Compatible_GetFileAttributesEx
  40. // g_pGetFileAttributesEx initially points to a function that chooses the new win32 api,
  41. // GetFileAttributesEx if supported, or selects a compatible function that uses FindFirstFile.
  42. //
  43. extern BOOL AFX_DATA (WINAPI *g_pGetFileAttributesEx)( LPCTSTR lpFileName, GET_FILEEX_INFO_LEVELS fInfoLevelId,
  44. LPVOID lpFileInformation);
  45. __inline BOOL Compatible_GetFileAttributesEx( LPCTSTR lpFileName, GET_FILEEX_INFO_LEVELS fInfoLevelId,
  46. LPVOID lpFileInformation)
  47. {
  48. return (*g_pGetFileAttributesEx)( lpFileName, fInfoLevelId, lpFileInformation);
  49. }
  50. //////////////////////////////////////////////////////////////////////
  51. // Classes defined in this file
  52. // CObject
  53. class CPath;
  54. class CDir;
  55. //////////////////////////////////////////////////////////////////////
  56. // Scan a path in see if it contains special charaters that would
  57. // required it to be quoted:
  58. BOOL ScanPathForSpecialCharacters (const TCHAR *pPath);
  59. //////////////////////////////////////////////////////////////////////
  60. // CPath
  61. class LTAPIENTRY CPath : public CObject
  62. {
  63. DECLARE_DYNAMIC(CPath)
  64. friend class CDir;
  65. friend static VOID ConstructElement(CPath *);
  66. friend static VOID DestructElement(CPath *);
  67. protected:
  68. // Data
  69. CString m_strCanon;
  70. int m_ichLastSlash; // used to quickly extract only dir or filename
  71. BOOL m_Flags;
  72. enum PathFlags
  73. {
  74. eIsActualCase = 1,
  75. eWantsRelative = 2,
  76. };
  77. // Canonicalized representation of pathname.
  78. static CMapStringToString c_DirCaseMap;
  79. public:
  80. // Constructors, destructors, initialization methods
  81. inline CPath() { m_ichLastSlash = -1; m_Flags = 0;}
  82. inline CPath(const CPath & path)
  83. {
  84. m_strCanon = path.m_strCanon;
  85. m_ichLastSlash = path.m_ichLastSlash;
  86. m_Flags = path.m_Flags;
  87. }
  88. virtual ~CPath();
  89. inline BOOL GetAlwaysRelative() const { return ((m_Flags & eWantsRelative) != 0); }
  90. inline void SetAlwaysRelative(BOOL bWantsRel = TRUE) { m_Flags =
  91. (bWantsRel) ? m_Flags | eWantsRelative : m_Flags & ~eWantsRelative;}
  92. inline BOOL IsInit() const { ASSERT(this!=NULL); return (m_ichLastSlash > 0); }
  93. BOOL Create(const TCHAR *);
  94. // Initialize the object, given a filename. The resulting
  95. // canonicalized filename will be relative to the current
  96. // directory. For example, if the current directory is
  97. // C:\TEST and the argument is "FOO.C", the resulting
  98. // canonicalized filename will be "C:\TEST\FOO.C". If the
  99. // argument is "..\FOO.C", the resulting canonicalized
  100. // filename will be "C:\FOO.C".
  101. BOOL CreateFromDirAndFilename(const CDir &, const TCHAR *);
  102. // Initialize the object given a directory (CDir object) and
  103. // a filename. This behaves exactly the same as the Create()
  104. // method, except that the Create() method canonicalizes the
  105. // filename relative to the CURRENT directory, whereas this
  106. // method canonicalizes the filename relative to the SPECIFIED
  107. // directory.
  108. BOOL CreateTemporaryName(const CDir &, BOOL fKeep = TRUE);
  109. // Initialize the object given a directory. The resulting
  110. // object will represent a UNIQUE filename in that directory.
  111. // This is useful for creating temporary filenames.
  112. //
  113. // WARNING
  114. // -------
  115. // After this method returns, the filename represented by this
  116. // object will EXIST ON DISK as a zero length file. This is
  117. // to prevent subsequent calls to this method from returning
  118. // the same filename (this method checks to make sure it
  119. // doesn't return the name of an existing file). IT IS YOUR
  120. // RESPONSIBILITY to delete the file one way or another.
  121. //
  122. // If you don't want this behavior, pass FALSE for 'fKeep',
  123. // and the file will not exist on disk. Be aware, though,
  124. // that if you do this, subsequent calls to this method may
  125. // return the same filename.
  126. BOOL ContainsSpecialCharacters () const
  127. {
  128. return ::ScanPathForSpecialCharacters(m_strCanon);
  129. }
  130. // Scan the pathname for special character. We cache this
  131. // information.
  132. inline CPath & operator =(const CPath & path)
  133. {
  134. ASSERT(path.IsInit());
  135. m_strCanon = path.m_strCanon;
  136. m_ichLastSlash = path.m_ichLastSlash;
  137. m_Flags = path.m_Flags;
  138. return(*this);
  139. }
  140. // Assignment operator.
  141. // Query methods
  142. inline const TCHAR * GetFileName() const
  143. {
  144. ASSERT(IsInit());
  145. ASSERT(m_ichLastSlash==m_strCanon.ReverseFind('\\'));
  146. return ((const TCHAR *)m_strCanon + m_ichLastSlash + 1);
  147. }
  148. // Return a pointer to the filename part of the canonicalized
  149. // pathname, i.e., the filename with no leading drive or path
  150. // information. Return whole string if no backslash (not init).
  151. //
  152. // Please do not write through this pointer, as it is pointing
  153. // to internal data!
  154. VOID PostFixNumber();
  155. // Modifies the path by postfixing a number on the end of the path's
  156. // basename. If there is no number on the end of the path's basename
  157. // then the number 1 is postfixed. Otherwise if there already is a
  158. // number on the end of the path's basename then that number is
  159. // incremented by 1 and postfixed on the end of the basename (less the
  160. // original number).
  161. //
  162. // e.g. foo.cpp -> foo1.cpp -> foo2.cpp -> foo3.cpp
  163. VOID GetBaseNameString(CString &) const;
  164. // Creates a CString representing the base name of the fully
  165. // canonicalized pathname. For example, the base name of
  166. // the pathname "C:\FOO\BAR.C" is "BAR".
  167. //
  168. // This method can't return a pointer to internal data like
  169. // some of the other methods since it would have to remove
  170. // the extension in order to do so.
  171. VOID GetDisplayNameString(
  172. CString &,
  173. int cchMax = 16,
  174. BOOL bTakeAllAsDefault = FALSE
  175. ) const;
  176. // Creates a CString representing the name of the file
  177. // shortened to cchMax CHARACTERS (TCHARs, not bytes) or
  178. // less. Only the actual characters are counted; the
  179. // terminating '\0' is not considered, so
  180. // CString::GetLength() on the result MAY return as much as
  181. // cchMax. If cchMax is less than the length of the base
  182. // filename, the resulting CString will be empty, unless
  183. // bTakeAllAsDefault is TRUE, in which the base name is
  184. // copied in, regardless of length.
  185. //
  186. // As an example, "C:\SOMEDIR\OTHERDIR\SUBDIR\SPECIAL\FOO.C"
  187. // will be shortened to "C:\...\SPECIAL\FOO.C" if cchMax is 25.
  188. inline const TCHAR * GetExtension() const
  189. {
  190. ASSERT(IsInit());
  191. int iDot = m_strCanon.ReverseFind(_T('.'));
  192. if (iDot < m_ichLastSlash)
  193. iDot = m_strCanon.GetLength();
  194. const TCHAR * retval = ((const TCHAR *)m_strCanon) + iDot;
  195. return retval;
  196. }
  197. // Return a pointer to the extension part of the canonicalized
  198. // pathname. Returns a pointer to the '.' character of the
  199. // extension. If the filename doesn't have an extension,
  200. // the pointer returned will point to the terminating '\0'.
  201. //
  202. // Please do not write through this pointer, as it is pointing
  203. // to internal data!
  204. inline const TCHAR * GetFullPath() const { return(m_strCanon); }
  205. // Return a pointer to the full (canonicalized) pathname.
  206. //
  207. // Please do not write through this pointer, as it is pointing
  208. // to internal data!
  209. inline const TCHAR * GetFullPath(CString & strPath) const { return(strPath = m_strCanon); }
  210. inline BOOL IsActualCase() const { ASSERT(this!=NULL); return ((m_Flags & eIsActualCase)!=0); }
  211. void GetActualCase(BOOL bEntirePath = FALSE);
  212. // Adjusts the paths case to match the actual path and filename
  213. // on disk.
  214. void SetActualCase(LPCTSTR pszFileCase);
  215. // Adjusts the paths case to match the actual path and filename
  216. // on disk, where pszFileCase already contains the correct case
  217. // for just the filename portion.
  218. static void ResetDirMap();
  219. inline operator const TCHAR *() const { return(m_strCanon); }
  220. // Return the fully canonicalized filename as a (const TCHAR *).
  221. // Same thing as GetFullPath(), but more convenient in some
  222. // cases.
  223. //
  224. // Please do not write through this pointer, as it is pointing
  225. // to internal data!
  226. inline BOOL IsUNC() const { return(m_strCanon[0] == _T('\\')); }
  227. // Returns TRUE if the pathname is UNC (e.g.,
  228. // "\\server\share\file"), FALSE if not.
  229. inline BOOL IsEmpty() const { return (m_strCanon.IsEmpty()); }
  230. // Comparison methods
  231. int operator ==(const CPath &) const;
  232. // Returns 1 if the two CPaths are identical, 0 if they are
  233. // different.
  234. inline int operator !=(const CPath & path) const { return(!(operator ==(path))); }
  235. // Returns 1 if the two CPaths are different, 0 if they are
  236. // identical.
  237. // Modification methods
  238. VOID ChangeFileName(const TCHAR *);
  239. // Changes the file name to that specified by the
  240. // (const TCHAR *) argument. The directory portion of the
  241. // pathname remains unchanged. DO NOT pass in anything
  242. // other than a simple filename, i.e., do not pass in
  243. // anything with path modifiers.
  244. VOID ChangeExtension(const TCHAR *);
  245. // Changes the extension of the pathname to be that specified
  246. // by the (const TCHAR *) argument. The argument can either be
  247. // of the form ".EXT" or "EXT". If the current pathname has
  248. // no extension, this is equivalent to adding the new extension.
  249. BOOL GetRelativeName (const CDir&, CString&, BOOL bQuote = FALSE, BOOL bIgnoreAlwaysRelative = FALSE) const;
  250. // Makes the path name relative to the supplied directory and
  251. // placed the result in strResult. Function will only go
  252. // down from the supplied directy (no ..'s). Returns TRUE if
  253. // relativization was successful, or FALSE if not (e.g. if
  254. // string doesn't start with ".\" or ..\ or at least \).
  255. //
  256. // Thus, if the base directory is c:\sushi\vcpp32:
  257. //
  258. // s:\sushi\vcpp32\c\fmake.c => s:\sushi\vcpp32\c\fmake.c
  259. // c:\sushi\vcpp32\c\fmake.c => .\fmake.c
  260. // c:\dolftool\bin\cl.exe => \dolftool\bin\cl.exe
  261. // \\danwhite\tmp\test.cpp => \\danwhite\tmp\test.cpp
  262. // Thus, if the base directory is \\danwhite\c$\sushi\vcpp32:
  263. //
  264. // \\danwhite\c$\dolftool\bin\cl.exe => \dolftool\bin\cl.exe
  265. // \\danwhite\tmp\test.cpp => \\danwhite\tmp\test.cpp
  266. // If bQuote is true, then quotes are put around the relative
  267. // file name. (Useful for writing the filename out to a file)
  268. // If (!bIgnoreAlwaysRelative && GetAlwaysRelative()) is TRUE
  269. // and if the file is on the same drive we will ALWAYS
  270. // relativize it. Thus for the base dir c:\sushi\vcpp32
  271. // c:\dolftool\bin\cl.exe => ..\..\dolftool\bin\cl.exe
  272. BOOL CreateFromDirAndRelative (const CDir&, const TCHAR *);
  273. // THIS FUNCTION IS OBSOLETE. New code should use
  274. // CreateFromDirAndFilename(). The only difference between
  275. // that function and this one is that this one will
  276. // automatically remove quotes from around the relative
  277. // path name (if present).
  278. // Miscellaneous methods
  279. inline BOOL IsReadOnlyOnDisk() const
  280. {
  281. HANDLE h;
  282. ASSERT(IsInit());
  283. h = CreateFile(m_strCanon, GENERIC_WRITE,
  284. FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
  285. FILE_ATTRIBUTE_NORMAL, NULL);
  286. if (h == INVALID_HANDLE_VALUE && GetLastError() != ERROR_FILE_NOT_FOUND)
  287. return TRUE;
  288. if (h != INVALID_HANDLE_VALUE)
  289. CloseHandle(h);
  290. return FALSE;
  291. }
  292. // Returns TRUE if the filename represented by this object
  293. // is read-only on disk, FALSE if not. NOT guaranteed to
  294. // work in all circumstances -- for example, will not return
  295. // TRUE for a file on a floppy drive that has been write-
  296. // protected. I don't know of any way to get this information
  297. // from NT (GetFileAttributes doesn't work; GetVolumeInformation
  298. // doesn't work; _access just calls GetFileAttributes; etc.).
  299. // This method WILL correctly detect:
  300. // - Files marked as read-only
  301. // - Files on read-only network drives
  302. inline BOOL ExistsOnDisk() const
  303. {
  304. ASSERT(IsInit());
  305. return(_access(m_strCanon, 00) != -1);
  306. }
  307. // Returns TRUE if the filename represented by this object
  308. // exists on disk, FALSE if not.
  309. inline BOOL CanCreateOnDisk(BOOL fOverwriteOK = FALSE) const
  310. {
  311. ASSERT(IsInit());
  312. if (!fOverwriteOK && ExistsOnDisk())
  313. return(FALSE);
  314. int hFile = _creat(m_strCanon, _S_IREAD | _S_IWRITE);
  315. BOOL fCreate = (hFile != -1);
  316. if (fCreate)
  317. {
  318. VERIFY(_close(hFile) == 0);
  319. VERIFY(_unlink(m_strCanon) == 0);
  320. }
  321. return(fCreate);
  322. }
  323. // Returns TRUE if the filename represented by this object
  324. // can be created on disk, FALSE if not.
  325. inline BOOL DeleteFromDisk() const
  326. {
  327. ASSERT(IsInit());
  328. #ifdef _WIN32
  329. return(DeleteFile((TCHAR *)(const TCHAR *)m_strCanon));
  330. #else
  331. return(remove(m_strCanon) != -1);
  332. #endif
  333. }
  334. // Removes the file represented by this object from the disk.
  335. BOOL GetFileTime(LPFILETIME lpftLastWrite);
  336. BOOL GetFileTime(CString& rstrLastWrite, DWORD dwFlags = DATE_SHORTDATE);
  337. // Returns the last modified time, as either an FILETIME struct or a string
  338. };
  339. // Creation and destruction functions used by CMapPathToOb:
  340. extern const CString AFX_DATA pthEmptyString;
  341. static inline VOID ConstructElement(CPath * pNewData)
  342. {
  343. memcpy(&pNewData->m_strCanon, &pthEmptyString, sizeof(CString));
  344. }
  345. static inline VOID DestructElement(CPath * pOldData)
  346. {
  347. pOldData->m_strCanon.Empty();
  348. }
  349. // File Name Utility Functions
  350. // These are redundant and could be replaced with use of CPath, but are
  351. // kept since they are easier to use and already exist in VRES.
  352. // Remove the drive and directory from a file name.
  353. CString StripPath(LPCTSTR szFilePath);
  354. // Remove the name part of a file path. Return just the drive and directory.
  355. CString StripName(LPCTSTR szFilePath);
  356. // Get only the extension of a file path.
  357. CString GetExtension(LPCTSTR szFilePath);
  358. // Return the path to szFilePath relative to szDirectory. (e.g. if szFilePath
  359. // is "C:\FOO\BAR\CDR.CAR" and szDirectory is "C:\FOO", then "BAR\CDR.CAR"
  360. // is returned. This will never use '..'; if szFilePath is not in szDirectory
  361. // or a sub-directory, then szFilePath is returned unchanged.
  362. //
  363. CString GetRelativeName(LPCTSTR szFilePath, LPCTSTR szDirectory = NULL);
  364. // Makes a file path look like in MRU.
  365. CString GetDisplayName(LPCTSTR szFilePath, int nMaxDisplayLength,
  366. LPCTSTR szDirectory = NULL);
  367. BOOL FileExists(LPCTSTR szFilePath);
  368. BOOL IsFileWritable(LPCTSTR szFilePath);
  369. UINT SushiGetFileTitle(LPCTSTR lpszPathName, LPTSTR lpszTitle, UINT nMax);
  370. //////////////////////////////////////////////////////////////////////
  371. // CDir
  372. //
  373. // The CDir object represents a file system directory on some disk.
  374. //
  375. // A CDir object can be created to represent the current directory,
  376. // to represent the directory of a CPath object (i.e., the directory
  377. // in which a file resides), and to represent a temporary directory.
  378. // Note that a CDir object CANNOT be created given an arbitrary string --
  379. // this is intentional, since this should not be necessary.
  380. //
  381. // The string representation of a CDir object (e.g., operator const TCHAR *())
  382. // MAY or MAY NOT end in '\'. The root directory of a local drive (e.g., C:)
  383. // will end in '\' ("C:\"), while other directories on a local drive will
  384. // not ("C:\OTHERDIR"). The root directory on a REMOTE drive will NOT end
  385. // in '\' ("\\server\share"). Don't make any assumptions about whether or
  386. // not the string representation ends in '\'.
  387. //
  388. // See also several CPath methods which use CDir objects.
  389. class LTAPIENTRY CDir : public CObject
  390. {
  391. DECLARE_DYNAMIC(CDir)
  392. friend class CPath;
  393. friend static VOID ConstructElement(CDir *);
  394. friend static VOID DestructElement(CDir *);
  395. protected:
  396. CString m_strDir;
  397. // Directory name, including drive letter or
  398. // server/share. Do NOT make any assumptions
  399. // about whether or not this ends in '\'!
  400. // Creates multi level directories just fine
  401. BOOL MakeDirectory(LPCTSTR lpszPathName) const;
  402. public:
  403. // Constructors, destructors, initialization methods
  404. inline CDir() {}
  405. inline CDir(const CDir & dir) { m_strDir = dir.m_strDir; }
  406. virtual ~CDir();
  407. BOOL CreateFromCurrent();
  408. // Initialize from the current working directory. This
  409. // may fail if the current working directory is unknown
  410. // or invalid.
  411. BOOL CreateFromPath(const CPath &);
  412. // Initialize based on the directory of the specified
  413. // CPath object. That is, if the CPath object represents
  414. // the file "C:\FOO\BAR\BLIX.C", the resulting directory
  415. // for this object will be "C:\FOO\BAR". Returns FALSE
  416. // on failure.
  417. BOOL CreateFromPath(const TCHAR *pszPath);
  418. // Initialize based on the directory of the specified
  419. // string. That is, if the string contains the file name
  420. // "C:\FOO\BAR\BLIX.C", the generated directory for this
  421. // string will be "C:\FOO\BAR". Returns FALSE on failure.
  422. BOOL CreateTemporaryName();
  423. // Initialize this object to represent a temporary directory
  424. // on disk (e.g., "C:\TMP").
  425. inline BOOL CreateFromString(const TCHAR * sz)
  426. {
  427. return CreateFromStringEx(sz, FALSE);
  428. }
  429. // Create from a string (e.g., "C:\", "C:\TMP", etc.). Please
  430. // do not use this method when another would suffice!
  431. BOOL CreateFromStringEx(const TCHAR * sz, BOOL fRootRelative);
  432. // Create from a string (e.g., "C:\", "C:\TMP", etc.). Please
  433. // do not use this method when another would suffice!
  434. // same as CreateFromString with minor change. Not treating as bug fix to CFS
  435. // due to lateness in VC 4.0 project time
  436. // if fRootRelative true, treat dir ending with colon as relative not root dir
  437. // (actual correct handling)
  438. BOOL ContainsSpecialCharacters () const
  439. {
  440. return ::ScanPathForSpecialCharacters(m_strDir);
  441. }
  442. // Scan the pathname for special character. We cache this information.
  443. inline CDir & operator =(const CDir & dir)
  444. {
  445. m_strDir = dir.m_strDir;
  446. return(*this);
  447. }
  448. // Assignment operator.
  449. // Query methods
  450. inline operator const TCHAR *() const { return(m_strDir); }
  451. // Return the directory name as a (const TCHAR *) string.
  452. inline int GetLength() const { return m_strDir.GetLength(); }
  453. // Returns the length of the directory name
  454. // Miscellaneous methods
  455. BOOL MakeCurrent() const;
  456. // Make this object the current working directory. May fail
  457. // if the directory no longer exists (e.g., a floppy drive).
  458. inline BOOL ExistsOnDisk() const
  459. {
  460. // Tests if the directory exists. We return FALSE
  461. // if <m_strDir> exists but is not a directory
  462. struct _stat statDir;
  463. if (_stat(m_strDir, &statDir) == -1)
  464. return FALSE; // Not found.
  465. else if (!(statDir.st_mode & _S_IFDIR))
  466. return FALSE; // Not a directory.
  467. else
  468. return TRUE;
  469. }
  470. // Returns TRUE if the directory represented by this object
  471. // exists on disk, FALSE if not.
  472. inline BOOL CreateOnDisk() const { return MakeDirectory(m_strDir); }
  473. // Creates the directory on disk. If this fails, returns
  474. // FALSE. If the directory already existed on disk, returns
  475. // TRUE (i.e., that is not an error condition).
  476. inline BOOL RemoveFromDisk() const { return RemoveDirectory(m_strDir); }
  477. // Removes the directory from the disk. If this fails for
  478. // any reason (directory does not exist, directory is not
  479. // empty, etc.), returns FALSE.
  480. BOOL IsRootDir() const;
  481. // Returns TRUE if the directory represented by this object
  482. // is a root directory (e.g., "C:\"), FALSE if not. Note that
  483. // calling this method will NOT tell you whether or not the
  484. // string representation ends in '\', since "\\server\share"
  485. // is a root directory, and does not end in '\'.
  486. inline BOOL IsUNC() const { return(m_strDir[0] == _T('\\')); }
  487. // Returns TRUE if this is a UNC directory, FALSE if not.
  488. VOID AppendSubdirName(const TCHAR *);
  489. // Adds a subdirectory name. For example, if this object
  490. // currently represents "C:\FOO\BAR", and the argument is
  491. // "$AUTSAV$", the resulting object represents
  492. // "C:\FOO\BAR\$AUTSAV$".
  493. //
  494. // WARNING: This method does NO validation of the result --
  495. // it does not check for illegal characters, or for a
  496. // directory name that is too long. In particular, don't
  497. // pass "DIR1/DIR2" as an argument, since no conversion
  498. // (of '/' to '\') will occur.
  499. VOID RemoveLastSubdirName();
  500. // Removes the last component of the directory name. For
  501. // example, if this object currently represents
  502. // "C:\FOO\BAR\$AUTSAV$", after this method it will
  503. // represent "C:\FOO\BAR". If you try to call this method
  504. // when the object represents a root directory (e.g., "C:\"),
  505. // it will ASSERT.
  506. // Comparison methods
  507. int operator ==(const CDir &) const;
  508. // Returns 1 if the two CDirs are identical, 0 if they are
  509. // different.
  510. inline int operator !=(const CDir & dir) const { return(!(operator ==(dir))); }
  511. // Returns 1 if the two CDirs are different, 0 if they are
  512. // identical.
  513. };
  514. // Creation and destruction functions used by CMapDirToOb:
  515. static inline VOID ConstructElement(CDir * pNewData)
  516. {
  517. memcpy(&pNewData->m_strDir, &pthEmptyString, sizeof(CString));
  518. }
  519. static inline VOID DestructElement(CDir * pOldData)
  520. {
  521. pOldData->m_strDir.Empty();
  522. }
  523. ///////////////////////////////////////////////////////////////////////////////
  524. // CCurDir
  525. // This class is used to switch the current drive/directory during the
  526. // life of the object and to restore the previous dirve/directory upon
  527. // destruction.
  528. class LTAPIENTRY CCurDir : CDir
  529. {
  530. public:
  531. CCurDir(const char* szPath, BOOL bFile = FALSE);
  532. CCurDir(const CDir& dir);
  533. CCurDir(); // just saves the current directory and resets it
  534. ~CCurDir();
  535. CDir m_dir;
  536. };
  537. ///////////////////////////////////////////////////////////////////////////////
  538. // CFileOpenReturn
  539. // This class represents the return value from the Common Dialogs
  540. // File.Open. It handles both single and multiple select types.
  541. //
  542. class LTAPIENTRY CFileOpenReturn : CObject
  543. {
  544. BOOL m_bSingle;
  545. BOOL m_bBufferInUse;
  546. BOOL m_bArrayHasChanged;
  547. int m_cbData;
  548. _TCHAR * m_pchData;
  549. // Multiple Files
  550. CPtrArray m_rgszNames;
  551. public:
  552. CFileOpenReturn (const _TCHAR * szRawString = NULL);
  553. ~CFileOpenReturn ();
  554. inline BOOL IsSingle () const;
  555. inline BOOL IsDirty() const;
  556. inline BOOL BufferOverflow () const;
  557. //inline int GetLength () const;
  558. // GetBuffer gives permission for something else to directly change the buffer
  559. // ReleaseBuffer signifies that the something else is done with it.
  560. _TCHAR * GetBuffer (int cbBufferNew);
  561. inline void ReleaseBuffer ();
  562. // allows the object to be re-initialized
  563. void ReInit (const _TCHAR * szRawString);
  564. // This supports the dynamic file extension update in OnFileNameOK().
  565. void ChangeExtension (int i, const CString& szExt);
  566. void CopyBuffer (_TCHAR * szTarget);
  567. // This is the function to use to get at the user's selections,
  568. // whether single or multiple.
  569. BOOL GetPathname (int i, CString& strPath) const;
  570. private:
  571. void GenArrayFromBuffer ();
  572. void GenBufferFromArray ();
  573. void ClearNamesArray ();
  574. void SetBuffer (const _TCHAR * szRawString);
  575. };
  576. inline BOOL CFileOpenReturn::IsSingle () const
  577. {
  578. return m_bSingle;
  579. }
  580. inline BOOL CFileOpenReturn::IsDirty() const
  581. {
  582. return m_bArrayHasChanged;
  583. }
  584. inline BOOL CFileOpenReturn::BufferOverflow () const
  585. {
  586. return m_cbData == 2 && m_pchData[0] == '?';
  587. }
  588. ///// ReleaseBuffer - Tell object we're done changing the buffer
  589. //
  590. // Processes the raw string
  591. //
  592. ///
  593. inline void CFileOpenReturn::ReleaseBuffer ()
  594. {
  595. m_bBufferInUse = FALSE;
  596. GenArrayFromBuffer ();
  597. }
  598. ///////////////////////////////////////////////////////////////////////////////
  599. // Smart case helpers.
  600. // These functions are used to do smart casing of paths and file extensions.
  601. extern BOOL GetActualFileCase( CString& rFilename, LPCTSTR lpszDir = NULL );
  602. extern LPCTSTR GetExtensionCase( LPCTSTR lpszFilename, LPCTSTR lpszExtension );
  603. extern BOOL GetDisplayFile(CString &rFilename, CDC *pDC, int &cxPels); // truncates from left
  604. /////////////////////////////////////////////////////////////////////////////
  605. #pragma warning(default : 4275 4251)
  606. #endif // __PATH_H__