• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // UpdateCallbackConsole.cpp
2 
3 #include "StdAfx.h"
4 
5 #include "../../../Common/IntToString.h"
6 
7 #include "../../../Windows/ErrorMsg.h"
8 #include "../../../Windows/FileName.h"
9 
10 #ifndef _7ZIP_ST
11 #include "../../../Windows/Synchronization.h"
12 #endif
13 
14 // #include "../Common/PropIDUtils.h"
15 
16 #include "ConsoleClose.h"
17 #include "UserInputUtils.h"
18 #include "UpdateCallbackConsole.h"
19 
20 using namespace NWindows;
21 
22 #ifndef _7ZIP_ST
23 static NSynchronization::CCriticalSection g_CriticalSection;
24 #define MT_LOCK NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
25 #else
26 #define MT_LOCK
27 #endif
28 
29 static const wchar_t * const kEmptyFileAlias = L"[Content]";
30 
31 static const char * const kOpenArchiveMessage = "Open archive: ";
32 static const char * const kCreatingArchiveMessage = "Creating archive: ";
33 static const char * const kUpdatingArchiveMessage = "Updating archive: ";
34 static const char * const kScanningMessage = "Scanning the drive:";
35 
36 static const char * const kError = "ERROR: ";
37 static const char * const kWarning = "WARNING: ";
38 
CheckBreak2()39 static HRESULT CheckBreak2()
40 {
41   return NConsoleClose::TestBreakSignal() ? E_ABORT : S_OK;
42 }
43 
44 HRESULT Print_OpenArchive_Props(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink);
45 HRESULT Print_OpenArchive_Error(CStdOutStream &so, const CCodecs *codecs, const CArchiveLink &arcLink);
46 
47 void PrintErrorFlags(CStdOutStream &so, const char *s, UInt32 errorFlags);
48 
49 void Print_ErrorFormatIndex_Warning(CStdOutStream *_so, const CCodecs *codecs, const CArc &arc);
50 
OpenResult(const CCodecs * codecs,const CArchiveLink & arcLink,const wchar_t * name,HRESULT result)51 HRESULT CUpdateCallbackConsole::OpenResult(
52     const CCodecs *codecs, const CArchiveLink &arcLink,
53     const wchar_t *name, HRESULT result)
54 {
55   ClosePercents2();
56 
57   FOR_VECTOR (level, arcLink.Arcs)
58   {
59     const CArc &arc = arcLink.Arcs[level];
60     const CArcErrorInfo &er = arc.ErrorInfo;
61 
62     UInt32 errorFlags = er.GetErrorFlags();
63 
64     if (errorFlags != 0 || !er.ErrorMessage.IsEmpty())
65     {
66       if (_se)
67       {
68         *_se << endl;
69         if (level != 0)
70           *_se << arc.Path << endl;
71       }
72 
73       if (errorFlags != 0)
74       {
75         if (_se)
76           PrintErrorFlags(*_se, "ERRORS:", errorFlags);
77       }
78 
79       if (!er.ErrorMessage.IsEmpty())
80       {
81         if (_se)
82           *_se << "ERRORS:" << endl << er.ErrorMessage << endl;
83       }
84 
85       if (_se)
86       {
87         *_se << endl;
88         _se->Flush();
89       }
90     }
91 
92     UInt32 warningFlags = er.GetWarningFlags();
93 
94     if (warningFlags != 0 || !er.WarningMessage.IsEmpty())
95     {
96       if (_so)
97       {
98         *_so << endl;
99         if (level != 0)
100           *_so << arc.Path << endl;
101       }
102 
103       if (warningFlags != 0)
104       {
105         if (_so)
106           PrintErrorFlags(*_so, "WARNINGS:", warningFlags);
107       }
108 
109       if (!er.WarningMessage.IsEmpty())
110       {
111         if (_so)
112           *_so << "WARNINGS:" << endl << er.WarningMessage << endl;
113       }
114 
115       if (_so)
116       {
117         *_so << endl;
118         if (NeedFlush)
119           _so->Flush();
120       }
121     }
122 
123 
124     if (er.ErrorFormatIndex >= 0)
125     {
126       if (_so)
127       {
128         Print_ErrorFormatIndex_Warning(_so, codecs, arc);
129         if (NeedFlush)
130           _so->Flush();
131       }
132     }
133   }
134 
135   if (result == S_OK)
136   {
137     if (_so)
138     {
139       RINOK(Print_OpenArchive_Props(*_so, codecs, arcLink));
140       *_so << endl;
141     }
142   }
143   else
144   {
145     if (_so)
146       _so->Flush();
147     if (_se)
148     {
149       *_se << kError;
150       _se->NormalizePrint_wstr(name);
151       *_se << endl;
152       HRESULT res = Print_OpenArchive_Error(*_se, codecs, arcLink);
153       RINOK(res);
154       _se->Flush();
155     }
156   }
157 
158   return S_OK;
159 }
160 
StartScanning()161 HRESULT CUpdateCallbackConsole::StartScanning()
162 {
163   if (_so)
164     *_so << kScanningMessage << endl;
165   _percent.Command = "Scan ";
166   return S_OK;
167 }
168 
ScanProgress(const CDirItemsStat & st,const FString & path,bool)169 HRESULT CUpdateCallbackConsole::ScanProgress(const CDirItemsStat &st, const FString &path, bool /* isDir */)
170 {
171   if (NeedPercents())
172   {
173     _percent.Files = st.NumDirs + st.NumFiles + st.NumAltStreams;
174     _percent.Completed = st.GetTotalBytes();
175     _percent.FileName = fs2us(path);
176     _percent.Print();
177   }
178 
179   return CheckBreak();
180 }
181 
CommonError(const FString & path,DWORD systemError,bool isWarning)182 void CCallbackConsoleBase::CommonError(const FString &path, DWORD systemError, bool isWarning)
183 {
184   ClosePercents2();
185 
186   if (_se)
187   {
188     if (_so)
189       _so->Flush();
190 
191     *_se << endl << (isWarning ? kWarning : kError)
192         << NError::MyFormatMessage(systemError)
193         << endl;
194     _se->NormalizePrint_UString(fs2us(path));
195     *_se << endl << endl;
196     _se->Flush();
197   }
198 }
199 
200 /*
201 void CCallbackConsoleBase::CommonError(const char *message)
202 {
203   ClosePercents2();
204 
205   if (_se)
206   {
207     if (_so)
208       _so->Flush();
209 
210     *_se << endl << kError << message << endl;
211     _se->Flush();
212   }
213 }
214 */
215 
216 
ScanError_Base(const FString & path,DWORD systemError)217 HRESULT CCallbackConsoleBase::ScanError_Base(const FString &path, DWORD systemError)
218 {
219   MT_LOCK
220 
221   ScanErrors.AddError(path, systemError);
222   CommonError(path, systemError, true);
223 
224   return S_OK;
225 }
226 
OpenFileError_Base(const FString & path,DWORD systemError)227 HRESULT CCallbackConsoleBase::OpenFileError_Base(const FString &path, DWORD systemError)
228 {
229   MT_LOCK
230   FailedFiles.AddError(path, systemError);
231   NumNonOpenFiles++;
232   /*
233   if (systemError == ERROR_SHARING_VIOLATION)
234   {
235   */
236     CommonError(path, systemError, true);
237     return S_FALSE;
238   /*
239   }
240   return systemError;
241   */
242 }
243 
ReadingFileError_Base(const FString & path,DWORD systemError)244 HRESULT CCallbackConsoleBase::ReadingFileError_Base(const FString &path, DWORD systemError)
245 {
246   MT_LOCK
247   CommonError(path, systemError, false);
248   return HRESULT_FROM_WIN32(systemError);
249 }
250 
ScanError(const FString & path,DWORD systemError)251 HRESULT CUpdateCallbackConsole::ScanError(const FString &path, DWORD systemError)
252 {
253   return ScanError_Base(path, systemError);
254 }
255 
256 
PrintPropPair(AString & s,const char * name,UInt64 val)257 static void PrintPropPair(AString &s, const char *name, UInt64 val)
258 {
259   char temp[32];
260   ConvertUInt64ToString(val, temp);
261   s += name;
262   s += ": ";
263   s += temp;
264 }
265 
266 void PrintSize_bytes_Smart(AString &s, UInt64 val);
267 void Print_DirItemsStat(AString &s, const CDirItemsStat &st);
268 void Print_DirItemsStat2(AString &s, const CDirItemsStat2 &st);
269 
FinishScanning(const CDirItemsStat & st)270 HRESULT CUpdateCallbackConsole::FinishScanning(const CDirItemsStat &st)
271 {
272   if (NeedPercents())
273   {
274     _percent.ClosePrint(true);
275     _percent.ClearCurState();
276   }
277 
278   if (_so)
279   {
280     AString s;
281     Print_DirItemsStat(s, st);
282     *_so << s << endl << endl;
283   }
284   return S_OK;
285 }
286 
287 static const char * const k_StdOut_ArcName = "StdOut";
288 
StartOpenArchive(const wchar_t * name)289 HRESULT CUpdateCallbackConsole::StartOpenArchive(const wchar_t *name)
290 {
291   if (_so)
292   {
293     *_so << kOpenArchiveMessage;
294     if (name)
295       *_so << name;
296     else
297       *_so << k_StdOut_ArcName;
298     *_so << endl;
299   }
300   return S_OK;
301 }
302 
StartArchive(const wchar_t * name,bool updating)303 HRESULT CUpdateCallbackConsole::StartArchive(const wchar_t *name, bool updating)
304 {
305   if (NeedPercents())
306     _percent.ClosePrint(true);
307 
308   _percent.ClearCurState();
309   NumNonOpenFiles = 0;
310 
311   if (_so)
312   {
313     *_so << (updating ? kUpdatingArchiveMessage : kCreatingArchiveMessage);
314     if (name)
315       _so->NormalizePrint_wstr(name);
316     else
317       *_so << k_StdOut_ArcName;
318    *_so << endl << endl;
319   }
320   return S_OK;
321 }
322 
FinishArchive(const CFinishArchiveStat & st)323 HRESULT CUpdateCallbackConsole::FinishArchive(const CFinishArchiveStat &st)
324 {
325   ClosePercents2();
326 
327   if (_so)
328   {
329     AString s;
330     // Print_UInt64_and_String(s, _percent.Files == 1 ? "file" : "files", _percent.Files);
331     PrintPropPair(s, "Files read from disk", _percent.Files - NumNonOpenFiles);
332     s.Add_LF();
333     s += "Archive size: ";
334     PrintSize_bytes_Smart(s, st.OutArcFileSize);
335     s.Add_LF();
336     *_so << endl;
337     *_so << s;
338     // *_so << endl;
339   }
340 
341   return S_OK;
342 }
343 
WriteSfx(const wchar_t * name,UInt64 size)344 HRESULT CUpdateCallbackConsole::WriteSfx(const wchar_t *name, UInt64 size)
345 {
346   if (_so)
347   {
348     *_so << "Write SFX: ";
349     *_so << name;
350     AString s (" : ");
351     PrintSize_bytes_Smart(s, size);
352     *_so << s << endl;
353   }
354   return S_OK;
355 }
356 
357 
DeletingAfterArchiving(const FString & path,bool)358 HRESULT CUpdateCallbackConsole::DeletingAfterArchiving(const FString &path, bool /* isDir */)
359 {
360   if (LogLevel > 0 && _so)
361   {
362     ClosePercents_for_so();
363 
364     if (!DeleteMessageWasShown)
365     {
366       if (_so)
367         *_so << endl << ": Removing files after including to archive" << endl;
368     }
369 
370     {
371       {
372         _tempA = "Removing";
373         _tempA.Add_Space();
374         *_so << _tempA;
375         _tempU = fs2us(path);
376         _so->Normalize_UString(_tempU);
377         _so->PrintUString(_tempU, _tempA);
378         *_so << endl;
379         if (NeedFlush)
380           _so->Flush();
381       }
382     }
383   }
384 
385   if (!DeleteMessageWasShown)
386   {
387     if (NeedPercents())
388     {
389       _percent.ClearCurState();
390     }
391     DeleteMessageWasShown = true;
392   }
393   else
394   {
395     _percent.Files++;
396   }
397 
398   if (NeedPercents())
399   {
400     // if (!FullLog)
401     {
402       _percent.Command = "Removing";
403       _percent.FileName = fs2us(path);
404     }
405     _percent.Print();
406   }
407 
408   return S_OK;
409 }
410 
411 
FinishDeletingAfterArchiving()412 HRESULT CUpdateCallbackConsole::FinishDeletingAfterArchiving()
413 {
414   ClosePercents2();
415   if (_so && DeleteMessageWasShown)
416     *_so << endl;
417   return S_OK;
418 }
419 
CheckBreak()420 HRESULT CUpdateCallbackConsole::CheckBreak()
421 {
422   return CheckBreak2();
423 }
424 
425 /*
426 HRESULT CUpdateCallbackConsole::Finalize()
427 {
428   // MT_LOCK
429   return S_OK;
430 }
431 */
432 
433 
PrintToDoStat(CStdOutStream * _so,const CDirItemsStat2 & stat,const char * name)434 void static PrintToDoStat(CStdOutStream *_so, const CDirItemsStat2 &stat, const char *name)
435 {
436   AString s;
437   Print_DirItemsStat2(s, stat);
438   *_so << name << ": " << s << endl;
439 }
440 
SetNumItems(const CArcToDoStat & stat)441 HRESULT CUpdateCallbackConsole::SetNumItems(const CArcToDoStat &stat)
442 {
443   if (_so)
444   {
445     ClosePercents_for_so();
446     if (!stat.DeleteData.IsEmpty())
447     {
448       *_so << endl;
449       PrintToDoStat(_so, stat.DeleteData, "Delete data from archive");
450     }
451     if (!stat.OldData.IsEmpty())
452       PrintToDoStat(_so, stat.OldData, "Keep old data in archive");
453     // if (!stat.NewData.IsEmpty())
454     {
455       PrintToDoStat(_so, stat.NewData, "Add new data to archive");
456     }
457     *_so << endl;
458   }
459   return S_OK;
460 }
461 
SetTotal(UInt64 size)462 HRESULT CUpdateCallbackConsole::SetTotal(UInt64 size)
463 {
464   MT_LOCK
465   if (NeedPercents())
466   {
467     _percent.Total = size;
468     _percent.Print();
469   }
470   return S_OK;
471 }
472 
SetCompleted(const UInt64 * completeValue)473 HRESULT CUpdateCallbackConsole::SetCompleted(const UInt64 *completeValue)
474 {
475   MT_LOCK
476   if (completeValue)
477   {
478     if (NeedPercents())
479     {
480       _percent.Completed = *completeValue;
481       _percent.Print();
482     }
483   }
484   return CheckBreak2();
485 }
486 
SetRatioInfo(const UInt64 *,const UInt64 *)487 HRESULT CUpdateCallbackConsole::SetRatioInfo(const UInt64 * /* inSize */, const UInt64 * /* outSize */)
488 {
489   return CheckBreak2();
490 }
491 
PrintProgress(const wchar_t * name,bool isDir,const char * command,bool showInLog)492 HRESULT CCallbackConsoleBase::PrintProgress(const wchar_t *name, bool isDir, const char *command, bool showInLog)
493 {
494   MT_LOCK
495 
496   bool show2 = (showInLog && _so);
497 
498   if (show2)
499   {
500     ClosePercents_for_so();
501 
502     _tempA = command;
503     if (name)
504       _tempA.Add_Space();
505     *_so << _tempA;
506 
507     _tempU.Empty();
508     if (name)
509     {
510       _tempU = name;
511       if (isDir)
512         NWindows::NFile::NName::NormalizeDirPathPrefix(_tempU);
513       _so->Normalize_UString(_tempU);
514     }
515     _so->PrintUString(_tempU, _tempA);
516     *_so << endl;
517     if (NeedFlush)
518       _so->Flush();
519   }
520 
521   if (NeedPercents())
522   {
523     if (PercentsNameLevel >= 1)
524     {
525       _percent.FileName.Empty();
526       _percent.Command.Empty();
527       if (PercentsNameLevel > 1 || !show2)
528       {
529         _percent.Command = command;
530         if (name)
531           _percent.FileName = name;
532       }
533     }
534     _percent.Print();
535   }
536 
537   return CheckBreak2();
538 }
539 
540 
541 /*
542 void CCallbackConsoleBase::PrintInfoLine(const UString &s)
543 {
544   if (LogLevel < 1000)
545     return;
546 
547   MT_LOCK
548 
549   const bool show2 = (_so != NULL);
550 
551   if (show2)
552   {
553     ClosePercents_for_so();
554     _so->PrintUString(s, _tempA);
555     *_so << endl;
556     if (NeedFlush)
557       _so->Flush();
558   }
559 }
560 */
561 
GetStream(const wchar_t * name,bool isDir,bool isAnti,UInt32 mode)562 HRESULT CUpdateCallbackConsole::GetStream(const wchar_t *name, bool isDir, bool isAnti, UInt32 mode)
563 {
564   if (StdOutMode)
565     return S_OK;
566 
567   if (!name || name[0] == 0)
568     name = kEmptyFileAlias;
569 
570   unsigned requiredLevel = 1;
571 
572   const char *s;
573   if (mode == NUpdateNotifyOp::kAdd ||
574       mode == NUpdateNotifyOp::kUpdate)
575   {
576     if (isAnti)
577       s = "Anti";
578     else if (mode == NUpdateNotifyOp::kAdd)
579       s = "+";
580     else
581       s = "U";
582   }
583   else
584   {
585     requiredLevel = 3;
586     if (mode == NUpdateNotifyOp::kAnalyze)
587       s = "A";
588     else
589       s = "Reading";
590   }
591 
592   return PrintProgress(name, isDir, s, LogLevel >= requiredLevel);
593 }
594 
OpenFileError(const FString & path,DWORD systemError)595 HRESULT CUpdateCallbackConsole::OpenFileError(const FString &path, DWORD systemError)
596 {
597   return OpenFileError_Base(path, systemError);
598 }
599 
ReadingFileError(const FString & path,DWORD systemError)600 HRESULT CUpdateCallbackConsole::ReadingFileError(const FString &path, DWORD systemError)
601 {
602   return ReadingFileError_Base(path, systemError);
603 }
604 
SetOperationResult(Int32)605 HRESULT CUpdateCallbackConsole::SetOperationResult(Int32 /* opRes */)
606 {
607   MT_LOCK
608   _percent.Files++;
609   /*
610   if (opRes != NArchive::NUpdate::NOperationResult::kOK)
611   {
612     if (opRes == NArchive::NUpdate::NOperationResult::kError_FileChanged)
613     {
614       CommonError("Input file changed");
615     }
616   }
617   */
618   return S_OK;
619 }
620 
621 void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, AString &dest);
622 
ReportExtractResult(Int32 opRes,Int32 isEncrypted,const wchar_t * name)623 HRESULT CUpdateCallbackConsole::ReportExtractResult(Int32 opRes, Int32 isEncrypted, const wchar_t *name)
624 {
625   // if (StdOutMode) return S_OK;
626 
627   if (opRes != NArchive::NExtract::NOperationResult::kOK)
628   {
629     ClosePercents2();
630 
631     if (_se)
632     {
633       if (_so)
634         _so->Flush();
635 
636       AString s;
637       SetExtractErrorMessage(opRes, isEncrypted, s);
638       *_se << s << " : " << endl;
639       _se->NormalizePrint_wstr(name);
640       *_se << endl << endl;
641       _se->Flush();
642     }
643     return S_OK;
644   }
645   return S_OK;
646 }
647 
648 
ReportUpdateOperation(UInt32 op,const wchar_t * name,bool isDir)649 HRESULT CUpdateCallbackConsole::ReportUpdateOperation(UInt32 op, const wchar_t *name, bool isDir)
650 {
651   // if (StdOutMode) return S_OK;
652 
653   char temp[16];
654   const char *s;
655 
656   unsigned requiredLevel = 1;
657 
658   switch (op)
659   {
660     case NUpdateNotifyOp::kAdd:       s = "+"; break;
661     case NUpdateNotifyOp::kUpdate:    s = "U"; break;
662     case NUpdateNotifyOp::kAnalyze:   s = "A"; requiredLevel = 3; break;
663     case NUpdateNotifyOp::kReplicate: s = "="; requiredLevel = 3; break;
664     case NUpdateNotifyOp::kRepack:    s = "R"; requiredLevel = 2; break;
665     case NUpdateNotifyOp::kSkip:      s = "."; requiredLevel = 2; break;
666     case NUpdateNotifyOp::kDelete:    s = "D"; requiredLevel = 3; break;
667     case NUpdateNotifyOp::kHeader:    s = "Header creation"; requiredLevel = 100; break;
668     case NUpdateNotifyOp::kInFileChanged: s = "Size of input file was changed:"; requiredLevel = 10; break;
669     // case NUpdateNotifyOp::kOpFinished:  s = "Finished"; requiredLevel = 100; break;
670     default:
671     {
672       temp[0] = 'o';
673       temp[1] = 'p';
674       ConvertUInt64ToString(op, temp + 2);
675       s = temp;
676     }
677   }
678 
679   return PrintProgress(name, isDir, s, LogLevel >= requiredLevel);
680 }
681 
682 /*
683 HRESULT CUpdateCallbackConsole::SetPassword(const UString &
684     #ifndef _NO_CRYPTO
685     password
686     #endif
687     )
688 {
689   #ifndef _NO_CRYPTO
690   PasswordIsDefined = true;
691   Password = password;
692   #endif
693   return S_OK;
694 }
695 */
696 
CryptoGetTextPassword2(Int32 * passwordIsDefined,BSTR * password)697 HRESULT CUpdateCallbackConsole::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)
698 {
699   COM_TRY_BEGIN
700 
701   *password = NULL;
702 
703   #ifdef _NO_CRYPTO
704 
705   *passwordIsDefined = false;
706   return S_OK;
707 
708   #else
709 
710   if (!PasswordIsDefined)
711   {
712     if (AskPassword)
713     {
714       RINOK(GetPassword_HRESULT(_so, Password));
715       PasswordIsDefined = true;
716     }
717   }
718   *passwordIsDefined = BoolToInt(PasswordIsDefined);
719   return StringToBstr(Password, password);
720 
721   #endif
722 
723   COM_TRY_END
724 }
725 
CryptoGetTextPassword(BSTR * password)726 HRESULT CUpdateCallbackConsole::CryptoGetTextPassword(BSTR *password)
727 {
728   COM_TRY_BEGIN
729 
730   *password = NULL;
731 
732   #ifdef _NO_CRYPTO
733 
734   return E_NOTIMPL;
735 
736   #else
737 
738   if (!PasswordIsDefined)
739   {
740     {
741       RINOK(GetPassword_HRESULT(_so, Password))
742       PasswordIsDefined = true;
743     }
744   }
745   return StringToBstr(Password, password);
746 
747   #endif
748   COM_TRY_END
749 }
750 
ShowDeleteFile(const wchar_t * name,bool isDir)751 HRESULT CUpdateCallbackConsole::ShowDeleteFile(const wchar_t *name, bool isDir)
752 {
753   if (StdOutMode)
754     return S_OK;
755 
756   if (LogLevel > 7)
757   {
758     if (!name || name[0] == 0)
759       name = kEmptyFileAlias;
760     return PrintProgress(name, isDir, "D", true);
761   }
762   return S_OK;
763 }
764 
765 /*
766 void GetPropName(PROPID propID, const wchar_t *name, AString &nameA, UString &nameU);
767 
768 static void GetPropName(PROPID propID, UString &nameU)
769 {
770   AString nameA;
771   GetPropName(propID, NULL, nameA, nameU);
772   // if (!nameA.IsEmpty())
773     nameU = nameA;
774 }
775 
776 
777 static void AddPropNamePrefix(UString &s, PROPID propID)
778 {
779   UString name;
780   GetPropName(propID, name);
781   s += name;
782   s += " = ";
783 }
784 
785 void CCallbackConsoleBase::PrintPropInfo(UString &s, PROPID propID, const PROPVARIANT *value)
786 {
787   AddPropNamePrefix(s, propID);
788   {
789     UString dest;
790     const int level = 9; // we show up to ns precision level
791     ConvertPropertyToString2(dest, *value, propID, level);
792     s += dest;
793   }
794   PrintInfoLine(s);
795 }
796 
797 static void Add_IndexType_Index(UString &s, UInt32 indexType, UInt32 index)
798 {
799   if (indexType == NArchive::NEventIndexType::kArcProp)
800   {
801   }
802   else
803   {
804     if (indexType == NArchive::NEventIndexType::kBlockIndex)
805     {
806       s += "#";
807     }
808     else if (indexType == NArchive::NEventIndexType::kOutArcIndex)
809     {
810     }
811     else
812     {
813       s += "indexType_";
814       s.Add_UInt32(indexType);
815       s.Add_Space();
816     }
817     s.Add_UInt32(index);
818   }
819   s += ": ";
820 }
821 
822 HRESULT CUpdateCallbackConsole::ReportProp(UInt32 indexType, UInt32 index, PROPID propID, const PROPVARIANT *value)
823 {
824   UString s;
825   Add_IndexType_Index(s, indexType, index);
826   PrintPropInfo(s, propID, value);
827   return S_OK;
828 }
829 
830 static inline char GetHex(Byte value)
831 {
832   return (char)((value < 10) ? ('0' + value) : ('a' + (value - 10)));
833 }
834 
835 static void AddHexToString(UString &dest, const Byte *data, UInt32 size)
836 {
837   for (UInt32 i = 0; i < size; i++)
838   {
839     Byte b = data[i];
840     dest += GetHex((Byte)((b >> 4) & 0xF));
841     dest += GetHex((Byte)(b & 0xF));
842   }
843 }
844 
845 void HashHexToString(char *dest, const Byte *data, UInt32 size);
846 
847 HRESULT CUpdateCallbackConsole::ReportRawProp(UInt32 indexType, UInt32 index,
848     PROPID propID, const void *data, UInt32 dataSize, UInt32 propType)
849 {
850   UString s;
851   propType = propType;
852   Add_IndexType_Index(s, indexType, index);
853   AddPropNamePrefix(s, propID);
854   if (propID == kpidChecksum)
855   {
856     char temp[k_HashCalc_DigestSize_Max + 8];
857     HashHexToString(temp, (const Byte *)data, dataSize);
858     s += temp;
859   }
860   else
861     AddHexToString(s, (const Byte *)data, dataSize);
862   PrintInfoLine(s);
863   return S_OK;
864 }
865 
866 HRESULT CUpdateCallbackConsole::ReportFinished(UInt32 indexType, UInt32 index, Int32 opRes)
867 {
868   UString s;
869   Add_IndexType_Index(s, indexType, index);
870   s += "finished";
871   if (opRes != NArchive::NUpdate::NOperationResult::kOK)
872   {
873     s += ": ";
874     s.Add_UInt32(opRes);
875   }
876   PrintInfoLine(s);
877   return S_OK;
878 }
879 */
880