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.

290 lines
8.1 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. FILETIME * pFileCreationTime
  23. )
  24. {
  25. HANDLE hFile;
  26. bool bOpenExisting;
  27. if (Offset > 0)
  28. {
  29. // Storing the creation time via SetFileTime doesn't provide ironclad reliability due to granularity problems.
  30. // A tighter condition for a changed server file would be to check the "etag" header if available from the server.
  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. if (dwError == ERROR_INVALID_PARAMETER)
  134. {
  135. dwError = BG_E_INVALID_SERVER_RESPONSE;
  136. }
  137. SetError( SOURCE_QMGR_FILE, ERROR_STYLE_WIN32, dwError, "SetFileTime" );
  138. return FALSE;
  139. }
  140. }
  141. }
  142. if (!GetFileTime( hFile, pFileCreationTime, NULL, NULL ) )
  143. {
  144. DWORD dwError = GetLastError();
  145. CloseHandle( hFile );
  146. LogError( "error %!winerr!, unable to get file creation time", dwError );
  147. SetError( SOURCE_QMGR_FILE, ERROR_STYLE_WIN32, dwError, "GetFileTime" );
  148. return FALSE;
  149. }
  150. if ( bOpenExisting )
  151. {
  152. if ( UrlModificationTime.dwHighDateTime ||
  153. UrlModificationTime.dwLowDateTime )
  154. {
  155. if ( CompareFileTime( &UrlModificationTime, pFileCreationTime ) > 0 )
  156. {
  157. // UrlModificationTime is newer
  158. CloseHandle( hFile );
  159. LogError("File time of '%S' changed", Path );
  160. m_pQMInfo->result = QM_SERVER_FILE_CHANGED;
  161. return FALSE;
  162. }
  163. }
  164. }
  165. m_hFile = hFile;
  166. m_CurrentOffset = Offset;
  167. return TRUE;
  168. }
  169. BOOL CProgressiveDL::CloseLocalFile()
  170. {
  171. if (m_hFile == INVALID_HANDLE_VALUE)
  172. {
  173. return FALSE;
  174. }
  175. CloseHandle( m_hFile );
  176. m_hFile = INVALID_HANDLE_VALUE;
  177. return TRUE;
  178. }
  179. BOOL
  180. CProgressiveDL::WriteBlockToCache(
  181. LPBYTE lpBuffer,
  182. DWORD dwRead
  183. )
  184. {
  185. DWORD dwWritten = 0;
  186. ASSERT( m_hFile != INVALID_HANDLE_VALUE );
  187. if (! WriteFile( m_hFile,
  188. lpBuffer,
  189. dwRead,
  190. &dwWritten,
  191. NULL)
  192. || (dwRead != dwWritten))
  193. {
  194. SetError( SOURCE_QMGR_FILE, ERROR_STYLE_WIN32, GetLastError(), "WriteFile" );
  195. return FALSE;
  196. }
  197. m_CurrentOffset += dwWritten;
  198. return TRUE;
  199. }
  200. BOOL
  201. CProgressiveDL::SetFileTimes()
  202. {
  203. ASSERT( m_hFile != INVALID_HANDLE_VALUE );
  204. if ( !m_wupdinfo->UrlModificationTime.dwHighDateTime &&
  205. !m_wupdinfo->UrlModificationTime.dwLowDateTime )
  206. {
  207. LogWarning( "Server doesn't support modification times, can't set it on the files." );
  208. return TRUE;
  209. }
  210. if ( !SetFileTime( m_hFile,
  211. &m_wupdinfo->UrlModificationTime,
  212. &m_wupdinfo->UrlModificationTime,
  213. &m_wupdinfo->UrlModificationTime ) )
  214. {
  215. DWORD dwError = GetLastError();
  216. LogError( "Unable to get times on the local file, error %!winerr!", dwError );
  217. SetError( SOURCE_QMGR_FILE, ERROR_STYLE_WIN32, dwError, "SetFileTime" );
  218. return FALSE;
  219. }
  220. return TRUE;
  221. }