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.

163 lines
3.3 KiB

  1. // Copyright (C) 1997 Microsoft Corporation. All rights reserved.
  2. #include "header.h"
  3. #include "state.h"
  4. #include "fs.h"
  5. #include "hhtypes.h"
  6. CState::CState(PCSTR pszChm)
  7. {
  8. m_pfs = NULL;
  9. m_pSubFS = NULL;
  10. // Make sure we have a name we can use to create a sub file with
  11. PCSTR pszTmp = StrChr(pszChm, CH_COLON);
  12. if (pszTmp)
  13. pszChm = pszTmp + 1;
  14. pszTmp = strstr(pszChm, "//");
  15. if (pszTmp)
  16. pszChm = pszTmp + 2;
  17. pszTmp = strstr(pszChm, "\\\\");
  18. if (pszTmp)
  19. pszChm = pszTmp + 2;
  20. m_cszChm = pszChm;
  21. }
  22. HRESULT CState::Open(PCSTR pszName, DWORD dwAccess)
  23. {
  24. HRESULT hr;
  25. lstrcpy(m_pszName, pszName);
  26. m_dwAccess = dwAccess;
  27. hr = _IOpen();
  28. Close();
  29. return hr;
  30. }
  31. HRESULT CState::_IOpen()
  32. {
  33. char szPath[MAX_URL];
  34. HRESULT hr;
  35. // force access modes
  36. if( (m_dwAccess & STGM_WRITE) || (m_dwAccess & STGM_READWRITE) ) {
  37. m_dwAccess &= ~STGM_WRITE;
  38. m_dwAccess |= STGM_READWRITE | STGM_SHARE_EXCLUSIVE;
  39. }
  40. else
  41. m_dwAccess |= STGM_SHARE_DENY_WRITE;
  42. if (!m_pfs) {
  43. GetRegWindowsDirectory(szPath);
  44. AddTrailingBackslash(szPath);
  45. HHGetUserDataPathname( szPath, sizeof(szPath) );
  46. m_pfs = new CFileSystem;
  47. m_pfs->Init();
  48. hr = m_pfs->Open(szPath, STGM_READWRITE | STGM_SHARE_EXCLUSIVE );
  49. if(hr == STG_E_SHAREVIOLATION)
  50. {
  51. Sleep(200);
  52. hr = m_pfs->Open(szPath, STGM_READWRITE | STGM_SHARE_EXCLUSIVE );
  53. if(FAILED(hr))
  54. {
  55. delete m_pfs;
  56. m_pfs = NULL;
  57. return hr;
  58. }
  59. }
  60. if (FAILED(hr))
  61. hr = m_pfs->CreateUncompressed(szPath);
  62. if (FAILED(hr)) {
  63. delete m_pfs;
  64. m_pfs = NULL;
  65. return hr;
  66. }
  67. }
  68. if (m_pSubFS)
  69. delete m_pSubFS; // close any previous subfile
  70. m_pSubFS = new CSubFileSystem(m_pfs);
  71. strcpy(szPath, m_cszChm);
  72. AddTrailingBackslash(szPath);
  73. strcat(szPath, m_pszName);
  74. hr = m_pSubFS->OpenSub(szPath, m_dwAccess);
  75. if (FAILED(hr) && ((m_dwAccess & STGM_WRITE) || (m_dwAccess & STGM_READWRITE)) )
  76. hr = m_pSubFS->CreateUncompressedSub(szPath);
  77. if (FAILED(hr)) {
  78. delete m_pSubFS;
  79. m_pSubFS = NULL;
  80. }
  81. return hr;
  82. }
  83. HRESULT CState::Read(void* pData, DWORD cb, DWORD* pcbRead)
  84. {
  85. HRESULT hr;
  86. _IOpen();
  87. if (!m_pSubFS)
  88. return STG_E_INVALIDHANDLE;
  89. hr = m_pSubFS->ReadSub(pData, cb, pcbRead);
  90. Close();
  91. return hr;
  92. }
  93. DWORD CState::Write(const void* pData, DWORD cb)
  94. {
  95. HRESULT hr;
  96. _IOpen();
  97. if (!m_pSubFS)
  98. return STG_E_INVALIDHANDLE;
  99. hr = m_pSubFS->WriteSub(pData, cb);
  100. Close();
  101. return hr;
  102. }
  103. CState::~CState()
  104. {
  105. if (m_pSubFS)
  106. delete m_pSubFS; // close any previous subfile
  107. if (m_pfs)
  108. delete m_pfs;
  109. }
  110. void CState::Close()
  111. {
  112. if (m_pSubFS) {
  113. delete m_pSubFS; // close any previous subfile
  114. m_pSubFS = NULL;
  115. }
  116. if (m_pfs)
  117. {
  118. delete m_pfs;
  119. m_pfs = NULL;
  120. }
  121. }
  122. ///////////////////////////////////////////////////////////
  123. //
  124. //
  125. //
  126. HRESULT
  127. CState::Delete()
  128. {
  129. HRESULT hr = S_FALSE ;
  130. _IOpen();
  131. if (m_pSubFS)
  132. {
  133. hr = m_pSubFS->DeleteSub() ; // Removes the element from the state.
  134. // Overkill, but what the hey!
  135. Close() ;
  136. }
  137. Close();
  138. return hr ;
  139. }