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