Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
1 // 7zMethods.cpp
3 #include "StdAfx.h"
5 #include "7zMethods.h"
7 #include "../../../Windows/FileFind.h"
8 #include "../../../Windows/DLL.h"
9 #include "../../../Windows/PropVariant.h"
10 #include "../../../Windows/Synchronization.h"
12 #include "../../ICoder.h"
13 #include "../Common/CodecsPath.h"
15 using namespace NWindows;
17 namespace NArchive {
18 namespace N7z {
20 static CObjectVector<CMethodInfo2> g_Methods;
21 static bool g_Loaded = false;
23 typedef UInt32 (WINAPI *GetNumberOfMethodsFunc)(UInt32 *numMethods);
25 typedef UInt32 (WINAPI *GetMethodPropertyFunc)(
26 UInt32 index, PROPID propID, PROPVARIANT *value);
28 static void Load(const CSysString &folderPrefix)
29 {
30 NFile::NFind::CEnumerator enumerator(folderPrefix + CSysString(TEXT("*")));
31 NFile::NFind::CFileInfo fileInfo;
32 while (enumerator.Next(fileInfo))
33 {
34 if (fileInfo.IsDirectory())
35 continue;
36 CSysString filePath = folderPrefix + fileInfo.Name;
37 {
38 NDLL::CLibrary library;
39 if (!library.LoadEx(filePath, LOAD_LIBRARY_AS_DATAFILE))
40 continue;
41 }
42 NDLL::CLibrary library;
43 if (!library.Load(filePath))
44 continue;
45 GetMethodPropertyFunc getMethodProperty = (GetMethodPropertyFunc)
46 library.GetProcAddress("GetMethodProperty");
47 if (getMethodProperty == NULL)
48 continue;
50 UInt32 numMethods = 1;
51 GetNumberOfMethodsFunc getNumberOfMethodsFunc = (GetNumberOfMethodsFunc)
52 library.GetProcAddress("GetNumberOfMethods");
53 if (getNumberOfMethodsFunc != NULL)
54 if (getNumberOfMethodsFunc(&numMethods) != S_OK)
55 continue;
57 for(UInt32 i = 0; i < numMethods; i++)
58 {
59 CMethodInfo2 info;
60 info.FilePath = filePath;
62 NWindows::NCOM::CPropVariant propVariant;
63 if (getMethodProperty(i, NMethodPropID::kID, &propVariant) != S_OK)
64 continue;
65 if (propVariant.vt != VT_BSTR)
66 continue;
67 info.MethodID.IDSize = SysStringByteLen(propVariant.bstrVal);
68 memmove(info.MethodID.ID, propVariant.bstrVal, info.MethodID.IDSize);
69 propVariant.Clear();
71 if (getMethodProperty(i, NMethodPropID::kName, &propVariant) != S_OK)
72 continue;
73 if (propVariant.vt == VT_EMPTY)
74 {
75 }
76 else if (propVariant.vt == VT_BSTR)
77 info.Name = propVariant.bstrVal;
78 else
79 continue;
80 propVariant.Clear();
82 if (getMethodProperty (i, NMethodPropID::kEncoder, &propVariant) != S_OK)
83 continue;
84 if (propVariant.vt == VT_EMPTY)
85 info.EncoderIsAssigned = false;
86 else if (propVariant.vt == VT_BSTR)
87 {
88 info.EncoderIsAssigned = true;
89 info.Encoder = *(const GUID *)propVariant.bstrVal;
90 }
91 else
92 continue;
93 propVariant.Clear();
95 if (getMethodProperty (i, NMethodPropID::kDecoder, &propVariant) != S_OK)
96 continue;
97 if (propVariant.vt == VT_EMPTY)
98 info.DecoderIsAssigned = false;
99 else if (propVariant.vt == VT_BSTR)
100 {
101 info.DecoderIsAssigned = true;
102 info.Decoder = *(const GUID *)propVariant.bstrVal;
103 }
104 else
105 continue;
106 propVariant.Clear();
108 if (getMethodProperty (i, NMethodPropID::kInStreams, &propVariant) != S_OK)
109 continue;
110 if (propVariant.vt == VT_EMPTY)
111 info.NumInStreams = 1;
112 else if (propVariant.vt == VT_UI4)
113 info.NumInStreams = propVariant.ulVal;
114 else
115 continue;
116 propVariant.Clear();
118 if (getMethodProperty (i, NMethodPropID::kOutStreams, &propVariant) != S_OK)
119 continue;
120 if (propVariant.vt == VT_EMPTY)
121 info.NumOutStreams = 1;
122 else if (propVariant.vt == VT_UI4)
123 info.NumOutStreams = propVariant.ulVal;
124 else
125 continue;
126 propVariant.Clear();
128 g_Methods.Add(info);
129 }
130 }
131 }
133 static NSynchronization::CCriticalSection g_CriticalSection;
135 void LoadMethodMap()
136 {
137 NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
138 if (g_Loaded)
139 return;
140 g_Loaded = true;
141 Load(GetCodecsFolderPrefix());
142 }
144 bool GetMethodInfo(const CMethodID &methodID, CMethodInfo &methodInfo)
145 {
146 for(int i = 0; i < g_Methods.Size(); i++)
147 {
148 const CMethodInfo2 &method = g_Methods[i];
149 if (method.MethodID == methodID)
150 {
151 methodInfo = (CMethodInfo)method;
152 return true;
153 }
154 }
155 return false;
156 }
158 bool GetMethodInfo(const UString &name, CMethodInfo2 &methodInfo)
159 {
160 for(int i = 0; i < g_Methods.Size(); i++)
161 {
162 const CMethodInfo2 &method = g_Methods[i];
163 if (method.Name.CompareNoCase(name) == 0)
164 {
165 methodInfo = method;
166 return true;
167 }
168 }
169 return false;
170 }
172 }}