|
|
/**********************************************************************/ /** Microsoft Windows NT **/ /** Copyright(c) Microsoft Corp., 1994 **/ /**********************************************************************/
/*
filemisc.cxx
This module contains some random functions for manipulating TS_OPEN_FILE_INFO objects
FILE HISTORY: MCourage 09-Dec-1997 Created */
#include <tsunami.hxx>
#include <imd.h>
#include <mb.hxx>
#include <mbstring.h>
#include "tsunamip.hxx"
#include "etagmb.h"
BOOL TsDeleteOnClose(PW3_URI_INFO pURIInfo, HANDLE OpeningUser, BOOL *fDeleted) /*++
Routine Description:
Marks the file associated with the passed URIInfo for deletion. When everyone is done using that file, it will be deleted
Arguments:
pURIInfo - The W3_URI_INFO whose file will be marked for deletion OpeningUser - HANDLE for the user attempting the delete operation fDeleted - Will be set if TsDeleteOnClose returns TRUE. If the user has access and the file was marked deleted fDeleted will be TRUE. Otherwise it will be FALSE.
Return Values:
TRUE - The user had access and the file was marked, or the user was denied access. FALSE - An error other than Access Denied occured.
--*/ { //
// Doesn't do anything. Ha ha!
//
*fDeleted = FALSE; return FALSE;
}
PSECURITY_DESCRIPTOR TsGetFileSecDesc( LPTS_OPEN_FILE_INFO pFile ) /*++
Routine Description:
Returns the security descriptor associated to the file To be freed using LocalFree()
Arguments:
pFile - ptr to fie object
Return Value:
ptr to security descriptor or NULL if error
--*/ { SECURITY_INFORMATION si = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION; BYTE abSecDesc[ SECURITY_DESC_DEFAULT_SIZE ]; DWORD dwSecDescSize; PSECURITY_DESCRIPTOR pAcl;
if ( GetKernelObjectSecurity( pFile->QueryFileHandle(), si, (PSECURITY_DESCRIPTOR)abSecDesc, SECURITY_DESC_DEFAULT_SIZE, &dwSecDescSize ) ) { if ( dwSecDescSize > SECURITY_DESC_DEFAULT_SIZE ) { if ( !(pAcl = (PSECURITY_DESCRIPTOR)LocalAlloc( LMEM_FIXED, dwSecDescSize )) ) { return NULL; } if ( !GetKernelObjectSecurity( pFile->QueryFileHandle(), si, pAcl, dwSecDescSize, &dwSecDescSize ) ) { LocalFree( pAcl );
return NULL; } } else { if ( dwSecDescSize = GetSecurityDescriptorLength(abSecDesc) ) { if ( !(pAcl = (PSECURITY_DESCRIPTOR)LocalAlloc( LMEM_FIXED, dwSecDescSize )) ) { return NULL; } memcpy( pAcl, abSecDesc, dwSecDescSize ); } else { //
// Security descriptor is empty : do not return ptr to security descriptor
//
pAcl = NULL; } } } else { pAcl = NULL; }
return pAcl; }
BOOL TsCreateETagFromHandle( IN HANDLE hFile, IN PCHAR ETag, IN BOOL *bWeakETag ) /*+++
TsCreateETagFromHandle
This routine takes a file handle as input, and creates an ETag in the supplied buffer for that file handle.
Arguments:
hFile - File handle for which to create an ETag. ETag - Where to store the ETag. This must be long enough to hold the maximum length ETag. bWeakETag - Set to TRUE if the newly created ETag is weak.
Returns:
TRUE if we create an ETag, FALSE otherwise. ---*/ { BY_HANDLE_FILE_INFORMATION FileInfo; BOOL bReturn; PUCHAR Temp; FILETIME ftNow; DWORD dwChangeNumber = ETagChangeNumber::GetChangeNumber();
bReturn = GetFileInformationByHandle( hFile, &FileInfo );
if (!bReturn) { return FALSE; }
FORMAT_ETAG(ETag, FileInfo.ftLastWriteTime, dwChangeNumber );
::GetSystemTimeAsFileTime(&ftNow);
FILETIME iNow, iFileTime;
iNow = ftNow; iFileTime = FileInfo.ftLastWriteTime;
if ( (FILETIMEToUINT64(iNow) - FILETIMEToUINT64(iFileTime)) > STRONG_ETAG_DELTA ) { *bWeakETag = FALSE; } else { *bWeakETag = TRUE; }
return TRUE; }
BOOL TsLastWriteTimeFromHandle( IN HANDLE hFile, IN FILETIME *tm ) /*+++
TsLastWriteTimeFromHandle
This routine takes a file handle as input, and returns the last write time for that handle.
Arguments:
hFile - File handle for which to get the last write time. tm - Where to return the last write time.
Returns:
TRUE if we succeed, FALSE otherwise. ---*/ { BY_HANDLE_FILE_INFORMATION FileInfo; BOOL bReturn;
bReturn = GetFileInformationByHandle( hFile, &FileInfo );
if (!bReturn) { return FALSE; }
*tm = FileInfo.ftLastWriteTime;
return TRUE; }
DWORD CheckIfShortFileName( IN CONST UCHAR * pszPath, IN HANDLE hImpersonation, OUT BOOL * pfShort ) /*++
Description:
This function takes a suspected NT/Win95 short filename and checks if there's an equivalent long filename. For example, c:\foobar\ABCDEF~1.ABC is the same as c:\foobar\abcdefghijklmnop.abc.
NOTE: This function should be called unimpersonated - the FindFirstFile() must be called in the system context since most systems have traverse checking turned off - except for the UNC case where we must be impersonated to get network access.
Arguments:
pszPath - Path to check hImpersonation - Impersonation handle if this is a UNC path - can be NULL if not UNC pfShort - Set to TRUE if an equivalent long filename is found
Returns:
Win32 error on failure --*/ { DWORD err = NO_ERROR; WIN32_FIND_DATA FindData; UCHAR * psz; BOOL fUNC;
psz = _mbschr( (UCHAR *) pszPath, '~' ); *pfShort = FALSE; fUNC = (*pszPath == '\\');
//
// Loop for multiple tildas - watch for a # after the tilda
//
while ( psz++ ) { if ( *psz >= '0' && *psz <= '9' ) { UCHAR achTmp[MAX_PATH]; UCHAR * pchEndSeg; UCHAR * pchBeginSeg; HANDLE hFind;
//
// Isolate the path up to the segment with the
// '~' and do the FindFirst with that path
//
pchEndSeg = _mbschr( psz, '\\' );
if ( !pchEndSeg ) { pchEndSeg = psz + _mbslen( psz ); }
//
// If the string is beyond MAX_PATH then we allow it through
//
if ( ((INT) (pchEndSeg - pszPath)) >= sizeof( achTmp )) { return NO_ERROR; }
memcpy( achTmp, pszPath, (INT) (pchEndSeg - pszPath) ); achTmp[pchEndSeg - pszPath] = '\0';
if ( fUNC && hImpersonation ) { if ( !ImpersonateLoggedOnUser( hImpersonation )) { return GetLastError(); } }
hFind = FindFirstFile( (CHAR *) achTmp, &FindData );
if ( fUNC && hImpersonation ) { RevertToSelf(); }
if ( hFind == INVALID_HANDLE_VALUE ) { err = GetLastError();
DBGPRINTF(( DBG_CONTEXT, "FindFirst failed!! - \"%s\", error %d\n", achTmp, GetLastError() ));
//
// If the FindFirstFile() fails to find the file then return
// success - the path doesn't appear to be a valid path which
// is ok.
//
if ( err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND ) { return NO_ERROR; }
return err; }
DBG_REQUIRE( FindClose( hFind ));
//
// Isolate the last segment of the string which should be
// the potential short name equivalency
//
pchBeginSeg = _mbsrchr( achTmp, '\\' ); DBG_ASSERT( pchBeginSeg ); pchBeginSeg++;
//
// If the last segment doesn't match the long name then this is
// the short name version of the path
//
if ( _mbsicmp( (UCHAR *) FindData.cFileName, pchBeginSeg )) { *pfShort = TRUE; return NO_ERROR; } }
psz = _mbschr( psz, '~' ); }
return err; }
//
// filemisc.cxx
//
|