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.

288 lines
7.7 KiB

  1. /************************************************************************
  2. Copyright (c) 2000 - 2000 Microsoft Corporation
  3. Module Name :
  4. cache.cpp
  5. Abstract :
  6. Sources files for file cache management
  7. Author :
  8. Revision History :
  9. ***********************************************************************/
  10. #include "stdafx.h"
  11. #include <accctrl.h>
  12. #include <aclapi.h>
  13. #if !defined(BITS_V12_ON_NT4)
  14. #include "cache.tmh"
  15. #endif
  16. BOOL
  17. CProgressiveDL::OpenLocalDownloadFile(
  18. LPCTSTR Path,
  19. UINT64 Offset,
  20. UINT64 Size,
  21. FILETIME UrlModificationTime // 0 if unknown
  22. )
  23. {
  24. HANDLE hFile;
  25. bool bOpenExisting;
  26. if (Offset > 0)
  27. {
  28. // BUGBUG storing the creation time via SetFileTime doesn't work due to granularity problems.
  29. // The queue manager needs to find out the size & time and store them in the CFile object,
  30. // and the downloader needs to check them when a download resumes.
  31. bOpenExisting = true;
  32. hFile = CreateFile( Path,
  33. GENERIC_READ | GENERIC_WRITE,
  34. 0,
  35. NULL,
  36. OPEN_EXISTING,
  37. 0,
  38. NULL );
  39. if (hFile == INVALID_HANDLE_VALUE )
  40. {
  41. DWORD dwError = GetLastError();
  42. LogError("error %!winerr!, opening '%S'", dwError, Path );
  43. SetError( SOURCE_QMGR_FILE, ERROR_STYLE_WIN32, dwError, "CreateFile" );
  44. return FALSE;
  45. }
  46. LARGE_INTEGER liFileSize;
  47. if ( !GetFileSizeEx( hFile, &liFileSize ) )
  48. {
  49. DWORD dwError = GetLastError();
  50. CloseHandle( hFile );
  51. LogError("error %!winerr!, retrieving size of '%S'", dwError, Path );
  52. SetError( SOURCE_QMGR_FILE, ERROR_STYLE_WIN32, dwError, "GetFileSizeEx" );
  53. return FALSE;
  54. }
  55. if ( Size != liFileSize.QuadPart )
  56. {
  57. CloseHandle( hFile );
  58. LogError("File size of '%S' changed", Path );
  59. m_pQMInfo->result = QM_SERVER_FILE_CHANGED;
  60. return FALSE;
  61. }
  62. LARGE_INTEGER liOffset;
  63. liOffset.QuadPart = Offset;
  64. if (!SetFilePointerEx( hFile,
  65. liOffset,
  66. NULL, // don't need the new file pointer
  67. FILE_BEGIN ))
  68. {
  69. DWORD dwError = GetLastError();
  70. CloseHandle( hFile );
  71. LogError("error %!winerr!, seeking to current position in '%S'", dwError, Path );
  72. SetError( SOURCE_QMGR_FILE, ERROR_STYLE_WIN32, dwError, "SetFilePointerEx" );
  73. return FALSE;
  74. }
  75. }
  76. else
  77. {
  78. bOpenExisting = false;
  79. hFile = CreateFile( Path,
  80. GENERIC_READ | GENERIC_WRITE,
  81. 0,
  82. NULL,
  83. CREATE_ALWAYS,
  84. FILE_ATTRIBUTE_HIDDEN,
  85. NULL );
  86. if (hFile == INVALID_HANDLE_VALUE )
  87. {
  88. SetError( SOURCE_QMGR_FILE, ERROR_STYLE_WIN32, GetLastError(), "CreateFile" );
  89. return FALSE;
  90. }
  91. // Reserve space for the file upfront.
  92. LARGE_INTEGER liOffset;
  93. liOffset.QuadPart = Size;
  94. if (!SetFilePointerEx( hFile,
  95. liOffset,
  96. NULL,
  97. FILE_BEGIN ))
  98. {
  99. DWORD dwError = GetLastError();
  100. CloseHandle( hFile );
  101. LogError( "error %!winerr! setting end of file, out of disk space?", dwError );
  102. SetError( SOURCE_QMGR_FILE, ERROR_STYLE_WIN32, dwError, "SetFilePointerEx" );
  103. return FALSE;
  104. }
  105. if ( !SetEndOfFile( hFile ) )
  106. {
  107. DWORD dwError = GetLastError();
  108. CloseHandle( hFile );
  109. LogError( "error %!winerr! setting end of file, out of disk space?", dwError );
  110. SetError( SOURCE_QMGR_FILE, ERROR_STYLE_WIN32, dwError, "SetFilePointerEx" );
  111. return FALSE;
  112. }
  113. liOffset.QuadPart = 0;
  114. if (!SetFilePointerEx( hFile,
  115. liOffset,
  116. NULL,
  117. FILE_BEGIN ))
  118. {
  119. DWORD dwError = GetLastError();
  120. CloseHandle( hFile );
  121. LogError( "error %!winerr! returning to the beginning of the file", dwError );
  122. SetError( SOURCE_QMGR_FILE, ERROR_STYLE_WIN32, dwError, "SetFilePointerEx" );
  123. return FALSE;
  124. }
  125. if ( UrlModificationTime.dwHighDateTime ||
  126. UrlModificationTime.dwLowDateTime )
  127. {
  128. if (!SetFileTime( hFile, &UrlModificationTime, NULL, NULL ) )
  129. {
  130. DWORD dwError = GetLastError();
  131. CloseHandle( hFile );
  132. LogError( "error %!winerr! setting creation time", dwError );
  133. SetError( SOURCE_QMGR_FILE, ERROR_STYLE_WIN32, dwError, "SetFileTime" );
  134. return FALSE;
  135. }
  136. }
  137. }
  138. FILETIME CreationTime;
  139. if (!GetFileTime( hFile, &CreationTime, NULL, NULL ) )
  140. {
  141. DWORD dwError = GetLastError();
  142. CloseHandle( hFile );
  143. LogError( "error %!winerr!, unable to get file creation time", dwError );
  144. SetError( SOURCE_QMGR_FILE, ERROR_STYLE_WIN32, dwError, "GetFileTime" );
  145. return FALSE;
  146. }
  147. if ( bOpenExisting )
  148. {
  149. if ( UrlModificationTime.dwHighDateTime ||
  150. UrlModificationTime.dwLowDateTime )
  151. {
  152. if ( CompareFileTime( &UrlModificationTime, &CreationTime ) > 0 )
  153. {
  154. // UrlModificationTime is newer
  155. CloseHandle( hFile );
  156. LogError("File time of '%S' changed", Path );
  157. m_pQMInfo->result = QM_SERVER_FILE_CHANGED;
  158. return FALSE;
  159. }
  160. }
  161. }
  162. m_hFile = hFile;
  163. m_wupdinfo->FileCreationTime = CreationTime;
  164. m_CurrentOffset = Offset;
  165. return TRUE;
  166. }
  167. BOOL CProgressiveDL::CloseLocalFile()
  168. {
  169. if (m_hFile == INVALID_HANDLE_VALUE)
  170. {
  171. return FALSE;
  172. }
  173. CloseHandle( m_hFile );
  174. m_hFile = INVALID_HANDLE_VALUE;
  175. return TRUE;
  176. }
  177. BOOL
  178. CProgressiveDL::WriteBlockToCache(
  179. LPBYTE lpBuffer,
  180. DWORD dwRead
  181. )
  182. {
  183. DWORD dwWritten = 0;
  184. ASSERT( m_hFile != INVALID_HANDLE_VALUE );
  185. if (! WriteFile( m_hFile,
  186. lpBuffer,
  187. dwRead,
  188. &dwWritten,
  189. NULL)
  190. || (dwRead != dwWritten))
  191. {
  192. SetError( SOURCE_QMGR_FILE, ERROR_STYLE_WIN32, GetLastError(), "WriteFile" );
  193. return FALSE;
  194. }
  195. m_CurrentOffset += dwWritten;
  196. return TRUE;
  197. }
  198. BOOL
  199. CProgressiveDL::SetFileTimes()
  200. {
  201. ASSERT( m_hFile != INVALID_HANDLE_VALUE );
  202. if ( !m_wupdinfo->UrlModificationTime.dwHighDateTime &&
  203. !m_wupdinfo->UrlModificationTime.dwLowDateTime )
  204. {
  205. LogWarning( "Server doesn't support modification times, can't set it on the files." );
  206. return TRUE;
  207. }
  208. if ( !SetFileTime( m_hFile,
  209. &m_wupdinfo->UrlModificationTime,
  210. &m_wupdinfo->UrlModificationTime,
  211. &m_wupdinfo->UrlModificationTime ) )
  212. {
  213. DWORD dwError = GetLastError();
  214. LogError( "Unable to get times on the local file, error %!winerr!", dwError );
  215. SetError( SOURCE_QMGR_FILE, ERROR_STYLE_WIN32, dwError, "SetFileTime" );
  216. return FALSE;
  217. }
  218. return TRUE;
  219. }