LyoKICogV0lORUQzRCBkcmF3IGZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMjAwMi0yMDA0IEphc29uIEVkbWVhZGVzCiAqIENvcHlyaWdodCAyMDAyLTIwMDQgUmFwaGFlbCBKdW5xdWVpcmEKICogQ29weXJpZ2h0IDIwMDQgQ2hyaXN0aWFuIENvc3RhCiAqIENvcHlyaWdodCAyMDA1IE9saXZlciBTdGllYmVyCiAqIENvcHlyaWdodCAyMDA2IEhlbnJpIFZlcmJlZXQKICogQ29weXJpZ2h0IDIwMDcgU3RlZmFuIET2c2luZ2VyIGZvciBDb2RlV2VhdmVycwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCiNpbmNsdWRlICJ3aW5lZDNkX3ByaXZhdGUuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGQzZF9kcmF3KTsKI2RlZmluZSBHTElORk9fTE9DQVRJT04gKChJV2luZUQzREltcGwgKikoVGhpcy0+d2luZUQzRCkpLT5nbF9pbmZvCgojaW5jbHVkZSA8c3RkaW8uaD4KCiNpZiAwIC8qIFRPRE8gKi8KZXh0ZXJuIElXaW5lRDNEVmVydGV4U2hhZGVySW1wbCogICAgICAgICAgICBWZXJ0ZXhTaGFkZXJzWzY0XTsKZXh0ZXJuIElXaW5lRDNEVmVydGV4RGVjbGFyYXRpb25JbXBsKiAgICAgICBWZXJ0ZXhTaGFkZXJEZWNsYXJhdGlvbnNbNjRdOwpleHRlcm4gSVdpbmVEM0RQaXhlbFNoYWRlckltcGwqICAgICAgICAgICAgIFBpeGVsU2hhZGVyc1s2NF07CgojdW5kZWYgR0xfVkVSU0lPTl8xXzQgLyogVG8gYmUgZml4ZWQsIGNhdXNlZCBieSBtZXNhIGhlYWRlcnMgKi8KI2VuZGlmCgovKiBJc3N1ZXMgdGhlIGdsQmVnaW4gY2FsbCBmb3IgZ2wgZ2l2ZW4gdGhlIHByaW1pdGl2ZSB0eXBlIGFuZCBjb3VudCAqLwpzdGF0aWMgRFdPUkQgcHJpbWl0aXZlVG9HbChXSU5FRDNEUFJJTUlUSVZFVFlQRSBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgICAgICAgIERXT1JEICAgICAgICAgICAgTnVtUHJpbWl0aXZlcywKICAgICAgICAgICAgICAgICAgICBHTGVudW0gICAgICAgICAgKnByaW1UeXBlKQp7CiAgICBEV09SRCAgIE51bVZlcnRleGVzID0gTnVtUHJpbWl0aXZlczsKCiAgICBzd2l0Y2ggKFByaW1pdGl2ZVR5cGUpIHsKICAgIGNhc2UgV0lORUQzRFBUX1BPSU5UTElTVDoKICAgICAgICBUUkFDRSgiUE9JTlRTXG4iKTsKICAgICAgICAqcHJpbVR5cGUgICA9IEdMX1BPSU5UUzsKICAgICAgICBOdW1WZXJ0ZXhlcyA9IE51bVByaW1pdGl2ZXM7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXSU5FRDNEUFRfTElORUxJU1Q6CiAgICAgICAgVFJBQ0UoIkxJTkVTXG4iKTsKICAgICAgICAqcHJpbVR5cGUgICA9IEdMX0xJTkVTOwogICAgICAgIE51bVZlcnRleGVzID0gTnVtUHJpbWl0aXZlcyAqIDI7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXSU5FRDNEUFRfTElORVNUUklQOgogICAgICAgIFRSQUNFKCJMSU5FX1NUUklQXG4iKTsKICAgICAgICAqcHJpbVR5cGUgICA9IEdMX0xJTkVfU1RSSVA7CiAgICAgICAgTnVtVmVydGV4ZXMgPSBOdW1QcmltaXRpdmVzICsgMTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIFdJTkVEM0RQVF9UUklBTkdMRUxJU1Q6CiAgICAgICAgVFJBQ0UoIlRSSUFOR0xFU1xuIik7CiAgICAgICAgKnByaW1UeXBlICAgPSBHTF9UUklBTkdMRVM7CiAgICAgICAgTnVtVmVydGV4ZXMgPSBOdW1QcmltaXRpdmVzICogMzsKICAgICAgICBicmVhazsKCiAgICBjYXNlIFdJTkVEM0RQVF9UUklBTkdMRVNUUklQOgogICAgICAgIFRSQUNFKCJUUklBTkdMRV9TVFJJUFxuIik7CiAgICAgICAgKnByaW1UeXBlICAgPSBHTF9UUklBTkdMRV9TVFJJUDsKICAgICAgICBOdW1WZXJ0ZXhlcyA9IE51bVByaW1pdGl2ZXMgKyAyOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgV0lORUQzRFBUX1RSSUFOR0xFRkFOOgogICAgICAgIFRSQUNFKCJUUklBTkdMRV9GQU5cbiIpOwogICAgICAgICpwcmltVHlwZSAgID0gR0xfVFJJQU5HTEVfRkFOOwogICAgICAgIE51bVZlcnRleGVzID0gTnVtUHJpbWl0aXZlcyArIDI7CiAgICAgICAgYnJlYWs7CgogICAgZGVmYXVsdDoKICAgICAgICBGSVhNRSgiVW5oYW5kbGVkIHByaW1pdGl2ZVxuIik7CiAgICAgICAgKnByaW1UeXBlICAgID0gR0xfUE9JTlRTOwogICAgICAgIGJyZWFrOwogICAgfQogICAgcmV0dXJuIE51bVZlcnRleGVzOwp9CgpzdGF0aWMgQk9PTCBmaXhlZF9nZXRfaW5wdXQoCiAgICBCWVRFIHVzYWdlLCBCWVRFIHVzYWdlX2lkeCwKICAgIHVuc2lnbmVkIGludCogcmVnbnVtKSB7CgogICAgKnJlZ251bSA9IC0xOwoKICAgIC8qIFRob3NlIHBvc2l0aW9ucyBtdXN0IGhhdmUgdGhlIG9yZGVyIGluIHRoZQogICAgICogbmFtZWQgcGFydCBvZiB0aGUgc3RyaWRlZCBkYXRhICovCgogICAgaWYgKCh1c2FnZSA9PSBXSU5FRDNEREVDTFVTQUdFX1BPU0lUSU9OIHx8IHVzYWdlID09IFdJTkVEM0RERUNMVVNBR0VfUE9TSVRJT05UKSAmJiB1c2FnZV9pZHggPT0gMCkKICAgICAgICAqcmVnbnVtID0gMDsKICAgIGVsc2UgaWYgKHVzYWdlID09IFdJTkVEM0RERUNMVVNBR0VfQkxFTkRXRUlHSFQgJiYgdXNhZ2VfaWR4ID09IDApCiAgICAgICAgKnJlZ251bSA9IDE7CiAgICBlbHNlIGlmICh1c2FnZSA9PSBXSU5FRDNEREVDTFVTQUdFX0JMRU5ESU5ESUNFUyAmJiB1c2FnZV9pZHggPT0gMCkKICAgICAgICAqcmVnbnVtID0gMjsKICAgIGVsc2UgaWYgKHVzYWdlID09IFdJTkVEM0RERUNMVVNBR0VfTk9STUFMICYmIHVzYWdlX2lkeCA9PSAwKQogICAgICAgICpyZWdudW0gPSAzOwogICAgZWxzZSBpZiAodXNhZ2UgPT0gV0lORUQzRERFQ0xVU0FHRV9QU0laRSAmJiB1c2FnZV9pZHggPT0gMCkKICAgICAgICAqcmVnbnVtID0gNDsKICAgIGVsc2UgaWYgKHVzYWdlID09IFdJTkVEM0RERUNMVVNBR0VfQ09MT1IgJiYgdXNhZ2VfaWR4ID09IDApCiAgICAgICAgKnJlZ251bSA9IDU7CiAgICBlbHNlIGlmICh1c2FnZSA9PSBXSU5FRDNEREVDTFVTQUdFX0NPTE9SICYmIHVzYWdlX2lkeCA9PSAxKQogICAgICAgICpyZWdudW0gPSA2OwogICAgZWxzZSBpZiAodXNhZ2UgPT0gV0lORUQzRERFQ0xVU0FHRV9URVhDT09SRCAmJiB1c2FnZV9pZHggPCBXSU5FRDNERFBfTUFYVEVYQ09PUkQpCiAgICAgICAgKnJlZ251bSA9IDcgKyB1c2FnZV9pZHg7CiAgICBlbHNlIGlmICgodXNhZ2UgPT0gV0lORUQzRERFQ0xVU0FHRV9QT1NJVElPTiB8fCB1c2FnZSA9PSBXSU5FRDNEREVDTFVTQUdFX1BPU0lUSU9OVCkgJiYgdXNhZ2VfaWR4ID09IDEpCiAgICAgICAgKnJlZ251bSA9IDcgKyBXSU5FRDNERFBfTUFYVEVYQ09PUkQ7CiAgICBlbHNlIGlmICh1c2FnZSA9PSBXSU5FRDNEREVDTFVTQUdFX05PUk1BTCAmJiB1c2FnZV9pZHggPT0gMSkKICAgICAgICAqcmVnbnVtID0gOCArIFdJTkVEM0REUF9NQVhURVhDT09SRDsKICAgIGVsc2UgaWYgKHVzYWdlID09IFdJTkVEM0RERUNMVVNBR0VfVEFOR0VOVCAmJiB1c2FnZV9pZHggPT0gMCkKICAgICAgICAqcmVnbnVtID0gOSArIFdJTkVEM0REUF9NQVhURVhDT09SRDsKICAgIGVsc2UgaWYgKHVzYWdlID09IFdJTkVEM0RERUNMVVNBR0VfQklOT1JNQUwgJiYgdXNhZ2VfaWR4ID09IDApCiAgICAgICAgKnJlZ251bSA9IDEwICsgV0lORUQzRERQX01BWFRFWENPT1JEOwogICAgZWxzZSBpZiAodXNhZ2UgPT0gV0lORUQzRERFQ0xVU0FHRV9URVNTRkFDVE9SICYmIHVzYWdlX2lkeCA9PSAwKQogICAgICAgICpyZWdudW0gPSAxMSArIFdJTkVEM0REUF9NQVhURVhDT09SRDsKICAgIGVsc2UgaWYgKHVzYWdlID09IFdJTkVEM0RERUNMVVNBR0VfRk9HICYmIHVzYWdlX2lkeCA9PSAwKQogICAgICAgICpyZWdudW0gPSAxMiArIFdJTkVEM0REUF9NQVhURVhDT09SRDsKICAgIGVsc2UgaWYgKHVzYWdlID09IFdJTkVEM0RERUNMVVNBR0VfREVQVEggJiYgdXNhZ2VfaWR4ID09IDApCiAgICAgICAgKnJlZ251bSA9IDEzICsgV0lORUQzRERQX01BWFRFWENPT1JEOwogICAgZWxzZSBpZiAodXNhZ2UgPT0gV0lORUQzRERFQ0xVU0FHRV9TQU1QTEUgJiYgdXNhZ2VfaWR4ID09IDApCiAgICAgICAgKnJlZ251bSA9IDE0ICsgV0lORUQzRERQX01BWFRFWENPT1JEOwoKICAgIGlmICgqcmVnbnVtIDwgMCkgewogICAgICAgIEZJWE1FKCJVbnN1cHBvcnRlZCBpbnB1dCBzdHJlYW0gW3VzYWdlPSVzLCB1c2FnZV9pZHg9JXVdXG4iLAogICAgICAgICAgICBkZWJ1Z19kM2RkZWNsdXNhZ2UodXNhZ2UpLCB1c2FnZV9pZHgpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KICAgIHJldHVybiBUUlVFOwp9Cgp2b2lkIHByaW1pdGl2ZURlY2xhcmF0aW9uQ29udmVydFRvU3RyaWRlZERhdGEoCiAgICAgSVdpbmVEM0REZXZpY2UgKmlmYWNlLAogICAgIEJPT0wgdXNlVmVydGV4U2hhZGVyRnVuY3Rpb24sCiAgICAgV2luZURpcmVjdDNEVmVydGV4U3RyaWRlZERhdGEgKnN0cmlkZWQsCiAgICAgQk9PTCAqZml4dXApIHsKCiAgICAgLyogV2UgbmVlZCB0byBkZWFsIHdpdGggZnJlcXVlbmN5IGRhdGEhKi8KCiAgICBCWVRFICAqZGF0YSAgICA9IE5VTEw7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFZlcnRleERlY2xhcmF0aW9uSW1wbCogdmVydGV4RGVjbGFyYXRpb24gPSAoSVdpbmVEM0RWZXJ0ZXhEZWNsYXJhdGlvbkltcGwgKilUaGlzLT5zdGF0ZUJsb2NrLT52ZXJ0ZXhEZWNsOwogICAgaW50IGk7CiAgICBXSU5FRDNEVkVSVEVYRUxFTUVOVCAqZWxlbWVudDsKICAgIERXT1JEIHN0cmlkZTsKICAgIGludCByZWc7CiAgICBjaGFyIGlzUHJlTG9hZGVkW01BWF9TVFJFQU1TXTsKICAgIERXT1JEIHByZUxvYWRTdHJlYW1zW01BWF9TVFJFQU1TXSwgbnVtUHJlbG9hZFN0cmVhbXMgPSAwOwoKICAgIG1lbXNldChpc1ByZUxvYWRlZCwgMCwgc2l6ZW9mKGlzUHJlTG9hZGVkKSk7CgogICAgLyogQ2hlY2sgZm9yIHRyYW5zZm9ybWVkIHZlcnRpY2VzLCBkaXNhYmxlIHZlcnRleCBzaGFkZXIgaWYgcHJlc2VudCAqLwogICAgc3RyaWRlZC0+dS5zLnBvc2l0aW9uX3RyYW5zZm9ybWVkID0gRkFMU0U7CiAgICBmb3IgKGkgPSAwOyBpIDwgdmVydGV4RGVjbGFyYXRpb24tPmRlY2xhcmF0aW9uV051bUVsZW1lbnRzIC0gMTsgKytpKSB7CiAgICAgICAgZWxlbWVudCA9IHZlcnRleERlY2xhcmF0aW9uLT5wRGVjbGFyYXRpb25XaW5lICsgaTsKCiAgICAgICAgaWYgKGVsZW1lbnQtPlVzYWdlID09IFdJTkVEM0RERUNMVVNBR0VfUE9TSVRJT05UKSB7CiAgICAgICAgICAgIHN0cmlkZWQtPnUucy5wb3NpdGlvbl90cmFuc2Zvcm1lZCA9IFRSVUU7CiAgICAgICAgICAgIHVzZVZlcnRleFNoYWRlckZ1bmN0aW9uID0gRkFMU0U7CiAgICAgICAgfQogICAgfQoKICAgIC8qIFRyYW5zbGF0ZSB0aGUgZGVjbGFyYXRpb24gaW50byBzdHJpZGVkIGRhdGEgKi8KICAgIGZvciAoaSA9IDAgOyBpIDwgdmVydGV4RGVjbGFyYXRpb24tPmRlY2xhcmF0aW9uV051bUVsZW1lbnRzIC0gMTsgKytpKSB7CiAgICAgICAgR0xpbnQgc3RyZWFtVkJPID0gMDsKICAgICAgICBCT09MIHN0cmlkZV91c2VkOwogICAgICAgIHVuc2lnbmVkIGludCBpZHg7CgogICAgICAgIGVsZW1lbnQgPSB2ZXJ0ZXhEZWNsYXJhdGlvbi0+cERlY2xhcmF0aW9uV2luZSArIGk7CiAgICAgICAgVFJBQ0UoIiVwIEVsZW1lbnQgJXAgKCVkIG9mICVkKVxuIiwgdmVydGV4RGVjbGFyYXRpb24tPnBEZWNsYXJhdGlvbldpbmUsCiAgICAgICAgICAgIGVsZW1lbnQsICBpICsgMSwgdmVydGV4RGVjbGFyYXRpb24tPmRlY2xhcmF0aW9uV051bUVsZW1lbnRzIC0gMSk7CgogICAgICAgIGlmIChUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2VbZWxlbWVudC0+U3RyZWFtXSA9PSBOVUxMKQogICAgICAgICAgICBjb250aW51ZTsKCiAgICAgICAgaWYgKFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbUlzVVApIHsKICAgICAgICAgICAgVFJBQ0UoIlN0cmVhbSBpcyB1cCAlZCwgJXBcbiIsIGVsZW1lbnQtPlN0cmVhbSwgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU291cmNlW2VsZW1lbnQtPlN0cmVhbV0pOwogICAgICAgICAgICBzdHJlYW1WQk8gPSAwOwogICAgICAgICAgICBkYXRhICAgID0gKEJZVEUgKilUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2VbZWxlbWVudC0+U3RyZWFtXTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBUUkFDRSgiU3RyZWFtIGlzbid0IHVwICVkLCAlcFxuIiwgZWxlbWVudC0+U3RyZWFtLCBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2VbZWxlbWVudC0+U3RyZWFtXSk7CiAgICAgICAgICAgIGlmKCFpc1ByZUxvYWRlZFtlbGVtZW50LT5TdHJlYW1dKSB7CiAgICAgICAgICAgICAgICBwcmVMb2FkU3RyZWFtc1tudW1QcmVsb2FkU3RyZWFtc10gPSBlbGVtZW50LT5TdHJlYW07CiAgICAgICAgICAgICAgICBudW1QcmVsb2FkU3RyZWFtcysrOwogICAgICAgICAgICAgICAgaXNQcmVMb2FkZWRbZWxlbWVudC0+U3RyZWFtXSA9IDE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZGF0YSAgICA9IElXaW5lRDNEVmVydGV4QnVmZmVySW1wbF9HZXRNZW1vcnkoVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU291cmNlW2VsZW1lbnQtPlN0cmVhbV0sIDAsICZzdHJlYW1WQk8pOwogICAgICAgICAgICBpZihmaXh1cCkgewogICAgICAgICAgICAgICAgaWYoIHN0cmVhbVZCTyAhPSAwKSAqZml4dXAgPSBUUlVFOwogICAgICAgICAgICAgICAgZWxzZSBpZigqZml4dXAgJiYgIXVzZVZlcnRleFNoYWRlckZ1bmN0aW9uKSB7CiAgICAgICAgICAgICAgICAgICAgLyogVGhpcyBtYXkgYmUgYmFkIHdpdGggdGhlIGZpeGVkIGZ1bmN0aW9uIHBpcGVsaW5lICovCiAgICAgICAgICAgICAgICAgICAgRklYTUUoIk1pc3NpbmcgZml4ZWQgYW5kIHVuZml4ZWQgdmVydGljZXMsIGV4cGVjdCBncmFwaGljcyBnbGl0Y2hlc1xuIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc3RyaWRlICA9IFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVN0cmlkZVtlbGVtZW50LT5TdHJlYW1dOwogICAgICAgIGRhdGEgKz0gZWxlbWVudC0+T2Zmc2V0OwogICAgICAgIHJlZyA9IGVsZW1lbnQtPlJlZzsKCiAgICAgICAgVFJBQ0UoIk9mZnNldCAlZCBTdHJlYW0gJWQgVXNhZ2VJbmRleCAlZFxuIiwgZWxlbWVudC0+T2Zmc2V0LCBlbGVtZW50LT5TdHJlYW0sIGVsZW1lbnQtPlVzYWdlSW5kZXgpOwoKICAgICAgICBpZiAodXNlVmVydGV4U2hhZGVyRnVuY3Rpb24pCiAgICAgICAgICAgIHN0cmlkZV91c2VkID0gdnNoYWRlcl9nZXRfaW5wdXQoVGhpcy0+c3RhdGVCbG9jay0+dmVydGV4U2hhZGVyLAogICAgICAgICAgICAgICAgZWxlbWVudC0+VXNhZ2UsIGVsZW1lbnQtPlVzYWdlSW5kZXgsICZpZHgpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgc3RyaWRlX3VzZWQgPSBmaXhlZF9nZXRfaW5wdXQoZWxlbWVudC0+VXNhZ2UsIGVsZW1lbnQtPlVzYWdlSW5kZXgsICZpZHgpOwoKICAgICAgICBpZiAoc3RyaWRlX3VzZWQpIHsKICAgICAgICAgICAgVFJBQ0UoIkxvYWRlZCAlcyBhcnJheSAldSBbdXNhZ2U9JXMsIHVzYWdlX2lkeD0ldSwgIgogICAgICAgICAgICAgICAgICAgICJzdHJlYW09JXUsIG9mZnNldD0ldSwgc3RyaWRlPSV1LCBWQk89JXVdXG4iLAogICAgICAgICAgICAgICAgICAgIHVzZVZlcnRleFNoYWRlckZ1bmN0aW9uPyAic2hhZGVyIjogImZpeGVkIGZ1bmN0aW9uIiwgaWR4LAogICAgICAgICAgICAgICAgICAgIGRlYnVnX2QzZGRlY2x1c2FnZShlbGVtZW50LT5Vc2FnZSksIGVsZW1lbnQtPlVzYWdlSW5kZXgsCiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC0+U3RyZWFtLCBlbGVtZW50LT5PZmZzZXQsIHN0cmlkZSwgc3RyZWFtVkJPKTsKCiAgICAgICAgICAgIHN0cmlkZWQtPnUuaW5wdXRbaWR4XS5scERhdGEgPSBkYXRhOwogICAgICAgICAgICBzdHJpZGVkLT51LmlucHV0W2lkeF0uZHdUeXBlID0gZWxlbWVudC0+VHlwZTsKICAgICAgICAgICAgc3RyaWRlZC0+dS5pbnB1dFtpZHhdLmR3U3RyaWRlID0gc3RyaWRlOwogICAgICAgICAgICBzdHJpZGVkLT51LmlucHV0W2lkeF0uVkJPID0gc3RyZWFtVkJPOwogICAgICAgICAgICBzdHJpZGVkLT51LmlucHV0W2lkeF0uc3RyZWFtTm8gPSBlbGVtZW50LT5TdHJlYW07CiAgICAgICAgfQogICAgfQogICAgLyogTm93IGNhbGwgUHJlTG9hZCBvbiBhbGwgdGhlIHZlcnRleCBidWZmZXJzLiBJbiB0aGUgdmVyeSByYXJlIGNhc2UKICAgICAqIHRoYXQgdGhlIGJ1ZmZlcnMgc3RvcHBzIGNvbnZlcnRpbmcgUHJlTG9hZCB3aWxsIGRpcnRpZnkgdGhlIFZERUNMIGFnYWluLgogICAgICogVGhlIHZlcnRleCBidWZmZXIgY2FuIG5vdyB1c2UgdGhlIHN0cmlkZWQgc3RydWN0dXJlIGluIHRoZSBkZXZpY2UgaW5zdGVhZCBvZiBmaW5kaW5nIGl0cwogICAgICogb3duIGFnYWluLgogICAgICoKICAgICAqIE5VTEwgc3RyZWFtcyB3b24ndCBiZSByZWNvcmRlZCBpbiB0aGUgYXJyYXksIFVQIHN0cmVhbXMgd29uJ3QgYmUgZWl0aGVyLiBBIHN0cmVhbSBpcyBvbmx5CiAgICAgKiBvbmNlIGluIHRoZXJlLgogICAgICovCiAgICBmb3IoaT0wOyBpIDwgbnVtUHJlbG9hZFN0cmVhbXM7IGkrKykgewogICAgICAgIElXaW5lRDNEVmVydGV4QnVmZmVyX1ByZUxvYWQoVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU291cmNlW3ByZUxvYWRTdHJlYW1zW2ldXSk7CiAgICB9Cn0KCnZvaWQgcHJpbWl0aXZlQ29udmVydEZWRnRvT2Zmc2V0KERXT1JEIHRoaXNGVkYsIERXT1JEIHN0cmlkZSwgQllURSAqZGF0YSwgV2luZURpcmVjdDNEVmVydGV4U3RyaWRlZERhdGEgKnN0cmlkZWQsIEdMaW50IHN0cmVhbVZCTywgVUlOVCBzdHJlYW1ObykgewogICAgaW50ICAgICAgICAgICBudW1CbGVuZHM7CiAgICBpbnQgICAgICAgICAgIG51bVRleHR1cmVzOwogICAgaW50ICAgICAgICAgICB0ZXh0dXJlTm87CiAgICBpbnQgICAgICAgICAgIGNvb3JkSWR4SW5mbyA9IDB4MDA7ICAgIC8qIEluZm9ybWF0aW9uIG9uIG51bWJlciBvZiBjb29yZHMgc3VwcGxpZWQgKi8KICAgIGludCAgICAgICAgICAgbnVtQ29vcmRzWzhdOyAgICAgICAgICAgLyogSG9sZGluZyBwbGFjZSBmb3IgV0lORUQzREZWRl9URVhUVVJFRk9STUFUeCAgKi8KCiAgICAvKiBFaXRoZXIgMyBvciA0IGZsb2F0cyBkZXBlbmRpbmcgb24gdGhlIEZWRiAqLwogICAgLyogRklYTUU6IENhbiBibGVuZGluZyBkYXRhIGJlIGluIGEgZGlmZmVyZW50IHN0cmVhbSB0byB0aGUgcG9zaXRpb24gZGF0YT8KICAgICAgICAgIGFuZCBpZiBzbyB1c2luZyB0aGUgZml4ZWQgcGlwZWxpbmUgaG93IGRvIHdlIGhhbmRsZSBpdCAgICAgICAgICAgICAgICovCiAgICBpZiAodGhpc0ZWRiAmIFdJTkVEM0RGVkZfUE9TSVRJT05fTUFTSykgewogICAgICAgIHN0cmlkZWQtPnUucy5wb3NpdGlvbi5scERhdGEgICAgPSBkYXRhOwogICAgICAgIHN0cmlkZWQtPnUucy5wb3NpdGlvbi5kd1R5cGUgICAgPSBXSU5FRDNEREVDTFRZUEVfRkxPQVQzOwogICAgICAgIHN0cmlkZWQtPnUucy5wb3NpdGlvbi5kd1N0cmlkZSAgPSBzdHJpZGU7CiAgICAgICAgc3RyaWRlZC0+dS5zLnBvc2l0aW9uLlZCTyAgICAgICA9IHN0cmVhbVZCTzsKICAgICAgICBzdHJpZGVkLT51LnMucG9zaXRpb24uc3RyZWFtTm8gID0gc3RyZWFtTm87CiAgICAgICAgZGF0YSArPSAzICogc2l6ZW9mKGZsb2F0KTsKICAgICAgICBpZiAoKHRoaXNGVkYgJiBXSU5FRDNERlZGX1BPU0lUSU9OX01BU0spID09IFdJTkVEM0RGVkZfWFlaUkhXKSB7CiAgICAgICAgICAgIHN0cmlkZWQtPnUucy5wb3NpdGlvbi5kd1R5cGUgPSBXSU5FRDNEREVDTFRZUEVfRkxPQVQ0OwogICAgICAgICAgICBzdHJpZGVkLT51LnMucG9zaXRpb25fdHJhbnNmb3JtZWQgPSBUUlVFOwogICAgICAgICAgICBkYXRhICs9IHNpemVvZihmbG9hdCk7CiAgICAgICAgfSBlbHNlCiAgICAgICAgICAgIHN0cmlkZWQtPnUucy5wb3NpdGlvbl90cmFuc2Zvcm1lZCA9IEZBTFNFOwogICAgfQoKICAgIC8qIEJsZW5kaW5nIGlzIG51bUJsZW5kcyAqIEZMT0FUcyBmb2xsb3dlZCBieSBhIERXT1JEIGZvciBVQllURTQgKi8KICAgIC8qKiBkbyB3ZSBoYXZlIHRvIENoZWNrIFRoaXMtPnN0YXRlQmxvY2stPnJlbmRlclN0YXRlW0QzRFJTX0lOREVYRURWRVJURVhCTEVOREVOQUJMRV0gPyAqLwogICAgbnVtQmxlbmRzID0gMSArICgoKHRoaXNGVkYgJiBXSU5FRDNERlZGX1hZWkI1KSAtIFdJTkVEM0RGVkZfWFlaQjEpID4+IDEpOwogICAgaWYodGhpc0ZWRiAmIFdJTkVEM0RGVkZfTEFTVEJFVEFfVUJZVEU0KSBudW1CbGVuZHMtLTsKCiAgICBpZiAoKHRoaXNGVkYgJiBXSU5FRDNERlZGX1BPU0lUSU9OX01BU0sgKSA+IFdJTkVEM0RGVkZfWFlaUkhXKSB7CiAgICAgICAgVFJBQ0UoIlNldHRpbmcgYmxlbmQgV2VpZ2h0cyB0byAlcFxuIiwgZGF0YSk7CiAgICAgICAgc3RyaWRlZC0+dS5zLmJsZW5kV2VpZ2h0cy5scERhdGEgICAgPSBkYXRhOwogICAgICAgIHN0cmlkZWQtPnUucy5ibGVuZFdlaWdodHMuZHdUeXBlICAgID0gV0lORUQzRERFQ0xUWVBFX0ZMT0FUMSArIG51bUJsZW5kcyAtIDE7CiAgICAgICAgc3RyaWRlZC0+dS5zLmJsZW5kV2VpZ2h0cy5kd1N0cmlkZSAgPSBzdHJpZGU7CiAgICAgICAgc3RyaWRlZC0+dS5zLmJsZW5kV2VpZ2h0cy5WQk8gICAgICAgPSBzdHJlYW1WQk87CiAgICAgICAgc3RyaWRlZC0+dS5zLmJsZW5kV2VpZ2h0cy5zdHJlYW1ObyAgPSBzdHJlYW1ObzsKICAgICAgICBkYXRhICs9IG51bUJsZW5kcyAqIHNpemVvZihGTE9BVCk7CgogICAgICAgIGlmICh0aGlzRlZGICYgV0lORUQzREZWRl9MQVNUQkVUQV9VQllURTQpIHsKICAgICAgICAgICAgc3RyaWRlZC0+dS5zLmJsZW5kTWF0cml4SW5kaWNlcy5scERhdGEgPSBkYXRhOwogICAgICAgICAgICBzdHJpZGVkLT51LnMuYmxlbmRNYXRyaXhJbmRpY2VzLmR3VHlwZSAgPSBXSU5FRDNEREVDTFRZUEVfVUJZVEU0OwogICAgICAgICAgICBzdHJpZGVkLT51LnMuYmxlbmRNYXRyaXhJbmRpY2VzLmR3U3RyaWRlPSBzdHJpZGU7CiAgICAgICAgICAgIHN0cmlkZWQtPnUucy5ibGVuZE1hdHJpeEluZGljZXMuVkJPICAgICA9IHN0cmVhbVZCTzsKICAgICAgICAgICAgc3RyaWRlZC0+dS5zLmJsZW5kTWF0cml4SW5kaWNlcy5zdHJlYW1Obz0gc3RyZWFtTm87CiAgICAgICAgICAgIGRhdGEgKz0gc2l6ZW9mKERXT1JEKTsKICAgICAgICB9CiAgICB9CgogICAgLyogTm9ybWFsIGlzIGFsd2F5cyAzIGZsb2F0cyAqLwogICAgaWYgKHRoaXNGVkYgJiBXSU5FRDNERlZGX05PUk1BTCkgewogICAgICAgIHN0cmlkZWQtPnUucy5ub3JtYWwubHBEYXRhICAgID0gZGF0YTsKICAgICAgICBzdHJpZGVkLT51LnMubm9ybWFsLmR3VHlwZSAgICA9IFdJTkVEM0RERUNMVFlQRV9GTE9BVDM7CiAgICAgICAgc3RyaWRlZC0+dS5zLm5vcm1hbC5kd1N0cmlkZSAgPSBzdHJpZGU7CiAgICAgICAgc3RyaWRlZC0+dS5zLm5vcm1hbC5WQk8gICAgICAgPSBzdHJlYW1WQk87CiAgICAgICAgc3RyaWRlZC0+dS5zLm5vcm1hbC5zdHJlYW1ObyAgPSBzdHJlYW1ObzsKICAgICAgICBkYXRhICs9IDMgKiBzaXplb2YoRkxPQVQpOwogICAgfQoKICAgIC8qIFBvaW50c2l6ZSBpcyBhIHNpbmdsZSBmbG9hdCAqLwogICAgaWYgKHRoaXNGVkYgJiBXSU5FRDNERlZGX1BTSVpFKSB7CiAgICAgICAgc3RyaWRlZC0+dS5zLnBTaXplLmxwRGF0YSAgICA9IGRhdGE7CiAgICAgICAgc3RyaWRlZC0+dS5zLnBTaXplLmR3VHlwZSAgICA9IFdJTkVEM0RERUNMVFlQRV9GTE9BVDE7CiAgICAgICAgc3RyaWRlZC0+dS5zLnBTaXplLmR3U3RyaWRlICA9IHN0cmlkZTsKICAgICAgICBzdHJpZGVkLT51LnMucFNpemUuVkJPICAgICAgID0gc3RyZWFtVkJPOwogICAgICAgIHN0cmlkZWQtPnUucy5wU2l6ZS5zdHJlYW1ObyAgPSBzdHJlYW1ObzsKICAgICAgICBkYXRhICs9IHNpemVvZihGTE9BVCk7CiAgICB9CgogICAgLyogRGlmZnVzZSBpcyA0IHVuc2lnbmVkIGJ5dGVzICovCiAgICBpZiAodGhpc0ZWRiAmIFdJTkVEM0RGVkZfRElGRlVTRSkgewogICAgICAgIHN0cmlkZWQtPnUucy5kaWZmdXNlLmxwRGF0YSAgICA9IGRhdGE7CiAgICAgICAgc3RyaWRlZC0+dS5zLmRpZmZ1c2UuZHdUeXBlICAgID0gV0lORUQzRERFQ0xUWVBFX1NIT1JUNDsKICAgICAgICBzdHJpZGVkLT51LnMuZGlmZnVzZS5kd1N0cmlkZSAgPSBzdHJpZGU7CiAgICAgICAgc3RyaWRlZC0+dS5zLmRpZmZ1c2UuVkJPICAgICAgID0gc3RyZWFtVkJPOwogICAgICAgIHN0cmlkZWQtPnUucy5kaWZmdXNlLnN0cmVhbU5vICA9IHN0cmVhbU5vOwogICAgICAgIGRhdGEgKz0gc2l6ZW9mKERXT1JEKTsKICAgIH0KCiAgICAvKiBTcGVjdWxhciBpcyA0IHVuc2lnbmVkIGJ5dGVzICovCiAgICBpZiAodGhpc0ZWRiAmIFdJTkVEM0RGVkZfU1BFQ1VMQVIpIHsKICAgICAgICBzdHJpZGVkLT51LnMuc3BlY3VsYXIubHBEYXRhICAgID0gZGF0YTsKICAgICAgICBzdHJpZGVkLT51LnMuc3BlY3VsYXIuZHdUeXBlICAgID0gV0lORUQzRERFQ0xUWVBFX1NIT1JUNDsKICAgICAgICBzdHJpZGVkLT51LnMuc3BlY3VsYXIuZHdTdHJpZGUgID0gc3RyaWRlOwogICAgICAgIHN0cmlkZWQtPnUucy5zcGVjdWxhci5WQk8gICAgICAgPSBzdHJlYW1WQk87CiAgICAgICAgc3RyaWRlZC0+dS5zLnNwZWN1bGFyLnN0cmVhbU5vICA9IHN0cmVhbU5vOwogICAgICAgIGRhdGEgKz0gc2l6ZW9mKERXT1JEKTsKICAgIH0KCiAgICAvKiBUZXh0dXJlIGNvb3JkcyAqLwogICAgbnVtVGV4dHVyZXMgICA9ICh0aGlzRlZGICYgV0lORUQzREZWRl9URVhDT1VOVF9NQVNLKSA+PiBXSU5FRDNERlZGX1RFWENPVU5UX1NISUZUOwogICAgY29vcmRJZHhJbmZvICA9ICh0aGlzRlZGICYgMHgwMEZGMDAwMCkgPj4gMTY7IC8qIDE2IGlzIGZyb20gZGVmaW5pdGlvbiBvZiBXSU5FRDNERlZGX1RFWENPT1JEU0laRTEsIGFuZCBpcyA4ICgwLTcgc3RhZ2VzKSAqIDJiaXRzIGxvbmcgKi8KCiAgICAvKiBudW1UZXh0dXJlcyBpbmRpY2F0ZXMgdGhlIG51bWJlciBvZiB0ZXh0dXJlIGNvb3JkaW5hdGVzIHN1cHBsaWVkICovCiAgICAvKiBIb3dldmVyLCB0aGUgZmlyc3Qgc2V0IG1heSBub3QgYmUgZm9yIHN0YWdlIDAgdGV4dHVyZSAtIGl0IGFsbCAgICovCiAgICAvKiAgIGRlcGVuZHMgb24gV0lORUQzRFRTU19URVhDT09SRElOREVYLiAgICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICAvKiBUaGUgbnVtYmVyIG9mIGJ5dGVzIGZvciBlYWNoIGNvb3JkaW5hdGUgc2V0IGlzIGJhc2VkIG9mZiAgICAgICAgICovCiAgICAvKiAgIFdJTkVEM0RGVkZfVEVYQ09PUkRTSVpFbiwgd2hpY2ggYXJlIHRoZSBib3R0b20gMiBiaXRzICAgICAgICAgICAgICAqLwoKICAgIC8qIFNvLCBmb3IgZWFjaCBzdXBwbGllZCB0ZXh0dXJlIGV4dHJhY3QgdGhlIGNvb3JkcyAqLwogICAgZm9yICh0ZXh0dXJlTm8gPSAwOyB0ZXh0dXJlTm8gPCBudW1UZXh0dXJlczsgKyt0ZXh0dXJlTm8pIHsKCiAgICAgICAgc3RyaWRlZC0+dS5zLnRleENvb3Jkc1t0ZXh0dXJlTm9dLmxwRGF0YSAgICA9IGRhdGE7CiAgICAgICAgc3RyaWRlZC0+dS5zLnRleENvb3Jkc1t0ZXh0dXJlTm9dLmR3VHlwZSAgICA9IFdJTkVEM0RERUNMVFlQRV9GTE9BVDE7CiAgICAgICAgc3RyaWRlZC0+dS5zLnRleENvb3Jkc1t0ZXh0dXJlTm9dLmR3U3RyaWRlICA9IHN0cmlkZTsKICAgICAgICBzdHJpZGVkLT51LnMudGV4Q29vcmRzW3RleHR1cmVOb10uVkJPICAgICAgID0gc3RyZWFtVkJPOwogICAgICAgIHN0cmlkZWQtPnUucy50ZXhDb29yZHNbdGV4dHVyZU5vXS5zdHJlYW1ObyAgPSBzdHJlYW1ObzsKICAgICAgICBudW1Db29yZHNbdGV4dHVyZU5vXSA9IGNvb3JkSWR4SW5mbyAmIDB4MDM7CgogICAgICAgIC8qIEFsd2F5cyBvbmUgc2V0ICovCiAgICAgICAgZGF0YSArPSBzaXplb2YoZmxvYXQpOwogICAgICAgIGlmIChudW1Db29yZHNbdGV4dHVyZU5vXSAhPSBXSU5FRDNERlZGX1RFWFRVUkVGT1JNQVQxKSB7CiAgICAgICAgICAgIHN0cmlkZWQtPnUucy50ZXhDb29yZHNbdGV4dHVyZU5vXS5kd1R5cGUgPSBXSU5FRDNEREVDTFRZUEVfRkxPQVQyOwogICAgICAgICAgICBkYXRhICs9IHNpemVvZihmbG9hdCk7CiAgICAgICAgICAgIGlmIChudW1Db29yZHNbdGV4dHVyZU5vXSAhPSBXSU5FRDNERlZGX1RFWFRVUkVGT1JNQVQyKSB7CiAgICAgICAgICAgICAgICBzdHJpZGVkLT51LnMudGV4Q29vcmRzW3RleHR1cmVOb10uZHdUeXBlID0gV0lORUQzRERFQ0xUWVBFX0ZMT0FUMzsKICAgICAgICAgICAgICAgIGRhdGEgKz0gc2l6ZW9mKGZsb2F0KTsKICAgICAgICAgICAgICAgIGlmIChudW1Db29yZHNbdGV4dHVyZU5vXSAhPSBXSU5FRDNERlZGX1RFWFRVUkVGT1JNQVQzKSB7CiAgICAgICAgICAgICAgICAgICAgc3RyaWRlZC0+dS5zLnRleENvb3Jkc1t0ZXh0dXJlTm9dLmR3VHlwZSA9IFdJTkVEM0RERUNMVFlQRV9GTE9BVDQ7CiAgICAgICAgICAgICAgICAgICAgZGF0YSArPSBzaXplb2YoZmxvYXQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGNvb3JkSWR4SW5mbyA9IGNvb3JkSWR4SW5mbyA+PiAyOyAvKiBEcm9wIGJvdHRvbSB0d28gYml0cyAqLwogICAgfQp9Cgp2b2lkIHByaW1pdGl2ZUNvbnZlcnRUb1N0cmlkZWREYXRhKElXaW5lRDNERGV2aWNlICppZmFjZSwgV2luZURpcmVjdDNEVmVydGV4U3RyaWRlZERhdGEgKnN0cmlkZWQsIEJPT0wgKmZpeHVwKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwogICAgR0xpbnQgICAgICAgICBzdHJlYW1WQk8gPSAwOwogICAgRFdPUkQgIHN0cmlkZSAgPSBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1TdHJpZGVbMF07CiAgICBCWVRFICAqZGF0YSAgICA9IE5VTEw7CiAgICBEV09SRCAgdGhpc0ZWRiA9IDA7CgogICAgLyogUmV0cmlldmUgYXBwcm9wcmlhdGUgRlZGICovCiAgICB0aGlzRlZGID0gVGhpcy0+c3RhdGVCbG9jay0+ZnZmOwogICAgLyogSGFuZGxlIG1lbW9yeSBwYXNzZWQgZGlyZWN0bHkgYXMgd2VsbCBhcyB2ZXJ0ZXggYnVmZmVycyAqLwogICAgaWYgKFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbUlzVVApIHsKICAgICAgICBzdHJlYW1WQk8gPSAwOwogICAgICAgIGRhdGEgICAgPSAoQllURSAqKVRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZVswXTsKICAgIH0gZWxzZSB7CiAgICAgICAgLyogVGhlIGZvciBsb29wIHNob3VsZCBpdGVyYXRlIHRocm91Z2ggaGVyZSBvbmx5IG9uY2UgcGVyIHN0cmVhbSwgc28gd2UgZG9uJ3QgbmVlZCBtYWdpYyB0byBwcmV2ZW50IGRvdWJsZSBsb2FkaW5nCiAgICAgICAgICogYnVmZmVycwogICAgICAgICAqLwogICAgICAgIGRhdGEgPSBJV2luZUQzRFZlcnRleEJ1ZmZlckltcGxfR2V0TWVtb3J5KFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZVswXSwgMCwgJnN0cmVhbVZCTyk7CiAgICAgICAgaWYoZml4dXApIHsKICAgICAgICAgICAgaWYoc3RyZWFtVkJPICE9IDAgKSAqZml4dXAgPSBUUlVFOwogICAgICAgIH0KICAgIH0KICAgIFZUUkFDRSgoIkZWRiBmb3Igc3RyZWFtIDAgaXMgJWx4XG4iLCB0aGlzRlZGKSk7CgogICAgLyogTm93IGNvbnZlcnQgdGhlIHN0cmVhbSBpbnRvIHBvaW50ZXJzICovCiAgICBwcmltaXRpdmVDb252ZXJ0RlZGdG9PZmZzZXQodGhpc0ZWRiwgc3RyaWRlLCBkYXRhLCBzdHJpZGVkLCBzdHJlYW1WQk8sIDApOwoKICAgIC8qIE5vdyBjYWxsIFByZUxvYWQgb24gdGhlIHZlcnRleCBidWZmZXIuIEluIHRoZSB2ZXJ5IHJhcmUgY2FzZQogICAgICogdGhhdCB0aGUgYnVmZmVycyBzdG9wcHMgY29udmVydGluZyBQcmVMb2FkIHdpbGwgZGlydGlmeSB0aGUgVkRFQ0wgYWdhaW4uCiAgICAgKiBUaGUgdmVydGV4IGJ1ZmZlciBjYW4gbm93IHVzZSB0aGUgc3RyaWRlZCBzdHJ1Y3R1cmUgaW4gdGhlIGRldmljZSBpbnN0ZWFkIG9mIGZpbmRpbmcgaXRzCiAgICAgKiBvd24gYWdhaW4uCiAgICAgKi8KICAgIGlmKCFUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Jc1VQKSB7CiAgICAgICAgSVdpbmVEM0RWZXJ0ZXhCdWZmZXJfUHJlTG9hZChUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2VbMF0pOwogICAgfQp9CgpzdGF0aWMgdm9pZCBkcmF3U3RyaWRlZEZhc3QoSVdpbmVEM0REZXZpY2UgKmlmYWNlLFVJTlQgbnVtYmVyT2ZWZXJ0aWNlcywgR0xlbnVtIGdsUHJpbWl0aXZlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgY29uc3Qgdm9pZCAqaWR4RGF0YSwgc2hvcnQgaWR4U2l6ZSwgVUxPTkcgbWluSW5kZXgsIFVMT05HIHN0YXJ0SWR4LCBVTE9ORyBzdGFydFZlcnRleCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwoKICAgIGlmIChpZHhTaXplICE9IDAgLyogVGhpcyBjcmFzaGVzIHNvbWV0aW1lcyEqLykgewogICAgICAgIFRSQUNFKCIoJXApIDogZ2xFbGVtZW50cygleCwgJWQsICVkLCAuLi4pXG4iLCBUaGlzLCBnbFByaW1pdGl2ZVR5cGUsIG51bWJlck9mVmVydGljZXMsIG1pbkluZGV4KTsKICAgICAgICBpZHhEYXRhID0gaWR4RGF0YSA9PSAodm9pZCAqKS0xID8gTlVMTCA6IGlkeERhdGE7CiNpZiAxCiAgICAgICAgZ2xEcmF3RWxlbWVudHMoZ2xQcmltaXRpdmVUeXBlLCBudW1iZXJPZlZlcnRpY2VzLCBpZHhTaXplID09IDIgPyBHTF9VTlNJR05FRF9TSE9SVCA6IEdMX1VOU0lHTkVEX0lOVCwKICAgICAgICAgICAgICAgICAgICAgKGNvbnN0IGNoYXIgKilpZHhEYXRhKyhpZHhTaXplICogc3RhcnRJZHgpKTsKI2Vsc2UgLyogdXNpbmcgZHJhd1JhbmdlRWxlbWVudHMgbWF5IGJlIGZhc3RlciAqLwoKICAgICAgICBnbERyYXdSYW5nZUVsZW1lbnRzKGdsUHJpbWl0aXZlVHlwZSwgbWluSW5kZXgsIG1pbkluZGV4ICsgbnVtYmVyT2ZWZXJ0aWNlcyAtIDEsIG51bWJlck9mVmVydGljZXMsCiAgICAgICAgICAgICAgICAgICAgICBpZHhTaXplID09IDIgPyBHTF9VTlNJR05FRF9TSE9SVCA6IEdMX1VOU0lHTkVEX0lOVCwKICAgICAgICAgICAgICAgICAgICAgIChjb25zdCBjaGFyICopaWR4RGF0YSsoaWR4U2l6ZSAqIHN0YXJ0SWR4KSk7CiNlbmRpZgogICAgICAgIGNoZWNrR0xjYWxsKCJnbERyYXdSYW5nZUVsZW1lbnRzIik7CgogICAgfSBlbHNlIHsKCiAgICAgICAgLyogTm90ZSBmaXJzdCBpcyBub3cgemVybyBhcyB3ZSBzaHVmZmxlZCBhbG9uZyBlYXJsaWVyICovCiAgICAgICAgVFJBQ0UoIiglcCkgOiBnbERyYXdBcnJheXMoJXgsIDAsICVkKVxuIiwgVGhpcywgZ2xQcmltaXRpdmVUeXBlLCBudW1iZXJPZlZlcnRpY2VzKTsKICAgICAgICBnbERyYXdBcnJheXMoZ2xQcmltaXRpdmVUeXBlLCBzdGFydFZlcnRleCwgbnVtYmVyT2ZWZXJ0aWNlcyk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0FycmF5cyIpOwoKICAgIH0KCiAgICByZXR1cm47Cn0KCi8qCiAqIEFjdHVhbGx5IGRyYXcgdXNpbmcgdGhlIHN1cHBsaWVkIGluZm9ybWF0aW9uLgogKiBTbG93ZXIgR0wgdmVyc2lvbiB3aGljaCBleHRyYWN0cyBpbmZvIGFib3V0IGVhY2ggdmVydGV4IGluIHR1cm4KICovCgpzdGF0aWMgdm9pZCBkcmF3U3RyaWRlZFNsb3coSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBXaW5lRGlyZWN0M0RWZXJ0ZXhTdHJpZGVkRGF0YSAqc2QsCiAgICAgICAgICAgICAgICAgICAgIFVJTlQgTnVtVmVydGV4ZXMsIEdMZW51bSBnbFByaW1UeXBlLAogICAgICAgICAgICAgICAgICAgICBjb25zdCB2b2lkICppZHhEYXRhLCBzaG9ydCBpZHhTaXplLCBVTE9ORyBtaW5JbmRleCwgVUxPTkcgc3RhcnRJZHgsIFVMT05HIHN0YXJ0VmVydGV4KSB7CgogICAgdW5zaWduZWQgaW50ICAgICAgICAgICAgICAgdGV4dHVyZU5vICAgID0gMDsKICAgIHVuc2lnbmVkIGludCAgICAgICAgICAgICAgIHRleHR1cmVfaWR4ICA9IDA7CiAgICBjb25zdCBXT1JEICAgICAgICAgICAgICAgICpwSWR4QnVmUyAgICAgPSBOVUxMOwogICAgY29uc3QgRFdPUkQgICAgICAgICAgICAgICAqcElkeEJ1ZkwgICAgID0gTlVMTDsKICAgIExPTkcgICAgICAgICAgICAgICAgICAgICAgIHZ4X2luZGV4OwogICAgZmxvYXQgeCAgPSAwLjBmLCB5ICA9IDAuMGYsIHogPSAwLjBmOyAgLyogeCx5LHogY29vcmRpbmF0ZXMgICAgICAgICAgKi8KICAgIGZsb2F0IHJodyA9IDAuMGY7ICAgICAgICAgICAgICAgICAgICAgIC8qIHJodyAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICBEV09SRCBkaWZmdXNlQ29sb3IgPSAweEZGRkZGRkZGOyAgICAgICAvKiBEaWZmdXNlIENvbG9yICAgICAgICAgICAgICAqLwogICAgRFdPUkQgc3BlY3VsYXJDb2xvciA9IDA7ICAgICAgICAgICAgICAgLyogU3BlY3VsYXIgQ29sb3IgICAgICAgICAgICAgKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFVJTlQgKnN0cmVhbU9mZnNldCA9IFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbU9mZnNldDsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgICAgIFNraXBuU3RyaWRlcyA9IHN0YXJ0VmVydGV4ICsgVGhpcy0+c3RhdGVCbG9jay0+bG9hZEJhc2VWZXJ0ZXhJbmRleDsKCiAgICBCWVRFICp0ZXhDb29yZHNbV0lORUQzRERQX01BWFRFWENPT1JEXTsKICAgIEJZVEUgKmRpZmZ1c2UgPSBOVUxMLCAqc3BlY3VsYXIgPSBOVUxMLCAqbm9ybWFsID0gTlVMTCwgKnBvc2l0aW9uID0gTlVMTDsKCiAgICBUUkFDRSgiVXNpbmcgc2xvdyB2ZXJ0ZXggYXJyYXkgY29kZVxuIik7CgogICAgLyogVmFyaWFibGUgSW5pdGlhbGl6YXRpb24gKi8KICAgIGlmIChpZHhTaXplICE9IDApIHsKICAgICAgICAvKiBJbW1lZGlhdGUgbW9kZSBkcmF3aW5nIGNhbid0IG1ha2UgdXNlIG9mIGluZGljZXMgaW4gYSB2Ym8gLSBnZXQgdGhlIGRhdGEgZnJvbSB0aGUgaW5kZXggYnVmZmVyLgogICAgICAgICAqIElmIHRoZSBpbmRleCBidWZmZXIgaGFzIG5vIHZibyhub3Qgc3VwcG9ydGVkIG9yIG90aGVyIHJlYXNvbiksIG9yIHdpdGggdXNlciBwb2ludGVyIGRyYXdpbmcKICAgICAgICAgKiBpZHhEYXRhIHdpbGwgYmUgIT0gTlVMTAogICAgICAgICAqLwogICAgICAgIGlmKGlkeERhdGEgPT0gTlVMTCkgewogICAgICAgICAgICBpZHhEYXRhID0gKChJV2luZUQzREluZGV4QnVmZmVySW1wbCAqKSBUaGlzLT5zdGF0ZUJsb2NrLT5wSW5kZXhEYXRhKS0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5OwogICAgICAgIH0KCiAgICAgICAgaWYgKGlkeFNpemUgPT0gMikgcElkeEJ1ZlMgPSAoY29uc3QgV09SRCAqKSBpZHhEYXRhOwogICAgICAgIGVsc2UgcElkeEJ1ZkwgPSAoY29uc3QgRFdPUkQgKikgaWR4RGF0YTsKICAgIH0KCiAgICAvKiBBZGRpbmcgdGhlIHN0cmVhbSBvZmZzZXQgb25jZSBpcyBjaGVhcGVyIHRoYW4gZG9pbmcgaXQgZXZlcnkgaXRlcmF0aW9uLiBEbyBub3QgbW9kaWZ5IHRoZSBzdHJpZGVkIGRhdGEsIGl0IGlzIGEgcG9pbnRlcgogICAgICogdG8gdGhlIHN0cmlkZWQgRGF0YSBpbiB0aGUgZGV2aWNlIGFuZCBtaWdodCBiZSBuZWVkZWQgaW50YWN0IG9uIHRoZSBuZXh0IGRyYXcKICAgICAqLwogICAgZm9yICh0ZXh0dXJlTm8gPSAwLCB0ZXh0dXJlX2lkeCA9IDA7IHRleHR1cmVObyA8IEdMX0xJTUlUUyh0ZXh0dXJlX3N0YWdlcyk7ICsrdGV4dHVyZU5vKSB7CiAgICAgICAgaWYoc2QtPnUucy50ZXhDb29yZHNbdGV4dHVyZU5vXS5scERhdGEpIHsKICAgICAgICAgICAgdGV4Q29vcmRzW3RleHR1cmVOb10gPSBzZC0+dS5zLnRleENvb3Jkc1t0ZXh0dXJlTm9dLmxwRGF0YSArIHN0cmVhbU9mZnNldFtzZC0+dS5zLnRleENvb3Jkc1t0ZXh0dXJlTm9dLnN0cmVhbU5vXTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0ZXhDb29yZHNbdGV4dHVyZU5vXSA9IE5VTEw7CiAgICAgICAgfQogICAgfQogICAgaWYoc2QtPnUucy5kaWZmdXNlLmxwRGF0YSkgewogICAgICAgIGRpZmZ1c2UgPSBzZC0+dS5zLmRpZmZ1c2UubHBEYXRhICsgc3RyZWFtT2Zmc2V0W3NkLT51LnMuZGlmZnVzZS5zdHJlYW1Ob107CiAgICB9CiAgICBpZihzZC0+dS5zLnNwZWN1bGFyLmxwRGF0YSkgewogICAgICAgIHNwZWN1bGFyID0gc2QtPnUucy5zcGVjdWxhci5scERhdGEgKyBzdHJlYW1PZmZzZXRbc2QtPnUucy5zcGVjdWxhci5zdHJlYW1Ob107CiAgICB9CiAgICBpZihzZC0+dS5zLm5vcm1hbC5scERhdGEpIHsKICAgICAgICBub3JtYWwgPSBzZC0+dS5zLm5vcm1hbC5scERhdGEgKyBzdHJlYW1PZmZzZXRbc2QtPnUucy5ub3JtYWwuc3RyZWFtTm9dOwogICAgfQogICAgaWYoc2QtPnUucy5wb3NpdGlvbi5scERhdGEpIHsKICAgICAgICBwb3NpdGlvbiA9IHNkLT51LnMucG9zaXRpb24ubHBEYXRhICsgc3RyZWFtT2Zmc2V0W3NkLT51LnMucG9zaXRpb24uc3RyZWFtTm9dOwogICAgfQoKICAgIC8qIFN0YXJ0IGRyYXdpbmcgaW4gR0wgKi8KICAgIFZUUkFDRSgoImdsQmVnaW4oJXgpXG4iLCBnbFByaW1UeXBlKSk7CiAgICBnbEJlZ2luKGdsUHJpbVR5cGUpOwoKICAgIC8qIERlZmF1bHQgc2V0dGluZ3MgZm9yIGRhdGEgdGhhdCBpcyBub3QgcGFzc2VkICovCiAgICBpZiAoc2QtPnUucy5ub3JtYWwubHBEYXRhID09IE5VTEwpIHsKICAgICAgICBnbE5vcm1hbDNmKDAsIDAsIDEpOwogICAgfQogICAgaWYoc2QtPnUucy5kaWZmdXNlLmxwRGF0YSA9PSBOVUxMKSB7CiAgICAgICAgZ2xDb2xvcjRmKDEuMGYsIDEuMGYsIDEuMGYsIDEuMGYpOwogICAgfQogICAgaWYoc2QtPnUucy5zcGVjdWxhci5scERhdGEgPT0gTlVMTCkgewogICAgICAgIGlmIChHTF9TVVBQT1JUKEVYVF9TRUNPTkRBUllfQ09MT1IpKSB7CiAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xTZWNvbmRhcnlDb2xvcjNmRVhUKSgwLCAwLCAwKTsKICAgICAgICB9CiAgICB9CgogICAgLyogV2Ugc2hvdWxkbid0IHN0YXJ0IHRoaXMgZnVuY3Rpb24gaWYgYW55IFZCTyBpcyBpbnZvbHZlZC4gU2hvdWxkIEkgcHV0IGEgc2FmZXR5IGNoZWNrIGhlcmU/CiAgICAgKiBHdWVzcyBpdCdzIG5vdCBuZWNlc3Nhcnkod2UgY3Jhc2ggdGhlbiBhbnl3YXkpIGFuZCB3b3VsZCBvbmx5IGVhdCBDUFUgdGltZQogICAgICovCgogICAgLyogRm9yIGVhY2ggcHJpbWl0aXZlICovCiAgICBmb3IgKHZ4X2luZGV4ID0gMDsgdnhfaW5kZXggPCBOdW1WZXJ0ZXhlczsgKyt2eF9pbmRleCkgewoKICAgICAgICAvKiBJbml0aWFsaXplIGRpZmZ1c2UgY29sb3IgKi8KICAgICAgICBkaWZmdXNlQ29sb3IgPSAweEZGRkZGRkZGOwoKICAgICAgICAvKiBCbGVuZGluZyBkYXRhIGFuZCBQb2ludCBzaXplcyBhcmUgbm90IHN1cHBvcnRlZCBieSB0aGlzIGZ1bmN0aW9uLiBUaGV5IGFyZSBub3Qgc3VwcG9ydGVkIGJ5IHRoZSBmaXhlZAogICAgICAgICAqIGZ1bmN0aW9uIHBpcGVsaW5lIGF0IGFsbC4gQSBGaXhtZSBmb3IgdGhlbSBpcyBwcmludGVkIGFmdGVyIGRlY29kaW5nIHRoZSB2ZXJ0ZXggZGVjbGFyYXRpb24KICAgICAgICAgKi8KCiAgICAgICAgLyogRm9yIGluZGV4ZWQgZGF0YSwgd2UgbmVlZCB0byBnbyBhIGZldyBtb3JlIHN0cmlkZXMgaW4gKi8KICAgICAgICBpZiAoaWR4RGF0YSAhPSBOVUxMKSB7CgogICAgICAgICAgICAvKiBJbmRleGVkIHNvIHdvcmsgb3V0IHRoZSBudW1iZXIgb2Ygc3RyaWRlcyB0byBza2lwICovCiAgICAgICAgICAgIGlmIChpZHhTaXplID09IDIpIHsKICAgICAgICAgICAgICAgIFZUUkFDRSgoIklkeCBmb3IgdmVydGV4ICVkID0gJWRcbiIsIHZ4X2luZGV4LCBwSWR4QnVmU1tzdGFydElkeCt2eF9pbmRleF0pKTsKICAgICAgICAgICAgICAgIFNraXBuU3RyaWRlcyA9IHBJZHhCdWZTW3N0YXJ0SWR4ICsgdnhfaW5kZXhdICsgVGhpcy0+c3RhdGVCbG9jay0+bG9hZEJhc2VWZXJ0ZXhJbmRleDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIFZUUkFDRSgoIklkeCBmb3IgdmVydGV4ICVkID0gJWRcbiIsIHZ4X2luZGV4LCBwSWR4QnVmTFtzdGFydElkeCt2eF9pbmRleF0pKTsKICAgICAgICAgICAgICAgIFNraXBuU3RyaWRlcyA9IHBJZHhCdWZMW3N0YXJ0SWR4ICsgdnhfaW5kZXhdICsgVGhpcy0+c3RhdGVCbG9jay0+bG9hZEJhc2VWZXJ0ZXhJbmRleDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyogVGV4dHVyZSBjb29yZHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCiAgICAgICAgZm9yICh0ZXh0dXJlTm8gPSAwLCB0ZXh0dXJlX2lkeCA9IDA7IHRleHR1cmVObyA8IEdMX0xJTUlUUyh0ZXh0dXJlX3N0YWdlcyk7ICsrdGV4dHVyZU5vKSB7CgogICAgICAgICAgICBpZiAoIUdMX1NVUFBPUlQoQVJCX01VTFRJVEVYVFVSRSkgJiYgdGV4dHVyZU5vID4gMCkgewogICAgICAgICAgICAgICAgRklYTUUoIlByb2dyYW0gdXNpbmcgbXVsdGlwbGUgY29uY3VycmVudCB0ZXh0dXJlcyB3aGljaCB0aGlzIG9wZW5nbCBpbXBsZW1lbnRhdGlvbiBkb2Vzbid0IHN1cHBvcnRcbiIpOwogICAgICAgICAgICAgICAgY29udGludWUgOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKiBRdWVyeSB0ZXggY29vcmRzICovCiAgICAgICAgICAgIGlmIChUaGlzLT5zdGF0ZUJsb2NrLT50ZXh0dXJlc1t0ZXh0dXJlTm9dICE9IE5VTEwpIHsKCiAgICAgICAgICAgICAgICBpbnQgICAgY29vcmRJZHggPSBUaGlzLT5zdGF0ZUJsb2NrLT50ZXh0dXJlU3RhdGVbdGV4dHVyZU5vXVtXSU5FRDNEVFNTX1RFWENPT1JESU5ERVhdOwogICAgICAgICAgICAgICAgZmxvYXQgKnB0clRvQ29vcmRzID0gTlVMTDsKICAgICAgICAgICAgICAgIGZsb2F0ICBzID0gMC4wLCB0ID0gMC4wLCByID0gMC4wLCBxID0gMC4wOwoKICAgICAgICAgICAgICAgIGlmIChjb29yZElkeCA+IDcpIHsKICAgICAgICAgICAgICAgICAgICBWVFJBQ0UoKCJ0ZXg6ICVkIC0gU2tpcCB0ZXggY29vcmRzLCBhcyBiZWluZyBzeXN0ZW0gZ2VuZXJhdGVkXG4iLCB0ZXh0dXJlTm8pKTsKICAgICAgICAgICAgICAgICAgICArK3RleHR1cmVfaWR4OwogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjb29yZElkeCA8IDApIHsKICAgICAgICAgICAgICAgICAgICBGSVhNRSgidGV4OiAlZCAtIENvb3JkIGluZGV4ICVkIGlzIGxlc3MgdGhhbiB6ZXJvLCBleHBlY3QgYSBjcmFzaC5cbiIsIHRleHR1cmVObywgY29vcmRJZHgpOwogICAgICAgICAgICAgICAgICAgICsrdGV4dHVyZV9pZHg7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcHRyVG9Db29yZHMgPSAoZmxvYXQgKikodGV4Q29vcmRzW2Nvb3JkSWR4XSArIChTa2lwblN0cmlkZXMgKiBzZC0+dS5zLnRleENvb3Jkc1tjb29yZElkeF0uZHdTdHJpZGUpKTsKICAgICAgICAgICAgICAgIGlmICh0ZXhDb29yZHNbY29vcmRJZHhdID09IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICBUUkFDRSgidGV4OiAlZCAtIFNraXBwaW5nIHRleCBjb29yZHMsIGFzIG5vIGRhdGEgc3VwcGxpZWRcbiIsIHRleHR1cmVObyk7CiAgICAgICAgICAgICAgICAgICAgKyt0ZXh0dXJlX2lkeDsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CgogICAgICAgICAgICAgICAgICAgIGludCBjb29yZHNUb1VzZSA9IHNkLT51LnMudGV4Q29vcmRzW2Nvb3JkSWR4XS5kd1R5cGUgKyAxOyAvKiAwID09IFdJTkVEM0RERUNMVFlQRV9GTE9BVDEgZXRjICovCgogICAgICAgICAgICAgICAgICAgIC8qIFRoZSBjb29yZHMgdG8gc3VwcGx5IGRlcGVuZCBjb21wbGV0ZWx5IG9uIHRoZSBmdmYgLyB2ZXJ0ZXggc2hhZGVyICovCiAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChjb29yZHNUb1VzZSkgewogICAgICAgICAgICAgICAgICAgIGNhc2UgNDogcSA9IHB0clRvQ29vcmRzWzNdOyAvKiBkcm9wIHRocm91Z2ggKi8KICAgICAgICAgICAgICAgICAgICBjYXNlIDM6IHIgPSBwdHJUb0Nvb3Jkc1syXTsgLyogZHJvcCB0aHJvdWdoICovCiAgICAgICAgICAgICAgICAgICAgY2FzZSAyOiB0ID0gcHRyVG9Db29yZHNbMV07IC8qIGRyb3AgdGhyb3VnaCAqLwogICAgICAgICAgICAgICAgICAgIGNhc2UgMTogcyA9IHB0clRvQ29vcmRzWzBdOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLyogUHJvamVjdGVkIGlzIG1vcmUgJ2Z1bicgLSBNb3ZlIHRoZSBsYXN0IGNvb3JkIHRvIHRoZSAncScKICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbWV0ZXIgKHNlZSBjb21tZW50cyB1bmRlciBXSU5FRDNEVFNTX1RFWFRVUkVUUkFOU0ZPUk1GTEFHUyAqLwogICAgICAgICAgICAgICAgICAgIGlmICgoVGhpcy0+c3RhdGVCbG9jay0+dGV4dHVyZVN0YXRlW3RleHR1cmVOb11bV0lORUQzRFRTU19URVhUVVJFVFJBTlNGT1JNRkxBR1NdICE9IFdJTkVEM0RUVEZGX0RJU0FCTEUpICYmCiAgICAgICAgICAgICAgICAgICAgICAgIChUaGlzLT5zdGF0ZUJsb2NrLT50ZXh0dXJlU3RhdGVbdGV4dHVyZU5vXVtXSU5FRDNEVFNTX1RFWFRVUkVUUkFOU0ZPUk1GTEFHU10gJiBXSU5FRDNEVFRGRl9QUk9KRUNURUQpKSB7CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoVGhpcy0+c3RhdGVCbG9jay0+dGV4dHVyZVN0YXRlW3RleHR1cmVOb11bV0lORUQzRFRTU19URVhUVVJFVFJBTlNGT1JNRkxBR1NdICYgV0lORUQzRFRURkZfUFJPSkVDVEVEKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGNvb3Jkc1RvVXNlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDA6ICAvKiBEcm9wIFRocm91Z2ggKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSVhNRSgiV0lORUQzRFRURkZfUFJPSkVDVEVEIGJ1dCBvbmx5IHplcm8gb3Igb25lIGNvb3JkaW5hdGU/XG4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxID0gdDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ID0gMC4wOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvb3Jkc1RvVXNlID0gNDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxID0gcjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByID0gMC4wOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvb3Jkc1RvVXNlID0gNDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgNDogIC8qIE5vcCBoZXJlICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJWE1FKCJVbmV4cGVjdGVkIFdJTkVEM0RUU1NfVEVYVFVSRVRSQU5TRk9STUZMQUdTIHZhbHVlIG9mICVkXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPnN0YXRlQmxvY2stPnRleHR1cmVTdGF0ZVt0ZXh0dXJlTm9dW1dJTkVEM0RUU1NfVEVYVFVSRVRSQU5TRk9STUZMQUdTXSAmIFdJTkVEM0RUVEZGX1BST0pFQ1RFRCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoY29vcmRzVG9Vc2UpIHsgICAvKiBTdXBwbHkgdGhlIHByb3ZpZGVkIHRleHR1cmUgY29vcmRzICovCiAgICAgICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEVFRGRl9DT1VOVDE6CiAgICAgICAgICAgICAgICAgICAgICAgIFZUUkFDRSgoInRleDolZCwgcz0lZlxuIiwgdGV4dHVyZU5vLCBzKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChHTF9TVVBQT1JUKEFSQl9NVUxUSVRFWFRVUkUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBHTF9FWFRDQUxMKGdsTXVsdGlUZXhDb29yZDFmQVJCKHRleHR1cmVfaWR4LCBzKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnbFRleENvb3JkMWYocyk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEVFRGRl9DT1VOVDI6CiAgICAgICAgICAgICAgICAgICAgICAgIFZUUkFDRSgoInRleDolZCwgcz0lZiwgdD0lZlxuIiwgdGV4dHVyZU5vLCBzLCB0KSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChHTF9TVVBQT1JUKEFSQl9NVUxUSVRFWFRVUkUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBHTF9FWFRDQUxMKGdsTXVsdGlUZXhDb29yZDJmQVJCKHRleHR1cmVfaWR4LCBzLCB0KSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnbFRleENvb3JkMmYocywgdCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEVFRGRl9DT1VOVDM6CiAgICAgICAgICAgICAgICAgICAgICAgIFZUUkFDRSgoInRleDolZCwgcz0lZiwgdD0lZiwgcj0lZlxuIiwgdGV4dHVyZU5vLCBzLCB0LCByKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChHTF9TVVBQT1JUKEFSQl9NVUxUSVRFWFRVUkUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBHTF9FWFRDQUxMKGdsTXVsdGlUZXhDb29yZDNmQVJCKHRleHR1cmVfaWR4LCBzLCB0LCByKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnbFRleENvb3JkM2YocywgdCwgcik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEVFRGRl9DT1VOVDQ6CiAgICAgICAgICAgICAgICAgICAgICAgIFZUUkFDRSgoInRleDolZCwgcz0lZiwgdD0lZiwgcj0lZiwgcT0lZlxuIiwgdGV4dHVyZU5vLCBzLCB0LCByLCBxKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChHTF9TVVBQT1JUKEFSQl9NVUxUSVRFWFRVUkUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBHTF9FWFRDQUxMKGdsTXVsdGlUZXhDb29yZDRmQVJCKHRleHR1cmVfaWR4LCBzLCB0LCByLCBxKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnbFRleENvb3JkNGYocywgdCwgciwgcSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgRklYTUUoIlNob3VsZCBub3QgZ2V0IGhlcmUgYXMgY29vcmRzVG9Vc2UgaXMgdHdvIGJpdHMgb25seSAoJXgpIVxuIiwgY29vcmRzVG9Vc2UpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoLyohR0xfU1VQUE9SVChOVl9SRUdJU1RFUl9DT01CSU5FUlMpIHx8IFRoaXMtPnN0YXRlQmxvY2stPnRleHR1cmVzW3RleHR1cmVOb10qL1RSVUUpICsrdGV4dHVyZV9pZHg7CiAgICAgICAgfSAvKiBFbmQgb2YgdGV4dHVyZXMgKi8KCiAgICAgICAgLyogRGlmZnVzZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwogICAgICAgIGlmIChkaWZmdXNlKSB7CiAgICAgICAgICAgIERXT1JEICpwdHJUb0Nvb3JkcyA9IChEV09SRCAqKShkaWZmdXNlICsgKFNraXBuU3RyaWRlcyAqIHNkLT51LnMuZGlmZnVzZS5kd1N0cmlkZSkpOwogICAgICAgICAgICBkaWZmdXNlQ29sb3IgPSBwdHJUb0Nvb3Jkc1swXTsKICAgICAgICAgICAgVlRSQUNFKCgiZGlmZnVzZUNvbG9yPSVseFxuIiwgZGlmZnVzZUNvbG9yKSk7CgogICAgICAgICAgICBnbENvbG9yNHViKEQzRENPTE9SX0JfUihkaWZmdXNlQ29sb3IpLAoJCSAgICAgRDNEQ09MT1JfQl9HKGRpZmZ1c2VDb2xvciksCgkJICAgICBEM0RDT0xPUl9CX0IoZGlmZnVzZUNvbG9yKSwKCQkgICAgIEQzRENPTE9SX0JfQShkaWZmdXNlQ29sb3IpKTsKICAgICAgICAgICAgVlRSQUNFKCgiZ2xDb2xvcjR1YjogcixnLGIsYT0lbHUsJWx1LCVsdSwlbHVcbiIsIAogICAgICAgICAgICAgICAgICAgIEQzRENPTE9SX0JfUihkaWZmdXNlQ29sb3IpLAoJCSAgICBEM0RDT0xPUl9CX0coZGlmZnVzZUNvbG9yKSwKCQkgICAgRDNEQ09MT1JfQl9CKGRpZmZ1c2VDb2xvciksCgkJICAgIEQzRENPTE9SX0JfQShkaWZmdXNlQ29sb3IpKSk7CiAgICAgICAgfQoKICAgICAgICAvKiBTcGVjdWxhciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCiAgICAgICAgaWYgKHNwZWN1bGFyKSB7CiAgICAgICAgICAgIERXT1JEICpwdHJUb0Nvb3JkcyA9IChEV09SRCAqKShzcGVjdWxhciArIChTa2lwblN0cmlkZXMgKiBzZC0+dS5zLnNwZWN1bGFyLmR3U3RyaWRlKSk7CiAgICAgICAgICAgIHNwZWN1bGFyQ29sb3IgPSBwdHJUb0Nvb3Jkc1swXTsKICAgICAgICAgICAgVlRSQUNFKCgic3BlY3VsYXJDb2xvcj0lbHhcbiIsIHNwZWN1bGFyQ29sb3IpKTsKCiAgICAgICAgICAgIC8qIHNwZWNpYWwgY2FzZSB3aGVyZSB0aGUgZm9nIGRlbnNpdHkgaXMgc3RvcmVkIGluIHRoZSBzcGVjdWxhciBhbHBoYSBjaGFubmVsICovCiAgICAgICAgICAgIGlmKFRoaXMtPnN0YXRlQmxvY2stPnJlbmRlclN0YXRlW1dJTkVEM0RSU19GT0dFTkFCTEVdICYmCiAgICAgICAgICAgICAgKFRoaXMtPnN0YXRlQmxvY2stPnJlbmRlclN0YXRlW1dJTkVEM0RSU19GT0dWRVJURVhNT0RFXSA9PSBXSU5FRDNERk9HX05PTkUgfHwgc2QtPnUucy5wb3NpdGlvbi5kd1R5cGUgPT0gV0lORUQzRERFQ0xUWVBFX0ZMT0FUNCApJiYKICAgICAgICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtXSU5FRDNEUlNfRk9HVEFCTEVNT0RFXSA9PSBXSU5FRDNERk9HX05PTkUpIHsKICAgICAgICAgICAgICAgIGlmKEdMX1NVUFBPUlQoRVhUX0ZPR19DT09SRCkpIHsKICAgICAgICAgICAgICAgICAgICBHTF9FWFRDQUxMKGdsRm9nQ29vcmRmRVhUKHNwZWN1bGFyQ29sb3IgPj4gMjQpKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgc3RhdGljIEJPT0wgd2FybmVkID0gRkFMU0U7CiAgICAgICAgICAgICAgICAgICAgaWYoIXdhcm5lZCkgewogICAgICAgICAgICAgICAgICAgICAgICAvKiBUT0RPOiBVc2UgdGhlIGZvZyB0YWJsZSBjb2RlIGZyb20gb2xkIGRkcmF3ICovCiAgICAgICAgICAgICAgICAgICAgICAgIEZJWE1FKCJJbXBsZW1lbnQgZm9nIGZvciB0cmFuc2Zvcm1lZCB2ZXJ0aWNlcyBpbiBzb2Z0d2FyZVxuIik7CiAgICAgICAgICAgICAgICAgICAgICAgIHdhcm5lZCA9IFRSVUU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBWVFJBQ0UoKCJnbFNlY29uZGFyeUNvbG9yNHViOiByLGcsYj0lbHUsJWx1LCVsdVxuIiwgCiAgICAgICAgICAgICAgICAgICAgRDNEQ09MT1JfQl9SKHNwZWN1bGFyQ29sb3IpLCAKICAgICAgICAgICAgICAgICAgICBEM0RDT0xPUl9CX0coc3BlY3VsYXJDb2xvciksIAogICAgICAgICAgICAgICAgICAgIEQzRENPTE9SX0JfQihzcGVjdWxhckNvbG9yKSkpOwogICAgICAgICAgICBpZiAoR0xfU1VQUE9SVChFWFRfU0VDT05EQVJZX0NPTE9SKSkgewogICAgICAgICAgICAgICAgR0xfRVhUQ0FMTChnbFNlY29uZGFyeUNvbG9yM3ViRVhUKSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEQ09MT1JfQl9SKHNwZWN1bGFyQ29sb3IpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RDT0xPUl9CX0coc3BlY3VsYXJDb2xvciksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRENPTE9SX0JfQihzcGVjdWxhckNvbG9yKSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvKiBEbyBub3Qgd29ycnkgaWYgc3BlY3VsYXIgY29sb3VyIG1pc3NpbmcgYW5kIGRpc2FibGUgcmVxdWVzdCAqLwogICAgICAgICAgICAgICAgVlRSQUNFKCgiU3BlY3VsYXIgY29sb3IgZXh0ZW5zaW9ucyBub3Qgc3VwcGxpZWRcbiIpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyogTm9ybWFsIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCiAgICAgICAgaWYgKG5vcm1hbCAhPSBOVUxMKSB7CiAgICAgICAgICAgIGZsb2F0ICpwdHJUb0Nvb3JkcyA9IChmbG9hdCAqKShub3JtYWwgKyAoU2tpcG5TdHJpZGVzICogc2QtPnUucy5ub3JtYWwuZHdTdHJpZGUpKTsKCiAgICAgICAgICAgIFZUUkFDRSgoImdsTm9ybWFsOm54LG55LG56PSVmLCVmLCVmXG4iLCBwdHJUb0Nvb3Jkc1swXSwgcHRyVG9Db29yZHNbMV0sIHB0clRvQ29vcmRzWzJdKSk7CiAgICAgICAgICAgIGdsTm9ybWFsM2YocHRyVG9Db29yZHNbMF0sIHB0clRvQ29vcmRzWzFdLCBwdHJUb0Nvb3Jkc1syXSk7CiAgICAgICAgfQoKICAgICAgICAvKiBQb3NpdGlvbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwogICAgICAgIGlmIChwb3NpdGlvbikgewogICAgICAgICAgICBmbG9hdCAqcHRyVG9Db29yZHMgPSAoZmxvYXQgKikocG9zaXRpb24gKyAoU2tpcG5TdHJpZGVzICogc2QtPnUucy5wb3NpdGlvbi5kd1N0cmlkZSkpOwogICAgICAgICAgICB4ID0gcHRyVG9Db29yZHNbMF07CiAgICAgICAgICAgIHkgPSBwdHJUb0Nvb3Jkc1sxXTsKICAgICAgICAgICAgeiA9IHB0clRvQ29vcmRzWzJdOwogICAgICAgICAgICByaHcgPSAxLjA7CiAgICAgICAgICAgIFZUUkFDRSgoIngseSx6PSVmLCVmLCVmXG4iLCB4LHkseikpOwoKICAgICAgICAgICAgLyogUkhXIGZvbGxvd3MsIG9ubHkgaWYgdHJhbnNmb3JtZWQsIGllIDQgZmxvYXRzIHdlcmUgcHJvdmlkZWQgKi8KICAgICAgICAgICAgaWYgKHNkLT51LnMucG9zaXRpb25fdHJhbnNmb3JtZWQpIHsKICAgICAgICAgICAgICAgIHJodyA9IHB0clRvQ29vcmRzWzNdOwogICAgICAgICAgICAgICAgVlRSQUNFKCgicmh3PSVmXG4iLCByaHcpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKDEuMGYgPT0gcmh3IHx8ICgocmh3IDwgZXBzKSAmJiAocmh3ID4gLWVwcykpKSB7CiAgICAgICAgICAgICAgICBWVFJBQ0UoKCJWZXJ0ZXg6IGdsVmVydGV4OngseSx6PSVmLCVmLCVmXG4iLCB4LHkseikpOwogICAgICAgICAgICAgICAgZ2xWZXJ0ZXgzZih4LCB5LCB6KTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIEdMZmxvYXQgdyA9IDEuMCAvIHJodzsKICAgICAgICAgICAgICAgIFZUUkFDRSgoIlZlcnRleDogZ2xWZXJ0ZXg6eCx5LHo9JWYsJWYsJWYgLyByaHc9JWZcbiIsIHgseSx6LHJodykpOwogICAgICAgICAgICAgICAgZ2xWZXJ0ZXg0Zih4KncsIHkqdywgeip3LCB3KTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyogRm9yIG5vbiBpbmRleGVkIG1vZGUsIHN0ZXAgb250byBuZXh0IHBhcnRzICovCiAgICAgICAgaWYgKGlkeERhdGEgPT0gTlVMTCkgewogICAgICAgICAgICArK1NraXBuU3RyaWRlczsKICAgICAgICB9CiAgICB9CgogICAgZ2xFbmQoKTsKICAgIGNoZWNrR0xjYWxsKCJnbEVuZCBhbmQgcHJldmlvdXMgY2FsbHMiKTsKfQoKc3RhdGljIHZvaWQgZGVwdGhfYmx0KElXaW5lRDNERGV2aWNlICppZmFjZSwgR0x1aW50IHRleHR1cmUpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIEdMaW50IG9sZF9iaW5kaW5nID0gMDsKCiAgICBnbFB1c2hBdHRyaWIoR0xfRU5BQkxFX0JJVCB8IEdMX0RFUFRIX0JVRkZFUl9CSVQpOwoKICAgIGdsRGlzYWJsZShHTF9DVUxMX0ZBQ0UpOwogICAgZ2xEaXNhYmxlKEdMX0JMRU5EKTsKICAgIGdsRGlzYWJsZShHTF9BTFBIQV9URVNUKTsKICAgIGdsRGlzYWJsZShHTF9TQ0lTU09SX1RFU1QpOwogICAgZ2xEaXNhYmxlKEdMX1NURU5DSUxfVEVTVCk7CiAgICBnbEVuYWJsZShHTF9ERVBUSF9URVNUKTsKICAgIGdsRGVwdGhGdW5jKEdMX0FMV0FZUyk7CgogICAgR0xfRVhUQ0FMTChnbEFjdGl2ZVRleHR1cmVBUkIoR0xfVEVYVFVSRTBfQVJCKSk7CiAgICBnbEdldEludGVnZXJ2KEdMX1RFWFRVUkVfQklORElOR18yRCwgJm9sZF9iaW5kaW5nKTsKICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgdGV4dHVyZSk7CiAgICBnbEVuYWJsZShHTF9URVhUVVJFXzJEKTsKCiAgICBUaGlzLT5zaGFkZXJfYmFja2VuZC0+c2hhZGVyX3NlbGVjdF9kZXB0aF9ibHQoaWZhY2UpOwoKICAgIGdsQmVnaW4oR0xfVFJJQU5HTEVfU1RSSVApOwogICAgZ2xWZXJ0ZXgyZigtMS4wZiwgLTEuMGYpOwogICAgZ2xWZXJ0ZXgyZigxLjBmLCAtMS4wZik7CiAgICBnbFZlcnRleDJmKC0xLjBmLCAxLjBmKTsKICAgIGdsVmVydGV4MmYoMS4wZiwgMS4wZik7CiAgICBnbEVuZCgpOwoKICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgb2xkX2JpbmRpbmcpOwoKICAgIGdsUG9wQXR0cmliKCk7CgogICAgLyogUmVzZWxlY3QgdGhlIG9sZCBzaGFkZXJzLiBUaGVyZSBkb2Vzbid0IHNlZW0gdG8gYmUgYW55IGdsUHVzaEF0dHJpYiBiaXQgZm9yIGFyYiBzaGFkZXJzLAogICAgICogYW5kIHRoaXMgc2VlbXMgZWFzaWVyIGFuZCBtb3JlIGVmZmljaWVudCB0aGFuIHByb3ZpZGluZyB0aGUgc2hhZGVyIGJhY2tlbmQgd2l0aCBhIHByaXZhdGUKICAgICAqIHN0b3JhZ2UgdG8gcmVhZCBhbmQgcmVzdG9yZSB0aGUgb2xkIHNoYWRlciBzZXR0aW5ncwogICAgICovCiAgICBUaGlzLT5zaGFkZXJfYmFja2VuZC0+c2hhZGVyX3NlbGVjdChpZmFjZSwgdXNlX3BzKFRoaXMpLCB1c2VfdnMoVGhpcykpOwp9CgpzdGF0aWMgdm9pZCBkZXB0aF9jb3B5KElXaW5lRDNERGV2aWNlICppZmFjZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqZGVwdGhfc3RlbmNpbCA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopVGhpcy0+ZGVwdGhTdGVuY2lsQnVmZmVyOwoKICAgIC8qIE9ubHkgY29weSB0aGUgZGVwdGggYnVmZmVyIGlmIHRoZXJlIGlzIG9uZS4gKi8KICAgIGlmICghZGVwdGhfc3RlbmNpbCkgcmV0dXJuOwoKICAgIC8qIFRPRE86IE1ha2UgdGhpcyB3b3JrIGZvciBtb2RlcyBvdGhlciB0aGFuIEZCTyAqLwogICAgaWYgKHdpbmVkM2Rfc2V0dGluZ3Mub2Zmc2NyZWVuX3JlbmRlcmluZ19tb2RlICE9IE9STV9GQk8pIHJldHVybjsKCiAgICBpZiAoZGVwdGhfc3RlbmNpbC0+Y3VycmVudF9yZW5kZXJidWZmZXIpIHsKICAgICAgICBGSVhNRSgiTm90IHN1cHBvcnRlZCB3aXRoIGZpeGVkIHVwIGRlcHRoIHN0ZW5jaWxcbiIpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBpZiAoVGhpcy0+cmVuZGVyX29mZnNjcmVlbikgewogICAgICAgIHN0YXRpYyBHTHVpbnQgdG1wX3RleHR1cmUgPSAwOwogICAgICAgIEdMaW50IG9sZF9iaW5kaW5nID0gMDsKCiAgICAgICAgVFJBQ0UoIkNvcHlpbmcgb25zY3JlZW4gZGVwdGggYnVmZmVyIHRvIG9mZnNjcmVlbiBzdXJmYWNlXG4iKTsKCiAgICAgICAgaWYgKCF0bXBfdGV4dHVyZSkgewogICAgICAgICAgICBnbEdlblRleHR1cmVzKDEsICZ0bXBfdGV4dHVyZSk7CiAgICAgICAgfQoKICAgICAgICAvKiBOb3RlIHRoYXQgd2UgdXNlIGRlcHRoX2JsdCBoZXJlIGFzIHdlbGwsIHJhdGhlciB0aGFuIGdsQ29weVRleEltYWdlMkQKICAgICAgICAgKiBkaXJlY3RseSBvbiB0aGUgRkJPIHRleHR1cmUuIFRoYXQncyBiZWNhdXNlIHdlIG5lZWQgdG8gZmxpcC4gKi8KICAgICAgICBHTF9FWFRDQUxMKGdsQmluZEZyYW1lYnVmZmVyRVhUKEdMX0ZSQU1FQlVGRkVSX0VYVCwgMCkpOwogICAgICAgIGdsR2V0SW50ZWdlcnYoR0xfVEVYVFVSRV9CSU5ESU5HXzJELCAmb2xkX2JpbmRpbmcpOwogICAgICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgdG1wX3RleHR1cmUpOwogICAgICAgIGdsQ29weVRleEltYWdlMkQoZGVwdGhfc3RlbmNpbC0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsCiAgICAgICAgICAgICAgICBkZXB0aF9zdGVuY2lsLT5nbERlc2NyaXB0aW9uLmxldmVsLAogICAgICAgICAgICAgICAgZGVwdGhfc3RlbmNpbC0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdEludGVybmFsLAogICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICBkZXB0aF9zdGVuY2lsLT5jdXJyZW50RGVzYy5XaWR0aCwKICAgICAgICAgICAgICAgIGRlcHRoX3N0ZW5jaWwtPmN1cnJlbnREZXNjLkhlaWdodCwKICAgICAgICAgICAgICAgIDApOwogICAgICAgIGdsVGV4UGFyYW1ldGVyaShHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX01JTl9GSUxURVIsIEdMX05FQVJFU1QpOwogICAgICAgIGdsVGV4UGFyYW1ldGVyaShHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX01BR19GSUxURVIsIEdMX05FQVJFU1QpOwogICAgICAgIGdsVGV4UGFyYW1ldGVyaShHTF9URVhUVVJFXzJELCBHTF9ERVBUSF9URVhUVVJFX01PREVfQVJCLCBHTF9MVU1JTkFOQ0UpOwogICAgICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgb2xkX2JpbmRpbmcpOwoKICAgICAgICBHTF9FWFRDQUxMKGdsQmluZEZyYW1lYnVmZmVyRVhUKEdMX0ZSQU1FQlVGRkVSX0VYVCwgVGhpcy0+ZmJvKSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQmluZEZyYW1lYnVmZmVyKCkiKTsKICAgICAgICBkZXB0aF9ibHQoaWZhY2UsIHRtcF90ZXh0dXJlKTsKICAgICAgICBjaGVja0dMY2FsbCgiZGVwdGhfYmx0Iik7CiAgICB9IGVsc2UgewogICAgICAgIFRSQUNFKCJDb3B5aW5nIG9mZnNjcmVlbiBzdXJmYWNlIHRvIG9uc2NyZWVuIGRlcHRoIGJ1ZmZlclxuIik7CgogICAgICAgIEdMX0VYVENBTEwoZ2xCaW5kRnJhbWVidWZmZXJFWFQoR0xfRlJBTUVCVUZGRVJfRVhULCAwKSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQmluZEZyYW1lYnVmZmVyKCkiKTsKICAgICAgICBkZXB0aF9ibHQoaWZhY2UsIGRlcHRoX3N0ZW5jaWwtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpOwogICAgICAgIGNoZWNrR0xjYWxsKCJkZXB0aF9ibHQiKTsKICAgIH0KfQoKc3RhdGljIGlubGluZSB2b2lkIGRyYXdTdHJpZGVkSW5zdGFuY2VkKElXaW5lRDNERGV2aWNlICppZmFjZSwgV2luZURpcmVjdDNEVmVydGV4U3RyaWRlZERhdGEgKnNkLCBVSU5UIG51bWJlck9mVmVydGljZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdMZW51bSBnbFByaW1pdGl2ZVR5cGUsIGNvbnN0IHZvaWQgKmlkeERhdGEsIHNob3J0IGlkeFNpemUsIFVMT05HIG1pbkluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVTE9ORyBzdGFydElkeCwgVUxPTkcgc3RhcnRWZXJ0ZXgpIHsKICAgIFVJTlQgbnVtSW5zdGFuY2VzID0gMDsKICAgIGludCBudW1JbnN0YW5jZWRBdHRyaWJzID0gMCwgaSwgajsKICAgIFVJTlQgaW5zdGFuY2VkRGF0YVtzaXplb2Yoc2QtPnUuaW5wdXQpIC8gc2l6ZW9mKHNkLT51LmlucHV0WzBdKSAvKiAxNiAqL107CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwogICAgSVdpbmVEM0RTdGF0ZUJsb2NrSW1wbCAqc3RhdGVibG9jayA9IFRoaXMtPnN0YXRlQmxvY2s7CgogICAgaWYgKGlkeFNpemUgPT0gMCkgewogICAgICAgIC8qIFRoaXMgaXMgYSBuYXN0eSB0aGluZy4gTVNETiBzYXlzIG5vIGhhcmR3YXJlIHN1cHBvcnRzIHRoYXQgYW5kIGFwcHMgaGF2ZSB0byB1c2Ugc29mdHdhcmUgdmVydGV4IHByb2Nlc3NpbmcuCiAgICAgICAgICogV2UgZG9uJ3Qgc3VwcG9ydCB0aGlzIGZvciBub3cKICAgICAgICAgKgogICAgICAgICAqIFNob3VsZG4ndCBiZSB0b28gaGFyZCB0byBzdXBwb3J0IHdpdGggb3BlbmdsLCBpbiB0aGVvcnkganVzdCBjYWxsIGdsRHJhd0FycmF5cyBpbnN0ZWFkIG9mIGRyYXdFbGVtZW50cy4KICAgICAgICAgKiBCdXQgdGhlIFN0cmVhbVNvdXJjZUZyZXEgdmFsdWUgaGFzIGEgZGlmZmVyZW50IG1lYW5pbmcgaW4gdGhhdCBzaXR1YXRpb24uCiAgICAgICAgICovCiAgICAgICAgRklYTUUoIk5vbi1pbmRleGVkIGluc3RhbmNlZCBkcmF3aW5nIGlzIG5vdCBzdXBwb3J0ZWRcbiIpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBUUkFDRSgiKCVwKSA6IGdsRWxlbWVudHMoJXgsICVkLCAlZCwgLi4uKVxuIiwgVGhpcywgZ2xQcmltaXRpdmVUeXBlLCBudW1iZXJPZlZlcnRpY2VzLCBtaW5JbmRleCk7CiAgICBpZHhEYXRhID0gaWR4RGF0YSA9PSAodm9pZCAqKS0xID8gTlVMTCA6IGlkeERhdGE7CgogICAgLyogRmlyc3QsIGZpZ3VyZSBvdXQgaG93IG1hbnkgaW5zdGFuY2VzIHdlIGhhdmUgdG8gZHJhdyAqLwogICAgZm9yKGkgPSAwOyBpIDwgTUFYX1NUUkVBTVM7IGkrKykgewogICAgICAgIC8qIExvb2sgYXQgYWxsIG5vbi1pbnN0YW5jZWQgc3RyZWFtcyAqLwogICAgICAgIGlmKCEoc3RhdGVibG9jay0+c3RyZWFtRmxhZ3NbaV0gJiBXSU5FRDNEU1RSRUFNU09VUkNFX0lOU1RBTkNFREFUQSkgJiYKICAgICAgICAgICBzdGF0ZWJsb2NrLT5zdHJlYW1Tb3VyY2VbaV0pIHsKICAgICAgICAgICAgaW50IGluc3QgPSBzdGF0ZWJsb2NrLT5zdHJlYW1GcmVxW2ldOwoKICAgICAgICAgICAgaWYobnVtSW5zdGFuY2VzICYmIGluc3QgIT0gbnVtSW5zdGFuY2VzKSB7CiAgICAgICAgICAgICAgICBFUlIoIlR3byBzdHJlYW1zIHNwZWNpZnkgYSBkaWZmZXJlbnQgbnVtYmVyIG9mIGluc3RhbmNlcy4gR290ICVkLCBuZXcgaXMgJWRcbiIsIG51bUluc3RhbmNlcywgaW5zdCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbnVtSW5zdGFuY2VzID0gaW5zdDsKICAgICAgICB9CiAgICB9CgogICAgZm9yKGkgPSAwOyBpIDwgc2l6ZW9mKHNkLT51LmlucHV0KSAvIHNpemVvZihzZC0+dS5pbnB1dFswXSk7IGkrKykgewogICAgICAgIGlmKHN0YXRlYmxvY2stPnN0cmVhbUZsYWdzW3NkLT51LmlucHV0W2ldLnN0cmVhbU5vXSAmIFdJTkVEM0RTVFJFQU1TT1VSQ0VfSU5TVEFOQ0VEQVRBKSB7CiAgICAgICAgICAgIGluc3RhbmNlZERhdGFbbnVtSW5zdGFuY2VkQXR0cmlic10gPSBpOwogICAgICAgICAgICBudW1JbnN0YW5jZWRBdHRyaWJzKys7CiAgICAgICAgfQogICAgfQoKICAgIC8qIG5vdyBkcmF3IG51bUluc3RhbmNlcyBpbnN0YW5jZXMgOi0pICovCiAgICBmb3IoaSA9IDA7IGkgPCBudW1JbnN0YW5jZXM7IGkrKykgewogICAgICAgIC8qIFNwZWNpZnkgdGhlIGluc3RhbmNlZCBhdHRyaWJ1dGVzIHVzaW5nIGltbWVkaWF0ZSBtb2RlIGNhbGxzICovCiAgICAgICAgZm9yKGogPSAwOyBqIDwgbnVtSW5zdGFuY2VkQXR0cmliczsgaisrKSB7CiAgICAgICAgICAgIEJZVEUgKnB0ciA9IHNkLT51LmlucHV0W2luc3RhbmNlZERhdGFbal1dLmxwRGF0YSArCiAgICAgICAgICAgICAgICAgICAgICAgIHNkLT51LmlucHV0W2luc3RhbmNlZERhdGFbal1dLmR3U3RyaWRlICogaSArCiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlYmxvY2stPnN0cmVhbU9mZnNldFtzZC0+dS5pbnB1dFtpbnN0YW5jZWREYXRhW2pdXS5zdHJlYW1Ob107CiAgICAgICAgICAgIGlmKHNkLT51LmlucHV0W2luc3RhbmNlZERhdGFbal1dLlZCTykgewogICAgICAgICAgICAgICAgSVdpbmVEM0RWZXJ0ZXhCdWZmZXJJbXBsICp2YiA9IChJV2luZUQzRFZlcnRleEJ1ZmZlckltcGwgKikgc3RhdGVibG9jay0+c3RyZWFtU291cmNlW3NkLT51LmlucHV0W2luc3RhbmNlZERhdGFbal1dLnN0cmVhbU5vXTsKICAgICAgICAgICAgICAgIHB0ciArPSAobG9uZykgdmItPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgc3dpdGNoKHNkLT51LmlucHV0W2luc3RhbmNlZERhdGFbal1dLmR3VHlwZSkgewogICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEREVDTFRZUEVfRkxPQVQxOgogICAgICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xWZXJ0ZXhBdHRyaWIxZnZBUkIoaW5zdGFuY2VkRGF0YVtqXSwgKGZsb2F0ICopIHB0cikpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEREVDTFRZUEVfRkxPQVQyOgogICAgICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xWZXJ0ZXhBdHRyaWIyZnZBUkIoaW5zdGFuY2VkRGF0YVtqXSwgKGZsb2F0ICopIHB0cikpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEREVDTFRZUEVfRkxPQVQzOgogICAgICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xWZXJ0ZXhBdHRyaWIzZnZBUkIoaW5zdGFuY2VkRGF0YVtqXSwgKGZsb2F0ICopIHB0cikpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEREVDTFRZUEVfRkxPQVQ0OgogICAgICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xWZXJ0ZXhBdHRyaWI0ZnZBUkIoaW5zdGFuY2VkRGF0YVtqXSwgKGZsb2F0ICopIHB0cikpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgV0lORUQzRERFQ0xUWVBFX1VCWVRFNDoKICAgICAgICAgICAgICAgICAgICBHTF9FWFRDQUxMKGdsVmVydGV4QXR0cmliNE51YnZBUkIoaW5zdGFuY2VkRGF0YVtqXSwgcHRyKSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIFdJTkVEM0RERUNMVFlQRV9VQllURTROOgogICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEREVDTFRZUEVfRDNEQ09MT1I6CiAgICAgICAgICAgICAgICAgICAgR0xfRVhUQ0FMTChnbFZlcnRleEF0dHJpYjROdWJ2QVJCKGluc3RhbmNlZERhdGFbal0sIHB0cikpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgV0lORUQzRERFQ0xUWVBFX1NIT1JUMjoKICAgICAgICAgICAgICAgICAgICBHTF9FWFRDQUxMKGdsVmVydGV4QXR0cmliNHN2QVJCKGluc3RhbmNlZERhdGFbal0sIChHTHNob3J0ICopIHB0cikpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEREVDTFRZUEVfU0hPUlQ0OgogICAgICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xWZXJ0ZXhBdHRyaWI0c3ZBUkIoaW5zdGFuY2VkRGF0YVtqXSwgKEdMc2hvcnQgKikgcHRyKSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEREVDTFRZUEVfU0hPUlQyTjoKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBHTHNob3J0IHNbNF0gPSB7KChzaG9ydCAqKSBwdHIpWzBdLCAoKHNob3J0ICopIHB0cilbMV0sIDAsIDF9OwogICAgICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xWZXJ0ZXhBdHRyaWI0TnN2QVJCKGluc3RhbmNlZERhdGFbal0sIHMpKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGNhc2UgV0lORUQzRERFQ0xUWVBFX1VTSE9SVDJOOgogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEdMdXNob3J0IHNbNF0gPSB7KCh1bnNpZ25lZCBzaG9ydCAqKSBwdHIpWzBdLCAoKHVuc2lnbmVkIHNob3J0ICopIHB0cilbMV0sIDAsIDF9OwogICAgICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xWZXJ0ZXhBdHRyaWI0TnVzdkFSQihpbnN0YW5jZWREYXRhW2pdLCBzKSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjYXNlIFdJTkVEM0RERUNMVFlQRV9TSE9SVDROOgogICAgICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xWZXJ0ZXhBdHRyaWI0TnN2QVJCKGluc3RhbmNlZERhdGFbal0sIChHTHNob3J0ICopIHB0cikpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEREVDTFRZUEVfVVNIT1JUNE46CiAgICAgICAgICAgICAgICAgICAgR0xfRVhUQ0FMTChnbFZlcnRleEF0dHJpYjROdXN2QVJCKGluc3RhbmNlZERhdGFbal0sIChHTHVzaG9ydCAqKSBwdHIpKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlIFdJTkVEM0RERUNMVFlQRV9VREVDMzoKICAgICAgICAgICAgICAgICAgICBGSVhNRSgiVW5zdXJlIGFib3V0IFdJTkVEM0RERUNMVFlQRV9VREVDM1xuIik7CiAgICAgICAgICAgICAgICAgICAgLypnbFZlcnRleEF0dHJpYjN1c3ZBUkIoaW5zdGFuY2VkRGF0YVtqXSwgKEdMdXNob3J0ICopIHB0cik7IERvZXMgbm90IGV4aXN0ICovCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIFdJTkVEM0RERUNMVFlQRV9ERUMzTjoKICAgICAgICAgICAgICAgICAgICBGSVhNRSgiVW5zdXJlIGFib3V0IFdJTkVEM0RERUNMVFlQRV9ERUMzTlxuIik7CiAgICAgICAgICAgICAgICAgICAgLypnbFZlcnRleEF0dHJpYjNOdXN2QVJCKGluc3RhbmNlZERhdGFbal0sIChHTHVzaG9ydCAqKSBwdHIpOyBEb2VzIG5vdCBleGlzdCAqLwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgV0lORUQzRERFQ0xUWVBFX0ZMT0FUMTZfMjoKICAgICAgICAgICAgICAgICAgICAvKiBBcmUgdGhvc2UgMTYgYml0IGZsb2F0cy4gQyBkb2Vzbid0IGhhdmUgYSAxNiBiaXQgZmxvYXQgdHlwZS4gSSBjb3VsZCByZWFkIHRoZSBzaW5nbGUgYml0cyBhbmQgY2FsY3VsYXRlIGEgNAogICAgICAgICAgICAgICAgICAgICAqIGJ5dGUgZmxvYXQgYWNjb3JkaW5nIHRvIHRoZSBJRUVFIHN0YW5kYXJkCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgRklYTUUoIlVuc3VwcG9ydGVkIFdJTkVEM0RERUNMVFlQRV9GTE9BVDE2XzJcbiIpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEREVDTFRZUEVfRkxPQVQxNl80OgogICAgICAgICAgICAgICAgICAgIEZJWE1FKCJVbnN1cHBvcnRlZCBXSU5FRDNEREVDTFRZUEVfRkxPQVQxNl80XG4iKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlIFdJTkVEM0RERUNMVFlQRV9VTlVTRUQ6CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIEVSUigiVW5leHBlY3RlZCBkZWNsYXJhdGlvbiBpbiBpbnN0YW5jZWQgYXR0cmlidXRlc1xuIik7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGdsRHJhd0VsZW1lbnRzKGdsUHJpbWl0aXZlVHlwZSwgbnVtYmVyT2ZWZXJ0aWNlcywgaWR4U2l6ZSA9PSAyID8gR0xfVU5TSUdORURfU0hPUlQgOiBHTF9VTlNJR05FRF9JTlQsCiAgICAgICAgICAgICAgICAgICAgKGNvbnN0IGNoYXIgKilpZHhEYXRhKyhpZHhTaXplICogc3RhcnRJZHgpKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xEcmF3RWxlbWVudHMiKTsKICAgIH0KfQoKc3RydWN0IGNvb3JkcyB7CiAgICBpbnQgeCwgeSwgejsKfTsKCnZvaWQgYmx0X3RvX2RyYXdhYmxlKElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcywgSVdpbmVEM0RTdXJmYWNlSW1wbCAqc3VyZmFjZSkgewogICAgc3RydWN0IGNvb3JkcyBjb29yZHNbNF07CiAgICBpbnQgbG93X2Nvb3JkOwoKICAgIC8qIFRPRE86IFRoaXMgY291bGQgYmUgc3VwcG9ydGVkIGZvciBsYXp5IHVubG9ja2luZyAqLwogICAgaWYoIShzdXJmYWNlLT5GbGFncyAmIFNGTEFHX0lOVEVYVFVSRSkpIHsKICAgICAgICAvKiBJdCBpcyBvayBhdCBpbml0IHRvIGJlIG5vd2hlcmUgKi8KICAgICAgICBpZighKHN1cmZhY2UtPkZsYWdzICYgU0ZMQUdfSU5TWVNNRU0pKSB7CiAgICAgICAgICAgIEVSUigiQmxpdHRpbmcgc3VyZmFjZXMgZnJvbSBzeXNtZW0gbm90IHN1cHBvcnRlZCB5ZXRcbiIpOwogICAgICAgIH0KICAgICAgICByZXR1cm47CiAgICB9CgogICAgRU5URVJfR0woKTsKICAgIEFjdGl2YXRlQ29udGV4dChUaGlzLCBUaGlzLT5yZW5kZXJfdGFyZ2V0c1swXSwgQ1RYVVNBR0VfQkxJVCk7CgogICAgaWYoc3VyZmFjZS0+Z2xEZXNjcmlwdGlvbi50YXJnZXQgPT0gR0xfVEVYVFVSRV8yRCkgewogICAgICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgc3VyZmFjZS0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSk7CiAgICAgICAgY2hlY2tHTGNhbGwoIkdMX1RFWFRVUkVfMkQsIFRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpIik7CgogICAgICAgIGNvb3Jkc1swXS54ID0gMDsgICAgY29vcmRzWzBdLnkgPSAwOyAgICBjb29yZHNbMF0ueiA9IDA7CiAgICAgICAgY29vcmRzWzFdLnggPSAwOyAgICBjb29yZHNbMV0ueSA9IDE7ICAgIGNvb3Jkc1sxXS56ID0gMDsKICAgICAgICBjb29yZHNbMl0ueCA9IDE7ICAgIGNvb3Jkc1syXS55ID0gMTsgICAgY29vcmRzWzJdLnogPSAwOwogICAgICAgIGNvb3Jkc1szXS54ID0gMTsgICAgY29vcmRzWzNdLnkgPSAwOyAgICBjb29yZHNbM10ueiA9IDA7CgogICAgICAgIGxvd19jb29yZCA9IDA7CiAgICB9IGVsc2UgewogICAgICAgIC8qIE11c3QgYmUgYSBjdWJlIG1hcCAqLwogICAgICAgIGdsRGlzYWJsZShHTF9URVhUVVJFXzJEKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlKEdMX1RFWFRVUkVfMkQpIik7CiAgICAgICAgZ2xFbmFibGUoR0xfVEVYVFVSRV9DVUJFX01BUF9BUkIpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZShzdXJmYWNlLT5nbERlc2NyaXB0aW9uLnRhcmdldCkiKTsKICAgICAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfQ1VCRV9NQVBfQVJCLCBzdXJmYWNlLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lKTsKICAgICAgICBjaGVja0dMY2FsbCgiR0xfVEVYVFVSRV9DVUJFX01BUF9BUkIsIFRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpIik7CgogICAgICAgIHN3aXRjaChzdXJmYWNlLT5nbERlc2NyaXB0aW9uLnRhcmdldCkgewogICAgICAgICAgICBjYXNlIEdMX1RFWFRVUkVfQ1VCRV9NQVBfUE9TSVRJVkVfWDoKICAgICAgICAgICAgICAgIGNvb3Jkc1swXS54ID0gIDE7ICAgY29vcmRzWzBdLnkgPSAtMTsgICBjb29yZHNbMF0ueiA9ICAxOwogICAgICAgICAgICAgICAgY29vcmRzWzFdLnggPSAgMTsgICBjb29yZHNbMV0ueSA9ICAxOyAgIGNvb3Jkc1sxXS56ID0gIDE7CiAgICAgICAgICAgICAgICBjb29yZHNbMl0ueCA9ICAxOyAgIGNvb3Jkc1syXS55ID0gIDE7ICAgY29vcmRzWzJdLnogPSAtMTsKICAgICAgICAgICAgICAgIGNvb3Jkc1szXS54ID0gIDE7ICAgY29vcmRzWzNdLnkgPSAtMTsgICBjb29yZHNbM10ueiA9IC0xOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIEdMX1RFWFRVUkVfQ1VCRV9NQVBfTkVHQVRJVkVfWDoKICAgICAgICAgICAgICAgIGNvb3Jkc1swXS54ID0gLTE7ICAgY29vcmRzWzBdLnkgPSAtMTsgICBjb29yZHNbMF0ueiA9ICAxOwogICAgICAgICAgICAgICAgY29vcmRzWzFdLnggPSAtMTsgICBjb29yZHNbMV0ueSA9ICAxOyAgIGNvb3Jkc1sxXS56ID0gIDE7CiAgICAgICAgICAgICAgICBjb29yZHNbMl0ueCA9IC0xOyAgIGNvb3Jkc1syXS55ID0gIDE7ICAgY29vcmRzWzJdLnogPSAtMTsKICAgICAgICAgICAgICAgIGNvb3Jkc1szXS54ID0gLTE7ICAgY29vcmRzWzNdLnkgPSAtMTsgICBjb29yZHNbM10ueiA9IC0xOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIEdMX1RFWFRVUkVfQ1VCRV9NQVBfUE9TSVRJVkVfWToKICAgICAgICAgICAgICAgIGNvb3Jkc1swXS54ID0gLTE7ICAgY29vcmRzWzBdLnkgPSAgMTsgICBjb29yZHNbMF0ueiA9ICAxOwogICAgICAgICAgICAgICAgY29vcmRzWzFdLnggPSAgMTsgICBjb29yZHNbMV0ueSA9ICAxOyAgIGNvb3Jkc1sxXS56ID0gIDE7CiAgICAgICAgICAgICAgICBjb29yZHNbMl0ueCA9ICAxOyAgIGNvb3Jkc1syXS55ID0gIDE7ICAgY29vcmRzWzJdLnogPSAtMTsKICAgICAgICAgICAgICAgIGNvb3Jkc1szXS54ID0gLTE7ICAgY29vcmRzWzNdLnkgPSAgMTsgICBjb29yZHNbM10ueiA9IC0xOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIEdMX1RFWFRVUkVfQ1VCRV9NQVBfTkVHQVRJVkVfWToKICAgICAgICAgICAgICAgIGNvb3Jkc1swXS54ID0gLTE7ICAgY29vcmRzWzBdLnkgPSAtMTsgICBjb29yZHNbMF0ueiA9ICAxOwogICAgICAgICAgICAgICAgY29vcmRzWzFdLnggPSAgMTsgICBjb29yZHNbMV0ueSA9IC0xOyAgIGNvb3Jkc1sxXS56ID0gIDE7CiAgICAgICAgICAgICAgICBjb29yZHNbMl0ueCA9ICAxOyAgIGNvb3Jkc1syXS55ID0gLTE7ICAgY29vcmRzWzJdLnogPSAtMTsKICAgICAgICAgICAgICAgIGNvb3Jkc1szXS54ID0gLTE7ICAgY29vcmRzWzNdLnkgPSAtMTsgICBjb29yZHNbM10ueiA9IC0xOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIEdMX1RFWFRVUkVfQ1VCRV9NQVBfUE9TSVRJVkVfWjoKICAgICAgICAgICAgICAgIGNvb3Jkc1swXS54ID0gLTE7ICAgY29vcmRzWzBdLnkgPSAtMTsgICBjb29yZHNbMF0ueiA9ICAxOwogICAgICAgICAgICAgICAgY29vcmRzWzFdLnggPSAgMTsgICBjb29yZHNbMV0ueSA9IC0xOyAgIGNvb3Jkc1sxXS56ID0gIDE7CiAgICAgICAgICAgICAgICBjb29yZHNbMl0ueCA9ICAxOyAgIGNvb3Jkc1syXS55ID0gLTE7ICAgY29vcmRzWzJdLnogPSAgMTsKICAgICAgICAgICAgICAgIGNvb3Jkc1szXS54ID0gLTE7ICAgY29vcmRzWzNdLnkgPSAtMTsgICBjb29yZHNbM10ueiA9ICAxOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIEdMX1RFWFRVUkVfQ1VCRV9NQVBfTkVHQVRJVkVfWjoKICAgICAgICAgICAgICAgIGNvb3Jkc1swXS54ID0gLTE7ICAgY29vcmRzWzBdLnkgPSAtMTsgICBjb29yZHNbMF0ueiA9IC0xOwogICAgICAgICAgICAgICAgY29vcmRzWzFdLnggPSAgMTsgICBjb29yZHNbMV0ueSA9IC0xOyAgIGNvb3Jkc1sxXS56ID0gLTE7CiAgICAgICAgICAgICAgICBjb29yZHNbMl0ueCA9ICAxOyAgIGNvb3Jkc1syXS55ID0gLTE7ICAgY29vcmRzWzJdLnogPSAtMTsKICAgICAgICAgICAgICAgIGNvb3Jkc1szXS54ID0gLTE7ICAgY29vcmRzWzNdLnkgPSAtMTsgICBjb29yZHNbM10ueiA9IC0xOwoKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIEVSUigiVW5leHBlY3RlZCB0ZXh0dXJlIHRhcmdldFxuIik7CiAgICAgICAgICAgICAgICBMRUFWRV9HTCgpOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgbG93X2Nvb3JkID0gLTE7CiAgICB9CgogICAgaWYoVGhpcy0+cmVuZGVyX29mZnNjcmVlbikgewogICAgICAgIGNvb3Jkc1swXS55ID0gY29vcmRzWzBdLnkgPT0gMSA/IGxvd19jb29yZCA6IDE7CiAgICAgICAgY29vcmRzWzFdLnkgPSBjb29yZHNbMV0ueSA9PSAxID8gbG93X2Nvb3JkIDogMTsKICAgICAgICBjb29yZHNbMl0ueSA9IGNvb3Jkc1syXS55ID09IDEgPyBsb3dfY29vcmQgOiAxOwogICAgICAgIGNvb3Jkc1szXS55ID0gY29vcmRzWzNdLnkgPT0gMSA/IGxvd19jb29yZCA6IDE7CiAgICB9CgogICAgZ2xCZWdpbihHTF9RVUFEUyk7CiAgICAgICAgZ2xUZXhDb29yZDNpdigoR0xpbnQgKikgJmNvb3Jkc1swXSk7CiAgICAgICAgZ2xWZXJ0ZXgyaSgwLCAwKTsKCiAgICAgICAgZ2xUZXhDb29yZDNpdigoR0xpbnQgKikgJmNvb3Jkc1sxXSk7CiAgICAgICAgZ2xWZXJ0ZXgyaSgwLCBzdXJmYWNlLT5wb3cySGVpZ2h0KTsKCiAgICAgICAgZ2xUZXhDb29yZDNpdigoR0xpbnQgKikgJmNvb3Jkc1syXSk7CiAgICAgICAgZ2xWZXJ0ZXgyaShzdXJmYWNlLT5wb3cyV2lkdGgsIHN1cmZhY2UtPnBvdzJIZWlnaHQpOwoKICAgICAgICBnbFRleENvb3JkM2l2KChHTGludCAqKSAmY29vcmRzWzNdKTsKICAgICAgICBnbFZlcnRleDJpKHN1cmZhY2UtPnBvdzJXaWR0aCwgMCk7CiAgICBnbEVuZCgpOwogICAgY2hlY2tHTGNhbGwoImdsRW5kIik7CgogICAgaWYoc3VyZmFjZS0+Z2xEZXNjcmlwdGlvbi50YXJnZXQgIT0gR0xfVEVYVFVSRV8yRCkgewogICAgICAgIGdsRW5hYmxlKEdMX1RFWFRVUkVfMkQpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZShHTF9URVhUVVJFXzJEKSIpOwogICAgICAgIGdsRGlzYWJsZShHTF9URVhUVVJFX0NVQkVfTUFQX0FSQik7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZShHTF9URVhUVVJFX0NVQkVfTUFQX0FSQikiKTsKICAgIH0KICAgIExFQVZFX0dMKCk7Cn0KCi8qIFJvdXRpbmUgY29tbW9uIHRvIHRoZSBkcmF3IHByaW1pdGl2ZSBhbmQgZHJhdyBpbmRleGVkIHByaW1pdGl2ZSByb3V0aW5lcyAqLwp2b2lkIGRyYXdQcmltaXRpdmUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgaW50IFByaW1pdGl2ZVR5cGUsCiAgICAgICAgICAgICAgICAgICBsb25nIE51bVByaW1pdGl2ZXMsCiAgICAgICAgICAgICAgICAgICAvKiBmb3IgSW5kZXhlZDogKi8KICAgICAgICAgICAgICAgICAgIGxvbmcgIFN0YXJ0VmVydGV4SW5kZXgsCiAgICAgICAgICAgICAgICAgICBVSU5UICBudW1iZXJPZlZlcnRpY2VzLAogICAgICAgICAgICAgICAgICAgbG9uZyAgU3RhcnRJZHgsCiAgICAgICAgICAgICAgICAgICBzaG9ydCBpZHhTaXplLAogICAgICAgICAgICAgICAgICAgY29uc3Qgdm9pZCAqaWR4RGF0YSwKICAgICAgICAgICAgICAgICAgIGludCAgIG1pbkluZGV4KSB7CgogICAgSVdpbmVEM0REZXZpY2VJbXBsICAgICAgICAgICAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEU3dhcENoYWluICAgICAgICAgICAgKnN3YXBjaGFpbjsKICAgIElXaW5lRDNEQmFzZVRleHR1cmUgICAgICAgICAgKnRleHR1cmUgPSBOVUxMOwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAgICAgICAgICAqdGFyZ2V0OwogICAgaW50IGk7CgogICAgLyogU2lnbmFscyBvdGhlciBtb2R1bGVzIHRoYXQgYSBkcmF3aW5nIGlzIGluIHByb2dyZXNzIGFuZCB0aGUgc3RhdGVibG9jayBmaW5hbGl6ZWQgKi8KICAgIFRoaXMtPmlzSW5EcmF3ID0gVFJVRTsKCiAgICAvKiBJbnZhbGlkYXRlIHRoZSBiYWNrIGJ1ZmZlciBtZW1vcnkgc28gTG9ja1JlY3Qgd2lsbCByZWFkIGl0IHRoZSBuZXh0IHRpbWUgKi8KICAgIGZvcihpID0gMDsgaSA8IEdMX0xJTUlUUyhidWZmZXJzKTsgaSsrKSB7CiAgICAgICAgdGFyZ2V0ID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgVGhpcy0+cmVuZGVyX3RhcmdldHNbaV07CgogICAgICAgIC8qIFRPRE86IE9ubHkgZG8gYWxsIHRoYXQgaWYgd2UncmUgZ29pbmcgdG8gY2hhbmdlIGFueXRoaW5nCiAgICAgICAgICogVGV4dHVyZSBjb250YWluZXIgZGlydGlmaWNhdGlvbiBkb2VzIG5vdCB3b3JrIHF1aXRlIHJpZ2h0IHlldAogICAgICAgICAqLwogICAgICAgIGlmKHRhcmdldCAvKiYmIHRhcmdldC0+RmxhZ3MgJiAoU0ZMQUdfSU5URVhUVVJFIHwgU0ZMQUdfSU5TWVNNRU0pKi8pIHsKICAgICAgICAgICAgc3dhcGNoYWluID0gTlVMTDsKICAgICAgICAgICAgdGV4dHVyZSA9IE5VTEw7CgogICAgICAgICAgICBpZihpID09IDApIHsKICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9HZXRDb250YWluZXIoKElXaW5lRDNEU3VyZmFjZSAqKSB0YXJnZXQsICZJSURfSVdpbmVEM0RTd2FwQ2hhaW4sICh2b2lkICoqKSZzd2FwY2hhaW4pOwoKICAgICAgICAgICAgICAgIC8qIE5lZWQgdGhlIHN1cmZhY2UgaW4gdGhlIGRyYXdhYmxlISAqLwogICAgICAgICAgICAgICAgaWYoISh0YXJnZXQtPkZsYWdzICYgU0ZMQUdfSU5EUkFXQUJMRSkgJiYgKHN3YXBjaGFpbiB8fCB3aW5lZDNkX3NldHRpbmdzLm9mZnNjcmVlbl9yZW5kZXJpbmdfbW9kZSAhPSBPUk1fRkJPKSkgewogICAgICAgICAgICAgICAgICAgIGJsdF90b19kcmF3YWJsZShUaGlzLCB0YXJnZXQpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmKHN3YXBjaGFpbikgewogICAgICAgICAgICAgICAgICAgIC8qIE9uc2NyZWVuIHRhcmdldC4gSW52YWxpZGF0ZSBzeXN0ZW0gbWVtb3J5IGNvcHkgYW5kIHRleHR1cmUgY29weSAqLwogICAgICAgICAgICAgICAgICAgIHRhcmdldC0+RmxhZ3MgJj0gfihTRkxBR19JTlNZU01FTSB8IFNGTEFHX0lOVEVYVFVSRSk7CiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0LT5GbGFncyB8PSBTRkxBR19JTkRSQVdBQkxFOwogICAgICAgICAgICAgICAgICAgIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2Uoc3dhcGNoYWluKTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZih3aW5lZDNkX3NldHRpbmdzLm9mZnNjcmVlbl9yZW5kZXJpbmdfbW9kZSAhPSBPUk1fRkJPKSB7CiAgICAgICAgICAgICAgICAgICAgLyogTm9uLUZCTyB0YXJnZXQ6IEludmFsaWRhdGUgc3lzdGVtIGNvcHksIHRleHR1cmUgY29weSBhbmQgZGlydGlmeSB0aGUgY29udGFpbmVyICovCiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lcigoSVdpbmVEM0RTdXJmYWNlICopIHRhcmdldCwgJklJRF9JV2luZUQzREJhc2VUZXh0dXJlLCAodm9pZCAqKikmdGV4dHVyZSk7CgogICAgICAgICAgICAgICAgICAgIGlmKHRleHR1cmUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9TZXREaXJ0eSh0ZXh0dXJlLCBUUlVFKTsKICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RUZXh0dXJlX1JlbGVhc2UodGV4dHVyZSk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICB0YXJnZXQtPkZsYWdzICY9IH4oU0ZMQUdfSU5TWVNNRU0gfCBTRkxBR19JTlRFWFRVUkUpOwogICAgICAgICAgICAgICAgICAgIHRhcmdldC0+RmxhZ3MgfD0gU0ZMQUdfSU5EUkFXQUJMRTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLyogRkJPIG9mZnNjcmVlbiB0YXJnZXQuIEludmFsaWRhdGUgc3lzdGVtIG1lbW9yeSBjb3B5ICovCiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0LT5GbGFncyAmPSB+U0ZMQUdfSU5TWVNNRU07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvKiBNdXN0IGJlIGFuIGZibyByZW5kZXIgdGFyZ2V0ICovCiAgICAgICAgICAgICAgICB0YXJnZXQtPkZsYWdzICY9IH5TRkxBR19JTlNZU01FTTsKICAgICAgICAgICAgICAgIHRhcmdldC0+RmxhZ3MgfD0gIFNGTEFHX0lOVEVYVFVSRTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKiBPaywgd2Ugd2lsbCBiZSB1cGRhdGluZyB0aGUgc2NyZWVuIGZyb20gaGVyZSBvbndhcmRzIHNvIGdyYWIgdGhlIGxvY2sgKi8KICAgIEVOVEVSX0dMKCk7CgogICAgaWYgKHdpbmVkM2Rfc2V0dGluZ3Mub2Zmc2NyZWVuX3JlbmRlcmluZ19tb2RlID09IE9STV9GQk8pIHsKICAgICAgICBhcHBseV9mYm9fc3RhdGUoaWZhY2UpOwogICAgfQoKICAgIEFjdGl2YXRlQ29udGV4dChUaGlzLCBUaGlzLT5yZW5kZXJfdGFyZ2V0c1swXSwgQ1RYVVNBR0VfRFJBV1BSSU0pOwoKICAgIGlmIChUaGlzLT5kZXB0aF9jb3B5X3N0YXRlID09IFdJTkVEM0RfRENTX0NPUFkpIHsKICAgICAgICBkZXB0aF9jb3B5KGlmYWNlKTsKICAgIH0KICAgIFRoaXMtPmRlcHRoX2NvcHlfc3RhdGUgPSBXSU5FRDNEX0RDU19JTklUSUFMOwoKICAgIHsKICAgICAgICBHTGVudW0gZ2xQcmltVHlwZTsKICAgICAgICAvKiBPaywgV29yayBvdXQgd2hpY2ggcHJpbWl0aXZlIGlzIHJlcXVlc3RlZCBhbmQgaG93IG1hbnkgdmVydGV4ZXMgdGhhdAogICAgICAgICAgIHdpbGwgYmUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgVUlOVCBjYWxjdWxhdGVkTnVtYmVyT2ZpbmRpY2VzID0gcHJpbWl0aXZlVG9HbChQcmltaXRpdmVUeXBlLCBOdW1QcmltaXRpdmVzLCAmZ2xQcmltVHlwZSk7CiAgICAgICAgaWYgKG51bWJlck9mVmVydGljZXMgPT0gMCApCiAgICAgICAgICAgIG51bWJlck9mVmVydGljZXMgPSBjYWxjdWxhdGVkTnVtYmVyT2ZpbmRpY2VzOwoKICAgICAgICBpZiAoVGhpcy0+dXNlRHJhd1N0cmlkZWRTbG93KSB7CiAgICAgICAgICAgIC8qIEltbWVkaWF0ZSBtb2RlIGRyYXdpbmcgKi8KICAgICAgICAgICAgZHJhd1N0cmlkZWRTbG93KGlmYWNlLCAmVGhpcy0+c3RyaWRlZF9zdHJlYW1zLCBjYWxjdWxhdGVkTnVtYmVyT2ZpbmRpY2VzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2xQcmltVHlwZSwgaWR4RGF0YSwgaWR4U2l6ZSwgbWluSW5kZXgsIFN0YXJ0SWR4LCBTdGFydFZlcnRleEluZGV4KTsKICAgICAgICB9IGVsc2UgaWYoVGhpcy0+aW5zdGFuY2VkRHJhdykgewogICAgICAgICAgICAvKiBJbnN0YW5jaW5nIGVtdWxhdGlvbiB3aXRoIG1peGluZyBpbW1lZGlhdGUgbW9kZSBhbmQgYXJyYXlzICovCiAgICAgICAgICAgIGRyYXdTdHJpZGVkSW5zdGFuY2VkKGlmYWNlLCAmVGhpcy0+c3RyaWRlZF9zdHJlYW1zLCBjYWxjdWxhdGVkTnVtYmVyT2ZpbmRpY2VzLCBnbFByaW1UeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWR4RGF0YSwgaWR4U2l6ZSwgbWluSW5kZXgsIFN0YXJ0SWR4LCBTdGFydFZlcnRleEluZGV4KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvKiBTaW1wbGUgYXJyYXkgZHJhdyBjYWxsICovCiAgICAgICAgICAgIGRyYXdTdHJpZGVkRmFzdChpZmFjZSwgY2FsY3VsYXRlZE51bWJlck9maW5kaWNlcywgZ2xQcmltVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkeERhdGEsIGlkeFNpemUsIG1pbkluZGV4LCBTdGFydElkeCwgU3RhcnRWZXJ0ZXhJbmRleCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qIEZpbnNoZWQgdXBkYXRpbmcgdGhlIHNjcmVlbiwgcmVzdG9yZSBsb2NrICovCiAgICBMRUFWRV9HTCgpOwogICAgVFJBQ0UoIkRvbmUgYWxsIGdsIGRyYXdpbmdcbiIpOwoKICAgIC8qIERpYWdub3N0aWNzICovCiNpZmRlZiBTSE9XX0ZSQU1FX01BS0VVUAogICAgewogICAgICAgIHN0YXRpYyBsb25nIGludCBwcmltQ291bnRlciA9IDA7CiAgICAgICAgLyogTk9URTogc2V0IHByaW1Db3VudGVyIHRvIHRoZSB2YWx1ZSByZXBvcnRlZCBieSBkcmF3cHJpbSAKICAgICAgICAgICBiZWZvcmUgeW91IHdhbnQgdG8gdG8gd3JpdGUgZnJhbWUgbWFrZXVwIHRvIC90bXAgKi8KICAgICAgICBpZiAocHJpbUNvdW50ZXIgPj0gMCkgewogICAgICAgICAgICBXSU5FRDNETE9DS0VEX1JFQ1QgcjsKICAgICAgICAgICAgY2hhciBidWZmZXJbODBdOwogICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfTG9ja1JlY3QoVGhpcy0+cmVuZGVyVGFyZ2V0LCAmciwgTlVMTCwgV0lORUQzRExPQ0tfUkVBRE9OTFkpOwogICAgICAgICAgICBzcHJpbnRmKGJ1ZmZlciwgIi90bXAvYmFja2J1ZmZlcl8lZC50Z2EiLCBwcmltQ291bnRlcik7CiAgICAgICAgICAgIFRSQUNFKCJTYXZpbmcgc2NyZWVuc2hvdCAlc1xuIiwgYnVmZmVyKTsKICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1NhdmVTbmFwc2hvdChUaGlzLT5yZW5kZXJUYXJnZXQsIGJ1ZmZlcik7CiAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9VbmxvY2tSZWN0KFRoaXMtPnJlbmRlclRhcmdldCk7CgojaWZkZWYgU0hPV19URVhUVVJFX01BS0VVUAogICAgICAgICAgIHsKICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlICpwU3VyOwogICAgICAgICAgICBpbnQgdGV4dHVyZU5vOwogICAgICAgICAgICBmb3IgKHRleHR1cmVObyA9IDA7IHRleHR1cmVObyA8IEdMX0xJTUlUUyh0ZXh0dXJlcyk7ICsrdGV4dHVyZU5vKSB7CiAgICAgICAgICAgICAgICBpZiAoVGhpcy0+c3RhdGVCbG9jay0+dGV4dHVyZXNbdGV4dHVyZU5vXSAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgc3ByaW50ZihidWZmZXIsICIvdG1wL3RleHR1cmVfJXBfJWRfJWQudGdhIiwgVGhpcy0+c3RhdGVCbG9jay0+dGV4dHVyZXNbdGV4dHVyZU5vXSwgcHJpbUNvdW50ZXIsIHRleHR1cmVObyk7CiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIlNhdmluZyB0ZXh0dXJlICVzXG4iLCBidWZmZXIpOwogICAgICAgICAgICAgICAgICAgIGlmIChJV2luZUQzREJhc2VUZXh0dXJlX0dldFR5cGUoVGhpcy0+c3RhdGVCbG9jay0+dGV4dHVyZXNbdGV4dHVyZU5vXSkgPT0gV0lORUQzRFJUWVBFX1RFWFRVUkUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEVGV4dHVyZV9HZXRTdXJmYWNlTGV2ZWwoKElXaW5lRDNEVGV4dHVyZSAqKVRoaXMtPnN0YXRlQmxvY2stPnRleHR1cmVzW3RleHR1cmVOb10sIDAsICZwU3VyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9TYXZlU25hcHNob3QocFN1ciwgYnVmZmVyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9SZWxlYXNlKHBTdXIpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSAgewogICAgICAgICAgICAgICAgICAgICAgICBGSVhNRSgiYmFzZSBUZXh0dXJlIGlzbid0IG9mIHR5cGUgdGV4dHVyZSAlZFxuIiwgSVdpbmVEM0RCYXNlVGV4dHVyZV9HZXRUeXBlKFRoaXMtPnN0YXRlQmxvY2stPnRleHR1cmVzW3RleHR1cmVOb10pKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICB9CiNlbmRpZgogICAgICAgIH0KICAgICAgICBUUkFDRSgiZHJhd3ByaW0gIyVkXG4iLCBwcmltQ291bnRlcik7CiAgICAgICAgKytwcmltQ291bnRlcjsKICAgIH0KI2VuZGlmCgogICAgLyogQ29udHJvbCBnb2VzIGJhY2sgdG8gdGhlIGRldmljZSwgc3RhdGVibG9jayB2YWx1ZXMgbWF5IGNoYW5nZSBhZ2FpbiAqLwogICAgVGhpcy0+aXNJbkRyYXcgPSBGQUxTRTsKfQo=