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.

395 lines
10 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows NT **/
  3. /** Copyright(c) Microsoft Corp., 1994 **/
  4. /**********************************************************************/
  5. /*
  6. filemisc.cxx
  7. This module contains some random functions for manipulating
  8. TS_OPEN_FILE_INFO objects
  9. FILE HISTORY:
  10. MCourage 09-Dec-1997 Created
  11. */
  12. #include <tsunami.hxx>
  13. #include <imd.h>
  14. #include <mb.hxx>
  15. #include <mbstring.h>
  16. #include "tsunamip.hxx"
  17. #include "etagmb.h"
  18. BOOL
  19. TsDeleteOnClose(PW3_URI_INFO pURIInfo,
  20. HANDLE OpeningUser,
  21. BOOL *fDeleted)
  22. /*++
  23. Routine Description:
  24. Marks the file associated with the passed URIInfo for deletion. When everyone
  25. is done using that file, it will be deleted
  26. Arguments:
  27. pURIInfo - The W3_URI_INFO whose file will be marked for deletion
  28. OpeningUser - HANDLE for the user attempting the delete operation
  29. fDeleted - Will be set if TsDeleteOnClose returns TRUE. If the user has access
  30. and the file was marked deleted fDeleted will be TRUE. Otherwise it will be
  31. FALSE.
  32. Return Values:
  33. TRUE - The user had access and the file was marked, or the user was denied access.
  34. FALSE - An error other than Access Denied occured.
  35. --*/
  36. {
  37. //
  38. // Doesn't do anything. Ha ha!
  39. //
  40. *fDeleted = FALSE;
  41. return FALSE;
  42. }
  43. PSECURITY_DESCRIPTOR
  44. TsGetFileSecDesc(
  45. LPTS_OPEN_FILE_INFO pFile
  46. )
  47. /*++
  48. Routine Description:
  49. Returns the security descriptor associated to the file
  50. To be freed using LocalFree()
  51. Arguments:
  52. pFile - ptr to fie object
  53. Return Value:
  54. ptr to security descriptor or NULL if error
  55. --*/
  56. {
  57. SECURITY_INFORMATION si
  58. = OWNER_SECURITY_INFORMATION |
  59. GROUP_SECURITY_INFORMATION |
  60. DACL_SECURITY_INFORMATION;
  61. BYTE abSecDesc[ SECURITY_DESC_DEFAULT_SIZE ];
  62. DWORD dwSecDescSize;
  63. PSECURITY_DESCRIPTOR pAcl;
  64. if ( GetKernelObjectSecurity(
  65. pFile->QueryFileHandle(),
  66. si,
  67. (PSECURITY_DESCRIPTOR)abSecDesc,
  68. SECURITY_DESC_DEFAULT_SIZE,
  69. &dwSecDescSize ) )
  70. {
  71. if ( dwSecDescSize > SECURITY_DESC_DEFAULT_SIZE )
  72. {
  73. if ( !(pAcl = (PSECURITY_DESCRIPTOR)LocalAlloc( LMEM_FIXED, dwSecDescSize )) )
  74. {
  75. return NULL;
  76. }
  77. if ( !GetKernelObjectSecurity(
  78. pFile->QueryFileHandle(),
  79. si,
  80. pAcl,
  81. dwSecDescSize,
  82. &dwSecDescSize ) )
  83. {
  84. LocalFree( pAcl );
  85. return NULL;
  86. }
  87. }
  88. else
  89. {
  90. if ( dwSecDescSize = GetSecurityDescriptorLength(abSecDesc) )
  91. {
  92. if ( !(pAcl = (PSECURITY_DESCRIPTOR)LocalAlloc( LMEM_FIXED,
  93. dwSecDescSize )) )
  94. {
  95. return NULL;
  96. }
  97. memcpy( pAcl, abSecDesc, dwSecDescSize );
  98. }
  99. else
  100. {
  101. //
  102. // Security descriptor is empty : do not return ptr to security descriptor
  103. //
  104. pAcl = NULL;
  105. }
  106. }
  107. }
  108. else
  109. {
  110. pAcl = NULL;
  111. }
  112. return pAcl;
  113. }
  114. BOOL TsCreateETagFromHandle(
  115. IN HANDLE hFile,
  116. IN PCHAR ETag,
  117. IN BOOL *bWeakETag
  118. )
  119. /*+++
  120. TsCreateETagFromHandle
  121. This routine takes a file handle as input, and creates an ETag in
  122. the supplied buffer for that file handle.
  123. Arguments:
  124. hFile - File handle for which to create an ETag.
  125. ETag - Where to store the ETag. This must be long
  126. enough to hold the maximum length ETag.
  127. bWeakETag - Set to TRUE if the newly created ETag is weak.
  128. Returns:
  129. TRUE if we create an ETag, FALSE otherwise.
  130. ---*/
  131. {
  132. BY_HANDLE_FILE_INFORMATION FileInfo;
  133. BOOL bReturn;
  134. PUCHAR Temp;
  135. FILETIME ftNow;
  136. DWORD dwChangeNumber = ETagChangeNumber::GetChangeNumber();
  137. bReturn = GetFileInformationByHandle(
  138. hFile,
  139. &FileInfo
  140. );
  141. if (!bReturn)
  142. {
  143. return FALSE;
  144. }
  145. FORMAT_ETAG(ETag, FileInfo.ftLastWriteTime, dwChangeNumber );
  146. ::GetSystemTimeAsFileTime(&ftNow);
  147. FILETIME iNow, iFileTime;
  148. iNow = ftNow;
  149. iFileTime = FileInfo.ftLastWriteTime;
  150. if ( (FILETIMEToUINT64(iNow) - FILETIMEToUINT64(iFileTime)) > STRONG_ETAG_DELTA )
  151. {
  152. *bWeakETag = FALSE;
  153. }
  154. else
  155. {
  156. *bWeakETag = TRUE;
  157. }
  158. return TRUE;
  159. }
  160. BOOL TsLastWriteTimeFromHandle(
  161. IN HANDLE hFile,
  162. IN FILETIME *tm
  163. )
  164. /*+++
  165. TsLastWriteTimeFromHandle
  166. This routine takes a file handle as input, and returns the last write time
  167. for that handle.
  168. Arguments:
  169. hFile - File handle for which to get the last write time.
  170. tm - Where to return the last write time.
  171. Returns:
  172. TRUE if we succeed, FALSE otherwise.
  173. ---*/
  174. {
  175. BY_HANDLE_FILE_INFORMATION FileInfo;
  176. BOOL bReturn;
  177. bReturn = GetFileInformationByHandle(
  178. hFile,
  179. &FileInfo
  180. );
  181. if (!bReturn)
  182. {
  183. return FALSE;
  184. }
  185. *tm = FileInfo.ftLastWriteTime;
  186. return TRUE;
  187. }
  188. DWORD
  189. CheckIfShortFileName(
  190. IN CONST UCHAR * pszPath,
  191. IN HANDLE hImpersonation,
  192. OUT BOOL * pfShort
  193. )
  194. /*++
  195. Description:
  196. This function takes a suspected NT/Win95 short filename and checks if there's
  197. an equivalent long filename. For example, c:\foobar\ABCDEF~1.ABC is the same
  198. as c:\foobar\abcdefghijklmnop.abc.
  199. NOTE: This function should be called unimpersonated - the FindFirstFile() must
  200. be called in the system context since most systems have traverse checking turned
  201. off - except for the UNC case where we must be impersonated to get network access.
  202. Arguments:
  203. pszPath - Path to check
  204. hImpersonation - Impersonation handle if this is a UNC path - can be NULL if not UNC
  205. pfShort - Set to TRUE if an equivalent long filename is found
  206. Returns:
  207. Win32 error on failure
  208. --*/
  209. {
  210. DWORD err = NO_ERROR;
  211. WIN32_FIND_DATA FindData;
  212. UCHAR * psz;
  213. BOOL fUNC;
  214. psz = _mbschr( (UCHAR *) pszPath, '~' );
  215. *pfShort = FALSE;
  216. fUNC = (*pszPath == '\\');
  217. //
  218. // Loop for multiple tildas - watch for a # after the tilda
  219. //
  220. while ( psz++ )
  221. {
  222. if ( *psz >= '0' && *psz <= '9' )
  223. {
  224. UCHAR achTmp[MAX_PATH];
  225. UCHAR * pchEndSeg;
  226. UCHAR * pchBeginSeg;
  227. HANDLE hFind;
  228. //
  229. // Isolate the path up to the segment with the
  230. // '~' and do the FindFirst with that path
  231. //
  232. pchEndSeg = _mbschr( psz, '\\' );
  233. if ( !pchEndSeg )
  234. {
  235. pchEndSeg = psz + _mbslen( psz );
  236. }
  237. //
  238. // If the string is beyond MAX_PATH then we allow it through
  239. //
  240. if ( ((INT) (pchEndSeg - pszPath)) >= sizeof( achTmp ))
  241. {
  242. return NO_ERROR;
  243. }
  244. memcpy( achTmp, pszPath, (INT) (pchEndSeg - pszPath) );
  245. achTmp[pchEndSeg - pszPath] = '\0';
  246. if ( fUNC && hImpersonation )
  247. {
  248. if ( !ImpersonateLoggedOnUser( hImpersonation ))
  249. {
  250. return GetLastError();
  251. }
  252. }
  253. hFind = FindFirstFile( (CHAR *) achTmp, &FindData );
  254. if ( fUNC && hImpersonation )
  255. {
  256. RevertToSelf();
  257. }
  258. if ( hFind == INVALID_HANDLE_VALUE )
  259. {
  260. err = GetLastError();
  261. DBGPRINTF(( DBG_CONTEXT,
  262. "FindFirst failed!! - \"%s\", error %d\n",
  263. achTmp,
  264. GetLastError() ));
  265. //
  266. // If the FindFirstFile() fails to find the file then return
  267. // success - the path doesn't appear to be a valid path which
  268. // is ok.
  269. //
  270. if ( err == ERROR_FILE_NOT_FOUND ||
  271. err == ERROR_PATH_NOT_FOUND )
  272. {
  273. return NO_ERROR;
  274. }
  275. return err;
  276. }
  277. DBG_REQUIRE( FindClose( hFind ));
  278. //
  279. // Isolate the last segment of the string which should be
  280. // the potential short name equivalency
  281. //
  282. pchBeginSeg = _mbsrchr( achTmp, '\\' );
  283. DBG_ASSERT( pchBeginSeg );
  284. pchBeginSeg++;
  285. //
  286. // If the last segment doesn't match the long name then this is
  287. // the short name version of the path
  288. //
  289. if ( _mbsicmp( (UCHAR *) FindData.cFileName, pchBeginSeg ))
  290. {
  291. *pfShort = TRUE;
  292. return NO_ERROR;
  293. }
  294. }
  295. psz = _mbschr( psz, '~' );
  296. }
  297. return err;
  298. }
  299. //
  300. // filemisc.cxx
  301. //