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.
 
 
 
 
 
 

328 lines
9.7 KiB

#ifndef CREATETEMPFILE_H
#define CREATETEMPFILE_H
#include <aclapi.h>
#include <shlwapi.h>
#include <shlobj.h>
/*
Routine Name: CreateTempFile
Routine Description:
Creates a temporary file only the caller can access.
Arguments:
pszTempFileName
[in/out] Pointer to a null terminated string that is the full path to the temp file or
receives the full path to the temp file if bCreateName is TRUE. You should set the size
of this buffer to MAX_PATH to ensure that it is large enough to hold the returned string.
pszExtension
[in] Pointer to a null terminated string that specifies the extension of the file name to be
created.If pszExtension is NULL, the default extension is tmp.
bCreateName
[in] Species whether pszTempFileName should receive a temp file name generated by the function.
if bCreateName is TRUE, a temp file in user's temp directory is created and full path to the file
is returned to the caller in pszTempFileName.
dwFlags
[in] Specifies the file attributes and flags for the file.
Return Values:
If the function succeeds, the return value is a handle to the temp file.
if the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information
call GetLastError()
Author:
gokmenh, March, 2002
*/
inline HANDLE _CreateTempFile (
LPTSTR pszTempFileName,
LPTSTR pszExtension = NULL,
BOOL bCreateName = TRUE,
DWORD dwFlags = 0
)
{
TCHAR szTempPath[MAX_PATH];
TCHAR szTempFile[MAX_PATH];
DWORD dwRC = ERROR_SUCCESS;
DWORD dwLength;
TOKEN_USER * pTokenUser = NULL;
EXPLICIT_ACCESS ea[1];
PACL pACL = NULL;
PSECURITY_DESCRIPTOR pSD = NULL;
SECURITY_ATTRIBUTES sa;
HANDLE hFile = INVALID_HANDLE_VALUE;
HANDLE hToken = NULL;
BOOL bCreateDir = FALSE;
szTempPath[0] = NULL;
szTempFile[0] = NULL;
ZeroMemory( ea, sizeof(ea) );
if (NULL == pszTempFileName)
{
SetLastError(ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE;
}
// If the caller does not specify the file name we
// need to come up with our own.
if (TRUE == bCreateName)
{
if (0 == GetTempPath(sizeof(szTempPath)/sizeof(TCHAR), szTempPath))
{
dwRC = GetLastError();
}
if (ERROR_SUCCESS == dwRC)
{
if (0 == GetTempFileName(szTempPath, _T("tmp"), 0, szTempFile))
{
dwRC = GetLastError();
}
else
{
if (NULL != pszExtension)
{
// We will change the extension, get rid of the file with the old extension
if (FALSE == DeleteFile(szTempFile))
{
dwRC = GetLastError();
}
if (ERROR_SUCCESS == dwRC)
{
if (FALSE == PathRenameExtension(szTempFile, pszExtension))
{
dwRC = ERROR_INVALID_DATA;
}
}
}
}
}
}
else
{
szTempPath[MAX_PATH - 1] = NULL;
_tcsncpy(szTempFile, pszTempFileName, MAX_PATH);
_tcsncpy(szTempPath, pszTempFileName, MAX_PATH);
if (NULL != szTempPath[MAX_PATH - 1])
{
dwRC = ERROR_INVALID_PARAMETER;
}
}
if (ERROR_SUCCESS == dwRC)
{
// We will first try to get to the impersonation token for the thread
if (0 == OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken))
{
dwRC = GetLastError();
if (ERROR_NO_TOKEN == dwRC)
{
// It seems that the thread is not doing impersonation. We will stick to the
// process token
if (0 == OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
{
dwRC = GetLastError();
}
else
{
dwRC = ERROR_SUCCESS;
}
}
}
}
if (ERROR_SUCCESS == dwRC)
{
// First try to obtain how much space we need
if (0 == GetTokenInformation(hToken, TokenUser, NULL, 0, &dwLength))
{
dwRC = GetLastError();
if (ERROR_INSUFFICIENT_BUFFER == dwRC)
{
// Allocate the required memory and retry.
dwRC = ERROR_SUCCESS;
pTokenUser = (TOKEN_USER *) new BYTE[dwLength];
if (NULL == pTokenUser)
{
dwRC = ERROR_NOT_ENOUGH_MEMORY;
}
else
if (0 == GetTokenInformation(hToken, TokenUser, pTokenUser, dwLength, &dwLength))
{
dwRC = GetLastError();
}
}
}
else
{
// GetTokenInformation works with a NULL pointer?
dwRC = ERROR_INVALID_DATA;
}
}
if (ERROR_SUCCESS == dwRC)
{
// We now have the token info for the current user which contains the sid for the user.
// We will try to create a security descriptor which allows only the user to access the file.
ea[0].grfAccessPermissions = GENERIC_ALL;
ea[0].grfAccessMode = SET_ACCESS;
ea[0].grfInheritance = NO_INHERITANCE;
ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea[0].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
ea[0].Trustee.ptstrName = (LPTSTR) pTokenUser->User.Sid;
dwRC = SetEntriesInAcl(1, ea, NULL, &pACL);
}
if (ERROR_SUCCESS == dwRC)
{
pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
if (NULL == pSD)
{
dwRC = ERROR_NOT_ENOUGH_MEMORY;
}
}
if (ERROR_SUCCESS == dwRC)
{
if ( 0 == InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION))
{
dwRC = GetLastError();
}
}
if (ERROR_SUCCESS == dwRC)
{
if (0 == SetSecurityDescriptorDacl(pSD, TRUE, pACL, FALSE))
{
dwRC = GetLastError();
}
}
if (ERROR_SUCCESS == dwRC)
{
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = FALSE;
sa.lpSecurityDescriptor = pSD;
if (FALSE == bCreateName)
{
if (FALSE == PathRemoveFileSpec(szTempPath))
{
dwRC = ERROR_INVALID_PARAMETER;
}
else
{
// We do not want to create root dirs
if (FALSE == PathIsRoot(szTempPath))
{
dwRC = SHCreateDirectoryEx(NULL, szTempPath, &sa);
if ((ERROR_FILE_EXISTS == dwRC) || (ERROR_ALREADY_EXISTS == dwRC))
{
dwRC = ERROR_SUCCESS;
}
}
}
}
}
if (ERROR_SUCCESS == dwRC)
{
hFile = CreateFile (
szTempFile,
GENERIC_ALL,
FILE_SHARE_READ,
&sa,
CREATE_ALWAYS,
FILE_ATTRIBUTE_TEMPORARY | dwFlags,
NULL
);
dwRC = GetLastError();
if (INVALID_HANDLE_VALUE != hFile)
{
if (ERROR_ALREADY_EXISTS == dwRC)
{
// If the file already exists, we will still have a handle to the file but
// CreateFile does not change the security descriptor for the file so we need
// to make sure that we ACL the file properly.
dwRC = SetNamedSecurityInfo (
(LPTSTR) szTempFile, // File name
SE_FILE_OBJECT, // This is a file
DACL_SECURITY_INFORMATION | // We will pass in an ACL
PROTECTED_DACL_SECURITY_INFORMATION, // File will not inherit anything from the parent
NULL, // Owner sid
NULL, // Group sid
pACL, // ACL
NULL // SACL
);
}
}
}
if (NULL != pSD)
{
LocalFree(pSD);
}
if (NULL != pACL)
{
LocalFree(pACL);
}
if (NULL != pTokenUser)
{
delete [] (LPBYTE) pTokenUser;
}
if (NULL != hToken)
{
CloseHandle(hToken);
}
if (ERROR_SUCCESS == dwRC)
{
_tcsncpy(pszTempFileName, szTempFile, MAX_PATH);
return hFile;
}
else
{
if (INVALID_HANDLE_VALUE != hFile)
{
CloseHandle(hFile);
}
SetLastError(dwRC);
return INVALID_HANDLE_VALUE;
}
}
#endif