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.

327 lines
9.7 KiB

  1. #ifndef CREATETEMPFILE_H
  2. #define CREATETEMPFILE_H
  3. #include <aclapi.h>
  4. #include <shlwapi.h>
  5. #include <shlobj.h>
  6. /*
  7. Routine Name: CreateTempFile
  8. Routine Description:
  9. Creates a temporary file only the caller can access.
  10. Arguments:
  11. pszTempFileName
  12. [in/out] Pointer to a null terminated string that is the full path to the temp file or
  13. receives the full path to the temp file if bCreateName is TRUE. You should set the size
  14. of this buffer to MAX_PATH to ensure that it is large enough to hold the returned string.
  15. pszExtension
  16. [in] Pointer to a null terminated string that specifies the extension of the file name to be
  17. created.If pszExtension is NULL, the default extension is tmp.
  18. bCreateName
  19. [in] Species whether pszTempFileName should receive a temp file name generated by the function.
  20. if bCreateName is TRUE, a temp file in user's temp directory is created and full path to the file
  21. is returned to the caller in pszTempFileName.
  22. dwFlags
  23. [in] Specifies the file attributes and flags for the file.
  24. Return Values:
  25. If the function succeeds, the return value is a handle to the temp file.
  26. if the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information
  27. call GetLastError()
  28. Author:
  29. gokmenh, March, 2002
  30. */
  31. inline HANDLE _CreateTempFile (
  32. LPTSTR pszTempFileName,
  33. LPTSTR pszExtension = NULL,
  34. BOOL bCreateName = TRUE,
  35. DWORD dwFlags = 0
  36. )
  37. {
  38. TCHAR szTempPath[MAX_PATH];
  39. TCHAR szTempFile[MAX_PATH];
  40. DWORD dwRC = ERROR_SUCCESS;
  41. DWORD dwLength;
  42. TOKEN_USER * pTokenUser = NULL;
  43. EXPLICIT_ACCESS ea[1];
  44. PACL pACL = NULL;
  45. PSECURITY_DESCRIPTOR pSD = NULL;
  46. SECURITY_ATTRIBUTES sa;
  47. HANDLE hFile = INVALID_HANDLE_VALUE;
  48. HANDLE hToken = NULL;
  49. BOOL bCreateDir = FALSE;
  50. szTempPath[0] = NULL;
  51. szTempFile[0] = NULL;
  52. ZeroMemory( ea, sizeof(ea) );
  53. if (NULL == pszTempFileName)
  54. {
  55. SetLastError(ERROR_INVALID_PARAMETER);
  56. return INVALID_HANDLE_VALUE;
  57. }
  58. // If the caller does not specify the file name we
  59. // need to come up with our own.
  60. if (TRUE == bCreateName)
  61. {
  62. if (0 == GetTempPath(sizeof(szTempPath)/sizeof(TCHAR), szTempPath))
  63. {
  64. dwRC = GetLastError();
  65. }
  66. if (ERROR_SUCCESS == dwRC)
  67. {
  68. if (0 == GetTempFileName(szTempPath, _T("tmp"), 0, szTempFile))
  69. {
  70. dwRC = GetLastError();
  71. }
  72. else
  73. {
  74. if (NULL != pszExtension)
  75. {
  76. // We will change the extension, get rid of the file with the old extension
  77. if (FALSE == DeleteFile(szTempFile))
  78. {
  79. dwRC = GetLastError();
  80. }
  81. if (ERROR_SUCCESS == dwRC)
  82. {
  83. if (FALSE == PathRenameExtension(szTempFile, pszExtension))
  84. {
  85. dwRC = ERROR_INVALID_DATA;
  86. }
  87. }
  88. }
  89. }
  90. }
  91. }
  92. else
  93. {
  94. szTempPath[MAX_PATH - 1] = NULL;
  95. _tcsncpy(szTempFile, pszTempFileName, MAX_PATH);
  96. _tcsncpy(szTempPath, pszTempFileName, MAX_PATH);
  97. if (NULL != szTempPath[MAX_PATH - 1])
  98. {
  99. dwRC = ERROR_INVALID_PARAMETER;
  100. }
  101. }
  102. if (ERROR_SUCCESS == dwRC)
  103. {
  104. // We will first try to get to the impersonation token for the thread
  105. if (0 == OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken))
  106. {
  107. dwRC = GetLastError();
  108. if (ERROR_NO_TOKEN == dwRC)
  109. {
  110. // It seems that the thread is not doing impersonation. We will stick to the
  111. // process token
  112. if (0 == OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
  113. {
  114. dwRC = GetLastError();
  115. }
  116. else
  117. {
  118. dwRC = ERROR_SUCCESS;
  119. }
  120. }
  121. }
  122. }
  123. if (ERROR_SUCCESS == dwRC)
  124. {
  125. // First try to obtain how much space we need
  126. if (0 == GetTokenInformation(hToken, TokenUser, NULL, 0, &dwLength))
  127. {
  128. dwRC = GetLastError();
  129. if (ERROR_INSUFFICIENT_BUFFER == dwRC)
  130. {
  131. // Allocate the required memory and retry.
  132. dwRC = ERROR_SUCCESS;
  133. pTokenUser = (TOKEN_USER *) new BYTE[dwLength];
  134. if (NULL == pTokenUser)
  135. {
  136. dwRC = ERROR_NOT_ENOUGH_MEMORY;
  137. }
  138. else
  139. if (0 == GetTokenInformation(hToken, TokenUser, pTokenUser, dwLength, &dwLength))
  140. {
  141. dwRC = GetLastError();
  142. }
  143. }
  144. }
  145. else
  146. {
  147. // GetTokenInformation works with a NULL pointer?
  148. dwRC = ERROR_INVALID_DATA;
  149. }
  150. }
  151. if (ERROR_SUCCESS == dwRC)
  152. {
  153. // We now have the token info for the current user which contains the sid for the user.
  154. // We will try to create a security descriptor which allows only the user to access the file.
  155. ea[0].grfAccessPermissions = GENERIC_ALL;
  156. ea[0].grfAccessMode = SET_ACCESS;
  157. ea[0].grfInheritance = NO_INHERITANCE;
  158. ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
  159. ea[0].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
  160. ea[0].Trustee.ptstrName = (LPTSTR) pTokenUser->User.Sid;
  161. dwRC = SetEntriesInAcl(1, ea, NULL, &pACL);
  162. }
  163. if (ERROR_SUCCESS == dwRC)
  164. {
  165. pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
  166. if (NULL == pSD)
  167. {
  168. dwRC = ERROR_NOT_ENOUGH_MEMORY;
  169. }
  170. }
  171. if (ERROR_SUCCESS == dwRC)
  172. {
  173. if ( 0 == InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION))
  174. {
  175. dwRC = GetLastError();
  176. }
  177. }
  178. if (ERROR_SUCCESS == dwRC)
  179. {
  180. if (0 == SetSecurityDescriptorDacl(pSD, TRUE, pACL, FALSE))
  181. {
  182. dwRC = GetLastError();
  183. }
  184. }
  185. if (ERROR_SUCCESS == dwRC)
  186. {
  187. sa.nLength = sizeof(SECURITY_ATTRIBUTES);
  188. sa.bInheritHandle = FALSE;
  189. sa.lpSecurityDescriptor = pSD;
  190. if (FALSE == bCreateName)
  191. {
  192. if (FALSE == PathRemoveFileSpec(szTempPath))
  193. {
  194. dwRC = ERROR_INVALID_PARAMETER;
  195. }
  196. else
  197. {
  198. // We do not want to create root dirs
  199. if (FALSE == PathIsRoot(szTempPath))
  200. {
  201. dwRC = SHCreateDirectoryEx(NULL, szTempPath, &sa);
  202. if ((ERROR_FILE_EXISTS == dwRC) || (ERROR_ALREADY_EXISTS == dwRC))
  203. {
  204. dwRC = ERROR_SUCCESS;
  205. }
  206. }
  207. }
  208. }
  209. }
  210. if (ERROR_SUCCESS == dwRC)
  211. {
  212. hFile = CreateFile (
  213. szTempFile,
  214. GENERIC_ALL,
  215. FILE_SHARE_READ,
  216. &sa,
  217. CREATE_ALWAYS,
  218. FILE_ATTRIBUTE_TEMPORARY | dwFlags,
  219. NULL
  220. );
  221. dwRC = GetLastError();
  222. if (INVALID_HANDLE_VALUE != hFile)
  223. {
  224. if (ERROR_ALREADY_EXISTS == dwRC)
  225. {
  226. // If the file already exists, we will still have a handle to the file but
  227. // CreateFile does not change the security descriptor for the file so we need
  228. // to make sure that we ACL the file properly.
  229. dwRC = SetNamedSecurityInfo (
  230. (LPTSTR) szTempFile, // File name
  231. SE_FILE_OBJECT, // This is a file
  232. DACL_SECURITY_INFORMATION | // We will pass in an ACL
  233. PROTECTED_DACL_SECURITY_INFORMATION, // File will not inherit anything from the parent
  234. NULL, // Owner sid
  235. NULL, // Group sid
  236. pACL, // ACL
  237. NULL // SACL
  238. );
  239. }
  240. }
  241. }
  242. if (NULL != pSD)
  243. {
  244. LocalFree(pSD);
  245. }
  246. if (NULL != pACL)
  247. {
  248. LocalFree(pACL);
  249. }
  250. if (NULL != pTokenUser)
  251. {
  252. delete [] (LPBYTE) pTokenUser;
  253. }
  254. if (NULL != hToken)
  255. {
  256. CloseHandle(hToken);
  257. }
  258. if (ERROR_SUCCESS == dwRC)
  259. {
  260. _tcsncpy(pszTempFileName, szTempFile, MAX_PATH);
  261. return hFile;
  262. }
  263. else
  264. {
  265. if (INVALID_HANDLE_VALUE != hFile)
  266. {
  267. CloseHandle(hFile);
  268. }
  269. SetLastError(dwRC);
  270. return INVALID_HANDLE_VALUE;
  271. }
  272. }
  273. #endif