• 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 Z7_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 Z7_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     if (st.IsMultiVolMode)
337     {
338       s += "Volumes: ";
339       s.Add_UInt32(st.NumVolumes);
340       s.Add_LF();
341     }
342     *_so << endl;
343     *_so << s;
344     // *_so << endl;
345   }
346 
347   return S_OK;
348 }
349 
WriteSfx(const wchar_t * name,UInt64 size)350 HRESULT CUpdateCallbackConsole::WriteSfx(const wchar_t *name, UInt64 size)
351 {
352   if (_so)
353   {
354     *_so << "Write SFX: ";
355     *_so << name;
356     AString s (" : ");
357     PrintSize_bytes_Smart(s, size);
358     *_so << s << endl;
359   }
360   return S_OK;
361 }
362 
363 
DeletingAfterArchiving(const FString & path,bool)364 HRESULT CUpdateCallbackConsole::DeletingAfterArchiving(const FString &path, bool /* isDir */)
365 {
366   if (LogLevel > 0 && _so)
367   {
368     ClosePercents_for_so();
369 
370     if (!DeleteMessageWasShown)
371     {
372       if (_so)
373         *_so << endl << ": Removing files after including to archive" << endl;
374     }
375 
376     {
377       {
378         _tempA = "Removing";
379         _tempA.Add_Space();
380         *_so << _tempA;
381         _tempU = fs2us(path);
382         _so->Normalize_UString(_tempU);
383         _so->PrintUString(_tempU, _tempA);
384         *_so << endl;
385         if (NeedFlush)
386           _so->Flush();
387       }
388     }
389   }
390 
391   if (!DeleteMessageWasShown)
392   {
393     if (NeedPercents())
394     {
395       _percent.ClearCurState();
396     }
397     DeleteMessageWasShown = true;
398   }
399   else
400   {
401     _percent.Files++;
402   }
403 
404   if (NeedPercents())
405   {
406     // if (!FullLog)
407     {
408       _percent.Command = "Removing";
409       _percent.FileName = fs2us(path);
410     }
411     _percent.Print();
412   }
413 
414   return S_OK;
415 }
416 
417 
FinishDeletingAfterArchiving()418 HRESULT CUpdateCallbackConsole::FinishDeletingAfterArchiving()
419 {
420   ClosePercents2();
421   if (_so && DeleteMessageWasShown)
422     *_so << endl;
423   return S_OK;
424 }
425 
CheckBreak()426 HRESULT CUpdateCallbackConsole::CheckBreak()
427 {
428   return CheckBreak2();
429 }
430 
431 /*
432 HRESULT CUpdateCallbackConsole::Finalize()
433 {
434   // MT_LOCK
435   return S_OK;
436 }
437 */
438 
439 
PrintToDoStat(CStdOutStream * _so,const CDirItemsStat2 & stat,const char * name)440 void static PrintToDoStat(CStdOutStream *_so, const CDirItemsStat2 &stat, const char *name)
441 {
442   AString s;
443   Print_DirItemsStat2(s, stat);
444   *_so << name << ": " << s << endl;
445 }
446 
SetNumItems(const CArcToDoStat & stat)447 HRESULT CUpdateCallbackConsole::SetNumItems(const CArcToDoStat &stat)
448 {
449   if (_so)
450   {
451     ClosePercents_for_so();
452     if (!stat.DeleteData.IsEmpty())
453     {
454       *_so << endl;
455       PrintToDoStat(_so, stat.DeleteData, "Delete data from archive");
456     }
457     if (!stat.OldData.IsEmpty())
458       PrintToDoStat(_so, stat.OldData, "Keep old data in archive");
459     // if (!stat.NewData.IsEmpty())
460     {
461       PrintToDoStat(_so, stat.NewData, "Add new data to archive");
462     }
463     *_so << endl;
464   }
465   return S_OK;
466 }
467 
SetTotal(UInt64 size)468 HRESULT CUpdateCallbackConsole::SetTotal(UInt64 size)
469 {
470   MT_LOCK
471   if (NeedPercents())
472   {
473     _percent.Total = size;
474     _percent.Print();
475   }
476   return S_OK;
477 }
478 
SetCompleted(const UInt64 * completeValue)479 HRESULT CUpdateCallbackConsole::SetCompleted(const UInt64 *completeValue)
480 {
481   MT_LOCK
482   if (completeValue)
483   {
484     if (NeedPercents())
485     {
486       _percent.Completed = *completeValue;
487       _percent.Print();
488     }
489   }
490   return CheckBreak2();
491 }
492 
SetRatioInfo(const UInt64 *,const UInt64 *)493 HRESULT CUpdateCallbackConsole::SetRatioInfo(const UInt64 * /* inSize */, const UInt64 * /* outSize */)
494 {
495   return CheckBreak2();
496 }
497 
PrintProgress(const wchar_t * name,bool isDir,const char * command,bool showInLog)498 HRESULT CCallbackConsoleBase::PrintProgress(const wchar_t *name, bool isDir, const char *command, bool showInLog)
499 {
500   MT_LOCK
501 
502   bool show2 = (showInLog && _so);
503 
504   if (show2)
505   {
506     ClosePercents_for_so();
507 
508     _tempA = command;
509     if (name)
510       _tempA.Add_Space();
511     *_so << _tempA;
512 
513     _tempU.Empty();
514     if (name)
515     {
516       _tempU = name;
517       if (isDir)
518         NWindows::NFile::NName::NormalizeDirPathPrefix(_tempU);
519       _so->Normalize_UString(_tempU);
520     }
521     _so->PrintUString(_tempU, _tempA);
522     *_so << endl;
523     if (NeedFlush)
524       _so->Flush();
525   }
526 
527   if (NeedPercents())
528   {
529     if (PercentsNameLevel >= 1)
530     {
531       _percent.FileName.Empty();
532       _percent.Command.Empty();
533       if (PercentsNameLevel > 1 || !show2)
534       {
535         _percent.Command = command;
536         if (name)
537           _percent.FileName = name;
538       }
539     }
540     _percent.Print();
541   }
542 
543   return CheckBreak2();
544 }
545 
546 
547 /*
548 void CCallbackConsoleBase::PrintInfoLine(const UString &s)
549 {
550   if (LogLevel < 1000)
551     return;
552 
553   MT_LOCK
554 
555   const bool show2 = (_so != NULL);
556 
557   if (show2)
558   {
559     ClosePercents_for_so();
560     _so->PrintUString(s, _tempA);
561     *_so << endl;
562     if (NeedFlush)
563       _so->Flush();
564   }
565 }
566 */
567 
GetStream(const wchar_t * name,bool isDir,bool isAnti,UInt32 mode)568 HRESULT CUpdateCallbackConsole::GetStream(const wchar_t *name, bool isDir, bool isAnti, UInt32 mode)
569 {
570   if (StdOutMode)
571     return S_OK;
572 
573   if (!name || name[0] == 0)
574     name = kEmptyFileAlias;
575 
576   unsigned requiredLevel = 1;
577 
578   const char *s;
579   if (mode == NUpdateNotifyOp::kAdd ||
580       mode == NUpdateNotifyOp::kUpdate)
581   {
582     if (isAnti)
583       s = "Anti";
584     else if (mode == NUpdateNotifyOp::kAdd)
585       s = "+";
586     else
587       s = "U";
588   }
589   else
590   {
591     requiredLevel = 3;
592     if (mode == NUpdateNotifyOp::kAnalyze)
593       s = "A";
594     else
595       s = "Reading";
596   }
597 
598   return PrintProgress(name, isDir, s, LogLevel >= requiredLevel);
599 }
600 
OpenFileError(const FString & path,DWORD systemError)601 HRESULT CUpdateCallbackConsole::OpenFileError(const FString &path, DWORD systemError)
602 {
603   return OpenFileError_Base(path, systemError);
604 }
605 
ReadingFileError(const FString & path,DWORD systemError)606 HRESULT CUpdateCallbackConsole::ReadingFileError(const FString &path, DWORD systemError)
607 {
608   return ReadingFileError_Base(path, systemError);
609 }
610 
SetOperationResult(Int32)611 HRESULT CUpdateCallbackConsole::SetOperationResult(Int32 /* opRes */)
612 {
613   MT_LOCK
614   _percent.Files++;
615   /*
616   if (opRes != NArchive::NUpdate::NOperationResult::kOK)
617   {
618     if (opRes == NArchive::NUpdate::NOperationResult::kError_FileChanged)
619     {
620       CommonError("Input file changed");
621     }
622   }
623   */
624   return S_OK;
625 }
626 
627 void SetExtractErrorMessage(Int32 opRes, Int32 encrypted, AString &dest);
628 
ReportExtractResult(Int32 opRes,Int32 isEncrypted,const wchar_t * name)629 HRESULT CUpdateCallbackConsole::ReportExtractResult(Int32 opRes, Int32 isEncrypted, const wchar_t *name)
630 {
631   // if (StdOutMode) return S_OK;
632 
633   if (opRes != NArchive::NExtract::NOperationResult::kOK)
634   {
635     ClosePercents2();
636 
637     if (_se)
638     {
639       if (_so)
640         _so->Flush();
641 
642       AString s;
643       SetExtractErrorMessage(opRes, isEncrypted, s);
644       *_se << s << " : " << endl;
645       _se->NormalizePrint_wstr(name);
646       *_se << endl << endl;
647       _se->Flush();
648     }
649     return S_OK;
650   }
651   return S_OK;
652 }
653 
654 
ReportUpdateOperation(UInt32 op,const wchar_t * name,bool isDir)655 HRESULT CUpdateCallbackConsole::ReportUpdateOperation(UInt32 op, const wchar_t *name, bool isDir)
656 {
657   // if (StdOutMode) return S_OK;
658 
659   char temp[16];
660   const char *s;
661 
662   unsigned requiredLevel = 1;
663 
664   switch (op)
665   {
666     case NUpdateNotifyOp::kAdd:       s = "+"; break;
667     case NUpdateNotifyOp::kUpdate:    s = "U"; break;
668     case NUpdateNotifyOp::kAnalyze:   s = "A"; requiredLevel = 3; break;
669     case NUpdateNotifyOp::kReplicate: s = "="; requiredLevel = 3; break;
670     case NUpdateNotifyOp::kRepack:    s = "R"; requiredLevel = 2; break;
671     case NUpdateNotifyOp::kSkip:      s = "."; requiredLevel = 2; break;
672     case NUpdateNotifyOp::kDelete:    s = "D"; requiredLevel = 3; break;
673     case NUpdateNotifyOp::kHeader:    s = "Header creation"; requiredLevel = 100; break;
674     case NUpdateNotifyOp::kInFileChanged: s = "Size of input file was changed:"; requiredLevel = 10; break;
675     // case NUpdateNotifyOp::kOpFinished:  s = "Finished"; requiredLevel = 100; break;
676     default:
677     {
678       temp[0] = 'o';
679       temp[1] = 'p';
680       ConvertUInt64ToString(op, temp + 2);
681       s = temp;
682     }
683   }
684 
685   return PrintProgress(name, isDir, s, LogLevel >= requiredLevel);
686 }
687 
688 /*
689 HRESULT CUpdateCallbackConsole::SetPassword(const UString &
690     #ifndef Z7_NO_CRYPTO
691     password
692     #endif
693     )
694 {
695   #ifndef Z7_NO_CRYPTO
696   PasswordIsDefined = true;
697   Password = password;
698   #endif
699   return S_OK;
700 }
701 */
702 
CryptoGetTextPassword2(Int32 * passwordIsDefined,BSTR * password)703 HRESULT CUpdateCallbackConsole::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)
704 {
705   COM_TRY_BEGIN
706 
707   *password = NULL;
708 
709   #ifdef Z7_NO_CRYPTO
710 
711   *passwordIsDefined = false;
712   return S_OK;
713 
714   #else
715 
716   if (!PasswordIsDefined)
717   {
718     if (AskPassword)
719     {
720       RINOK(GetPassword_HRESULT(_so, Password))
721       PasswordIsDefined = true;
722     }
723   }
724   *passwordIsDefined = BoolToInt(PasswordIsDefined);
725   return StringToBstr(Password, password);
726 
727   #endif
728 
729   COM_TRY_END
730 }
731 
CryptoGetTextPassword(BSTR * password)732 HRESULT CUpdateCallbackConsole::CryptoGetTextPassword(BSTR *password)
733 {
734   COM_TRY_BEGIN
735 
736   *password = NULL;
737 
738   #ifdef Z7_NO_CRYPTO
739 
740   return E_NOTIMPL;
741 
742   #else
743 
744   if (!PasswordIsDefined)
745   {
746     {
747       RINOK(GetPassword_HRESULT(_so, Password))
748       PasswordIsDefined = true;
749     }
750   }
751   return StringToBstr(Password, password);
752 
753   #endif
754   COM_TRY_END
755 }
756 
ShowDeleteFile(const wchar_t * name,bool isDir)757 HRESULT CUpdateCallbackConsole::ShowDeleteFile(const wchar_t *name, bool isDir)
758 {
759   if (StdOutMode)
760     return S_OK;
761 
762   if (LogLevel > 7)
763   {
764     if (!name || name[0] == 0)
765       name = kEmptyFileAlias;
766     return PrintProgress(name, isDir, "D", true);
767   }
768   return S_OK;
769 }
770 
771 /*
772 void GetPropName(PROPID propID, const wchar_t *name, AString &nameA, UString &nameU);
773 
774 static void GetPropName(PROPID propID, UString &nameU)
775 {
776   AString nameA;
777   GetPropName(propID, NULL, nameA, nameU);
778   // if (!nameA.IsEmpty())
779     nameU = nameA;
780 }
781 
782 
783 static void AddPropNamePrefix(UString &s, PROPID propID)
784 {
785   UString name;
786   GetPropName(propID, name);
787   s += name;
788   s += " = ";
789 }
790 
791 void CCallbackConsoleBase::PrintPropInfo(UString &s, PROPID propID, const PROPVARIANT *value)
792 {
793   AddPropNamePrefix(s, propID);
794   {
795     UString dest;
796     const int level = 9; // we show up to ns precision level
797     ConvertPropertyToString2(dest, *value, propID, level);
798     s += dest;
799   }
800   PrintInfoLine(s);
801 }
802 
803 static void Add_IndexType_Index(UString &s, UInt32 indexType, UInt32 index)
804 {
805   if (indexType == NArchive::NEventIndexType::kArcProp)
806   {
807   }
808   else
809   {
810     if (indexType == NArchive::NEventIndexType::kBlockIndex)
811     {
812       s += "#";
813     }
814     else if (indexType == NArchive::NEventIndexType::kOutArcIndex)
815     {
816     }
817     else
818     {
819       s += "indexType_";
820       s.Add_UInt32(indexType);
821       s.Add_Space();
822     }
823     s.Add_UInt32(index);
824   }
825   s += ": ";
826 }
827 
828 HRESULT CUpdateCallbackConsole::ReportProp(UInt32 indexType, UInt32 index, PROPID propID, const PROPVARIANT *value)
829 {
830   UString s;
831   Add_IndexType_Index(s, indexType, index);
832   PrintPropInfo(s, propID, value);
833   return S_OK;
834 }
835 
836 static inline char GetHex(Byte value)
837 {
838   return (char)((value < 10) ? ('0' + value) : ('a' + (value - 10)));
839 }
840 
841 static void AddHexToString(UString &dest, const Byte *data, UInt32 size)
842 {
843   for (UInt32 i = 0; i < size; i++)
844   {
845     Byte b = data[i];
846     dest += GetHex((Byte)((b >> 4) & 0xF));
847     dest += GetHex((Byte)(b & 0xF));
848   }
849 }
850 
851 void HashHexToString(char *dest, const Byte *data, UInt32 size);
852 
853 HRESULT CUpdateCallbackConsole::ReportRawProp(UInt32 indexType, UInt32 index,
854     PROPID propID, const void *data, UInt32 dataSize, UInt32 propType)
855 {
856   UString s;
857   propType = propType;
858   Add_IndexType_Index(s, indexType, index);
859   AddPropNamePrefix(s, propID);
860   if (propID == kpidChecksum)
861   {
862     char temp[k_HashCalc_DigestSize_Max + 8];
863     HashHexToString(temp, (const Byte *)data, dataSize);
864     s += temp;
865   }
866   else
867     AddHexToString(s, (const Byte *)data, dataSize);
868   PrintInfoLine(s);
869   return S_OK;
870 }
871 
872 HRESULT CUpdateCallbackConsole::ReportFinished(UInt32 indexType, UInt32 index, Int32 opRes)
873 {
874   UString s;
875   Add_IndexType_Index(s, indexType, index);
876   s += "finished";
877   if (opRes != NArchive::NUpdate::NOperationResult::kOK)
878   {
879     s += ": ";
880     s.Add_UInt32(opRes);
881   }
882   PrintInfoLine(s);
883   return S_OK;
884 }
885 */
886