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