forked from RehabMan/EAPD-Codec-Commander
-
Notifications
You must be signed in to change notification settings - Fork 0
/
extract_hda.sh
executable file
·312 lines (282 loc) · 9.51 KB
/
extract_hda.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
#!/bin/bash
#set -x
# check arguments
if [[ "$#" -lt 3 ]]; then
echo Usage: $0 {AppleHDA-path} {name} {codec-id-1} [codec-id-2 codec-id-n ...]
echo
echo "{AppleHDA-path} is path of patched AppleHDA.kext or AppleHDA injector"
echo "{name} is \"Resources\" folder suffix to be created for extracted files (Extract_name)"
echo "Following the fixed arguments, are one or more codec ids, usually specified in hex, such as 0x10ec0892"
echo "Specifiying zero (0) for a codec id, will result in it matching all that are present"
echo
echo "Examples:"
echo " $0 ~/Downloads/realtekALC.kext ALC892 0x10ec0892"
echo " $0 ~/Downloads/AppleHDA.kext ALC280 0x10ec0892"
echo " $0 ~/Projects/probook.git/AppleHDA_ProBook.kext ProBook 0x10ec0282 0x10ec0280"
echo " $0 ~/Projects/probook.git/AppleHDA_ProBook.kext ProBook 0"
exit
fi
# g_codecFilter array
declare -a g_codecFilter
function add_codec()
# $1 is codec_id
{
local count=${#g_codecFilter[@]}
g_codecFilter[$count]=$(($1))
}
function check_codec()
# $1 is codec_id to check
# echo true/false
{
local count=${#g_codecFilter[@]}
local i
for((i=0; i<$count; i++)); do
if [[ "$1" -eq ${g_codecFilter[$i]} || ${g_codecFilter[$i]} -eq 0 ]]; then
break
fi
done
if [[ $i -eq $count ]]; then
echo false
else
echo true
fi
}
# g_layoutList
declare -a g_layoutList
function add_layout()
# $1 is layout-id to add
{
local count=${#g_layoutList[@]}
local i
for((i=0; i<$count; i++)); do
if [[ "$1" -eq ${g_layoutList[$i]} ]]; then
break
fi
done
if [[ $i == $count ]]; then
g_layoutList[$count]=$(($1))
fi
}
# g_layoutList
declare -a g_pathmapList
function add_pathmap()
# $1 is pathmap-id to add
{
local count=${#g_pathmapList[@]}
local i
for((i=0; i<$count; i++)); do
if [[ "$1" -eq ${g_pathmapList[$i]} ]]; then
break
fi
done
if [[ $i == $count ]]; then
g_pathmapList[$count]=$(($1))
fi
}
function check_pathmap()
# $1 is pathmap_id to check
# echo true/false
{
local count=${#g_pathmapList[@]}
local i
for((i=0; i<$count; i++)); do
if [[ "$1" -eq ${g_pathmapList[$i]} ]]; then
break
fi
done
if [[ $i -eq $count ]]; then
echo false
else
echo true
fi
}
function merge_entry()
# $1 is keypath to read
# $2 is source plist
# $3 is keypath to write
# #4 is dest plist
{
/usr/libexec/PlistBuddy -x -c "Print \"$1\"" "$2" >/tmp/org_rehabman_temp.plist
/usr/libexec/PlistBuddy -x -c "Add \"$3\" dict" "$4"
/usr/libexec/PlistBuddy -c "Merge /tmp/org_rehabman_temp.plist \"$3\"" "$4"
}
hda="$1"
extract=Extract_"$2"
# build list of codecs to filter
for ((i=3; i<=$#; i++)); do
add_codec "${!i}"
done
#echo [dbg] g_codecFilter: ${g_codecFilter[*]}
# determine plist to scan
plist="$hda"/Contents/PlugIns/AppleHDAHardwareConfigDriver.kext/Contents/Info.plist
if [[ ! -e "$plist" ]]; then
plist="$hda"/Contents/Info.plist
fi
if [[ ! -e "$plist" ]]; then
plist=./Info.plist
fi
#echo [dbg] plist: "$plist"
if [[ ! -e "$plist" ]]; then
if [[ ! -e "./hdaconfig.txt" ]]; then
echo "Info.plist at $plist does not exist (and no hdaconfig.txt)"
exit
fi
fi
if [[ ! -d "$extract" ]]; then
rm -rf "$extract"
mkdir "$extract"
fi
rm -f "$extract"/Platforms.plist
rm -f "$extract"/layout*.plist
cat >"$extract"/ahhcd.plist <<ahhcd_starter_plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>HDAConfigDefault</key>
<array/>
</dict>
</plist>
ahhcd_starter_plist
ahhcd_count=0
if [[ -e "$plist" ]]; then
# use PlistBuddy to look at the Info.plist
for ((i=0; 1; i++)); do
prefix=":IOKitPersonalities:HDA Hardware Config Resource:HDAConfigDefault:$i"
codec=`/usr/libexec/PlistBuddy -c "Print \"$prefix:CodecID\"" $plist 2>&1`
if [[ "$codec" == *"Does Not Exist"* ]]; then
break
fi
if [[ `check_codec $codec` == 'true' ]]; then
merge_entry "$prefix" $plist "HDAConfigDefault:$ahhcd_count" "$extract"/ahhcd.plist
((ahhcd_count++))
layout=`/usr/libexec/PlistBuddy -c "Print \"$prefix:LayoutID\"" $plist 2>&1`
if [[ "$layout" != *"Does Not Exist"* ]]; then
add_layout "$layout"
fi
fi
#printf "[dbg] found codec: 0x%x\n" $codec
done
fi
# also look at the root (AppleHDAPatcher style hdaconfig.txt as Info.plist)
plist=hdaconfig.txt
prefix=""
codec=`/usr/libexec/PlistBuddy -c "Print \"$prefix:CodecID\"" $plist 2>&1`
if [[ "$codec" != *"Does Not Exist"* ]]; then
if [[ `check_codec $codec` == 'true' ]]; then
merge_entry "$prefix" $plist "HDAConfigDefault:$ahhcd_count" "$extract"/ahhcd.plist
((ahhcd_count++))
layout=`/usr/libexec/PlistBuddy -c "Print \"$prefix:LayoutID\"" $plist 2>&1`
fi
if [[ "$layout" != *"Does Not Exist"* ]]; then
add_layout "$layout"
fi
fi
#printf "[dbg] found codec: 0x%x\n" $codec
# look at PostConstructionInitialization for additional layout-ids (and perhaps other data)
pci_count=0
for ((i=0; 1; i++)); do
prefix=":IOKitPersonalities:HDA Hardware Config Resource:PostConstructionInitialization:$i"
codec=`/usr/libexec/PlistBuddy -c "Print \"$prefix:CodecID\"" $plist 2>&1`
if [[ "$codec" == *"Does Not Exist"* ]]; then
break
fi
if [[ `check_codec $codec` == 'true' ]]; then
merge_entry "$prefix" $plist "PostConstructionInitialization:$pci_count" "$extract"/ahhcd.plist
((pci_count++))
for((j=0; 1; j++)); do
layout=`/usr/libexec/PlistBuddy -c "Print \"$prefix:Layouts:$j\"" $plist 2>&1`
if [[ "$layout" == *"Does Not Exist"* ]]; then
break
fi
add_layout "$layout"
done
fi
done
echo [dbg] g_layoutList: ${g_layoutList[*]}
for ((i=0; i<${#g_layoutList[@]}; i++)); do
# copy available layout file
layout=${g_layoutList[$i]}
echo layout$layout.zml.zlib
if [[ -e layout$layout.zml.zlib ]]; then
zlib inflate layout$layout.zml.zlib >"$extract"/layout$layout.plist
elif [[ -e layout$layout.xml.zlib ]]; then
zlib inflate layout$layout.xml.zlib >"$extract"/layout$layout.plist
elif [[ -e $1/Contents/Resources/layout$layout.xml.zlib ]]; then
zlib inflate $1/Contents/Resources/layout$layout.xml.zlib >"$extract"/layout$layout.plist
elif [[ -e $1/Contents/Resources/layout$layout.xml ]]; then
cp $1/Contents/Resources/layout$layout.xml "$extract"/layout$layout.plist
fi
done
if [ 0 -eq 1 ]; then
if [[ ! -e "$extract"/layout.bak ]]; then mkdir "$extract"/layout.bak; fi
rm -f "$extract"/layout.bak/*
cp "$extract"/layout*.plist "$extract"/layout.bak
fi
# clean each layout*.plist for codec filter
for layout in "$extract"/layout*.plist; do
for ((i=0; 1; i++)); do
prefix=":PathMapRef:$i"
pathmap=`/usr/libexec/PlistBuddy -c "Print \"$prefix:PathMapID\"" $layout 2>&1`
if [[ "$pathmap" == *"Does Not Exist"* ]]; then
break
fi
for ((j=0; 1; j++)); do
prefix=":PathMapRef:$i:CodecID:$j"
codec=`/usr/libexec/PlistBuddy -c "Print \"$prefix\"" $layout 2>&1`
if [[ "$codec" == *"Does Not Exist"* ]]; then
break
fi
if [[ `check_codec $codec` != "true" ]]; then
#echo [dbg] $layout: deleting \"$prefix\" for codec $codec
/usr/libexec/PlistBuddy -c "Delete \"$prefix\"" $layout
((j--))
fi
done
done
done
# now, delete any PathMapRef with an empty codec list
for layout in "$extract"/layout*.plist; do
for ((i=0; 1; i++)); do
prefix=":PathMapRef:$i"
pathmap=`/usr/libexec/PlistBuddy -c "Print \"$prefix:PathMapID\"" $layout 2>&1`
if [[ "$pathmap" == *"Does Not Exist"* ]]; then
break
fi
test=`/usr/libexec/PlistBuddy -c "Print \"$prefix:CodecID:0\"" $layout 2>&1`
if [[ "$test" == *"Does Not Exist"* ]]; then
#echo [dbg] $layout: deleting \"$prefix\" \($pathmap\)
/usr/libexec/PlistBuddy -c "Delete \"$prefix\"" $layout
((i--))
else
add_pathmap "$pathmap"
fi
done
done
#echo [dbg] g_pathmapList: ${g_pathmapList[*]}
# copy available Platforms
if [[ -e Platforms.zml.zlib ]]; then
zlib inflate Platforms.zml.zlib >"$extract"/Platforms.plist
elif [[ -e Platforms.xml.zlib ]]; then
zlib inflate Platforms.xml.zlib >"$extract"/Platforms.plist
elif [[ -e $1/Contents/Resources/Platforms.xml.zlib ]]; then
zlib inflate $1/Contents/Resources/Platforms.xml.zlib >"$extract"/Platforms.plist
elif [[ -e $1/Contents/Resources/Platforms.xml ]]; then
cp $1/Contents/Resources/Platforms.xml "$extract"/Platforms.plist
fi
/usr/libexec/PlistBuddy -c "Delete :CommonPeripheralDSP" "$extract"/Platforms.plist
# in Platforms.plist, remove any pathmap not in g_pathmapList
plist="$extract"/Platforms.plist
for ((i=0; 1; i++)); do
pathmap=`/usr/libexec/PlistBuddy -c "Print :PathMaps:$i:PathMapID" $plist 2>&1`
if [[ "$pathmap" == *"Does Not Exist"* ]]; then
break
fi
if [[ `check_pathmap $pathmap` != "true" ]]; then
#echo [dbg] Platforms.plist: deleting \":PathMaps:$i\" \($pathmap\)
/usr/libexec/PlistBuddy -c "Delete :PathMaps:$i" $plist
((i--))
fi
done
echo "Extracted files in $extract:"
ls -l "$extract"