win32stm.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. #if !defined(SFX_MODULE) && defined(_WIN_ALL)
  2. void ExtractStreams20(Archive &Arc,const wchar *FileName)
  3. {
  4. if (Arc.BrokenHeader)
  5. {
  6. uiMsg(UIERROR_STREAMBROKEN,Arc.FileName,FileName);
  7. ErrHandler.SetErrorCode(RARX_CRC);
  8. return;
  9. }
  10. if (Arc.StreamHead.Method<0x31 || Arc.StreamHead.Method>0x35 || Arc.StreamHead.UnpVer>VER_PACK)
  11. {
  12. uiMsg(UIERROR_STREAMUNKNOWN,Arc.FileName,FileName);
  13. ErrHandler.SetErrorCode(RARX_WARNING);
  14. return;
  15. }
  16. wchar StreamName[NM+2];
  17. if (FileName[0]!=0 && FileName[1]==0)
  18. {
  19. // Convert single character names like f:stream to .\f:stream to
  20. // resolve the ambiguity with drive letters.
  21. wcsncpyz(StreamName,L".\\",ASIZE(StreamName));
  22. wcsncatz(StreamName,FileName,ASIZE(StreamName));
  23. }
  24. else
  25. wcsncpyz(StreamName,FileName,ASIZE(StreamName));
  26. if (wcslen(StreamName)+strlen(Arc.StreamHead.StreamName)>=ASIZE(StreamName) ||
  27. Arc.StreamHead.StreamName[0]!=':')
  28. {
  29. uiMsg(UIERROR_STREAMBROKEN,Arc.FileName,FileName);
  30. ErrHandler.SetErrorCode(RARX_CRC);
  31. return;
  32. }
  33. wchar StoredName[NM];
  34. CharToWide(Arc.StreamHead.StreamName,StoredName,ASIZE(StoredName));
  35. ConvertPath(StoredName+1,StoredName+1,ASIZE(StoredName)-1);
  36. wcsncatz(StreamName,StoredName,ASIZE(StreamName));
  37. FindData fd;
  38. bool Found=FindFile::FastFind(FileName,&fd);
  39. if ((fd.FileAttr & FILE_ATTRIBUTE_READONLY)!=0)
  40. SetFileAttr(FileName,fd.FileAttr & ~FILE_ATTRIBUTE_READONLY);
  41. File CurFile;
  42. if (CurFile.WCreate(StreamName))
  43. {
  44. ComprDataIO DataIO;
  45. Unpack Unpack(&DataIO);
  46. Unpack.Init(0x10000,false);
  47. DataIO.SetPackedSizeToRead(Arc.StreamHead.DataSize);
  48. DataIO.EnableShowProgress(false);
  49. DataIO.SetFiles(&Arc,&CurFile);
  50. DataIO.UnpHash.Init(HASH_CRC32,1);
  51. Unpack.SetDestSize(Arc.StreamHead.UnpSize);
  52. Unpack.DoUnpack(Arc.StreamHead.UnpVer,false);
  53. if (Arc.StreamHead.StreamCRC!=DataIO.UnpHash.GetCRC32())
  54. {
  55. uiMsg(UIERROR_STREAMBROKEN,Arc.FileName,StreamName);
  56. ErrHandler.SetErrorCode(RARX_CRC);
  57. }
  58. else
  59. CurFile.Close();
  60. }
  61. File HostFile;
  62. if (Found && HostFile.Open(FileName,FMF_OPENSHARED|FMF_UPDATE))
  63. SetFileTime(HostFile.GetHandle(),&fd.ftCreationTime,&fd.ftLastAccessTime,
  64. &fd.ftLastWriteTime);
  65. if ((fd.FileAttr & FILE_ATTRIBUTE_READONLY)!=0)
  66. SetFileAttr(FileName,fd.FileAttr);
  67. }
  68. #endif
  69. #ifdef _WIN_ALL
  70. void ExtractStreams(Archive &Arc,const wchar *FileName,bool TestMode)
  71. {
  72. wchar FullName[NM+2];
  73. if (FileName[0]!=0 && FileName[1]==0)
  74. {
  75. // Convert single character names like f:stream to .\f:stream to
  76. // resolve the ambiguity with drive letters.
  77. wcsncpyz(FullName,L".\\",ASIZE(FullName));
  78. wcsncatz(FullName,FileName,ASIZE(FullName));
  79. }
  80. else
  81. wcsncpyz(FullName,FileName,ASIZE(FullName));
  82. wchar StreamName[NM];
  83. GetStreamNameNTFS(Arc,StreamName,ASIZE(StreamName));
  84. if (*StreamName!=':')
  85. {
  86. uiMsg(UIERROR_STREAMBROKEN,Arc.FileName,FileName);
  87. ErrHandler.SetErrorCode(RARX_CRC);
  88. return;
  89. }
  90. if (TestMode)
  91. {
  92. File CurFile;
  93. Arc.ReadSubData(NULL,&CurFile,true);
  94. return;
  95. }
  96. wcsncatz(FullName,StreamName,ASIZE(FullName));
  97. FindData fd;
  98. bool Found=FindFile::FastFind(FileName,&fd);
  99. if ((fd.FileAttr & FILE_ATTRIBUTE_READONLY)!=0)
  100. SetFileAttr(FileName,fd.FileAttr & ~FILE_ATTRIBUTE_READONLY);
  101. File CurFile;
  102. if (CurFile.WCreate(FullName) && Arc.ReadSubData(NULL,&CurFile,false))
  103. CurFile.Close();
  104. File HostFile;
  105. if (Found && HostFile.Open(FileName,FMF_OPENSHARED|FMF_UPDATE))
  106. SetFileTime(HostFile.GetHandle(),&fd.ftCreationTime,&fd.ftLastAccessTime,
  107. &fd.ftLastWriteTime);
  108. // Restoring original file attributes. Important if file was read only
  109. // or did not have "Archive" attribute
  110. SetFileAttr(FileName,fd.FileAttr);
  111. }
  112. #endif
  113. void GetStreamNameNTFS(Archive &Arc,wchar *StreamName,size_t MaxSize)
  114. {
  115. byte *Data=&Arc.SubHead.SubData[0];
  116. size_t DataSize=Arc.SubHead.SubData.Size();
  117. if (Arc.Format==RARFMT15)
  118. {
  119. size_t DestSize=Min(DataSize/2,MaxSize-1);
  120. RawToWide(Data,StreamName,DestSize);
  121. StreamName[DestSize]=0;
  122. }
  123. else
  124. {
  125. char UtfString[NM*4];
  126. size_t DestSize=Min(DataSize,ASIZE(UtfString)-1);
  127. memcpy(UtfString,Data,DestSize);
  128. UtfString[DestSize]=0;
  129. UtfToWide(UtfString,StreamName,MaxSize);
  130. }
  131. }