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.

464 lines
12 KiB

  1. // Copyright (C) 1997 Microsoft Corporation. All rights reserved.
  2. #include "stdafx.h"
  3. #include "titleinfo.h"
  4. #define STRSAFE_NO_DEPRECATE
  5. #include <strsafe.h>
  6. ////////////////////////////////////////////////////////////////////////////////
  7. static const WCHAR txtwUncompressed[] = L"uncompressed";
  8. typedef struct tagITSControlData
  9. {
  10. UINT cdwFollowing; // Must be 6 or 13
  11. DWORD cdwITFS_Control; // Must be 5
  12. DWORD dwMagicITS; // Must be MAGIC_ITSFS_CONTROL (see below)
  13. DWORD dwVersionITS; // Must be 1
  14. DWORD cbDirectoryBlock; // Size in bytes of directory blocks (Default is 8192)
  15. DWORD cMinCacheEntries; // Least upper bound on the number of directory blocks
  16. // which we'll cache in memory. (Default is 20)
  17. DWORD fFlags; // Control bit flags (see below).
  18. // Default value is fDefaultIsCompression.
  19. UINT cdwControlData; // Must be 6
  20. DWORD dwLZXMagic; // Must be LZX_MAGIC (see below)
  21. DWORD dwVersion; // Must be 2
  22. DWORD dwMulResetBlock; // Number of blocks between compression resets. (Default: 4)
  23. DWORD dwMulWindowSize; // Maximum number of blocks kept in data history (Default: 4)
  24. DWORD dwMulSecondPartition; // Granularity in blocks of sliding history(Default: 2)
  25. DWORD dwOptions; // Option flags (Default: fOptimizeCodeStreams)
  26. } ITCD;
  27. ////////////////////////////////////////////////////////////////////////////////
  28. CFileSystem::CFileSystem()
  29. {
  30. m_pITStorage = NULL;
  31. m_pStorage = NULL;
  32. m_szPathName[0] = 0;
  33. }
  34. CFileSystem::~CFileSystem()
  35. {
  36. ReleaseObjPtr( m_pStorage );
  37. ReleaseObjPtr( m_pITStorage );
  38. }
  39. HRESULT CFileSystem::Init()
  40. {
  41. if(m_pITStorage) return S_OK;
  42. return ::CoCreateInstance( CLSID_ITStorage, NULL, CLSCTX_INPROC_SERVER, IID_ITStorage, (VOID**)&m_pITStorage );
  43. }
  44. HRESULT CFileSystem::Create( LPCSTR szPathName )
  45. {
  46. USES_CONVERSION;
  47. HRESULT hr;
  48. ITCD itcd;
  49. if(!m_pITStorage || m_pStorage) return E_FAIL;
  50. itcd.cdwFollowing = 13;
  51. itcd.cdwITFS_Control = 5;
  52. itcd.dwMagicITS = MAGIC_ITSFS_CONTROL;
  53. itcd.dwVersionITS = 1;
  54. itcd.cbDirectoryBlock = 4096; // default = 8192
  55. itcd.cMinCacheEntries = 10; // default = 20
  56. itcd.fFlags = 1; // 0 == Uncompressed, 1 == Compressed.
  57. itcd.cdwControlData = 6;
  58. itcd.dwLZXMagic = LZX_MAGIC;
  59. itcd.dwVersion = 2;
  60. itcd.dwMulResetBlock = 2; // Default = 4
  61. itcd.dwMulWindowSize = 2; // Default = 4
  62. itcd.dwMulSecondPartition = 1; // Default = 2
  63. itcd.dwOptions = 0; // Default = fOptimizeCodeStreams
  64. m_pITStorage->SetControlData( PITS_Control_Data(&itcd) );
  65. hr = m_pITStorage->StgCreateDocfile( A2W(szPathName), STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_DIRECT, 0, &m_pStorage );
  66. if(FAILED(hr)) return hr;
  67. StringCchCopyA( (LPSTR)m_szPathName, ARRAYSIZE(m_szPathName), szPathName );
  68. return S_OK;
  69. }
  70. // NOTE: The below function is required for the ITIR full-text indexer to
  71. // initialize. I'm working to find out why this is and what impact
  72. // the below has on the file system.
  73. //
  74. HRESULT CFileSystem::CreateUncompressed( LPCSTR szPathName )
  75. {
  76. USES_CONVERSION;
  77. HRESULT hr;
  78. ITCD itcd;
  79. if(!m_pITStorage || m_pStorage) return E_FAIL;
  80. itcd.cdwFollowing = 6;
  81. itcd.cdwITFS_Control = 5;
  82. itcd.dwMagicITS = MAGIC_ITSFS_CONTROL;
  83. itcd.dwVersionITS = 1;
  84. itcd.cbDirectoryBlock = 8192; // default = 8192
  85. itcd.cMinCacheEntries = 20; // default = 20
  86. itcd.fFlags = 0; // 0 == Uncompressed, 1 == Compressed.
  87. m_pITStorage->SetControlData( PITS_Control_Data(&itcd) );
  88. hr = m_pITStorage->StgCreateDocfile( A2W(szPathName), STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_DIRECT, 0, &m_pStorage);
  89. if(FAILED(hr)) return hr;
  90. StringCchCopyA( (LPSTR) m_szPathName, ARRAYSIZE(m_szPathName), szPathName );
  91. return S_OK;
  92. }
  93. HRESULT CFileSystem::Open( LPCWSTR wszPathName, DWORD dwAccess )
  94. {
  95. HRESULT hr = S_OK;
  96. if(!m_pITStorage || m_pStorage) return E_FAIL;
  97. // force access modes
  98. if((dwAccess & STGM_WRITE ) ||
  99. (dwAccess & STGM_READWRITE) )
  100. {
  101. dwAccess &= ~STGM_WRITE;
  102. dwAccess |= STGM_READWRITE | STGM_SHARE_EXCLUSIVE;
  103. }
  104. else
  105. {
  106. dwAccess |= STGM_SHARE_DENY_WRITE;
  107. }
  108. hr = m_pITStorage->StgOpenStorage( wszPathName, NULL, dwAccess, NULL, 0, &m_pStorage );
  109. if(FAILED(hr)) return hr;
  110. // this will break the deletesub function, but we don't need it here
  111. //
  112. m_szPathName[0] = 0;
  113. return hr;
  114. }
  115. HRESULT CFileSystem::Compact( LPCSTR szPathName )
  116. {
  117. USES_CONVERSION;
  118. m_pITStorage->Compact( A2W(szPathName), COMPACT_DATA_AND_PATH );
  119. return S_OK;
  120. }
  121. HRESULT CFileSystem::Close()
  122. {
  123. ReleaseObjPtr( m_pStorage );
  124. return S_OK;
  125. }
  126. //////////////////////////////////////////////////////////////////////////////////////////////
  127. //
  128. // Here are a set of "sub" file I/O calls.
  129. //
  130. //
  131. CSubFileSystem::CSubFileSystem( CFileSystem* pFS )
  132. {
  133. m_pFS = pFS;
  134. m_pStorage = NULL;
  135. m_pStream = NULL;
  136. m_szPathName[0] = 0;
  137. }
  138. CSubFileSystem::~CSubFileSystem()
  139. {
  140. ReleaseStorage();
  141. ReleaseObjPtr( m_pStream );
  142. }
  143. void CSubFileSystem::ReleaseStorage()
  144. {
  145. if(m_pStorage && (m_pStorage != m_pFS->m_pStorage))
  146. {
  147. m_pStorage->Release(); m_pStorage = NULL;
  148. }
  149. }
  150. HRESULT CSubFileSystem::CreateSub( LPCSTR szPathName )
  151. {
  152. USES_CONVERSION;
  153. HRESULT hr;
  154. LPCSTR szFilePortion;
  155. if(m_pStorage || m_pStream) return E_FAIL;
  156. if((szFilePortion = FindFilePortion( szPathName )) && szFilePortion > szPathName)
  157. {
  158. CHAR szPath[MAX_PATH];
  159. LPCWSTR wszStorage;
  160. StringCchCopyA( szPath, ARRAYSIZE(szPath), szPathName ); szPath[(szFilePortion - 1) - szPathName] = '\0';
  161. wszStorage = A2W( szPath );
  162. hr = m_pFS->m_pStorage->OpenStorage( wszStorage, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &m_pStorage );
  163. if(FAILED(hr) || !m_pStorage) // storage didn't exist, so create it
  164. {
  165. hr = m_pFS->m_pStorage->CreateStorage( wszStorage, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &m_pStorage );
  166. if(FAILED(hr)) return hr;
  167. }
  168. }
  169. else // no folder, so store the file in the root
  170. {
  171. m_pStorage = m_pFS->m_pStorage;
  172. szFilePortion = szPathName;
  173. }
  174. hr = m_pStorage->CreateStream( A2W(szFilePortion), STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &m_pStream );
  175. if(FAILED(hr))
  176. {
  177. ReleaseStorage();
  178. return hr;
  179. }
  180. // Needed for delete.
  181. StringCchCopyA( m_szPathName, ARRAYSIZE(m_szPathName), szFilePortion );
  182. return S_OK;
  183. }
  184. HRESULT CSubFileSystem::CreateUncompressedSub( LPCSTR szPathName )
  185. {
  186. USES_CONVERSION;
  187. HRESULT hr;
  188. LPCSTR szFilePortion;
  189. IStorageITEx* pIStorageEx;
  190. if(m_pStorage || m_pStream) return E_FAIL;
  191. if((szFilePortion = FindFilePortion( szPathName )) && szFilePortion > szPathName)
  192. {
  193. CHAR szPath[MAX_PATH];
  194. LPCWSTR wszStorage;
  195. StringCchCopyA( szPath, ARRAYSIZE(szPath), szPathName ); szPath[(szFilePortion - 1) - szPathName] = '\0';
  196. wszStorage = A2W(szPath);
  197. hr = m_pFS->m_pStorage->OpenStorage( wszStorage, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &m_pStorage );
  198. if(FAILED(hr) || !m_pStorage) // storage didn't exist, so create it
  199. {
  200. hr = m_pFS->m_pStorage->CreateStorage( wszStorage, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &m_pStorage );
  201. if(FAILED(hr))
  202. {
  203. return hr;
  204. }
  205. }
  206. }
  207. else // no folder, so store the file in the root
  208. {
  209. m_pStorage = m_pFS->m_pStorage;
  210. szFilePortion = szPathName;
  211. }
  212. if(FAILED(hr = m_pStorage->QueryInterface( IID_IStorageITEx, (void**)&pIStorageEx )))
  213. {
  214. return hr; // The QI call above should work!
  215. }
  216. hr = pIStorageEx->CreateStreamITEx( A2W(szFilePortion), txtwUncompressed, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, (IStreamITEx**)&m_pStream );
  217. ReleaseObjPtr( pIStorageEx );
  218. if(FAILED(hr))
  219. {
  220. ReleaseStorage();
  221. return hr;
  222. }
  223. // Needed for delete.
  224. StringCchCopyA( m_szPathName, ARRAYSIZE(m_szPathName), szFilePortion );
  225. return S_OK;
  226. }
  227. HRESULT CSubFileSystem::CreateSystemFile( LPCSTR szPathName )
  228. {
  229. USES_CONVERSION;
  230. HRESULT hr;
  231. m_pStorage = m_pFS->m_pStorage;
  232. hr = m_pStorage->CreateStream( A2W(szPathName), STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &m_pStream );
  233. if(FAILED(hr)) return hr;
  234. // Needed for delete.
  235. StringCchCopyA( m_szPathName, ARRAYSIZE(m_szPathName), szPathName );
  236. return S_OK;
  237. }
  238. HRESULT CSubFileSystem::CreateUncompressedSystemFile( LPCSTR szPathName )
  239. {
  240. USES_CONVERSION;
  241. HRESULT hr;
  242. IStorageITEx* pIStorageEx;
  243. m_pStorage = m_pFS->m_pStorage;
  244. if(FAILED(hr = m_pStorage->QueryInterface(IID_IStorageITEx, (void**)&pIStorageEx )))
  245. {
  246. return hr; // The QI call above should work!
  247. }
  248. hr = pIStorageEx->CreateStreamITEx( A2W(szPathName), txtwUncompressed, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, (IStreamITEx**)&m_pStream );
  249. ReleaseObjPtr( pIStorageEx );
  250. if(FAILED(hr)) return hr;
  251. // Needed for delete.
  252. StringCchCopyA( m_szPathName, ARRAYSIZE(m_szPathName), szPathName );
  253. return S_OK;
  254. }
  255. HRESULT CSubFileSystem::OpenSub( LPCSTR szPathName, DWORD dwAccess )
  256. {
  257. USES_CONVERSION;
  258. HRESULT hr;
  259. PCSTR szFilePortion;
  260. if(m_pStorage || m_pStream) return E_FAIL;
  261. // force access modes
  262. if((dwAccess & STGM_WRITE ) ||
  263. (dwAccess & STGM_READWRITE) )
  264. {
  265. dwAccess &= ~STGM_WRITE;
  266. dwAccess |= STGM_READWRITE | STGM_SHARE_EXCLUSIVE;
  267. }
  268. else
  269. {
  270. dwAccess |= STGM_SHARE_DENY_WRITE;
  271. }
  272. if((szFilePortion = FindFilePortion(szPathName)) && szFilePortion > szPathName + 2) // +2 to support / && ./
  273. {
  274. CHAR szPath[MAX_PATH];
  275. StringCchCopyA( szPath, ARRAYSIZE(szPath), szPathName ); szPath[(szFilePortion - 1) - szPathName] = '\0';
  276. hr = m_pFS->m_pStorage->OpenStorage( A2W(szPath), NULL, dwAccess, NULL, 0, &m_pStorage);
  277. if(FAILED(hr)) return hr;
  278. }
  279. else // no folder, so store the file in the root
  280. {
  281. m_pStorage = m_pFS->m_pStorage;
  282. szFilePortion = szPathName;
  283. }
  284. hr = m_pStorage->OpenStream( A2W(szFilePortion), NULL, dwAccess, 0, &m_pStream);
  285. if(FAILED(hr))
  286. {
  287. ReleaseStorage();
  288. return hr;
  289. }
  290. // Needed for delete.
  291. StringCchCopyA( m_szPathName, ARRAYSIZE(m_szPathName), szFilePortion );
  292. return S_OK;
  293. }
  294. ULONG CSubFileSystem::WriteSub( const void* pData, int cb )
  295. {
  296. HRESULT hr;
  297. ULONG cbWritten;
  298. if(!m_pStorage || !m_pStream) return (ULONG)-1;
  299. hr = m_pStream->Write( pData, cb, &cbWritten );
  300. if(FAILED(hr) || (cbWritten != (ULONG)cb))
  301. {
  302. return (ULONG)-1;
  303. }
  304. // REVIEW: 30-May-1997 [ralphw] Why are we returning this? We fail if
  305. // we don't write cb bytes.
  306. return cbWritten;
  307. }
  308. /*
  309. * iOrigin:
  310. * 0 = Seek from beginning.
  311. * 1 = Seek from current.
  312. * 2 = Seek from end.
  313. */
  314. ULONG CSubFileSystem::SeekSub( int cb, int iOrigin )
  315. {
  316. HRESULT hr;
  317. LARGE_INTEGER liCount = { 0, 0 };
  318. ULARGE_INTEGER liNewPos;
  319. if(!m_pStorage || !m_pStream) return (ULONG)-1;
  320. liCount.LowPart = cb;
  321. if(FAILED(hr = m_pStream->Seek( liCount, iOrigin, &liNewPos )))
  322. {
  323. return (ULONG)-1;
  324. }
  325. return liNewPos.LowPart;
  326. }
  327. //
  328. // Pre-allocate the size of the stream.
  329. //
  330. HRESULT CSubFileSystem::SetSize( unsigned uSize )
  331. {
  332. HRESULT hr;
  333. ULARGE_INTEGER liSize = {0,0};
  334. if(!m_pStorage || !m_pStream) return E_FAIL;
  335. liSize.LowPart = uSize;
  336. return m_pStream->SetSize( liSize );
  337. }
  338. //
  339. // Delete substorage.
  340. //
  341. HRESULT CSubFileSystem::DeleteSub()
  342. {
  343. USES_CONVERSION;
  344. HRESULT hr = S_OK;
  345. if(m_pStorage)
  346. {
  347. // Release the stream.
  348. ReleaseObjPtr( m_pStream );
  349. // Now delete the storage.
  350. hr = m_pStorage->DestroyElement( A2W(m_szPathName) );
  351. // Get back to the constructor state.
  352. ReleaseStorage();
  353. }
  354. return hr;
  355. }