ArchiveOpenCallback.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. // ArchiveOpenCallback.cpp
  2. #include "StdAfx.h"
  3. #include "ArchiveOpenCallback.h"
  4. #include "Common/StringConvert.h"
  5. #include "Common/ComTry.h"
  6. #include "Windows/PropVariant.h"
  7. #include "../../Common/FileStreams.h"
  8. using namespace NWindows;
  9. STDMETHODIMP COpenCallbackImp::SetTotal(const UInt64 *files, const UInt64 *bytes)
  10. {
  11. COM_TRY_BEGIN
  12. if (!Callback)
  13. return S_OK;
  14. return Callback->SetTotal(files, bytes);
  15. COM_TRY_END
  16. }
  17. STDMETHODIMP COpenCallbackImp::SetCompleted(const UInt64 *files, const UInt64 *bytes)
  18. {
  19. COM_TRY_BEGIN
  20. if (!Callback)
  21. return S_OK;
  22. return Callback->SetTotal(files, bytes);
  23. COM_TRY_END
  24. }
  25. STDMETHODIMP COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value)
  26. {
  27. COM_TRY_BEGIN
  28. NCOM::CPropVariant propVariant;
  29. if (_subArchiveMode)
  30. {
  31. switch(propID)
  32. {
  33. case kpidName:
  34. propVariant = _subArchiveName;
  35. break;
  36. }
  37. propVariant.Detach(value);
  38. return S_OK;
  39. }
  40. switch(propID)
  41. {
  42. case kpidName:
  43. propVariant = _fileInfo.Name;
  44. break;
  45. case kpidIsFolder:
  46. propVariant = _fileInfo.IsDirectory();
  47. break;
  48. case kpidSize:
  49. propVariant = _fileInfo.Size;
  50. break;
  51. case kpidAttributes:
  52. propVariant = (UInt32)_fileInfo.Attributes;
  53. break;
  54. case kpidLastAccessTime:
  55. propVariant = _fileInfo.LastAccessTime;
  56. break;
  57. case kpidCreationTime:
  58. propVariant = _fileInfo.CreationTime;
  59. break;
  60. case kpidLastWriteTime:
  61. propVariant = _fileInfo.LastWriteTime;
  62. break;
  63. }
  64. propVariant.Detach(value);
  65. return S_OK;
  66. COM_TRY_END
  67. }
  68. int COpenCallbackImp::FindName(const UString &name)
  69. {
  70. for (int i = 0; i < FileNames.Size(); i++)
  71. if (name.CompareNoCase(FileNames[i]) == 0)
  72. return i;
  73. return -1;
  74. }
  75. struct CInFileStreamVol: public CInFileStream
  76. {
  77. UString Name;
  78. COpenCallbackImp *OpenCallbackImp;
  79. CMyComPtr<IArchiveOpenCallback> OpenCallbackRef;
  80. ~CInFileStreamVol()
  81. {
  82. int index = OpenCallbackImp->FindName(Name);
  83. if (index >= 0)
  84. OpenCallbackImp->FileNames.Delete(index);
  85. }
  86. };
  87. STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name, IInStream **inStream)
  88. {
  89. COM_TRY_BEGIN
  90. if (_subArchiveMode)
  91. return S_FALSE;
  92. if (Callback)
  93. {
  94. RINOK(Callback->CheckBreak());
  95. }
  96. *inStream = NULL;
  97. UString fullPath = _folderPrefix + name;
  98. if (!NFile::NFind::FindFile(fullPath, _fileInfo))
  99. return S_FALSE;
  100. if (_fileInfo.IsDirectory())
  101. return S_FALSE;
  102. CInFileStreamVol *inFile = new CInFileStreamVol;
  103. CMyComPtr<IInStream> inStreamTemp = inFile;
  104. if (!inFile->Open(fullPath))
  105. return ::GetLastError();
  106. *inStream = inStreamTemp.Detach();
  107. inFile->Name = name;
  108. inFile->OpenCallbackImp = this;
  109. inFile->OpenCallbackRef = this;
  110. FileNames.Add(name);
  111. TotalSize += _fileInfo.Size;
  112. return S_OK;
  113. COM_TRY_END
  114. }
  115. #ifndef _NO_CRYPTO
  116. STDMETHODIMP COpenCallbackImp::CryptoGetTextPassword(BSTR *password)
  117. {
  118. COM_TRY_BEGIN
  119. if (!Callback)
  120. return E_NOTIMPL;
  121. return Callback->CryptoGetTextPassword(password);
  122. COM_TRY_END
  123. }
  124. #endif