Source code of Windows XP (NT5)
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.

355 lines
8.6 KiB

  1. #include "precomp.h"
  2. #include <RegEntry.h>
  3. #include <ConfReg.h>
  4. #include <oprahcom.h>
  5. BOOL NMINTERNAL CanShellExecHttp()
  6. {
  7. RegEntry re(CLASSES_HTTP_KEY, HKEY_LOCAL_MACHINE, FALSE);
  8. return (re.GetError() == ERROR_SUCCESS);
  9. }
  10. BOOL NMINTERNAL CanShellExecMailto()
  11. {
  12. RegEntry re(CLASSES_MAILTO_KEY, HKEY_LOCAL_MACHINE, FALSE);
  13. return (re.GetError() == ERROR_SUCCESS);
  14. }
  15. /* G E T I N S T A L L D I R E C T O R Y */
  16. /*----------------------------------------------------------------------------
  17. %%Function: GetInstallDirectory
  18. Return TRUE if the installation directory was read from the registry.
  19. The string is set empty if the function fails and returns FALSE.
  20. The buffer pointed to by psz is assumed to be at least MAX_PATH characters.
  21. Note that the name is always terminated with a final backslash.
  22. ----------------------------------------------------------------------------*/
  23. BOOL NMINTERNAL GetInstallDirectory(LPTSTR psz)
  24. {
  25. RegEntry reInstall(CONFERENCING_KEY, HKEY_LOCAL_MACHINE);
  26. ASSERT(NULL != psz);
  27. lstrcpyn(psz, reInstall.GetString(REGVAL_INSTALL_DIR), MAX_PATH);
  28. if (_T('\0') == *psz)
  29. return FALSE; // No registry entry was found
  30. // Make sure the directory name has a trailing '\'
  31. // BUGBUG - Don't call CharNext twice in each iteration
  32. for ( ; _T('\0') != *psz; psz = CharNext(psz))
  33. {
  34. if ((_T('\\') == *psz) && (_T('\0') == *CharNext(psz)) )
  35. {
  36. // The path already ends with a backslash
  37. return TRUE;
  38. }
  39. }
  40. // Append a trailing backslash
  41. // BUGBUG - Can't we just append the char in place with an assignment?
  42. lstrcat(psz, _TEXT("\\"));
  43. return TRUE;
  44. }
  45. /* F F I L E E X I S T S */
  46. /*-------------------------------------------------------------------------
  47. %%Function: FFileExists
  48. Return TRUE if the file exists and can be read & written.
  49. -------------------------------------------------------------------------*/
  50. BOOL NMINTERNAL FFileExists(LPCTSTR szFile)
  51. {
  52. HANDLE hFile;
  53. if ((NULL == szFile) || (_T('\0') == *szFile))
  54. return FALSE;
  55. UINT uErrorMode = SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS);
  56. hFile = CreateFile(szFile, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
  57. NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  58. SetErrorMode(uErrorMode); // Restore error mode
  59. if (hFile == INVALID_HANDLE_VALUE)
  60. return FALSE;
  61. CloseHandle(hFile);
  62. return TRUE;
  63. }
  64. /* F D I R E X I S T S */
  65. /*-------------------------------------------------------------------------
  66. %%Function: FDirExists
  67. Return TRUE if the directory exists.
  68. -------------------------------------------------------------------------*/
  69. BOOL NMINTERNAL FDirExists(LPCTSTR szDir)
  70. {
  71. UINT uErrorMode = SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS);
  72. DWORD dwFa = GetFileAttributes(szDir);
  73. SetErrorMode(uErrorMode); // Restore error mode
  74. if (0xFFFFFFFF == dwFa)
  75. return FALSE;
  76. return (0 != (dwFa & FILE_ATTRIBUTE_DIRECTORY));
  77. }
  78. /* F E N S U R E D I R E X I S T S */
  79. /*-------------------------------------------------------------------------
  80. %%Function: FEnsureDirExists
  81. Ensure the Directory exists, creating the entire path if necessary.
  82. Returns FALSE if there was a problem.
  83. -------------------------------------------------------------------------*/
  84. BOOL NMINTERNAL FEnsureDirExists(LPCTSTR szDir)
  85. {
  86. TCHAR szPath[MAX_PATH+1];
  87. TCHAR * pszDirEnd;
  88. TCHAR * pszDirT;
  89. ASSERT(lstrlen(szDir) < MAX_PATH);
  90. if (FDirExists(szDir))
  91. return TRUE; // Nothing to do - already exists
  92. // Work with a copy of the path
  93. lstrcpy(szPath, szDir);
  94. for(pszDirT = szPath, pszDirEnd = &szPath[lstrlen(szPath)];
  95. pszDirT <= pszDirEnd;
  96. pszDirT = CharNext(pszDirT))
  97. {
  98. if ((*pszDirT == _T('\\')) || (pszDirT == pszDirEnd))
  99. {
  100. *pszDirT = _T('\0');
  101. if (!FDirExists(szPath))
  102. {
  103. UINT uErrorMode = SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS);
  104. BOOL fOk = CreateDirectory(szPath, NULL);
  105. SetErrorMode(uErrorMode); // Restore error mode
  106. if (!fOk)
  107. return FALSE;
  108. }
  109. *pszDirT = _T('\\');
  110. }
  111. }
  112. TRACE_OUT(("Created Directory [%s]", szDir));
  113. return TRUE;
  114. }
  115. /* E X T R A C T F I L E N A M E */
  116. /*-------------------------------------------------------------------------
  117. %%Function: ExtractFileName, ExtractFileNameA
  118. Extracts the file name from a path name.
  119. Returns a pointer to file name in path string.
  120. -------------------------------------------------------------------------*/
  121. LPCTSTR NMINTERNAL ExtractFileName(LPCTSTR pcszPathName)
  122. {
  123. LPCTSTR pcszLastComponent;
  124. LPCTSTR pcsz;
  125. ASSERT(IS_VALID_STRING_PTR(pcszPathName, CSTR));
  126. for (pcszLastComponent = pcsz = pcszPathName;
  127. *pcsz;
  128. pcsz = CharNext(pcsz))
  129. {
  130. if (IS_SLASH(*pcsz) || *pcsz == COLON)
  131. pcszLastComponent = CharNext(pcsz);
  132. }
  133. ASSERT(IsValidPath(pcszLastComponent));
  134. return(pcszLastComponent);
  135. }
  136. #if defined(UNICODE)
  137. LPCSTR NMINTERNAL ExtractFileNameA(LPCSTR pcszPathName)
  138. {
  139. LPCSTR pcszLastComponent;
  140. LPCSTR pcsz;
  141. ASSERT(IS_VALID_STRING_PTR_A(pcszPathName, CSTR));
  142. for (pcszLastComponent = pcsz = pcszPathName;
  143. *pcsz;
  144. pcsz = CharNextA(pcsz))
  145. {
  146. if (IS_SLASH(*pcsz) || *pcsz == COLON)
  147. pcszLastComponent = CharNextA(pcsz);
  148. }
  149. ASSERT(IsValidPathA(pcszLastComponent));
  150. return(pcszLastComponent);
  151. }
  152. #endif // defined(UNICODE)
  153. /* S A N I T I Z E F I L E N A M E */
  154. /*-------------------------------------------------------------------------
  155. %%Function: SanitizeFileName
  156. -------------------------------------------------------------------------*/
  157. BOOL NMINTERNAL SanitizeFileName(LPTSTR psz)
  158. {
  159. if (NULL == psz)
  160. return FALSE;
  161. while (*psz)
  162. {
  163. switch (*psz)
  164. {
  165. case _T('\\'):
  166. case _T('\"'):
  167. case _T('/'):
  168. case _T(':'):
  169. case _T('*'):
  170. case _T('?'):
  171. case _T('<'):
  172. case _T('>'):
  173. case _T('|'):
  174. *psz = _T('_');
  175. default:
  176. break;
  177. }
  178. psz = ::CharNext(psz);
  179. }
  180. return TRUE;
  181. }
  182. ///////////////////////////////////////////////////////////////////////////
  183. /* C R E A T E N E W F I L E */
  184. /*----------------------------------------------------------------------------
  185. %%Function: CreateNewFile
  186. Attempt to create a new file.
  187. Note this returns either 0 (success)
  188. or the result from GetLastError (usually ERROR_FILE_EXISTS)
  189. ----------------------------------------------------------------------------*/
  190. DWORD CreateNewFile(LPTSTR pszFile)
  191. {
  192. DWORD errRet;
  193. HANDLE hFile;
  194. if (lstrlen(pszFile) >= MAX_PATH)
  195. {
  196. // don't allow long path/filenames
  197. return 1;
  198. }
  199. SetLastError(0);
  200. UINT uErrorMode = SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS);
  201. hFile = CreateFile(pszFile, GENERIC_READ | GENERIC_WRITE, 0,
  202. NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
  203. SetErrorMode(uErrorMode); // Restore error mode
  204. errRet = GetLastError();
  205. if (hFile != INVALID_HANDLE_VALUE)
  206. {
  207. CloseHandle(hFile);
  208. }
  209. return errRet;
  210. }
  211. /* F C R E A T E N E W F I L E */
  212. /*-------------------------------------------------------------------------
  213. %%Function: FCreateNewFile
  214. Create a new file in a directory, with a name and extension.
  215. Returns the full path name in the buffer.
  216. -------------------------------------------------------------------------*/
  217. BOOL FCreateNewFile(LPCTSTR pcszPath, LPCTSTR pcszName, LPCTSTR pcszExt, LPTSTR pszResult, int cchMax)
  218. {
  219. TCHAR szFile[MAX_PATH*2];
  220. lstrcpy(szFile, pcszPath);
  221. if (!FEnsureDirName(szFile))
  222. return FALSE;
  223. LPTSTR psz = szFile + lstrlen(szFile);
  224. lstrcpy(psz, pcszName);
  225. SanitizeFileName(psz);
  226. lstrcat(psz, pcszExt);
  227. DWORD dwErr = CreateNewFile(szFile);
  228. if (0 != dwErr)
  229. {
  230. // Create a duplicate filename
  231. psz += lstrlen(pcszName);
  232. for (int iFile = 2; iFile < 999; iFile++)
  233. {
  234. wsprintf(psz, TEXT(" (%d).%s"), iFile, pcszExt);
  235. if (ERROR_FILE_EXISTS != (dwErr = CreateNewFile(szFile)) )
  236. break;
  237. }
  238. if (0 != dwErr)
  239. {
  240. WARNING_OUT(("Unable to create duplicate filename (err=%d)", dwErr));
  241. return FALSE;
  242. }
  243. }
  244. if (cchMax > lstrlen(szFile))
  245. {
  246. lstrcpy(pszResult, szFile);
  247. }
  248. else
  249. {
  250. // try and make the full name fit within the buffer
  251. dwErr = GetShortPathName(szFile, pszResult, cchMax);
  252. if ((0 == dwErr) || (dwErr >= MAX_PATH))
  253. return FALSE;
  254. }
  255. return TRUE;
  256. }
  257. /* F E N S U R E D I R N A M E */
  258. /*-------------------------------------------------------------------------
  259. %%Function: FEnsureDirName
  260. -------------------------------------------------------------------------*/
  261. BOOL FEnsureDirName(LPTSTR pszPath)
  262. {
  263. if (NULL == pszPath)
  264. return FALSE;
  265. LPTSTR pszCurr = pszPath;
  266. // Make sure the directory name has a trailing '\'
  267. for ( ; ; )
  268. {
  269. LPTSTR pszNext = CharNext(pszCurr);
  270. if (*pszNext == _T('\0'))
  271. {
  272. if (_T('\\') != *pszCurr)
  273. {
  274. *pszNext++ = _T('\\');
  275. *pszNext = _T('\0');
  276. }
  277. break;
  278. }
  279. pszCurr = pszNext;
  280. }
  281. return FEnsureDirExists(pszPath);
  282. }