UpdateCallback.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. // UpdateCallback.cpp
  2. #include "StdAfx.h"
  3. #include "UpdateCallback.h"
  4. #include "Common/StringConvert.h"
  5. #include "Common/IntToString.h"
  6. #include "Common/Defs.h"
  7. #include "Common/ComTry.h"
  8. #include "Windows/PropVariant.h"
  9. #include "../../Common/FileStreams.h"
  10. using namespace NWindows;
  11. CArchiveUpdateCallback::CArchiveUpdateCallback():
  12. Callback(0),
  13. ShareForWrite(false),
  14. StdInMode(false),
  15. DirItems(0),
  16. ArchiveItems(0),
  17. UpdatePairs(0)
  18. {}
  19. STDMETHODIMP CArchiveUpdateCallback::SetTotal(UInt64 size)
  20. {
  21. COM_TRY_BEGIN
  22. return Callback->SetTotal(size);
  23. COM_TRY_END
  24. }
  25. STDMETHODIMP CArchiveUpdateCallback::SetCompleted(const UInt64 *completeValue)
  26. {
  27. COM_TRY_BEGIN
  28. return Callback->SetCompleted(completeValue);
  29. COM_TRY_END
  30. }
  31. STDMETHODIMP CArchiveUpdateCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
  32. {
  33. COM_TRY_BEGIN
  34. return Callback->SetRatioInfo(inSize, outSize);
  35. COM_TRY_END
  36. }
  37. /*
  38. STATPROPSTG kProperties[] =
  39. {
  40. { NULL, kpidPath, VT_BSTR},
  41. { NULL, kpidIsFolder, VT_BOOL},
  42. { NULL, kpidSize, VT_UI8},
  43. { NULL, kpidLastAccessTime, VT_FILETIME},
  44. { NULL, kpidCreationTime, VT_FILETIME},
  45. { NULL, kpidLastWriteTime, VT_FILETIME},
  46. { NULL, kpidAttributes, VT_UI4},
  47. { NULL, kpidIsAnti, VT_BOOL}
  48. };
  49. */
  50. STDMETHODIMP CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG **)
  51. {
  52. return E_NOTIMPL;
  53. /*
  54. return CStatPropEnumerator::CreateEnumerator(kProperties,
  55. sizeof(kProperties) / sizeof(kProperties[0]), enumerator);
  56. */
  57. }
  58. STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 index,
  59. Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive)
  60. {
  61. COM_TRY_BEGIN
  62. RINOK(Callback->CheckBreak());
  63. const CUpdatePair2 &updatePair = (*UpdatePairs)[index];
  64. if(newData != NULL)
  65. *newData = BoolToInt(updatePair.NewData);
  66. if(newProperties != NULL)
  67. *newProperties = BoolToInt(updatePair.NewProperties);
  68. if(indexInArchive != NULL)
  69. {
  70. if (updatePair.ExistInArchive)
  71. {
  72. if (ArchiveItems == 0)
  73. *indexInArchive = updatePair.ArchiveItemIndex;
  74. else
  75. *indexInArchive = (*ArchiveItems)[updatePair.ArchiveItemIndex].IndexInServer;
  76. }
  77. else
  78. *indexInArchive = UInt32(-1);
  79. }
  80. return S_OK;
  81. COM_TRY_END
  82. }
  83. STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
  84. {
  85. COM_TRY_BEGIN
  86. const CUpdatePair2 &updatePair = (*UpdatePairs)[index];
  87. NWindows::NCOM::CPropVariant propVariant;
  88. if (propID == kpidIsAnti)
  89. {
  90. propVariant = updatePair.IsAnti;
  91. propVariant.Detach(value);
  92. return S_OK;
  93. }
  94. if (updatePair.IsAnti)
  95. {
  96. switch(propID)
  97. {
  98. case kpidIsFolder:
  99. case kpidPath:
  100. break;
  101. case kpidSize:
  102. propVariant = (UInt64)0;
  103. propVariant.Detach(value);
  104. return S_OK;
  105. default:
  106. propVariant.Detach(value);
  107. return S_OK;
  108. }
  109. }
  110. if(updatePair.ExistOnDisk)
  111. {
  112. const CDirItem &dirItem = (*DirItems)[updatePair.DirItemIndex];
  113. switch(propID)
  114. {
  115. case kpidPath:
  116. propVariant = dirItem.Name;
  117. break;
  118. case kpidIsFolder:
  119. propVariant = dirItem.IsDirectory();
  120. break;
  121. case kpidSize:
  122. propVariant = dirItem.Size;
  123. break;
  124. case kpidAttributes:
  125. propVariant = dirItem.Attributes;
  126. break;
  127. case kpidLastAccessTime:
  128. propVariant = dirItem.LastAccessTime;
  129. break;
  130. case kpidCreationTime:
  131. propVariant = dirItem.CreationTime;
  132. break;
  133. case kpidLastWriteTime:
  134. propVariant = dirItem.LastWriteTime;
  135. break;
  136. }
  137. }
  138. else
  139. {
  140. if (propID == kpidPath)
  141. {
  142. if (updatePair.NewNameIsDefined)
  143. {
  144. propVariant = updatePair.NewName;
  145. propVariant.Detach(value);
  146. return S_OK;
  147. }
  148. }
  149. if (updatePair.ExistInArchive && Archive)
  150. {
  151. UInt32 indexInArchive;
  152. if (ArchiveItems == 0)
  153. indexInArchive = updatePair.ArchiveItemIndex;
  154. else
  155. indexInArchive = (*ArchiveItems)[updatePair.ArchiveItemIndex].IndexInServer;
  156. return Archive->GetProperty(indexInArchive, propID, value);
  157. }
  158. }
  159. propVariant.Detach(value);
  160. return S_OK;
  161. COM_TRY_END
  162. }
  163. STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream)
  164. {
  165. COM_TRY_BEGIN
  166. const CUpdatePair2 &updatePair = (*UpdatePairs)[index];
  167. if(!updatePair.NewData)
  168. return E_FAIL;
  169. RINOK(Callback->CheckBreak());
  170. RINOK(Callback->Finilize());
  171. if(updatePair.IsAnti)
  172. {
  173. return Callback->GetStream((*ArchiveItems)[updatePair.ArchiveItemIndex].Name, true);
  174. }
  175. const CDirItem &dirItem = (*DirItems)[updatePair.DirItemIndex];
  176. RINOK(Callback->GetStream(dirItem.Name, false));
  177. if(dirItem.IsDirectory())
  178. return S_OK;
  179. if (StdInMode)
  180. {
  181. CStdInFileStream *inStreamSpec = new CStdInFileStream;
  182. CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
  183. *inStream = inStreamLoc.Detach();
  184. }
  185. else
  186. {
  187. CInFileStream *inStreamSpec = new CInFileStream;
  188. CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
  189. UString path = DirPrefix + dirItem.FullPath;
  190. if(!inStreamSpec->OpenShared(path, ShareForWrite))
  191. {
  192. return Callback->OpenFileError(path, ::GetLastError());
  193. }
  194. *inStream = inStreamLoc.Detach();
  195. }
  196. return S_OK;
  197. COM_TRY_END
  198. }
  199. STDMETHODIMP CArchiveUpdateCallback::SetOperationResult(Int32 operationResult)
  200. {
  201. COM_TRY_BEGIN
  202. return Callback->SetOperationResult(operationResult);
  203. COM_TRY_END
  204. }
  205. STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size)
  206. {
  207. if (VolumesSizes.Size() == 0)
  208. return S_FALSE;
  209. if (index >= (UInt32)VolumesSizes.Size())
  210. index = VolumesSizes.Size() - 1;
  211. *size = VolumesSizes[index];
  212. return S_OK;
  213. }
  214. STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream)
  215. {
  216. COM_TRY_BEGIN
  217. wchar_t temp[32];
  218. ConvertUInt64ToString(index + 1, temp);
  219. UString res = temp;
  220. while (res.Length() < 2)
  221. res = UString(L'0') + res;
  222. UString fileName = VolName;
  223. fileName += L'.';
  224. fileName += res;
  225. fileName += VolExt;
  226. COutFileStream *streamSpec = new COutFileStream;
  227. CMyComPtr<ISequentialOutStream> streamLoc(streamSpec);
  228. if(!streamSpec->Create(fileName, false))
  229. return ::GetLastError();
  230. *volumeStream = streamLoc.Detach();
  231. return S_OK;
  232. COM_TRY_END
  233. }
  234. STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)
  235. {
  236. COM_TRY_BEGIN
  237. return Callback->CryptoGetTextPassword2(passwordIsDefined, password);
  238. COM_TRY_END
  239. }