LyoKICogSVdpbmVEM0RTdXJmYWNlIEltcGxlbWVudGF0aW9uCiAqCiAqIENvcHlyaWdodCAxOTk4IExpb25lbCBVbG1lcgogKiBDb3B5cmlnaHQgMjAwMC0yMDAxIFRyYW5zR2FtaW5nIFRlY2hub2xvZ2llcyBJbmMuCiAqIENvcHlyaWdodCAyMDAyLTIwMDUgSmFzb24gRWRtZWFkZXMKICogQ29weXJpZ2h0IDIwMDItMjAwMyBSYXBoYWVsIEp1bnF1ZWlyYQogKiBDb3B5cmlnaHQgMjAwNCBDaHJpc3RpYW4gQ29zdGEKICogQ29weXJpZ2h0IDIwMDUgT2xpdmVyIFN0aWViZXIKICogQ29weXJpZ2h0IDIwMDYgU3RlZmFuIET2c2luZ2VyIGZvciBDb2RlV2VhdmVycwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCiNpbmNsdWRlICJ3aW5lL3BvcnQuaCIKI2luY2x1ZGUgIndpbmVkM2RfcHJpdmF0ZS5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoZDNkX3N1cmZhY2UpOwojZGVmaW5lIEdMSU5GT19MT0NBVElPTiAoKElXaW5lRDNESW1wbCAqKSgoKElXaW5lRDNERGV2aWNlSW1wbCAqKVRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2UpLT53aW5lRDNEKSktPmdsX2luZm8KCnR5cGVkZWYgZW51bSB7CiAgICBOT19DT05WRVJTSU9OLAogICAgQ09OVkVSVF9QQUxFVFRFRCwKICAgIENPTlZFUlRfUEFMRVRURURfQ0ssCiAgICBDT05WRVJUX0NLXzU2NSwKICAgIENPTlZFUlRfQ0tfNTU1MSwKICAgIENPTlZFUlRfQ0tfNDQ0NCwKICAgIENPTlZFUlRfQ0tfNDQ0NF9BUkdCLAogICAgQ09OVkVSVF9DS18xNTU1LAogICAgQ09OVkVSVF81NTUsCiAgICBDT05WRVJUX0NLX1JHQjI0LAogICAgQ09OVkVSVF9DS184ODg4LAogICAgQ09OVkVSVF9DS184ODg4X0FSR0IsCiAgICBDT05WRVJUX1JHQjMyXzg4OCwKICAgIENPTlZFUlRfVjhVOAp9IENPTlZFUlRfVFlQRVM7CgpIUkVTVUxUIGQzZGZtdF9jb252ZXJ0X3N1cmZhY2UoQllURSAqc3JjLCBCWVRFICpkc3QsIFVJTlQgcGl0Y2gsIFVJTlQgd2lkdGgsIFVJTlQgaGVpZ2h0LCBVSU5UIG91dHBpdGNoLCBDT05WRVJUX1RZUEVTIGNvbnZlcnQsIElXaW5lRDNEU3VyZmFjZUltcGwgKnN1cmYpOwoKc3RhdGljIHZvaWQgc3VyZmFjZV9kb3dubG9hZF9kYXRhKElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMpIHsKICAgIGlmIChUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQxIHx8CiAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDIgfHwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMyB8fAogICAgICAgICAgICBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQ0IHx8IFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDUpIHsKICAgICAgICBpZiAoIUdMX1NVUFBPUlQoRVhUX1RFWFRVUkVfQ09NUFJFU1NJT05fUzNUQykpIHsgLyogV2UgY2FuIGFzc3VtZSB0aGlzIGFzIHRoZSB0ZXh0dXJlIHdvdWxkIG5vdCBoYXZlIGJlZW4gY3JlYXRlZCBvdGhlcndpc2UgKi8KICAgICAgICAgICAgRklYTUUoIiglcCkgOiBBdHRlbXB0aW5nIHRvIGxvY2sgYSBjb21wcmVzc2VkIHRleHR1cmUgd2hlbiB0ZXh0dXJlIGNvbXByZXNzaW9uIGlzbid0IHN1cHBvcnRlZCBieSBvcGVuZ2xcbiIsIFRoaXMpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIFRSQUNFKCIoJXApIDogQ2FsbGluZyBnbEdldENvbXByZXNzZWRUZXhJbWFnZUFSQiBsZXZlbCAlZCwgZm9ybWF0ICUjeCwgdHlwZSAlI3gsIGRhdGEgJXBcbiIsIFRoaXMsIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsCiAgICAgICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0LCBUaGlzLT5nbERlc2NyaXB0aW9uLmdsVHlwZSwgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKCiAgICAgICAgICAgIEVOVEVSX0dMKCk7CgogICAgICAgICAgICBHTF9FWFRDQUxMKGdsR2V0Q29tcHJlc3NlZFRleEltYWdlQVJCKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLCBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsR2V0Q29tcHJlc3NlZFRleEltYWdlQVJCKCkiKTsKCiAgICAgICAgICAgIExFQVZFX0dMKCk7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICB2b2lkICptZW07CiAgICAgICAgaW50IHNyY19waXRjaCA9IDA7CiAgICAgICAgaW50IGRzdF9waXRjaCA9IDA7CgogICAgICAgICBpZihUaGlzLT5GbGFncyAmIFNGTEFHX0NPTlZFUlRFRCkgewogICAgICAgICAgICAgRklYTUUoIlJlYWQgYmFjayBjb252ZXJ0ZWQgdGV4dHVyZXMgdW5zdXBwb3J0ZWRcbiIpOwogICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICB9CgogICAgICAgIGlmIChUaGlzLT5GbGFncyAmIFNGTEFHX05PTlBPVzIpIHsKICAgICAgICAgICAgc3JjX3BpdGNoID0gVGhpcy0+Ynl0ZXNQZXJQaXhlbCAqIFRoaXMtPnBvdzJXaWR0aDsKICAgICAgICAgICAgZHN0X3BpdGNoID0gSVdpbmVEM0RTdXJmYWNlX0dldFBpdGNoKChJV2luZUQzRFN1cmZhY2UgKikgVGhpcyk7CiAgICAgICAgICAgIHNyY19waXRjaCA9IChzcmNfcGl0Y2ggKyBTVVJGQUNFX0FMSUdOTUVOVCAtIDEpICYgfihTVVJGQUNFX0FMSUdOTUVOVCAtIDEpOwogICAgICAgICAgICBtZW0gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3JjX3BpdGNoICogVGhpcy0+cG93MkhlaWdodCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbWVtID0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5OwogICAgICAgIH0KCiAgICAgICAgVFJBQ0UoIiglcCkgOiBDYWxsaW5nIGdsR2V0VGV4SW1hZ2UgbGV2ZWwgJWQsIGZvcm1hdCAlI3gsIHR5cGUgJSN4LCBkYXRhICVwXG4iLCBUaGlzLCBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLAogICAgICAgICAgICAgICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdCwgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbFR5cGUsIG1lbSk7CgogICAgICAgIEVOVEVSX0dMKCk7CgogICAgICAgIGdsR2V0VGV4SW1hZ2UoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsIFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xGb3JtYXQsCiAgICAgICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmdsVHlwZSwgbWVtKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xHZXRUZXhJbWFnZSgpIik7CgogICAgICAgIExFQVZFX0dMKCk7CgogICAgICAgIGlmIChUaGlzLT5GbGFncyAmIFNGTEFHX05PTlBPVzIpIHsKICAgICAgICAgICAgTFBCWVRFIHNyY19kYXRhLCBkc3RfZGF0YTsKICAgICAgICAgICAgaW50IHk7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFNvbWUgZ2FtZXMgKGUuZy4gd2FyaGFtbWVyIDQwaykgZG9uJ3Qgd29yayBwcm9wZXJseSB3aXRoIHRoZSBvZGQgcGl0Y2hlcywgcHJldmVudGluZwogICAgICAgICAgICAgKiB0aGUgc3VyZmFjZSBwaXRjaCBmcm9tIGJlaW5nIHVzZWQgdG8gYm94IG5vbi1wb3dlcjIgdGV4dHVyZXMuIEluc3RlYWQgd2UgaGF2ZSB0byB1c2UgYSBoYWNrIHRvCiAgICAgICAgICAgICAqIHJlcGFjayB0aGUgdGV4dHVyZSBzbyB0aGF0IHRoZSBicHAgKiB3aWR0aCBwaXRjaCBjYW4gYmUgdXNlZCBpbnN0ZWFkIG9mIGJwcCAqIHBvdzJ3aWR0aC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogV2UncmUgZG9pbmcgdGhpcy4uLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBpbnN0ZWFkIG9mIGJveGluZyB0aGUgdGV4dHVyZSA6CiAgICAgICAgICAgICAqIHw8LXRleHR1cmUgd2lkdGggLT58ICAtLT5wb3cyd2lkdGh8ICAgL1wKICAgICAgICAgICAgICogfDExMTExMTExMTExMTExMTExMXwgICAgICAgICAgICAgIHwgICB8CiAgICAgICAgICAgICAqIHwyMjIgVGV4dHVyZSAyMjIyMjJ8IGJveGVkIGVtcHR5ICB8IHRleHR1cmUgaGVpZ2h0CiAgICAgICAgICAgICAqIHwzMzMzIERhdGEgMzMzMzMzMzN8ICAgICAgICAgICAgICB8ICAgfAogICAgICAgICAgICAgKiB8NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0fCAgICAgICAgICAgICAgfCAgIFwvCiAgICAgICAgICAgICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICAgfAogICAgICAgICAgICAgKiB8ICAgICBib3hlZCAgZW1wdHkgfCBib3hlZCBlbXB0eSAgfCBwb3cyaGVpZ2h0CiAgICAgICAgICAgICAqIHwgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICB8ICAgXC8KICAgICAgICAgICAgICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAgICAgICoKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogd2UncmUgcmVwYWNraW5nIHRoZSBkYXRhIHRvIHRoZSBleHBlY3RlZCB0ZXh0dXJlIHdpZHRoCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIHw8LXRleHR1cmUgd2lkdGggLT58ICAtLT5wb3cyd2lkdGh8ICAgL1wKICAgICAgICAgICAgICogfDExMTExMTExMTExMTExMTExMTIyMjIyMjIyMjIyMjIyMnwgICB8CiAgICAgICAgICAgICAqIHwyMjIzMzMzMzMzMzMzMzMzMzMzMzM0NDQ0NDQ0NDQ0NDR8IHRleHR1cmUgaGVpZ2h0CiAgICAgICAgICAgICAqIHw0NDQ0NDQgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgfAogICAgICAgICAgICAgKiB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgIFwvCiAgICAgICAgICAgICAqIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgfAogICAgICAgICAgICAgKiB8ICAgICAgICAgICAgZW1wdHkgICAgICAgICAgICAgICAgfCBwb3cyaGVpZ2h0CiAgICAgICAgICAgICAqIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgXC8KICAgICAgICAgICAgICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogPT0gaXMgdGhlIHNhbWUgYXMKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogfDwtdGV4dHVyZSB3aWR0aCAtPnwgICAgL1wKICAgICAgICAgICAgICogfDExMTExMTExMTExMTExMTExMXwKICAgICAgICAgICAgICogfDIyMjIyMjIyMjIyMjIyMjIyMnx0ZXh0dXJlIGhlaWdodAogICAgICAgICAgICAgKiB8MzMzMzMzMzMzMzMzMzMzMzMzfAogICAgICAgICAgICAgKiB8NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0fCAgICBcLwogICAgICAgICAgICAgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiB0aGlzIGFsc28gbWVhbnMgdGhhdCBhbnkgcmVmZXJlbmNlcyB0byBhbGxvY2F0ZWRNZW1vcnkgc2hvdWxkIHdvcmsgd2l0aCB0aGUgZGF0YSBhcyBpZiB3ZXJlIGEKICAgICAgICAgICAgICogc3RhbmRhcmQgdGV4dHVyZSB3aXRoIGEgbm9uLXBvd2VyMiB3aWR0aCBpbnN0ZWFkIG9mIHRleHR1cmUgYm94ZWQgdXAgdG8gYmUgYSBwb3dlcjIgdGV4dHVyZS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogaW50ZXJuYWxseSB0aGUgdGV4dHVyZSBpcyBzdGlsbCBzdG9yZWQgaW4gYSBib3hlZCBmb3JtYXQgc28gYW55IHJlZmVyZW5jZXMgdG8gdGV4dHVyZU5hbWUgd2lsbAogICAgICAgICAgICAgKiBnZXQgYSBib3hlZCB0ZXh0dXJlIHdpdGggd2lkdGggcG93MndpZHRoIGFuZCBub3QgYSB0ZXh0dXJlIG9mIHdpZHRoIGN1cnJlbnREZXNjLldpZHRoLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBQZXJmb3JtYW5jZSBzaG91bGQgbm90IGJlIGFuIGlzc3VlLCBiZWNhdXNlIGFwcGxpY2F0aW9ucyBub3JtYWxseSBkbyBub3QgbG9jayB0aGUgc3VyZmFjZXMgd2hlbgogICAgICAgICAgICAgKiByZW5kZXJpbmcuIElmIGFuIGFwcCBkb2VzLCB0aGUgU0ZMQUdfRFlOTE9DSyBmbGFnIHdpbGwga2ljayBpbiBhbmQgdGhlIG1lbW9yeSBjb3B5IHdvbid0IGJlIHJlbGVhc2VkLAogICAgICAgICAgICAgKiBhbmQgZG9lc24ndCBoYXZlIHRvIGJlIHJlLXJlYWQuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBzcmNfZGF0YSA9IG1lbTsKICAgICAgICAgICAgZHN0X2RhdGEgPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnk7CiAgICAgICAgICAgIFRSQUNFKCIoJXApIDogUmVwYWNraW5nIHRoZSBzdXJmYWNlIGRhdGEgZnJvbSBwaXRjaCAlZCB0byBwaXRjaCAlZFxuIiwgVGhpcywgc3JjX3BpdGNoLCBkc3RfcGl0Y2gpOwogICAgICAgICAgICBmb3IgKHkgPSAxIDsgeSA8IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodDsgeSsrKSB7CiAgICAgICAgICAgICAgICAvKiBza2lwIHRoZSBmaXJzdCByb3cgKi8KICAgICAgICAgICAgICAgIHNyY19kYXRhICs9IHNyY19waXRjaDsKICAgICAgICAgICAgICAgIGRzdF9kYXRhICs9IGRzdF9waXRjaDsKICAgICAgICAgICAgICAgIG1lbWNweShkc3RfZGF0YSwgc3JjX2RhdGEsIGRzdF9waXRjaCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG1lbSk7CiAgICAgICAgfQogICAgfQp9CgpzdGF0aWMgdm9pZCBzdXJmYWNlX3VwbG9hZF9kYXRhKElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMsIEdMc2l6ZWkgd2lkdGgsIEdMc2l6ZWkgaGVpZ2h0LCBHTGVudW0gZm9ybWF0LCBHTGVudW0gdHlwZSwgY29uc3QgR0x2b2lkICpkYXRhKSB7CiAgICBpZiAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMSB8fAogICAgICAgICAgICBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQyIHx8IFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDMgfHwKICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNCB8fCBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQ1KSB7CiAgICAgICAgaWYgKCFHTF9TVVBQT1JUKEVYVF9URVhUVVJFX0NPTVBSRVNTSU9OX1MzVEMpKSB7CiAgICAgICAgICAgIEZJWE1FKCJVc2luZyBEWFQxLzMvNSB3aXRob3V0IGFkdmVydGl6ZWQgc3VwcG9ydFxuIik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgVFJBQ0UoIiglcCkgOiBDYWxsaW5nIGdsQ29tcHJlc3NlZFRleFN1YkltYWdlMkQgdyAlZCwgaCAlZCwgZGF0YSAlcFxuIiwgVGhpcywgd2lkdGgsIGhlaWdodCwgZGF0YSk7CiAgICAgICAgICAgIEVOVEVSX0dMKCk7CiAgICAgICAgICAgIC8qIGdsQ29tcHJlc3NlZFRleFN1YkltYWdlMkQgZm9yIHVwbG9hZGluZyBhbmQgZ2xUZXhJbWFnZTJEIGZvciBhbGxvY2F0aW5nIGRvZXMgbm90IHdvcmsgd2VsbCBvbiBzb21lIGRyaXZlcnMocjIwMCBkcmksIE1hY09TIEFUSSBkcml2ZXIpCiAgICAgICAgICAgICAqIGdsQ29tcHJlc3NlZFRleEltYWdlMkQgZG9lcyBub3QgYWNjZXB0IE5VTEwgcG9pbnRlcnMuIFNvIGZvciBjb21wcmVzc2VkIHRleHR1cmVzIHN1cmZhY2VfYWxsb2NhdGVfc3VyZmFjZSBkb2VzIG5vdGhpbmcsIGFuZCB0aGlzCiAgICAgICAgICAgICAqIGZ1bmN0aW9uIHVzZXMgZ2xDb21wcmVzc2VkVGV4SW1hZ2UyRCBpbnN0ZWFkIG9mIHRoZSBTdWJJbWFnZSBjYWxsCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBHTF9FWFRDQUxMKGdsQ29tcHJlc3NlZFRleEltYWdlMkRBUkIoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsIFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xGb3JtYXRJbnRlcm5hbCwKICAgICAgICAgICAgICAgICAgICAgICB3aWR0aCwgaGVpZ2h0LCAwIC8qIGJvcmRlciAqLywgVGhpcy0+cmVzb3VyY2Uuc2l6ZSwgZGF0YSkpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xDb21wcmVzc2VkVGV4U3ViSW1hZ2UyRCIpOwogICAgICAgICAgICBMRUFWRV9HTCgpOwogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgVFJBQ0UoIiglcCkgOiBDYWxsaW5nIGdsVGV4U3ViSW1hZ2UyRCB3ICVkLCAgaCAlZCwgZGF0YSwgJXBcbiIsIFRoaXMsIHdpZHRoLCBoZWlnaHQsIGRhdGEpOwogICAgICAgIEVOVEVSX0dMKCk7CiAgICAgICAgZ2xUZXhTdWJJbWFnZTJEKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLCAwLCAwLCB3aWR0aCwgaGVpZ2h0LCBmb3JtYXQsIHR5cGUsIGRhdGEpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbFRleFN1YkltYWdlMkQiKTsKICAgICAgICBMRUFWRV9HTCgpOwogICAgfQp9CgpzdGF0aWMgdm9pZCBzdXJmYWNlX2FsbG9jYXRlX3N1cmZhY2UoSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcywgR0xlbnVtIGludGVybmFsLCBHTHNpemVpIHdpZHRoLCBHTHNpemVpIGhlaWdodCwgR0xlbnVtIGZvcm1hdCwgR0xlbnVtIHR5cGUpIHsKICAgIFRSQUNFKCIoJXApIDogQ3JlYXRpbmcgc3VyZmFjZSAodGFyZ2V0ICUjeCkgIGxldmVsICVkLCBkM2QgZm9ybWF0ICVzLCBpbnRlcm5hbCBmb3JtYXQgJSN4LCB3aWR0aCAlZCwgaGVpZ2h0ICVkLCBnbCBmb3JtYXQgJSN4LCBnbCB0eXBlPSUjeFxuIiwgVGhpcywKICAgICAgICAgICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsIGRlYnVnX2QzZGZvcm1hdChUaGlzLT5yZXNvdXJjZS5mb3JtYXQpLCBpbnRlcm5hbCwgd2lkdGgsIGhlaWdodCwgZm9ybWF0LCB0eXBlKTsKCiAgICBpZiAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMSB8fAogICAgICAgICAgICBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQyIHx8IFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDMgfHwKICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNCB8fCBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQ1KSB7CiAgICAgICAgLyogZ2xDb21wcmVzc2VkVGV4SW1hZ2UyRCBkb2VzIG5vdCBhY2NlcHQgTlVMTCBwb2ludGVycywgc28gd2UgY2Fubm90IGFsbG9jYXRlIGEgY29tcHJlc3NlZCB0ZXh0dXJlIHdpdGhvdXQgdXBsb2FkaW5nIGRhdGEgKi8KICAgICAgICBUUkFDRSgiTm90IGFsbG9jYXRpbmcgY29tcHJlc3NlZCBzdXJmYWNlcywgc3VyZmFjZV91cGxvYWRfZGF0YSB3aWxsIHNwZWNpZnkgdGhlbVxuIik7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIEVOVEVSX0dMKCk7CgogICAgZ2xUZXhJbWFnZTJEKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLCBpbnRlcm5hbCwgd2lkdGgsIGhlaWdodCwgMCwgZm9ybWF0LCB0eXBlLCBOVUxMKTsKICAgIGNoZWNrR0xjYWxsKCJnbFRleEltYWdlMkQiKTsKCiAgICBMRUFWRV9HTCgpOwp9CgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgIElXaW5lRDNEU3VyZmFjZSBJVW5rbm93biBwYXJ0cyBmb2xsb3cKICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqLwpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1F1ZXJ5SW50ZXJmYWNlKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIFJFRklJRCByaWlkLCBMUFZPSUQgKnBwb2JqKQp7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIC8qIFdhcm4gLGJ1dCBiZSBuaWNlIGFib3V0IHRoaW5ncyAqLwogICAgVFJBQ0UoIiglcCktPiglcywlcClcbiIsIFRoaXMsZGVidWdzdHJfZ3VpZChyaWlkKSxwcG9iaik7CgogICAgaWYgKElzRXF1YWxHVUlEKHJpaWQsICZJSURfSVVua25vd24pCiAgICAgICAgfHwgSXNFcXVhbEdVSUQocmlpZCwgJklJRF9JV2luZUQzREJhc2UpCiAgICAgICAgfHwgSXNFcXVhbEdVSUQocmlpZCwgJklJRF9JV2luZUQzRFJlc291cmNlKQogICAgICAgIHx8IElzRXF1YWxHVUlEKHJpaWQsICZJSURfSVdpbmVEM0RTdXJmYWNlKSkgewogICAgICAgIElVbmtub3duX0FkZFJlZigoSVVua25vd24qKWlmYWNlKTsKICAgICAgICAqcHBvYmogPSBUaGlzOwogICAgICAgIHJldHVybiBTX09LOwogICAgfQogICAgKnBwb2JqID0gTlVMTDsKICAgIHJldHVybiBFX05PSU5URVJGQUNFOwp9CgpVTE9ORyBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9BZGRSZWYoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVzb3VyY2UucmVmKTsKICAgIFRSQUNFKCIoJXApIDogQWRkUmVmIGluY3JlYXNpbmcgZnJvbSAlZFxuIiwgVGhpcyxyZWYgLSAxKTsKICAgIHJldHVybiByZWY7Cn0KClVMT05HIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1JlbGVhc2UoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+cmVzb3VyY2UucmVmKTsKICAgIFRSQUNFKCIoJXApIDogUmVsZWFzaW5nIGZyb20gJWRcbiIsIFRoaXMsIHJlZiArIDEpOwogICAgaWYgKHJlZiA9PSAwKSB7CiAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsICpkZXZpY2UgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CiAgICAgICAgVFJBQ0UoIiglcCkgOiBjbGVhbmluZyB1cFxuIiwgVGhpcyk7CgogICAgICAgIGlmKGlmYWNlID09IGRldmljZS0+bGFzdEFjdGl2ZVJlbmRlclRhcmdldCkgewogICAgICAgICAgICBJV2luZUQzRFN3YXBDaGFpbkltcGwgKnN3YXBjaGFpbiA9IGRldmljZS0+c3dhcGNoYWlucyA/IChJV2luZUQzRFN3YXBDaGFpbkltcGwgKikgZGV2aWNlLT5zd2FwY2hhaW5zWzBdIDogTlVMTDsKCiAgICAgICAgICAgIFRSQUNFKCJMYXN0IGFjdGl2ZSByZW5kZXIgdGFyZ2V0IGRlc3Ryb3llZFxuIik7CiAgICAgICAgICAgIC8qIEZpbmQgYSByZXBsYWNlbWVudCBzdXJmYWNlIGZvciB0aGUgY3VycmVudGx5IGFjdGl2ZSBiYWNrIGJ1ZmZlci4gVGhlIGNvbnRleHQgbWFuYWdlciBkb2VzIG5vdCBkbyBOVUxMCiAgICAgICAgICAgICAqIGNoZWNrcywgc28gc3dpdGNoIHRvIGEgdmFsaWQgdGFyZ2V0IGFzIGxvbmcgYXMgdGhlIGN1cnJlbnRseSBzZXQgc3VyZmFjZSBpcyBzdGlsbCB2YWxpZC4gVXNlIHRoZQogICAgICAgICAgICAgKiBzdXJmYWNlIG9mIHRoZSBpbXBsaWNpdCBzd3BjaGFpbi4gSWYgdGhhdCBpcyB0aGUgc2FtZSBhcyB0aGUgZGVzdHJveWVkIHN1cmZhY2UgdGhlIGRldmljZSBpcyBkZXN0cm95ZWQKICAgICAgICAgICAgICogYW5kIHRoZSBsYXN0QWN0aXZlUmVuZGVyVGFyZ2V0IG1lbWJlciBzaG91bGRuJ3QgbWF0dGVyCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZihzd2FwY2hhaW4pIHsKICAgICAgICAgICAgICAgIGlmKHN3YXBjaGFpbi0+YmFja0J1ZmZlciAmJiBzd2FwY2hhaW4tPmJhY2tCdWZmZXJbMF0gIT0gaWZhY2UpIHsKICAgICAgICAgICAgICAgICAgICBUUkFDRSgiQWN0aXZhdGluZyBwcmltYXJ5IGJhY2sgYnVmZmVyXG4iKTsKICAgICAgICAgICAgICAgICAgICBBY3RpdmF0ZUNvbnRleHQoZGV2aWNlLCBzd2FwY2hhaW4tPmJhY2tCdWZmZXJbMF0sIENUWFVTQUdFX1JFU09VUkNFTE9BRCk7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYoIXN3YXBjaGFpbi0+YmFja0J1ZmZlciAmJiBzd2FwY2hhaW4tPmZyb250QnVmZmVyICE9IGlmYWNlKSB7CiAgICAgICAgICAgICAgICAgICAgLyogU2luZ2xlIGJ1ZmZlcmluZyBlbnZpcm9ubWVudCAqLwogICAgICAgICAgICAgICAgICAgIFRSQUNFKCJBY3RpdmF0aW5nIHByaW1hcnkgZnJvbnQgYnVmZmVyXG4iKTsKICAgICAgICAgICAgICAgICAgICBBY3RpdmF0ZUNvbnRleHQoZGV2aWNlLCBzd2FwY2hhaW4tPmZyb250QnVmZmVyLCBDVFhVU0FHRV9SRVNPVVJDRUxPQUQpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBUUkFDRSgiRGV2aWNlIGlzIGJlaW5nIGRlc3Ryb3llZCwgc2V0dGluZyBsYXN0QWN0aXZlUmVuZGVyVGFyZ2V0ID0gMHhkZWFkYmFiZVxuIik7CiAgICAgICAgICAgICAgICAgICAgLyogSW1wbGljaXQgcmVuZGVyIHRhcmdldCBkZXN0cm95ZWQsIHRoYXQgbWVhbnMgdGhlIGRldmljZSBpcyBiZWluZyBkZXN0cm95ZWQKICAgICAgICAgICAgICAgICAgICAgKiB3aGF0ZXZlciB3ZSBzZXQgaGVyZSwgaXQgc2hvdWxkbid0IG1hdHRlcgogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIGRldmljZS0+bGFzdEFjdGl2ZVJlbmRlclRhcmdldCA9IChJV2luZUQzRFN1cmZhY2UgKikgMHhkZWFkYmFiZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8qIE1heSBoYXBwZW4gZHVyaW5nIGRkcmF3IHVuaW5pdGlhbGl6YXRpb24gKi8KICAgICAgICAgICAgICAgIFRSQUNFKCJSZW5kZXIgdGFyZ2V0IHNldCwgYnV0IHN3YXBjaGFpbiBkb2VzIG5vdCBleGlzdCFcbiIpOwogICAgICAgICAgICAgICAgZGV2aWNlLT5sYXN0QWN0aXZlUmVuZGVyVGFyZ2V0ID0gKElXaW5lRDNEU3VyZmFjZSAqKSAweGRlYWRjYWZlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSAhPSAwKSB7IC8qIHJlbGVhc2UgdGhlIG9wZW5HTCB0ZXh0dXJlLi4gKi8KICAgICAgICAgICAgRU5URVJfR0woKTsKICAgICAgICAgICAgVFJBQ0UoIkRlbGV0aW5nIHRleHR1cmUgJWRcbiIsIFRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpOwogICAgICAgICAgICBnbERlbGV0ZVRleHR1cmVzKDEsICZUaGlzLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lKTsKICAgICAgICAgICAgTEVBVkVfR0woKTsKICAgICAgICB9CgogICAgICAgIGlmKFRoaXMtPkZsYWdzICYgU0ZMQUdfRElCU0VDVElPTikgewogICAgICAgICAgICAvKiBSZWxlYXNlIHRoZSBEQyAqLwogICAgICAgICAgICBTZWxlY3RPYmplY3QoVGhpcy0+aERDLCBUaGlzLT5kaWIuaG9sZGJpdG1hcCk7CiAgICAgICAgICAgIERlbGV0ZURDKFRoaXMtPmhEQyk7CiAgICAgICAgICAgIC8qIFJlbGVhc2UgdGhlIERJQiBzZWN0aW9uICovCiAgICAgICAgICAgIERlbGV0ZU9iamVjdChUaGlzLT5kaWIuRElCc2VjdGlvbik7CiAgICAgICAgICAgIFRoaXMtPmRpYi5iaXRtYXBfZGF0YSA9IE5VTEw7CiAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IE5VTEw7CiAgICAgICAgfQogICAgICAgIGlmKFRoaXMtPkZsYWdzICYgU0ZMQUdfVVNFUlBUUikgSVdpbmVEM0RTdXJmYWNlX1NldE1lbShpZmFjZSwgTlVMTCk7CgogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnBhbGV0dGU5KTsKCiAgICAgICAgSVdpbmVEM0RSZXNvdXJjZUltcGxfQ2xlYW5VcCgoSVdpbmVEM0RSZXNvdXJjZSAqKWlmYWNlKTsKICAgICAgICBpZihpZmFjZSA9PSBkZXZpY2UtPmRkcmF3X3ByaW1hcnkpCiAgICAgICAgICAgIGRldmljZS0+ZGRyYXdfcHJpbWFyeSA9IE5VTEw7CgogICAgICAgIFRSQUNFKCIoJXApIFJlbGVhc2VkXG4iLCBUaGlzKTsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzKTsKCiAgICB9CiAgICByZXR1cm4gcmVmOwp9CgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgIElXaW5lRDNEU3VyZmFjZSBJV2luZUQzRFJlc291cmNlIHBhcnRzIGZvbGxvdwogICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0RGV2aWNlKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIElXaW5lRDNERGV2aWNlKiogcHBEZXZpY2UpIHsKICAgIHJldHVybiBJV2luZUQzRFJlc291cmNlSW1wbF9HZXREZXZpY2UoKElXaW5lRDNEUmVzb3VyY2UgKilpZmFjZSwgcHBEZXZpY2UpOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1NldFByaXZhdGVEYXRhKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIFJFRkdVSUQgcmVmZ3VpZCwgQ09OU1Qgdm9pZCogcERhdGEsIERXT1JEIFNpemVPZkRhdGEsIERXT1JEIEZsYWdzKSB7CiAgICByZXR1cm4gSVdpbmVEM0RSZXNvdXJjZUltcGxfU2V0UHJpdmF0ZURhdGEoKElXaW5lRDNEUmVzb3VyY2UgKilpZmFjZSwgcmVmZ3VpZCwgcERhdGEsIFNpemVPZkRhdGEsIEZsYWdzKTsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRQcml2YXRlRGF0YShJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBSRUZHVUlEIHJlZmd1aWQsIHZvaWQqIHBEYXRhLCBEV09SRCogcFNpemVPZkRhdGEpIHsKICAgIHJldHVybiBJV2luZUQzRFJlc291cmNlSW1wbF9HZXRQcml2YXRlRGF0YSgoSVdpbmVEM0RSZXNvdXJjZSAqKWlmYWNlLCByZWZndWlkLCBwRGF0YSwgcFNpemVPZkRhdGEpOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0ZyZWVQcml2YXRlRGF0YShJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBSRUZHVUlEIHJlZmd1aWQpIHsKICAgIHJldHVybiBJV2luZUQzRFJlc291cmNlSW1wbF9GcmVlUHJpdmF0ZURhdGEoKElXaW5lRDNEUmVzb3VyY2UgKilpZmFjZSwgcmVmZ3VpZCk7Cn0KCkRXT1JEICAgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0UHJpb3JpdHkoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgRFdPUkQgUHJpb3JpdHlOZXcpIHsKICAgIHJldHVybiBJV2luZUQzRFJlc291cmNlSW1wbF9TZXRQcmlvcml0eSgoSVdpbmVEM0RSZXNvdXJjZSAqKWlmYWNlLCBQcmlvcml0eU5ldyk7Cn0KCkRXT1JEICAgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0UHJpb3JpdHkoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgcmV0dXJuIElXaW5lRDNEUmVzb3VyY2VJbXBsX0dldFByaW9yaXR5KChJV2luZUQzRFJlc291cmNlICopaWZhY2UpOwp9Cgp2b2lkIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1ByZUxvYWQoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgLyogVE9ETzogcmUtd3JpdGUgdGhlIHdheSB0ZXh0dXJlcyBhbmQgbWFuYWdlZCwKICAgICogIHVzZSBhICdvcGVuZ2wgY29udGV4dCBtYW5hZ2VyJyB0byBtYW5hZ2UgUmVuZGVyVGFyZ2V0IHN1cmZhY2VzCiAgICAqKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgLyogVE9ETzogY2hlY2sgZm9yIGxvY2tzICovCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEQmFzZVRleHR1cmUgKmJhc2VUZXh0dXJlID0gTlVMTDsKICAgIFRSQUNFKCIoJXApQ2hlY2tpbmcgdG8gc2VlIGlmIHRoZSBjb250YWluZXIgaXMgYSBiYXNlIHRleHR1cmVcbiIsIFRoaXMpOwogICAgaWYgKElXaW5lRDNEU3VyZmFjZV9HZXRDb250YWluZXIoaWZhY2UsICZJSURfSVdpbmVEM0RCYXNlVGV4dHVyZSwgKHZvaWQgKiopJmJhc2VUZXh0dXJlKSA9PSBXSU5FRDNEX09LKSB7CiAgICAgICAgVFJBQ0UoIlBhc3NpbmcgdG8gY29uYXRpbmVyXG4iKTsKICAgICAgICBJV2luZUQzREJhc2VUZXh0dXJlX1ByZUxvYWQoYmFzZVRleHR1cmUpOwogICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVfUmVsZWFzZShiYXNlVGV4dHVyZSk7CiAgICB9IGVsc2UgewogICAgVFJBQ0UoIiglcCkgOiBBYm91dCB0byBsb2FkIHN1cmZhY2VcbiIsIFRoaXMpOwogICAgRU5URVJfR0woKTsKI2lmIDAgLyogVE9ETzogY29udGV4dCBtYW5hZ2VyIHN1cHBvcnQgKi8KICAgICBJV2luZUQzRENvbnRleHRNYW5hZ2VyX1B1c2hTdGF0ZShUaGlzLT5jb250ZXh0TWFuYWdlciwgR0xfVEVYVFVSRV8yRCwgRU5BQkxFRCwgTk9XIC8qIG1ha2Ugc3VyZSB0aGUgc3RhdGUgaXMgYXBwbGllZCBub3cgKi8pOwojZW5kaWYKICAgIGdsRW5hYmxlKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0KTsvKiBtYWtlIHN1cmUgdGV4dHVyZSBzdXBwb3J0IGlzIGVuYWJsZWQgaW4gdGhpcyBjb250ZXh0ICovCiAgICBpZiAoIVRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwpIHsKICAgICAgICBpZiAoIVRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpIHsKICAgICAgICAgICAgZ2xHZW5UZXh0dXJlcygxLCAmVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEdlblRleHR1cmVzIik7CiAgICAgICAgICAgIFRSQUNFKCJTdXJmYWNlICVwIGdpdmVuIG5hbWUgJWRcbiIsIFRoaXMsIFRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpOwogICAgICAgIH0KICAgICAgICBnbEJpbmRUZXh0dXJlKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCBUaGlzLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xCaW5kVGV4dHVyZSIpOwogICAgICAgIElXaW5lRDNEU3VyZmFjZV9Mb2FkVGV4dHVyZShpZmFjZSk7CiAgICAgICAgLyogVGhpcyBpcyB3aGVyZSB3ZSBzaG91bGQgYmUgcmVkdWNpbmcgdGhlIGFtb3VudCBvZiBHTE1lbW9yeVVzZWQgKi8KICAgIH0gZWxzZSBpZiAoVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSkgeyAvKiBOT1RFOiB0aGUgbGV2ZWwgMCBzdXJmYWNlIG9mIGEgbXBtYXBwZWQgdGV4dHVyZSBtdXN0IGJlIGxvYWRlZCBmaXJzdCEgKi8KICAgICAgICAvKiBhc3N1bWUgdGhpcyBpcyBhIGNvZGluZyBlcnJvciBub3QgYSByZWFsIGVycm9yIGZvciBub3cgKi8KICAgICAgICBGSVhNRSgiTWlwbWFwIHN1cmZhY2UgaGFzIGEgZ2xUZXh0dXJlIGJvdW5kIHRvIGl0IVxuIik7CiAgICB9CiAgICBpZiAoVGhpcy0+cmVzb3VyY2UucG9vbCA9PSBXSU5FRDNEUE9PTF9ERUZBVUxUKSB7CiAgICAgICAvKiBUZWxsIG9wZW5nbCB0byB0cnkgYW5kIGtlZXAgdGhpcyB0ZXh0dXJlIGluIHZpZGVvIHJhbSAod2VsbCBtb3N0bHkpICovCiAgICAgICBHTGNsYW1wZiB0bXA7CiAgICAgICB0bXAgPSAwLjlmOwogICAgICAgIGdsUHJpb3JpdGl6ZVRleHR1cmVzKDEsICZUaGlzLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lLCAmdG1wKTsKICAgIH0KICAgIC8qIFRPRE86IGRpc2FibGUgdGV4dHVyZSBzdXBwb3J0LCBpZiBpdCB3YXN0bid0IGVuYWJsZWQgd2hlbiB3ZSBlbnRlcmVkLiAqLwojaWYgMCAvKiBUT0RPOiBjb250ZXh0IG1hbmFnZXIgc3VwcG9ydCAqLwogICAgIElXaW5lRDNEQ29udGV4dE1hbmFnZXJfUG9wU3RhdGUoVGhpcy0+Y29udGV4dE1hbmFnZXIsIEdMX1RFWFRVUkVfMkQsIERJU0FCTEVELERFTEFZRUQKICAgICAgICAgICAgICAvKiB3ZSBkb24ndCBjYXJlIHdoZW4gdGhlIHN0YXRlIGlzIGRpc2FibGVkKGlmIGF0YWxsKSAqLyk7CiNlbmRpZgogICAgTEVBVkVfR0woKTsKICAgIH0KICAgIHJldHVybjsKfQoKV0lORUQzRFJFU09VUkNFVFlQRSBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRUeXBlKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpIHsKICAgIFRSQUNFKCIoJXApIDogY2FsbGluZyByZXNvdXJjZWltcGxfR2V0VHlwZVxuIiwgaWZhY2UpOwogICAgcmV0dXJuIElXaW5lRDNEUmVzb3VyY2VJbXBsX0dldFR5cGUoKElXaW5lRDNEUmVzb3VyY2UgKilpZmFjZSk7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0UGFyZW50KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIElVbmtub3duICoqcFBhcmVudCkgewogICAgVFJBQ0UoIiglcCkgOiBjYWxsaW5nIHJlc291cmNlaW1wbF9HZXRQYXJlbnRcbiIsIGlmYWNlKTsKICAgIHJldHVybiBJV2luZUQzRFJlc291cmNlSW1wbF9HZXRQYXJlbnQoKElXaW5lRDNEUmVzb3VyY2UgKilpZmFjZSwgcFBhcmVudCk7Cn0KCi8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogICBJV2luZUQzRFN1cmZhY2UgSVdpbmVEM0RTdXJmYWNlIHBhcnRzIGZvbGxvdwogICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi8KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0Q29udGFpbmVyKElXaW5lRDNEU3VyZmFjZSogaWZhY2UsIFJFRklJRCByaWlkLCB2b2lkKiogcHBDb250YWluZXIpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RCYXNlICpjb250YWluZXIgPSAwOwoKICAgIFRSQUNFKCIoVGhpcyAlcCwgcmlpZCAlcywgcHBDb250YWluZXIgJXApXG4iLCBUaGlzLCBkZWJ1Z3N0cl9ndWlkKHJpaWQpLCBwcENvbnRhaW5lcik7CgogICAgaWYgKCFwcENvbnRhaW5lcikgewogICAgICAgIEVSUigiQ2FsbGVkIHdpdGhvdXQgYSB2YWxpZCBwcENvbnRhaW5lci5cbiIpOwogICAgfQoKICAgIC8qKiBGcm9tIE1TRE46CiAgICAgKiBJZiB0aGUgc3VyZmFjZSBpcyBjcmVhdGVkIHVzaW5nIENyZWF0ZUltYWdlU3VyZmFjZS9DcmVhdGVPZmZzY3JlZW5QbGFpblN1cmZhY2UsIENyZWF0ZVJlbmRlclRhcmdldCwKICAgICAqIG9yIENyZWF0ZURlcHRoU3RlbmNpbFN1cmZhY2UsIHRoZSBzdXJmYWNlIGlzIGNvbnNpZGVyZWQgc3RhbmQgYWxvbmUuIEluIHRoaXMgY2FzZSwKICAgICAqIEdldENvbnRhaW5lciB3aWxsIHJldHVybiB0aGUgRGlyZWN0M0QgZGV2aWNlIHVzZWQgdG8gY3JlYXRlIHRoZSBzdXJmYWNlLgogICAgICovCiAgICBpZiAoVGhpcy0+Y29udGFpbmVyKSB7CiAgICAgICAgY29udGFpbmVyID0gVGhpcy0+Y29udGFpbmVyOwogICAgfSBlbHNlIHsKICAgICAgICBjb250YWluZXIgPSAoSVdpbmVEM0RCYXNlICopVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZTsKICAgIH0KCiAgICBUUkFDRSgiUmVsYXlpbmcgdG8gUXVlcnlJbnRlcmZhY2VcbiIpOwogICAgcmV0dXJuIElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGNvbnRhaW5lciwgcmlpZCwgcHBDb250YWluZXIpOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0dldERlc2MoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgV0lORUQzRFNVUkZBQ0VfREVTQyAqcERlc2MpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwoKICAgIFRSQUNFKCIoJXApIDogY29weWluZyBpbnRvICVwXG4iLCBUaGlzLCBwRGVzYyk7CiAgICBpZihwRGVzYy0+Rm9ybWF0ICE9IE5VTEwpICAgICAgICAgICAgICoocERlc2MtPkZvcm1hdCkgPSBUaGlzLT5yZXNvdXJjZS5mb3JtYXQ7CiAgICBpZihwRGVzYy0+VHlwZSAhPSBOVUxMKSAgICAgICAgICAgICAgICoocERlc2MtPlR5cGUpICAgPSBUaGlzLT5yZXNvdXJjZS5yZXNvdXJjZVR5cGU7CiAgICBpZihwRGVzYy0+VXNhZ2UgIT0gTlVMTCkgICAgICAgICAgICAgICoocERlc2MtPlVzYWdlKSAgICAgICAgICAgICAgPSBUaGlzLT5yZXNvdXJjZS51c2FnZTsKICAgIGlmKHBEZXNjLT5Qb29sICE9IE5VTEwpICAgICAgICAgICAgICAgKihwRGVzYy0+UG9vbCkgICAgICAgICAgICAgICA9IFRoaXMtPnJlc291cmNlLnBvb2w7CiAgICBpZihwRGVzYy0+U2l6ZSAhPSBOVUxMKSAgICAgICAgICAgICAgICoocERlc2MtPlNpemUpICAgICAgICAgICAgICAgPSBUaGlzLT5yZXNvdXJjZS5zaXplOyAgIC8qIGR4OCBvbmx5ICovCiAgICBpZihwRGVzYy0+TXVsdGlTYW1wbGVUeXBlICE9IE5VTEwpICAgICoocERlc2MtPk11bHRpU2FtcGxlVHlwZSkgICAgPSBUaGlzLT5jdXJyZW50RGVzYy5NdWx0aVNhbXBsZVR5cGU7CiAgICBpZihwRGVzYy0+TXVsdGlTYW1wbGVRdWFsaXR5ICE9IE5VTEwpICoocERlc2MtPk11bHRpU2FtcGxlUXVhbGl0eSkgPSBUaGlzLT5jdXJyZW50RGVzYy5NdWx0aVNhbXBsZVF1YWxpdHk7CiAgICBpZihwRGVzYy0+V2lkdGggIT0gTlVMTCkgICAgICAgICAgICAgICoocERlc2MtPldpZHRoKSAgICAgICAgICAgICAgPSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgIGlmKHBEZXNjLT5IZWlnaHQgIT0gTlVMTCkgICAgICAgICAgICAgKihwRGVzYy0+SGVpZ2h0KSAgICAgICAgICAgICA9IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9Cgp2b2lkIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1NldEdsVGV4dHVyZURlc2MoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgVUlOVCB0ZXh0dXJlTmFtZSwgaW50IHRhcmdldCkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKSA6IHNldHRpbmcgdGV4dHVyZU5hbWUgJXUsIHRhcmdldCAlaVxuIiwgVGhpcywgdGV4dHVyZU5hbWUsIHRhcmdldCk7CiAgICBpZiAoVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSA9PSAwICYmIHRleHR1cmVOYW1lICE9IDApIHsKICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19ESVJUWTsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfQWRkRGlydHlSZWN0KGlmYWNlLCBOVUxMKTsKICAgIH0KICAgIFRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUgPSB0ZXh0dXJlTmFtZTsKICAgIFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0ICAgICAgPSB0YXJnZXQ7Cn0KCnZvaWQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0R2xEZXNjKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIGdsRGVzY3JpcHRvciAqKmdsRGVzY3JpcHRpb24pIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCkgOiByZXR1cm5pbmcgJXBcbiIsIFRoaXMsICZUaGlzLT5nbERlc2NyaXB0aW9uKTsKICAgICpnbERlc2NyaXB0aW9uID0gJlRoaXMtPmdsRGVzY3JpcHRpb247Cn0KCi8qIFRPRE86IHRoaW5rIGFib3V0IG1vdmluZyB0aGlzIGRvd24gdG8gcmVzb3VyY2U/ICovCmNvbnN0IHZvaWQgKldJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0dldERhdGEoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICAvKiBUaGlzIHNob3VsZCBvbmx5IGJlIGNhbGxlZCBmb3Igc3lzbWVtIHRleHR1cmVzLCBpdCBtYXkgYmUgYSBnb29kIGlkZWEgdG8gZXh0ZW5kIHRoaXMgdG8gYWxsIHBvb2xzIGF0IHNvbWUgcG9pbnQgaW4gdGhlIGZ1dHR1cmUgICovCiAgICBpZiAoVGhpcy0+cmVzb3VyY2UucG9vbCAhPSBXSU5FRDNEUE9PTF9TWVNURU1NRU0pIHsKICAgICAgICBGSVhNRSgiICglcClBdHRlbXB0aW5nIHRvIGdldCBzeXN0ZW0gbWVtb3J5IGZvciBhIG5vbi1zeXN0ZW0gbWVtb3J5IHRleHR1cmVcbiIsIGlmYWNlKTsKICAgIH0KICAgIHJldHVybiAoQ09OU1Qgdm9pZCopKFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSk7Cn0KCnN0YXRpYyB2b2lkIHJlYWRfZnJvbV9mcmFtZWJ1ZmZlcihJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzLCBDT05TVCBSRUNUICpyZWN0LCB2b2lkICpkZXN0LCBVSU5UIHBpdGNoLCBCT09MIHNyY1Vwc2lkZURvd24pIHsKICAgIEJZVEUgKm1lbTsKICAgIEdMaW50IGZtdDsKICAgIEdMaW50IHR5cGU7CiAgICBCWVRFICpyb3csICp0b3AsICpib3R0b207CiAgICBpbnQgaTsKICAgIEJPT0wgYnBwOwoKICAgIHN3aXRjaChUaGlzLT5yZXNvdXJjZS5mb3JtYXQpCiAgICB7CiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1A4OgogICAgICAgIHsKICAgICAgICAgICAgLyogR0wgY2FuJ3QgcmV0dXJuIHBhbGV0dGl6ZWQgZGF0YSwgc28gcmVhZCBBUkdCIHBpeGVscyBpbnRvIGEKICAgICAgICAgICAgICogc2VwYXJhdGUgYmxvY2sgb2YgbWVtb3J5IGFuZCBjb252ZXJ0IHRoZW0gaW50byBwYWxldHRpemVkIGZvcm1hdAogICAgICAgICAgICAgKiBpbiBzb2Z0d2FyZS4gU2xvdywgYnV0IGlmIHRoZSBhcHAgbWVhbnMgdG8gdXNlIHBhbGV0dGl6ZWQgcmVuZGVyCiAgICAgICAgICAgICAqIHRhcmdldHMgYW5kIGxvY2tzIGl0Li4uCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIFVzZSBHTF9SR0IsIEdMX1VOU0lHTkVEX0JZVEUgdG8gcmVhZCB0aGUgc3VyZmFjZSBmb3IgcGVyZm9ybWFuY2UgcmVhc29ucwogICAgICAgICAgICAgKiBEb24ndCB1c2UgR0xfQkdSIGFzIGluIHRoZSBXSU5FRDNERk1UX1I4RzhCOCBjYXNlLCBpbnN0ZWFkIHdhdGNoIG91dAogICAgICAgICAgICAgKiBmb3IgdGhlIGNvbG9yIGNoYW5uZWxzIHdoZW4gcGFsZXR0aXppbmcgdGhlIGNvbG9ycy4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGZtdCA9IEdMX1JHQjsKICAgICAgICAgICAgdHlwZSA9IEdMX1VOU0lHTkVEX0JZVEU7CiAgICAgICAgICAgIHBpdGNoICo9IDM7CiAgICAgICAgICAgIG1lbSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5yZXNvdXJjZS5zaXplICogMyk7CiAgICAgICAgICAgIGlmKCFtZW0pIHsKICAgICAgICAgICAgICAgIEVSUigiT3V0IG9mIG1lbW9yeVxuIik7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnBwID0gVGhpcy0+Ynl0ZXNQZXJQaXhlbCAqIDM7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBtZW0gPSBkZXN0OwogICAgICAgICAgICBmbXQgPSBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0OwogICAgICAgICAgICB0eXBlID0gVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbFR5cGU7CiAgICAgICAgICAgIGJwcCA9IFRoaXMtPmJ5dGVzUGVyUGl4ZWw7CiAgICB9CgogICAgZ2xSZWFkUGl4ZWxzKHJlY3QtPmxlZnQsIHJlY3QtPnRvcCwKICAgICAgICAgICAgICAgICByZWN0LT5yaWdodCAtIHJlY3QtPmxlZnQsCiAgICAgICAgICAgICAgICAgcmVjdC0+Ym90dG9tIC0gcmVjdC0+dG9wLAogICAgICAgICAgICAgICAgIGZtdCwgdHlwZSwgbWVtKTsKICAgIHZjaGVja0dMY2FsbCgiZ2xSZWFkUGl4ZWxzIik7CgogICAgLyogVE9ETzogTWVyZ2UgdGhpcyB3aXRoIHRoZSBwYWxldHRpemF0aW9uIGxvb3AgYmVsb3cgZm9yIFA4IHRhcmdldHMgKi8KCiAgICBpZighc3JjVXBzaWRlRG93bikgewogICAgICAgIFVJTlQgbGVuLCBvZmY7CiAgICAgICAgLyogZ2xSZWFkUGl4ZWxzIHJldHVybnMgdGhlIGltYWdlIHVwc2lkZSBkb3duLCBhbmQgdGhlcmUgaXMgbm8gd2F5IHRvIHByZXZlbnQgdGhpcy4KICAgICAgICAgICAgRmxpcCB0aGUgbGluZXMgaW4gc29mdHdhcmUgKi8KICAgICAgICBsZW4gPSAocmVjdC0+cmlnaHQgLSByZWN0LT5sZWZ0KSAqIGJwcDsKICAgICAgICBvZmYgPSByZWN0LT5sZWZ0ICogYnBwOwoKICAgICAgICByb3cgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuKTsKICAgICAgICBpZighcm93KSB7CiAgICAgICAgICAgIEVSUigiT3V0IG9mIG1lbW9yeVxuIik7CiAgICAgICAgICAgIGlmKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX1A4KSBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBtZW0pOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICB0b3AgPSBtZW0gKyBwaXRjaCAqIHJlY3QtPnRvcDsKICAgICAgICBib3R0b20gPSAoKEJZVEUgKikgbWVtKSArIHBpdGNoICogKCByZWN0LT5ib3R0b20gLSByZWN0LT50b3AgLSAxKTsKICAgICAgICBmb3IoaSA9IDA7IGkgPCAocmVjdC0+Ym90dG9tIC0gcmVjdC0+dG9wKSAvIDI7IGkrKykgewogICAgICAgICAgICBtZW1jcHkocm93LCB0b3AgKyBvZmYsIGxlbik7CiAgICAgICAgICAgIG1lbWNweSh0b3AgKyBvZmYsIGJvdHRvbSArIG9mZiwgbGVuKTsKICAgICAgICAgICAgbWVtY3B5KGJvdHRvbSArIG9mZiwgcm93LCBsZW4pOwogICAgICAgICAgICB0b3AgKz0gcGl0Y2g7CiAgICAgICAgICAgIGJvdHRvbSAtPSBwaXRjaDsKICAgICAgICB9CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcm93KTsKICAgIH0KCiAgICBpZihUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9QOCkgewogICAgICAgIFBBTEVUVEVFTlRSWSAqcGFsOwogICAgICAgIERXT1JEIHdpZHRoID0gcGl0Y2ggLyAzOwogICAgICAgIGludCB4LCB5LCBjOwogICAgICAgIGlmKFRoaXMtPnBhbGV0dGUpIHsKICAgICAgICAgICAgcGFsID0gVGhpcy0+cGFsZXR0ZS0+cGFsZW50czsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBwYWwgPSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlLT5wYWxldHRlc1tUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlLT5jdXJyZW50UGFsZXR0ZV07CiAgICAgICAgfQoKICAgICAgICBmb3IoeSA9IHJlY3QtPnRvcDsgeSA8IHJlY3QtPmJvdHRvbTsgeSsrKSB7CiAgICAgICAgICAgIGZvcih4ID0gcmVjdC0+bGVmdDsgeCA8IHJlY3QtPnJpZ2h0OyB4KyspIHsKICAgICAgICAgICAgICAgIC8qICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0ICAgICAgICAgICAgICBsaW5lcyAgICAgICAgICAgIHBpeGVscyAgICAgICovCiAgICAgICAgICAgICAgICBCWVRFICpibHVlID0gIChCWVRFICopICgoQllURSAqKSBtZW0pICsgeSAqIHBpdGNoICsgeCAqIChzaXplb2YoQllURSkgKiAzKTsKICAgICAgICAgICAgICAgIEJZVEUgKmdyZWVuID0gYmx1ZSAgKyAxOwogICAgICAgICAgICAgICAgQllURSAqcmVkID0gICBncmVlbiArIDE7CgogICAgICAgICAgICAgICAgZm9yKGMgPSAwOyBjIDwgMjU2OyBjKyspIHsKICAgICAgICAgICAgICAgICAgICBpZigqcmVkICAgPT0gcGFsW2NdLnBlUmVkICAgJiYKICAgICAgICAgICAgICAgICAgICAgICAqZ3JlZW4gPT0gcGFsW2NdLnBlR3JlZW4gJiYKICAgICAgICAgICAgICAgICAgICAgICAqYmx1ZSAgPT0gcGFsW2NdLnBlQmx1ZSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICooKEJZVEUgKikgZGVzdCArIHkgKiB3aWR0aCArIHgpID0gYzsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG1lbSk7CiAgICB9Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0xvY2tSZWN0KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIFdJTkVEM0RMT0NLRURfUkVDVCogcExvY2tlZFJlY3QsIENPTlNUIFJFQ1QqIHBSZWN0LCBEV09SRCBGbGFncykgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRERldmljZUltcGwgICpteURldmljZSA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CiAgICBJV2luZUQzRFN3YXBDaGFpbkltcGwgKnN3YXBjaGFpbiA9IE5VTEw7CgogICAgVFJBQ0UoIiglcCkgOiByZWN0QCVwIGZsYWdzKCUwOHgpLCBvdXRwdXQgbG9ja2VkUmVjdEAlcCwgbWVtb3J5QCVwXG4iLCBUaGlzLCBwUmVjdCwgRmxhZ3MsIHBMb2NrZWRSZWN0LCBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpOwoKICAgIGlmICghKFRoaXMtPkZsYWdzICYgU0ZMQUdfTE9DS0FCTEUpKSB7CiAgICAgICAgLyogTm90ZTogVXBkYXRlVGV4dHVyZXMgY2FsbHMgQ29weVJlY3RzIHdoaWNoIGNhbGxzIHRoaXMgcm91dGluZSB0byBwb3B1bGF0ZSB0aGUKICAgICAgICAgICAgICB0ZXh0dXJlIHJlZ2lvbnMsIGFuZCBzaW5jZSB0aGUgZGVzdGluYXRpb24gaXMgYW4gdW5sb2NrYWJsZSByZWdpb24gd2UgbmVlZAogICAgICAgICAgICAgIHRvIHRvbGVyYXRlIHRoaXMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgVFJBQ0UoIldhcm5pbmc6IHRyeWluZyB0byBsb2NrIHVubG9ja2FibGUgc3VyZkAlcFxuIiwgVGhpcyk7CiAgICAgICAgLypyZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsgKi8KICAgIH0KCiAgICBwTG9ja2VkUmVjdC0+UGl0Y2ggPSBJV2luZUQzRFN1cmZhY2VfR2V0UGl0Y2goaWZhY2UpOwoKICAgIC8qIE1hcmsgdGhlIHN1cmZhY2UgbG9ja2VkICovCiAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19MT0NLRUQ7CgogICAgLyogV2hhdGV2ZXIgc3VyZmFjZSB3ZSBoYXZlLCBtYWtlIHN1cmUgdGhhdCB0aGVyZSBpcyBtZW1vcnkgYWxsb2NhdGVkIGZvciB0aGUgZG93bmxvYWRlZCBjb3B5ICovCiAgICBpZighVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KSB7CiAgICAgICAgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCkgLDAgLCBUaGlzLT5yZXNvdXJjZS5zaXplICsgNCk7CiAgICAgICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfR0xESVJUWTsgLyogVGhpcyBpcyB0aGUgbWFya2VyIHRoYXQgc3VyZmFjZSBkYXRhIGhhcyB0byBiZSBkb3dubG9hZGVkICovCiAgICB9CgogICAgLyogQ2FsY3VsYXRlIHRoZSBjb3JyZWN0IHN0YXJ0IGFkZHJlc3MgdG8gcmVwb3J0ICovCiAgICBpZiAoTlVMTCA9PSBwUmVjdCkgewogICAgICAgIHBMb2NrZWRSZWN0LT5wQml0cyA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeTsKICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LmxlZnQgICA9IDA7CiAgICAgICAgVGhpcy0+bG9ja2VkUmVjdC50b3AgICAgPSAwOwogICAgICAgIFRoaXMtPmxvY2tlZFJlY3QucmlnaHQgID0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAgICAgVGhpcy0+bG9ja2VkUmVjdC5ib3R0b20gPSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICAgICAgVFJBQ0UoIkxvY2tlZCBSZWN0ICglcCkgPSBsICVkLCB0ICVkLCByICVkLCBiICVkXG4iLCAmVGhpcy0+bG9ja2VkUmVjdCwgVGhpcy0+bG9ja2VkUmVjdC5sZWZ0LCBUaGlzLT5sb2NrZWRSZWN0LnRvcCwgVGhpcy0+bG9ja2VkUmVjdC5yaWdodCwgVGhpcy0+bG9ja2VkUmVjdC5ib3R0b20pOwogICAgfSBlbHNlIHsKICAgICAgICBUUkFDRSgiTG9jayBSZWN0ICglcCkgPSBsICVkLCB0ICVkLCByICVkLCBiICVkXG4iLCBwUmVjdCwgcFJlY3QtPmxlZnQsIHBSZWN0LT50b3AsIHBSZWN0LT5yaWdodCwgcFJlY3QtPmJvdHRvbSk7CgogICAgICAgIGlmICgocFJlY3QtPnRvcCA8IDApIHx8CiAgICAgICAgICAgICAocFJlY3QtPmxlZnQgPCAwKSB8fAogICAgICAgICAgICAgKHBSZWN0LT5sZWZ0ID49IHBSZWN0LT5yaWdodCkgfHwKICAgICAgICAgICAgIChwUmVjdC0+dG9wID49IHBSZWN0LT5ib3R0b20pIHx8CiAgICAgICAgICAgICAocFJlY3QtPnJpZ2h0ID4gVGhpcy0+Y3VycmVudERlc2MuV2lkdGgpIHx8CiAgICAgICAgICAgICAocFJlY3QtPmJvdHRvbSA+IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodCkpCiAgICAgICAgewogICAgICAgICAgICBXQVJOKCIgSW52YWxpZCB2YWx1ZXMgaW4gcFJlY3QgISEhXG4iKTsKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICAgICAgfQoKICAgICAgICBpZiAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMSkgeyAvKiBEWFQxIGlzIGhhbGYgYnl0ZSBwZXIgcGl4ZWwgKi8KICAgICAgICAgICAgcExvY2tlZFJlY3QtPnBCaXRzID0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ICsgKHBMb2NrZWRSZWN0LT5QaXRjaCAqIHBSZWN0LT50b3ApICsgKChwUmVjdC0+bGVmdCAqIFRoaXMtPmJ5dGVzUGVyUGl4ZWwgLyAyKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcExvY2tlZFJlY3QtPnBCaXRzID0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ICsgKHBMb2NrZWRSZWN0LT5QaXRjaCAqIHBSZWN0LT50b3ApICsgKHBSZWN0LT5sZWZ0ICogVGhpcy0+Ynl0ZXNQZXJQaXhlbCk7CiAgICAgICAgfQogICAgICAgIFRoaXMtPmxvY2tlZFJlY3QubGVmdCAgID0gcFJlY3QtPmxlZnQ7CiAgICAgICAgVGhpcy0+bG9ja2VkUmVjdC50b3AgICAgPSBwUmVjdC0+dG9wOwogICAgICAgIFRoaXMtPmxvY2tlZFJlY3QucmlnaHQgID0gcFJlY3QtPnJpZ2h0OwogICAgICAgIFRoaXMtPmxvY2tlZFJlY3QuYm90dG9tID0gcFJlY3QtPmJvdHRvbTsKICAgIH0KCiAgICBpZiAoVGhpcy0+RmxhZ3MgJiBTRkxBR19OT05QT1cyKSB7CiAgICAgICAgVFJBQ0UoIkxvY2tpbmcgbm9uLXBvd2VyIDIgdGV4dHVyZVxuIik7CiAgICB9CgogICAgLyogUGVyZm9ybWFuY2Ugb3B0aW1pemF0aW9uOiBDb3VudCBob3cgb2Z0ZW4gYSBzdXJmYWNlIGlzIGxvY2tlZCwgaWYgaXQgaXMgbG9ja2VkIHJlZ3VsYXJseSBkbyBub3QgdGhyb3cgYXdheSB0aGUgc3lzdGVtIG1lbW9yeSBjb3B5LgogICAgICogVGhpcyBhdm9pZHMgdGhlIG5lZWQgdG8gZG93bmxvYWQgdGhlIHN1cmZhY2UgZnJvbSBvcGVuZ2wgYWxsIHRoZSB0aW1lLiBUaGUgc3VyZmFjZSBpcyBzdGlsbCBkb3dubG9hZGVkIGlmIHRoZSBvcGVuZ2wgdGV4dHVyZSBpcwogICAgICogY2hhbmdlZAogICAgICovCiAgICBpZighKFRoaXMtPkZsYWdzICYgU0ZMQUdfRFlOTE9DSykpIHsKICAgICAgICBUaGlzLT5sb2NrQ291bnQrKzsKICAgICAgICAvKiBNQVhMT0NLQ09VTlQgaXMgZGVmaW5lZCBpbiB3aW5lZDNkX3ByaXZhdGUuaCAqLwogICAgICAgIGlmKFRoaXMtPmxvY2tDb3VudCA+IE1BWExPQ0tDT1VOVCkgewogICAgICAgICAgICBUUkFDRSgiU3VyZmFjZSBpcyBsb2NrZWQgcmVndWxhcmlseSwgbm90IGZyZWVpbmcgdGhlIHN5c3RlbSBtZW1vcnkgY29weSBhbnkgbW9yZVxuIik7CiAgICAgICAgICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX0RZTkxPQ0s7CiAgICAgICAgfQogICAgfQoKICAgIGlmKChGbGFncyAmIFdJTkVEM0RMT0NLX0RJU0NBUkQpIHx8ICEoVGhpcy0+RmxhZ3MgJiBTRkxBR19HTERJUlRZKSApIHsKICAgICAgICBUUkFDRSgiV0lORUQzRExPQ0tfRElTQ0FSRCBmbGFnIHBhc3NlZCwgb3IgbG9jYWwgY29weSBpcyB1cCB0byBkYXRlLCBub3QgZG93bmxvYWRpbmcgZGF0YVxuIik7CiAgICAgICAgZ290byBsb2NrX2VuZDsKICAgIH0KCiAgICAvKiBOb3cgZG93bmxvYWQgdGhlIHN1cmZhY2UgY29udGVudCBmcm9tIG9wZW5nbAogICAgICogVXNlIHRoZSByZW5kZXIgdGFyZ2V0IHJlYWRiYWNrIGlmIHRoZSBzdXJmYWNlIGlzIG9uIGEgc3dhcGNoYWluKD1vbnNjcmVlbiByZW5kZXIgdGFyZ2V0KSBvciB0aGUgY3VycmVudCBwcmltYXJ5IHRhcmdldAogICAgICogT2Zmc2NyZWVuIHRhcmdldHMgd2hpY2ggYXJlIG5vdCBhY3RpdmUgYXQgdGhlIG1vbWVudCBvciBhcmUgaGlnaGVyIHRhcmdldHMoZmJvcykgY2FuIGJlIGxvY2tlZCB3aXRoIHRoZSB0ZXh0dXJlIHBhdGgKICAgICAqLwogICAgSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lcihpZmFjZSwgJklJRF9JV2luZUQzRFN3YXBDaGFpbiwgKHZvaWQgKiopJnN3YXBjaGFpbik7CiAgICBpZihzd2FwY2hhaW4gfHwgaWZhY2UgPT0gbXlEZXZpY2UtPnJlbmRlcl90YXJnZXRzWzBdKSB7CiAgICAgICAgQk9PTCBzcmNJc1Vwc2lkZURvd247CgogICAgICAgIGlmKHdpbmVkM2Rfc2V0dGluZ3MucmVuZGVydGFyZ2V0bG9ja19tb2RlID09IFJUTF9ESVNBQkxFKSB7CiAgICAgICAgICAgIHN0YXRpYyBCT09MIHdhcm5lZCA9IEZBTFNFOwogICAgICAgICAgICBpZighd2FybmVkKSB7CiAgICAgICAgICAgICAgICBFUlIoIlRoZSBhcHBsaWNhdGlvbiB0cmllcyB0byBsb2NrIHRoZSByZW5kZXIgdGFyZ2V0LCBidXQgcmVuZGVyIHRhcmdldCBsb2NraW5nIGlzIGRpc2FibGVkXG4iKTsKICAgICAgICAgICAgICAgIHdhcm5lZCA9IFRSVUU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYoc3dhcGNoYWluKSBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKChJV2luZUQzRFN3YXBDaGFpbiAqKSBzd2FwY2hhaW4pOwogICAgICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgICAgICB9CgogICAgICAgIC8qIEFjdGl2YXRlIHRoZSBzdXJmYWNlLiBTZXQgaXQgdXAgZm9yIGJsaXR0aW5nIG5vdywgYWx0aG91Z2ggbm90IG5lY2Vzc2FyaWx5IG5lZWRlZCBmb3IgTG9ja1JlY3QuCiAgICAgICAgICogQ2VydGFpbiBncmFwaGljcyBkcml2ZXJzIHNlZW0gdG8gZGlzbGlrZSBzb21lIGVuYWJsZWQgc3RhdGVzIHdoZW4gcmVhZGluZyBmcm9tIG9wZW5nbCwgdGhlIGJsaXR0aW5nIHVzYWdlCiAgICAgICAgICogc2hvdWxkIGhlbHAgaGVyZS4gRnVydGhlcm1vcmUgdW5sb2NrcmVjdCB3aWxsIG5lZWQgdGhlIGNvbnRleHQgc2V0IHVwIGZvciBibGl0dGluZy4gVGhlIGNvbnRleHQgbWFuYWdlciB3aWxsIGZpbmQKICAgICAgICAgKiBjb250ZXh0LT5sYXN0X3dhc19ibGl0IHNldCBvbiB0aGUgdW5sb2NrLgogICAgICAgICAqLwogICAgICAgIEVOVEVSX0dMKCk7CiAgICAgICAgQWN0aXZhdGVDb250ZXh0KG15RGV2aWNlLCBpZmFjZSwgQ1RYVVNBR0VfQkxJVCk7CgogICAgICAgIC8qIFNlbGVjdCB0aGUgY29ycmVjdCByZWFkIGJ1ZmZlciwgYW5kIGdpdmUgc29tZSBkZWJ1ZyBvdXRwdXQuCiAgICAgICAgICogVGhlcmUgaXMgbm8gbmVlZCB0byBrZWVwIHRyYWNrIG9mIHRoZSBjdXJyZW50IHJlYWQgYnVmZmVyIG9yIHJlc2V0IGl0LCBldmVyeSBwYXJ0IG9mIHRoZSBjb2RlCiAgICAgICAgICogdGhhdCByZWFkcyBzZXRzIHRoZSByZWFkIGJ1ZmZlciBhcyBkZXNpcmVkLgogICAgICAgICAqLwogICAgICAgIGlmKCFzd2FwY2hhaW4pIHsKICAgICAgICAgICAgLyogTG9ja2luZyB0aGUgcHJpbWFyeSByZW5kZXIgdGFyZ2V0IHdoaWNoIGlzIG5vdCBvbiBhIHN3YXBjaGFpbig9b2Zmc2NyZWVuIHJlbmRlciB0YXJnZXQpLgogICAgICAgICAgICAgKiBSZWFkIGZyb20gdGhlIGJhY2sgYnVmZmVyCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBUUkFDRSgiTG9ja2luZyBvZmZzY3JlZW4gcmVuZGVyIHRhcmdldFxuIik7CiAgICAgICAgICAgIGdsUmVhZEJ1ZmZlcihHTF9CQUNLKTsKICAgICAgICAgICAgc3JjSXNVcHNpZGVEb3duID0gVFJVRTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZihpZmFjZSA9PSBzd2FwY2hhaW4tPmZyb250QnVmZmVyKSB7CiAgICAgICAgICAgICAgICBUUkFDRSgiTG9ja2luZyB0aGUgZnJvbnQgYnVmZmVyXG4iKTsKICAgICAgICAgICAgICAgIGdsUmVhZEJ1ZmZlcihHTF9GUk9OVCk7CiAgICAgICAgICAgIH0gZWxzZSBpZihzd2FwY2hhaW4tPmJhY2tCdWZmZXIgJiYgaWZhY2UgPT0gc3dhcGNoYWluLT5iYWNrQnVmZmVyWzBdKSB7CiAgICAgICAgICAgICAgICBUUkFDRSgiTG9ja2luZyB0aGUgYmFjayBidWZmZXJcbiIpOwogICAgICAgICAgICAgICAgZ2xSZWFkQnVmZmVyKEdMX0JBQ0spOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLyogT2ssIHRoZXJlIGlzIGFuIGlzc3VlOiBPcGVuR0wgZG9lcyBub3QgZ3VhcmFudCBhbnkgYmFjayBidWZmZXIgbnVtYmVyLCBzbyBhbGwgd2UgY2FuIGRvIGlzIHRvIHJlYWQgR0xfQkFDSwogICAgICAgICAgICAgICAgICogYW5kIGhvcGUgaXQgZ2l2ZXMgd2hhdCB0aGUgYXBwIHdhbnRzCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIEZJWE1FKCJBcHBsaWNhdGlvbiBpcyBsb2NraW5nIGEgMm5kIG9yIGhpZ2hlciBiYWNrIGJ1ZmZlclxuIik7CiAgICAgICAgICAgICAgICBnbFJlYWRCdWZmZXIoR0xfQkFDSyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZSgoSVdpbmVEM0RTd2FwQ2hhaW4gKikgc3dhcGNoYWluKTsKICAgICAgICAgICAgc3JjSXNVcHNpZGVEb3duID0gRkFMU0U7CiAgICAgICAgfQoKICAgICAgICBzd2l0Y2god2luZWQzZF9zZXR0aW5ncy5yZW5kZXJ0YXJnZXRsb2NrX21vZGUpIHsKICAgICAgICAgICAgY2FzZSBSVExfQVVUTzoKICAgICAgICAgICAgY2FzZSBSVExfUkVBRERSQVc6CiAgICAgICAgICAgIGNhc2UgUlRMX1JFQURURVg6CiAgICAgICAgICAgICAgICByZWFkX2Zyb21fZnJhbWVidWZmZXIoVGhpcywgJlRoaXMtPmxvY2tlZFJlY3QsIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSwgcExvY2tlZFJlY3QtPlBpdGNoLCBzcmNJc1Vwc2lkZURvd24pOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIFJUTF9URVhEUkFXOgogICAgICAgICAgICBjYXNlIFJUTF9URVhURVg6CiAgICAgICAgICAgICAgICByZWFkX2Zyb21fZnJhbWVidWZmZXIoVGhpcywgJlRoaXMtPmxvY2tlZFJlY3QsIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSwgcExvY2tlZFJlY3QtPlBpdGNoLCBzcmNJc1Vwc2lkZURvd24pOwogICAgICAgICAgICAgICAgRklYTUUoIlJlYWRpbmcgZnJvbSByZW5kZXIgdGFyZ2V0IHdpdGggYSB0ZXh0dXJlIGlzbid0IGltcGxlbWVudGVkIHlldCwgZmFsbGluZyBiYWNrIHRvIGZyYW1lYnVmZmVyIHJlYWRpbmdcbiIpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIExFQVZFX0dMKCk7CgogICAgICAgIC8qIE1hcmsgdGhlIGxvY2FsIGNvcHkgdXAgdG8gZGF0ZSBpZiBhIGZ1bGwgZG93bmxvYWQgd2FzIGRvbmUgKi8KICAgICAgICBpZihUaGlzLT5sb2NrZWRSZWN0LmxlZnQgPT0gMCAmJgogICAgICAgICAgIFRoaXMtPmxvY2tlZFJlY3QudG9wID09IDAgJiYKICAgICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LnJpZ2h0ID09IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoICYmCiAgICAgICAgICAgVGhpcy0+bG9ja2VkUmVjdC5ib3R0b20gPT0gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0KSB7CiAgICAgICAgICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19HTERJUlRZOwogICAgICAgIH0KICAgIH0gZWxzZSBpZihpZmFjZSA9PSBteURldmljZS0+c3RlbmNpbEJ1ZmZlclRhcmdldCkgewogICAgICAgIC8qKiB0aGUgZGVwdGggc3RlbmNpbCBpbiBvcGVuR0wgaGFzIGEgZm9ybWF0IG9mIEdMX0ZMT0FUCiAgICAgICAgICogd2hpY2ggc2hvdWxkIGJlIGdvb2QgZm9yIFdJTkVEM0RGTVRfRDE2X0xPQ0tBQkxFCiAgICAgICAgICogYW5kIFdJTkVEM0RGTVRfRDE2CiAgICAgICAgICogaXQgaXMgdW5jbGVhciB3aGF0IGZvcm1hdCB0aGUgc3RlbmNpbCBidWZmZXIgaXMgaW4gZXhjZXB0LgogICAgICAgICAqICdFYWNoIGluZGV4IGlzIGNvbnZlcnRlZCB0byBmaXhlZCBwb2ludC4uLgogICAgICAgICAqIElmIEdMX01BUF9TVEVOQ0lMIGlzIEdMX1RSVUUsIGluZGljZXMgYXJlIHJlcGxhY2VkIGJ5IHRoZWlyCiAgICAgICAgICogbWFwcGluZ3MgaW4gdGhlIHRhYmxlIEdMX1BJWEVMX01BUF9TX1RPX1MuCiAgICAgICAgICogZ2xSZWFkUGl4ZWxzKFRoaXMtPmxvY2tlZFJlY3QubGVmdCwKICAgICAgICAgKiAgICAgICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LmJvdHRvbSAtIGogLSAxLAogICAgICAgICAqICAgICAgICAgICAgIFRoaXMtPmxvY2tlZFJlY3QucmlnaHQgLSBUaGlzLT5sb2NrZWRSZWN0LmxlZnQsCiAgICAgICAgICogICAgICAgICAgICAgMSwKICAgICAgICAgKiAgICAgICAgICAgICBHTF9ERVBUSF9DT01QT05FTlQsCiAgICAgICAgICogICAgICAgICAgICAgdHlwZSwKICAgICAgICAgKiAgICAgICAgICAgICAoY2hhciAqKXBMb2NrZWRSZWN0LT5wQml0cyArIChwTG9ja2VkUmVjdC0+UGl0Y2ggKiAoai1UaGlzLT5sb2NrZWRSZWN0LnRvcCkpKTsKICAgICAgICAgKgogICAgICAgICAqIERlcHRoIFN0ZW5jaWwgc3VyZmFjZXMgd2hpY2ggYXJlIG5vdCB0aGUgY3VycmVudCBkZXB0aCBzdGVuY2lsIHRhcmdldCBzaG91bGQgaGF2ZSB0aGVpciBkYXRhIGluIGEKICAgICAgICAgKiBnbCB0ZXh0dXJlKG5leHQgcGF0aCksIG9yIGluIGxvY2FsIG1lbW9yeShlYXJseSByZXR1cm4gYmVjYXVzZSBvZiBtaXNzaW5nIFNGTEFHX0dMRElSVFkgYWJvdmUpLiBJZgogICAgICAgICAqIG5vbmUgb2YgdGhhdCBpcyB0aGUgY2FzZSB0aGUgcHJvYmxlbSBpcyBub3QgaW4gdGhpcyBmdW5jdGlvbiA6LSkKICAgICAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCiAgICAgICAgRklYTUUoIkRlcHRoIHN0ZW5jaWwgbG9ja2luZyBub3Qgc3VwcG9ydGVkIHlldFxuIik7CiAgICB9IGVsc2UgewogICAgICAgIC8qIFRoaXMgcGF0aCBpcyBmb3Igbm9ybWFsIHN1cmZhY2VzLCBvZmZzY3JlZW4gcmVuZGVyIHRhcmdldHMgYW5kIGV2ZXJ5dGhpbmcgZWxzZSB0aGF0IGlzIGluIGEgZ2wgdGV4dHVyZSAqLwogICAgICAgIFRSQUNFKCJsb2NraW5nIGFuIG9yZGluYXJhcnkgc3VyZmFjZVxuIik7CgogICAgICAgIC8qIFRPRE86IE1ha2Ugc3VyZSB0aGF0ICphbnkqIGNvbnRleHQgaXMgYWN0aXZlIGZvciB0aGlzIHRocmVhZC4gSXQgaXMgbm90IGltcG9ydGFudCB3aGljaCBjb250ZXh0IHRoYXQgaXMsCiAgICAgICAgICogbm9yIHRoYXQgaXMgaGFzIGFueSBzcGVjaWFsIHNldHVwKENUWFVTQUdFX0xPQURSRVNPVVJDRSBpcyBmaW5lKSwgYnV0IHRoZSBjb2RlIGJlbG93IG5lZWRzIGEgY29udGV4dC4KICAgICAgICAgKiBBIGNvbnRleHQgaXMgZ3VhcmFudGVlZCB0byBiZSB0aGVyZSBpbiBhIHNpbmdsZSB0aHJlYWRlZCBlbnZpcm9ubWVudCwgYnV0IG5vdCB3aXRoIG11bHRpdGhyZWFkaW5nCiAgICAgICAgICovCiAgICAgICAgaWYgKDAgIT0gVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSkgewogICAgICAgICAgICAvKiBOb3cgSSBoYXZlIHRvIGNvcHkgdGhpbmcgYml0cyBiYWNrICovCgogICAgICAgICAgICAvKiBNYWtlIHN1cmUgdGhhdCBhIHByb3BlciB0ZXh0dXJlIHVuaXQgaXMgc2VsZWN0ZWQsIGJpbmQgdGhlIHRleHR1cmUgYW5kIGRpcnRpZnkgdGhlIHNhbXBsZXIgdG8gcmVzdG9yZSB0aGUgdGV4dHVyZSBvbiB0aGUgbmV4dCBkcmF3ICovCiAgICAgICAgICAgIGlmIChHTF9TVVBQT1JUKEFSQl9NVUxUSVRFWFRVUkUpKSB7CiAgICAgICAgICAgICAgICBFTlRFUl9HTCgpOwogICAgICAgICAgICAgICAgR0xfRVhUQ0FMTChnbEFjdGl2ZVRleHR1cmVBUkIoR0xfVEVYVFVSRTBfQVJCKSk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xBY3RpdmVUZXh0dXJlQVJCIik7CiAgICAgICAgICAgICAgICBMRUFWRV9HTCgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlLCBTVEFURV9TQU1QTEVSKDApKTsKICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1ByZUxvYWQoaWZhY2UpOwoKICAgICAgICAgICAgc3VyZmFjZV9kb3dubG9hZF9kYXRhKFRoaXMpOwogICAgICAgIH0KCiAgICAgICAgLyogVGhlIGxvY2FsIGNvcHkgaXMgbm93IHVwIHRvIGRhdGUgdG8gdGhlIG9wZW5nbCBvbmUgYmVjYXVzZSBhIGZ1bGwgZG93bmxvYWQgd2FzIGRvbmUgKi8KICAgICAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfR0xESVJUWTsKICAgIH0KCmxvY2tfZW5kOgogICAgaWYgKEZsYWdzICYgKFdJTkVEM0RMT0NLX05PX0RJUlRZX1VQREFURSB8IFdJTkVEM0RMT0NLX1JFQURPTkxZKSkgewogICAgICAgIC8qIERvbid0IGRpcnRpZnkgKi8KICAgIH0gZWxzZSB7CiAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZSAqcEJhc2VUZXh0dXJlOwogICAgICAgIC8qKgogICAgICAgICAqIERpcnRpZnkgb24gbG9jawogICAgICAgICAqIGFzIHNlZW4gaW4gbXNkbiBkb2NzCiAgICAgICAgICovCiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0FkZERpcnR5UmVjdChpZmFjZSwgJlRoaXMtPmxvY2tlZFJlY3QpOwoKICAgICAgICAvKiogRGlydGlmeSBDb250YWluZXIgaWYgbmVlZGVkICovCiAgICAgICAgaWYgKFdJTkVEM0RfT0sgPT0gSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lcihpZmFjZSwgJklJRF9JV2luZUQzREJhc2VUZXh0dXJlLCAodm9pZCAqKikmcEJhc2VUZXh0dXJlKSAmJiBwQmFzZVRleHR1cmUgIT0gTlVMTCkgewogICAgICAgICAgICBUUkFDRSgiTWFraW5nIGNvbnRhaW5lciBkaXJ0eVxuIik7CiAgICAgICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVfU2V0RGlydHkocEJhc2VUZXh0dXJlLCBUUlVFKTsKICAgICAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9SZWxlYXNlKHBCYXNlVGV4dHVyZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgVFJBQ0UoIlN1cmZhY2UgaXMgc3RhbmRhbG9uZSwgbm8gbmVlZCB0byBkaXJ0eSB0aGUgY29udGFpbmVyXG4iKTsKICAgICAgICB9CiAgICB9CgogICAgVFJBQ0UoInJldHVybmluZyBtZW1vcnlAJXAsIHBpdGNoKCVkKSBkaXJ0eWZpZWQoJWQpXG4iLCBwTG9ja2VkUmVjdC0+cEJpdHMsIHBMb2NrZWRSZWN0LT5QaXRjaCwgVGhpcy0+RmxhZ3MgJiBTRkxBR19ESVJUWSA/IDAgOiAxKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgdm9pZCBmbHVzaF90b19mcmFtZWJ1ZmZlcl9kcmF3cGl4ZWxzKElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMpIHsKICAgIEdMaW50ICBwcmV2X3N0b3JlOwogICAgR0xpbnQgIHByZXZfcmFzdGVycG9zWzRdOwogICAgR0xpbnQgc2tpcEJ5dGVzID0gMDsKICAgIEJPT0wgc3RvcmVjaGFuZ2VkID0gRkFMU0UsIG1lbW9yeV9hbGxvY2F0ZWQgPSBGQUxTRTsKICAgIEdMaW50IGZtdCwgdHlwZTsKICAgIEJZVEUgKm1lbTsKICAgIFVJTlQgYnBwOwogICAgVUlOVCBwaXRjaCA9IElXaW5lRDNEU3VyZmFjZV9HZXRQaXRjaCgoSVdpbmVEM0RTdXJmYWNlICopIFRoaXMpOyAgICAvKiB0YXJnZXQgaXMgYXJnYiwgNCBieXRlICovCgogICAgZ2xEaXNhYmxlKEdMX1RFWFRVUkVfMkQpOwogICAgdmNoZWNrR0xjYWxsKCJnbERpc2FibGUoR0xfVEVYVFVSRV8yRCkiKTsKCiAgICBnbEZsdXNoKCk7CiAgICB2Y2hlY2tHTGNhbGwoImdsRmx1c2giKTsKICAgIGdsR2V0SW50ZWdlcnYoR0xfUEFDS19TV0FQX0JZVEVTLCAmcHJldl9zdG9yZSk7CiAgICB2Y2hlY2tHTGNhbGwoImdsSW50ZWdlcnYiKTsKICAgIGdsR2V0SW50ZWdlcnYoR0xfQ1VSUkVOVF9SQVNURVJfUE9TSVRJT04sICZwcmV2X3Jhc3RlcnBvc1swXSk7CiAgICB2Y2hlY2tHTGNhbGwoImdsSW50ZWdlcnYiKTsKICAgIGdsUGl4ZWxab29tKDEuMCwgLTEuMCk7CiAgICB2Y2hlY2tHTGNhbGwoImdsUGl4ZWxab29tIik7CgogICAgLyogSWYgbm90IGZ1bGxzY3JlZW4sIHdlIG5lZWQgdG8gc2tpcCBhIG51bWJlciBvZiBieXRlcyB0byBmaW5kIHRoZSBuZXh0IHJvdyBvZiBkYXRhICovCiAgICBnbEdldEludGVnZXJ2KEdMX1VOUEFDS19ST1dfTEVOR1RILCAmc2tpcEJ5dGVzKTsKICAgIGdsUGl4ZWxTdG9yZWkoR0xfVU5QQUNLX1JPV19MRU5HVEgsIFRoaXMtPmN1cnJlbnREZXNjLldpZHRoKTsKCiAgICBnbFJhc3RlclBvczNpKFRoaXMtPmxvY2tlZFJlY3QubGVmdCwgVGhpcy0+bG9ja2VkUmVjdC50b3AsIDEpOwogICAgdmNoZWNrR0xjYWxsKCJnbFJhc3RlclBvczJmIik7CgogICAgLyogU29tZSBkcml2ZXJzKHJhZGVvbiBkcmksIG90aGVycz8pIGRvbid0IGxpa2UgZXhjZXB0aW9ucyBkdXJpbmcKICAgICAqIGdsRHJhd1BpeGVscy4gSWYgdGhlIHN1cmZhY2UgaXMgYSBESUIgc2VjdGlvbiwgaXQgbWlnaHQgYmUgaW4gR0RJTW9kZQogICAgICogYWZ0ZXIgUmVsZWFzZURDLiBSZWFkaW5nIGl0IHdpbGwgY2F1c2UgYW4gZXhjZXB0aW9uLCB3aGljaCB4MTFkcnYgd2lsbAogICAgICogY2F0Y2ggdG8gcHV0IHRoZSBkaWIgc2VjdGlvbiBpbiBJblN5bmMgbW9kZSwgd2hpY2ggbGVhZHMgdG8gYSBjcmFzaAogICAgICogYW5kIGEgYmxvY2tlZCB4IHNlcnZlciBvbiBteSByYWRlb24gY2FyZC4KICAgICAqCiAgICAgKiBUaGUgZm9sbG93aW5nIGxpbmVzIHJlYWQgdGhlIGRpYiBzZWN0aW9uIHNvIGl0IGlzIHB1dCBpbiBpblN5bmMgbW9kZQogICAgICogYmVmb3JlIGdsRHJhd1BpeGVscyBpcyBjYWxsZWQgYW5kIHRoZSBjcmFzaCBpcyBwcmV2ZW50ZWQuIFRoZXJlIHdvbid0CiAgICAgKiBiZSBhbnkgaW50ZXJmZXJpbmcgZ2RpIGFjY2Vzc2VzLCBiZWNhdXNlIFVubG9ja1JlY3QgaXMgY2FsbGVkIGZyb20KICAgICAqIFJlbGVhc2VEQywgYW5kIHRoZSBhcHAgd29uJ3QgdXNlIHRoZSBkYyBhbnkgbW9yZSBhZnRlcndhcmRzLgogICAgICovCiAgICBpZihUaGlzLT5GbGFncyAmIFNGTEFHX0RJQlNFQ1RJT04pIHsKICAgICAgICB2b2xhdGlsZSBCWVRFIHJlYWQ7CiAgICAgICAgcmVhZCA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeVswXTsKICAgIH0KCiAgICBzd2l0Y2ggKFRoaXMtPnJlc291cmNlLmZvcm1hdCkgewogICAgICAgIC8qIE5vIHNwZWNpYWwgY2FyZSBuZWVkZWQgKi8KICAgICAgICBjYXNlIFdJTkVEM0RGTVRfQTRSNEc0QjQ6CiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1I1RzZCNToKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfQTFSNUc1QjU6CiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1I4RzhCODoKICAgICAgICAgICAgdHlwZSA9IFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xUeXBlOwogICAgICAgICAgICBmbXQgPSBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0OwogICAgICAgICAgICBtZW0gPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnk7CiAgICAgICAgICAgIGJwcCA9IFRoaXMtPmJ5dGVzUGVyUGl4ZWw7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfWDRSNEc0QjQ6CiAgICAgICAgewogICAgICAgICAgICBpbnQgc2l6ZTsKICAgICAgICAgICAgdW5zaWduZWQgc2hvcnQgKmRhdGE7CiAgICAgICAgICAgIGRhdGEgPSAodW5zaWduZWQgc2hvcnQgKilUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnk7CiAgICAgICAgICAgIHNpemUgPSAoVGhpcy0+bG9ja2VkUmVjdC5ib3R0b20gLSBUaGlzLT5sb2NrZWRSZWN0LnRvcCkgKiAoVGhpcy0+bG9ja2VkUmVjdC5yaWdodCAtIFRoaXMtPmxvY2tlZFJlY3QubGVmdCk7CiAgICAgICAgICAgIHdoaWxlKHNpemUgPiAwKSB7CiAgICAgICAgICAgICAgICAqZGF0YSB8PSAweEYwMDA7CiAgICAgICAgICAgICAgICBkYXRhKys7CiAgICAgICAgICAgICAgICBzaXplLS07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdHlwZSA9IFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xUeXBlOwogICAgICAgICAgICBmbXQgPSBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0OwogICAgICAgICAgICBtZW0gPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnk7CiAgICAgICAgICAgIGJwcCA9IFRoaXMtPmJ5dGVzUGVyUGl4ZWw7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfWDFSNUc1QjU6CiAgICAgICAgewogICAgICAgICAgICBpbnQgc2l6ZTsKICAgICAgICAgICAgdW5zaWduZWQgc2hvcnQgKmRhdGE7CiAgICAgICAgICAgIGRhdGEgPSAodW5zaWduZWQgc2hvcnQgKilUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnk7CiAgICAgICAgICAgIHNpemUgPSAoVGhpcy0+bG9ja2VkUmVjdC5ib3R0b20gLSBUaGlzLT5sb2NrZWRSZWN0LnRvcCkgKiAoVGhpcy0+bG9ja2VkUmVjdC5yaWdodCAtIFRoaXMtPmxvY2tlZFJlY3QubGVmdCk7CiAgICAgICAgICAgIHdoaWxlKHNpemUgPiAwKSB7CiAgICAgICAgICAgICAgICAqZGF0YSB8PSAweDgwMDA7CiAgICAgICAgICAgICAgICBkYXRhKys7CiAgICAgICAgICAgICAgICBzaXplLS07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdHlwZSA9IFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xUeXBlOwogICAgICAgICAgICBmbXQgPSBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0OwogICAgICAgICAgICBtZW0gPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnk7CiAgICAgICAgICAgIGJwcCA9IFRoaXMtPmJ5dGVzUGVyUGl4ZWw7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfWDhSOEc4Qjg6CiAgICAgICAgewogICAgICAgICAgICAvKiBtYWtlIHN1cmUgdGhlIFggYnl0ZSBpcyBzZXQgdG8gYWxwaGEgb24sIHNpbmNlIGl0IAogICAgICAgICAgICAgICBjb3VsZCBiZSBhbnkgcmFuZG9tIHZhbHVlLiBUaGlzIGZpeGVzIHRoZSBpbnRybyBtb3ZpZSBpbiBQaXJhdGVzISAqLwogICAgICAgICAgICBpbnQgc2l6ZTsKICAgICAgICAgICAgdW5zaWduZWQgaW50ICpkYXRhOwogICAgICAgICAgICBkYXRhID0gKHVuc2lnbmVkIGludCAqKVRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeTsKICAgICAgICAgICAgc2l6ZSA9IChUaGlzLT5sb2NrZWRSZWN0LmJvdHRvbSAtIFRoaXMtPmxvY2tlZFJlY3QudG9wKSAqIChUaGlzLT5sb2NrZWRSZWN0LnJpZ2h0IC0gVGhpcy0+bG9ja2VkUmVjdC5sZWZ0KTsKICAgICAgICAgICAgd2hpbGUoc2l6ZSA+IDApIHsKICAgICAgICAgICAgICAgICpkYXRhIHw9IDB4RkYwMDAwMDA7CiAgICAgICAgICAgICAgICBkYXRhKys7CiAgICAgICAgICAgICAgICBzaXplLS07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLyogRmFsbCB0aHJvdWdoICovCgogICAgICAgIGNhc2UgV0lORUQzREZNVF9BOFI4RzhCODoKICAgICAgICB7CiAgICAgICAgICAgIGdsUGl4ZWxTdG9yZWkoR0xfUEFDS19TV0FQX0JZVEVTLCBUUlVFKTsKICAgICAgICAgICAgdmNoZWNrR0xjYWxsKCJnbFBpeGVsU3RvcmVpIik7CiAgICAgICAgICAgIHN0b3JlY2hhbmdlZCA9IFRSVUU7CiAgICAgICAgICAgIHR5cGUgPSBUaGlzLT5nbERlc2NyaXB0aW9uLmdsVHlwZTsKICAgICAgICAgICAgZm10ID0gVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdDsKICAgICAgICAgICAgbWVtID0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5OwogICAgICAgICAgICBicHAgPSBUaGlzLT5ieXRlc1BlclBpeGVsOwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBXSU5FRDNERk1UX0EyUjEwRzEwQjEwOgogICAgICAgIHsKICAgICAgICAgICAgZ2xQaXhlbFN0b3JlaShHTF9QQUNLX1NXQVBfQllURVMsIFRSVUUpOwogICAgICAgICAgICB2Y2hlY2tHTGNhbGwoImdsUGl4ZWxTdG9yZWkiKTsKICAgICAgICAgICAgc3RvcmVjaGFuZ2VkID0gVFJVRTsKICAgICAgICAgICAgdHlwZSA9IFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xUeXBlOwogICAgICAgICAgICBmbXQgPSBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0OwogICAgICAgICAgICBtZW0gPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnk7CiAgICAgICAgICAgIGJwcCA9IFRoaXMtPmJ5dGVzUGVyUGl4ZWw7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfUDg6CiAgICAgICAgewogICAgICAgICAgICBpbnQgaGVpZ2h0ID0gVGhpcy0+Z2xSZWN0LmJvdHRvbSAtIFRoaXMtPmdsUmVjdC50b3A7CiAgICAgICAgICAgIHR5cGUgPSBHTF9VTlNJR05FRF9CWVRFOwogICAgICAgICAgICBmbXQgPSBHTF9SR0JBOwoKICAgICAgICAgICAgbWVtID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnJlc291cmNlLnNpemUgKiBzaXplb2YoRFdPUkQpKTsKICAgICAgICAgICAgaWYoIW1lbSkgewogICAgICAgICAgICAgICAgRVJSKCJPdXQgb2YgbWVtb3J5XG4iKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICBtZW1vcnlfYWxsb2NhdGVkID0gVFJVRTsKICAgICAgICAgICAgZDNkZm10X2NvbnZlcnRfc3VyZmFjZShUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpdGNoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpdGNoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaXRjaCAqIDQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09OVkVSVF9QQUxFVFRFRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzKTsKICAgICAgICAgICAgYnBwID0gVGhpcy0+Ynl0ZXNQZXJQaXhlbCAqIDQ7CiAgICAgICAgICAgIHBpdGNoICo9IDQ7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBGSVhNRSgiVW5zdXBwb3J0ZWQgRm9ybWF0ICV1IGluIGxvY2tpbmcgZnVuY1xuIiwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0KTsKCiAgICAgICAgICAgIC8qIEdpdmUgaXQgYSB0cnkgKi8KICAgICAgICAgICAgdHlwZSA9IFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xUeXBlOwogICAgICAgICAgICBmbXQgPSBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0OwogICAgICAgICAgICBtZW0gPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnk7CiAgICAgICAgICAgIGJwcCA9IFRoaXMtPmJ5dGVzUGVyUGl4ZWw7CiAgICB9CgogICAgZ2xEcmF3UGl4ZWxzKFRoaXMtPmxvY2tlZFJlY3QucmlnaHQgLSBUaGlzLT5sb2NrZWRSZWN0LmxlZnQsCiAgICAgICAgICAgICAgICAgKFRoaXMtPmxvY2tlZFJlY3QuYm90dG9tIC0gVGhpcy0+bG9ja2VkUmVjdC50b3ApLTEsCiAgICAgICAgICAgICAgICAgZm10LCB0eXBlLAogICAgICAgICAgICAgICAgIG1lbSArIGJwcCAqIFRoaXMtPmxvY2tlZFJlY3QubGVmdCArIHBpdGNoICogVGhpcy0+bG9ja2VkUmVjdC50b3ApOwogICAgY2hlY2tHTGNhbGwoImdsRHJhd1BpeGVscyIpOwogICAgZ2xQaXhlbFpvb20oMS4wLDEuMCk7CiAgICB2Y2hlY2tHTGNhbGwoImdsUGl4ZWxab29tIik7CgogICAgZ2xSYXN0ZXJQb3MzaXYoJnByZXZfcmFzdGVycG9zWzBdKTsKICAgIHZjaGVja0dMY2FsbCgiZ2xSYXN0ZXJQb3MzaXYiKTsKCiAgICAvKiBSZXNldCB0byBwcmV2aW91cyBwYWNrIHJvdyBsZW5ndGggKi8KICAgIGdsUGl4ZWxTdG9yZWkoR0xfVU5QQUNLX1JPV19MRU5HVEgsIHNraXBCeXRlcyk7CiAgICB2Y2hlY2tHTGNhbGwoImdsUGl4ZWxTdG9yZWkgR0xfVU5QQUNLX1JPV19MRU5HVEgiKTsKICAgIGlmKHN0b3JlY2hhbmdlZCkgewogICAgICAgIGdsUGl4ZWxTdG9yZWkoR0xfUEFDS19TV0FQX0JZVEVTLCBwcmV2X3N0b3JlKTsKICAgICAgICB2Y2hlY2tHTGNhbGwoImdsUGl4ZWxTdG9yZWkgR0xfUEFDS19TV0FQX0JZVEVTIik7CiAgICB9CgogICAgLyogQmxpdHRpbmcgZW52aXJvbm1lbnQgcmVxdWlyZXMgdGhhdCAyRCB0ZXh0dXJpbmcgaXMgZW5hYmxlZC4gSXQgd2FzIHR1cm5lZCBvZmYgYmVmb3JlLAogICAgICogdHVybiBpdCBvbiBhZ2FpbgogICAgICovCiAgICBnbEVuYWJsZShHTF9URVhUVVJFXzJEKTsKICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZShHTF9URVhUVVJFXzJEKSIpOwoKICAgIGlmKG1lbW9yeV9hbGxvY2F0ZWQpIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG1lbSk7CiAgICByZXR1cm47Cn0KCnN0YXRpYyB2b2lkIGZsdXNoX3RvX2ZyYW1lYnVmZmVyX3RleHR1cmUoSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcykgewogICAgZmxvYXQgZ2xUZXhDb29yZFs0XTsKCiAgICBnbFRleENvb3JkWzBdID0gKGZsb2F0KSBUaGlzLT5sb2NrZWRSZWN0LmxlZnQgICAvIChmbG9hdCkgVGhpcy0+cG93MldpZHRoOyAvKiBsZWZ0ICovCiAgICBnbFRleENvb3JkWzFdID0gKGZsb2F0KSBUaGlzLT5sb2NrZWRSZWN0LnJpZ2h0ICAvIChmbG9hdCkgVGhpcy0+cG93MldpZHRoOyAvKiByaWdodCAqLwogICAgZ2xUZXhDb29yZFsyXSA9IChmbG9hdCkgVGhpcy0+bG9ja2VkUmVjdC50b3AgICAgLyAoZmxvYXQpIFRoaXMtPnBvdzJIZWlnaHQ7IC8qIHRvcCAqLwogICAgZ2xUZXhDb29yZFszXSA9IChmbG9hdCkgVGhpcy0+bG9ja2VkUmVjdC5ib3R0b20gLyAoZmxvYXQpIFRoaXMtPnBvdzJIZWlnaHQ7IC8qIGJvdHRvbSAqLwoKICAgIElXaW5lRDNEU3VyZmFjZV9QcmVMb2FkKChJV2luZUQzRFN1cmZhY2UgKikgVGhpcyk7CgogICAgRU5URVJfR0woKTsKCiAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIFRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpOwogICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlIGdsQmluZFRleHR1cmUiKTsKCiAgICAvKiBObyBmaWx0ZXJpbmcgZm9yIGJsdHMgKi8KICAgIGdsVGV4UGFyYW1ldGVyaShHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX01BR19GSUxURVIsIEdMX05FQVJFU1QpOwogICAgY2hlY2tHTGNhbGwoImdsVGV4UGFyYW1ldGVyaSIpOwogICAgZ2xUZXhQYXJhbWV0ZXJpKEdMX1RFWFRVUkVfMkQsIEdMX1RFWFRVUkVfTUlOX0ZJTFRFUiwgR0xfTkVBUkVTVCk7CiAgICBjaGVja0dMY2FsbCgiZ2xUZXhQYXJhbWV0ZXJpIik7CgogICAgLyogU3RhcnQgZHJhd2luZyBhIHF1YWQgKi8KICAgIGdsQmVnaW4oR0xfUVVBRFMpOwoKICAgIGdsQ29sb3IzZCgxLjBmLCAxLjBmLCAxLjBmKTsKICAgIGdsVGV4Q29vcmQyZihnbFRleENvb3JkWzBdLCBnbFRleENvb3JkWzJdKTsKICAgIGdsVmVydGV4M2YoVGhpcy0+bG9ja2VkUmVjdC5sZWZ0LCBUaGlzLT5sb2NrZWRSZWN0LnRvcCwgMC4wKTsKCiAgICBnbFRleENvb3JkMmYoZ2xUZXhDb29yZFswXSwgZ2xUZXhDb29yZFszXSk7CiAgICBnbFZlcnRleDNmKFRoaXMtPmxvY2tlZFJlY3QubGVmdCwgVGhpcy0+bG9ja2VkUmVjdC5ib3R0b20sIDAuMCk7CgogICAgZ2xUZXhDb29yZDJmKGdsVGV4Q29vcmRbMV0sIGdsVGV4Q29vcmRbM10pOwogICAgZ2xWZXJ0ZXgzZChUaGlzLT5sb2NrZWRSZWN0LnJpZ2h0LCBUaGlzLT5sb2NrZWRSZWN0LmJvdHRvbSwgMC4wKTsKCiAgICBnbFRleENvb3JkMmYoZ2xUZXhDb29yZFsxXSwgZ2xUZXhDb29yZFsyXSk7CiAgICBnbFZlcnRleDNmKFRoaXMtPmxvY2tlZFJlY3QucmlnaHQsIFRoaXMtPmxvY2tlZFJlY3QudG9wLCAwLjApOwoKICAgIGdsRW5kKCk7CiAgICBjaGVja0dMY2FsbCgiZ2xFbmQiKTsKCiAgICAvKiBVbmJpbmQgdGhlIHRleHR1cmUgKi8KICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgMCk7CiAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUgZ2xCaW5kVGV4dHVyZSIpOwoKICAgIExFQVZFX0dMKCk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1VubG9ja1JlY3QoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRERldmljZUltcGwgICpteURldmljZSA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CiAgICBJV2luZUQzRFN3YXBDaGFpbkltcGwgKnN3YXBjaGFpbiA9IE5VTEw7CgogICAgaWYgKCEoVGhpcy0+RmxhZ3MgJiBTRkxBR19MT0NLRUQpKSB7CiAgICAgICAgV0FSTigidHJ5aW5nIHRvIFVubG9jayBhbiB1bmxvY2tlZCBzdXJmQCVwXG4iLCBUaGlzKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBUUkFDRSgiKCVwKSA6IGRpcnR5ZmllZCglZClcbiIsIFRoaXMsIFRoaXMtPkZsYWdzICYgU0ZMQUdfRElSVFkgPyAxIDogMCk7CgogICAgaWYgKCEoVGhpcy0+RmxhZ3MgJiBTRkxBR19ESVJUWSkpIHsKICAgICAgICBUUkFDRSgiKCVwKSA6IE5vdCBEaXJ0aWZpZWQgc28gbm90aGluZyB0byBkbywgcmV0dXJuIG5vd1xuIiwgVGhpcyk7CiAgICAgICAgZ290byB1bmxvY2tfZW5kOwogICAgfQoKICAgIElXaW5lRDNEU3VyZmFjZV9HZXRDb250YWluZXIoaWZhY2UsICZJSURfSVdpbmVEM0RTd2FwQ2hhaW4sICh2b2lkICoqKSZzd2FwY2hhaW4pOwogICAgaWYoc3dhcGNoYWluIHx8IGlmYWNlID09IG15RGV2aWNlLT5yZW5kZXJfdGFyZ2V0c1swXSkgewogICAgICAgIGlmKHdpbmVkM2Rfc2V0dGluZ3MucmVuZGVydGFyZ2V0bG9ja19tb2RlID09IFJUTF9ESVNBQkxFKSB7CiAgICAgICAgICAgIHN0YXRpYyBCT09MIHdhcm5lZCA9IEZBTFNFOwogICAgICAgICAgICBpZighd2FybmVkKSB7CiAgICAgICAgICAgICAgICBFUlIoIlRoZSBhcHBsaWNhdGlvbiB0cmllcyB0byB3cml0ZSB0byB0aGUgcmVuZGVyIHRhcmdldCwgYnV0IHJlbmRlciB0YXJnZXQgbG9ja2luZyBpcyBkaXNhYmxlZFxuIik7CiAgICAgICAgICAgICAgICB3YXJuZWQgPSBUUlVFOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKHN3YXBjaGFpbikgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZSgoSVdpbmVEM0RTd2FwQ2hhaW4gKikgc3dhcGNoYWluKTsKICAgICAgICAgICAgZ290byB1bmxvY2tfZW5kOwogICAgICAgIH0KCiAgICAgICAgLyogQWN0aXZhdGUgdGhlIGNvcnJlY3QgY29udGV4dCBmb3IgdGhlIHJlbmRlciB0YXJnZXQgKi8KICAgICAgICBFTlRFUl9HTCgpOwogICAgICAgIEFjdGl2YXRlQ29udGV4dChteURldmljZSwgaWZhY2UsIENUWFVTQUdFX0JMSVQpOwoKICAgICAgICBpZighc3dhcGNoYWluKSB7CiAgICAgICAgICAgIC8qIFByaW1hcnkgb2Zmc2NyZWVuIHJlbmRlciB0YXJnZXQgKi8KICAgICAgICAgICAgVFJBQ0UoIk9mZnNjcmVlbiByZW5kZXIgdGFyZ2V0XG4iKTsKICAgICAgICAgICAgZ2xEcmF3QnVmZmVyKEdMX0JBQ0spOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEcmF3QnVmZmVyKEdMX0JBQ0spIik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaWYoaWZhY2UgPT0gc3dhcGNoYWluLT5mcm9udEJ1ZmZlcikgewogICAgICAgICAgICAgICAgVFJBQ0UoIk9uc2NyZWVuIGZyb250IGJ1ZmZlclxuIik7CiAgICAgICAgICAgICAgICBnbERyYXdCdWZmZXIoR0xfRlJPTlQpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlcihHTF9GUk9OVCkiKTsKICAgICAgICAgICAgfSBlbHNlIGlmKGlmYWNlID09IHN3YXBjaGFpbi0+YmFja0J1ZmZlclswXSkgewogICAgICAgICAgICAgICAgVFJBQ0UoIk9uc2NyZWVuIGJhY2sgYnVmZmVyXG4iKTsKICAgICAgICAgICAgICAgIGdsRHJhd0J1ZmZlcihHTF9CQUNLKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERyYXdCdWZmZXIoR0xfQkFDSykiKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIEZJWE1FKCJVbmxvY2tpbmcgYSBoaWdoZXIgYmFjayBidWZmZXJcbiIpOwogICAgICAgICAgICAgICAgZ2xEcmF3QnVmZmVyKEdMX0JBQ0spOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlcihHTF9CQUNLKSIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2UoKElXaW5lRDNEU3dhcENoYWluICopc3dhcGNoYWluKTsKICAgICAgICB9CgogICAgICAgIHN3aXRjaCh3aW5lZDNkX3NldHRpbmdzLnJlbmRlcnRhcmdldGxvY2tfbW9kZSkgewogICAgICAgICAgICBjYXNlIFJUTF9BVVRPOgogICAgICAgICAgICBjYXNlIFJUTF9SRUFERFJBVzoKICAgICAgICAgICAgY2FzZSBSVExfVEVYRFJBVzoKICAgICAgICAgICAgICAgIGZsdXNoX3RvX2ZyYW1lYnVmZmVyX2RyYXdwaXhlbHMoVGhpcyk7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgUlRMX1JFQURURVg6CiAgICAgICAgICAgIGNhc2UgUlRMX1RFWFRFWDoKICAgICAgICAgICAgICAgIGZsdXNoX3RvX2ZyYW1lYnVmZmVyX3RleHR1cmUoVGhpcyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgaWYoIXN3YXBjaGFpbiB8fCBzd2FwY2hhaW4tPmJhY2tCdWZmZXIpIHsKICAgICAgICAgICAgZ2xEcmF3QnVmZmVyKEdMX0JBQ0spOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEcmF3QnVmZmVyKEdMX0JBQ0spIik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZ2xEcmF3QnVmZmVyKEdMX0ZST05UKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlcihHTF9GUk9OVCkiKTsKICAgICAgICB9CiAgICAgICAgTEVBVkVfR0woKTsKCiAgICAgICAgLyoqIHJlc3RvcmUgY2xlYW4gZGlydHkgc3RhdGUgKi8KICAgICAgICBJV2luZUQzRFN1cmZhY2VfQ2xlYW5EaXJ0eVJlY3QoaWZhY2UpOwogICAgfSBlbHNlIGlmKGlmYWNlID09IG15RGV2aWNlLT5zdGVuY2lsQnVmZmVyVGFyZ2V0KSB7CiAgICAgICAgRklYTUUoIkRlcHRoIFN0ZW5jaWwgYnVmZmVyIGxvY2tpbmcgaXMgbm90IGltcGxlbWVudGVkXG4iKTsKICAgIH0gZWxzZSB7CiAgICAgICAgLyogVGhlIHJlc3Qgc2hvdWxkIGJlIGEgbm9ybWFsIHRleHR1cmUgKi8KICAgICAgICBJV2luZUQzREJhc2VUZXh0dXJlSW1wbCAqaW1wbDsKICAgICAgICAvKiBDaGVjayBpZiB0aGUgdGV4dHVyZSBpcyBib3VuZCwgaWYgeWVzIGRpcnRpZnkgdGhlIHNhbXBsZXIgdG8gZm9yY2UgYSByZS11cGxvYWQgb2YgdGhlIHRleHR1cmUKICAgICAgICAgKiBDYW4ndCBsb2FkIHRoZSB0ZXh0dXJlIGhlcmUgYmVjYXVzZSBQcmVMb2FkIG1heSBkZXN0cm95IGFuZCByZWNyZWF0ZSB0aGUgZ2wgdGV4dHVyZSwgc28gc2FtcGxlcgogICAgICAgICAqIHN0YXRlcyBuZWVkIHJlc2V0dGluZwogICAgICAgICAqLwogICAgICAgIGlmKElXaW5lRDNEU3VyZmFjZV9HZXRDb250YWluZXIoaWZhY2UsICZJSURfSVdpbmVEM0RCYXNlVGV4dHVyZSwgKHZvaWQgKiopJmltcGwpID09IFdJTkVEM0RfT0spIHsKICAgICAgICAgICAgaWYoaW1wbC0+YmFzZVRleHR1cmUuYmluZENvdW50KSB7CiAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkobXlEZXZpY2UsIFNUQVRFX1NBTVBMRVIoaW1wbC0+YmFzZVRleHR1cmUuc2FtcGxlcikpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVfUmVsZWFzZSgoSVdpbmVEM0RCYXNlVGV4dHVyZSAqKSBpbXBsKTsKICAgICAgICB9CiAgICB9CgogICAgdW5sb2NrX2VuZDoKICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19MT0NLRUQ7CiAgICBtZW1zZXQoJlRoaXMtPmxvY2tlZFJlY3QsIDAsIHNpemVvZihSRUNUKSk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXREQyhJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBIREMgKnBIREMpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgV0lORUQzRExPQ0tFRF9SRUNUIGxvY2s7CiAgICBVSU5UIHVzYWdlOwogICAgQklUTUFQSU5GTyogYl9pbmZvOwogICAgSERDIGRkYzsKICAgIERXT1JEICptYXNrczsKICAgIEhSRVNVTFQgaHI7CiAgICBSR0JRVUFEIGNvbFsyNTZdOwogICAgY29uc3QgUGl4ZWxGb3JtYXREZXNjICpmb3JtYXRFbnRyeSA9IGdldEZvcm1hdERlc2NFbnRyeShUaGlzLT5yZXNvdXJjZS5mb3JtYXQpOwoKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLFRoaXMscEhEQyk7CgogICAgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19VU0VSUFRSKSB7CiAgICAgICAgRVJSKCJOb3Qgc3VwcG9ydGVkIG9uIHN1cmZhY2VzIHdpdGggYW4gYXBwbGljYXRpb24tcHJvdmlkZWQgc3VyZmFjZXNcbiIpOwogICAgICAgIHJldHVybiBEREVSUl9OT0RDOwogICAgfQoKICAgIC8qIEdpdmUgbW9yZSBkZXRhaWxlZCBpbmZvIGZvciBkZHJhdyAqLwogICAgaWYgKFRoaXMtPkZsYWdzICYgU0ZMQUdfRENJTlVTRSkKICAgICAgICByZXR1cm4gRERFUlJfRENBTFJFQURZQ1JFQVRFRDsKCiAgICAvKiBDYW4ndCBHZXREQyBpZiB0aGUgc3VyZmFjZSBpcyBsb2NrZWQgKi8KICAgIGlmIChUaGlzLT5GbGFncyAmIFNGTEFHX0xPQ0tFRCkKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKCiAgICBtZW1zZXQoJmxvY2ssIDAsIHNpemVvZihsb2NrKSk7IC8qIFRvIGJlIHN1cmUgKi8KCiAgICAvKiBDcmVhdGUgYSBESUIgc2VjdGlvbiBpZiB0aGVyZSBpc24ndCBhIGhkYyB5ZXQgKi8KICAgIGlmKCFUaGlzLT5oREMpIHsKICAgICAgICBpbnQgZXh0cmFsaW5lID0gMDsKICAgICAgICBTWVNURU1fSU5GTyBzeXNJbmZvOwoKICAgICAgICBzd2l0Y2ggKFRoaXMtPmJ5dGVzUGVyUGl4ZWwpIHsKICAgICAgICAgICAgY2FzZSAyOgogICAgICAgICAgICBjYXNlIDQ6CiAgICAgICAgICAgICAgICAvKiBBbGxvY2F0ZSBleHRyYSBzcGFjZSB0byBzdG9yZSB0aGUgUkdCIGJpdCBtYXNrcy4gKi8KICAgICAgICAgICAgICAgIGJfaW5mbyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoQklUTUFQSU5GT0hFQURFUikgKyAzICogc2l6ZW9mKERXT1JEKSk7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgICAgIGJfaW5mbyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoQklUTUFQSU5GT0hFQURFUikpOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgLyogQWxsb2NhdGUgZXh0cmEgc3BhY2UgZm9yIGEgcGFsZXR0ZS4gKi8KICAgICAgICAgICAgICAgIGJfaW5mbyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKEJJVE1BUElORk9IRUFERVIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIHNpemVvZihSR0JRVUFEKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiAoMSA8PCAoVGhpcy0+Ynl0ZXNQZXJQaXhlbCAqIDgpKSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGlmICghYl9pbmZvKQogICAgICAgICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKCiAgICAgICAgLyogU29tZSBhcHBzIGFjY2VzcyB0aGUgc3VyZmFjZSBpbiB2aWEgRFdPUkRzLCBhbmQgZG8gbm90IHRha2UgdGhlIG5lY2Vzc2FyeSBjYXJlIGF0IHRoZSBlbmQgb2YgdGhlCiAgICAgICAgICogc3VyZmFjZS4gU28gd2UgbmVlZCBhdCBsZWFzdCBleHRyYSA0IGJ5dGVzIGF0IHRoZSBlbmQgb2YgdGhlIHN1cmZhY2UuIENoZWNrIGFnYWluc3QgdGhlIHBhZ2Ugc2l6ZSwKICAgICAgICAgKiBpZiB0aGUgbGFzdCBwYWdlIHVzZWQgZm9yIHRoZSBzdXJmYWNlIGhhcyBhdCBsZWFzdCA0IHNwYXJlIGJ5dGVzIHdlJ3JlIHNhZmUsIG90aGVyd2lzZQogICAgICAgICAqIGFkZCBhbiBleHRyYSBsaW5lIHRvIHRoZSBkaWIgc2VjdGlvbgogICAgICAgICAqLwogICAgICAgIEdldFN5c3RlbUluZm8oJnN5c0luZm8pOwogICAgICAgIGlmKCAoKFRoaXMtPnJlc291cmNlLnNpemUgKyAzKSAlIHN5c0luZm8uZHdQYWdlU2l6ZSkgPCA0KSB7CiAgICAgICAgICAgIGV4dHJhbGluZSA9IDE7CiAgICAgICAgICAgIFRSQUNFKCJBZGRpbmcgYW4gZXh0cmEgbGluZSB0byB0aGUgZGliIHNlY3Rpb25cbiIpOwogICAgICAgIH0KCiAgICAgICAgYl9pbmZvLT5ibWlIZWFkZXIuYmlTaXplID0gc2l6ZW9mKEJJVE1BUElORk9IRUFERVIpOwogICAgICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpV2lkdGggPSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICBiX2luZm8tPmJtaUhlYWRlci5iaUhlaWdodCA9IC1UaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQgLWV4dHJhbGluZTsKICAgICAgICBiX2luZm8tPmJtaUhlYWRlci5iaVNpemVJbWFnZSA9ICggVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0ICsgZXh0cmFsaW5lKSAqIElXaW5lRDNEU3VyZmFjZV9HZXRQaXRjaChpZmFjZSk7CiAgICAgICAgYl9pbmZvLT5ibWlIZWFkZXIuYmlQbGFuZXMgPSAxOwogICAgICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpQml0Q291bnQgPSBUaGlzLT5ieXRlc1BlclBpeGVsICogODsKCiAgICAgICAgYl9pbmZvLT5ibWlIZWFkZXIuYmlYUGVsc1Blck1ldGVyID0gMDsKICAgICAgICBiX2luZm8tPmJtaUhlYWRlci5iaVlQZWxzUGVyTWV0ZXIgPSAwOwogICAgICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpQ2xyVXNlZCA9IDA7CiAgICAgICAgYl9pbmZvLT5ibWlIZWFkZXIuYmlDbHJJbXBvcnRhbnQgPSAwOwoKICAgICAgICAvKiBHZXQgdGhlIGJpdCBtYXNrcyAqLwogICAgICAgIG1hc2tzID0gKERXT1JEICopICYoYl9pbmZvLT5ibWlDb2xvcnMpOwogICAgICAgIHN3aXRjaCAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0KSB7CiAgICAgICAgICAgIGNhc2UgV0lORUQzREZNVF9SOEc4Qjg6CiAgICAgICAgICAgICAgICB1c2FnZSA9IERJQl9SR0JfQ09MT1JTOwogICAgICAgICAgICAgICAgYl9pbmZvLT5ibWlIZWFkZXIuYmlDb21wcmVzc2lvbiA9IEJJX1JHQjsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBXSU5FRDNERk1UX1gxUjVHNUI1OgogICAgICAgICAgICBjYXNlIFdJTkVEM0RGTVRfQTFSNUc1QjU6CiAgICAgICAgICAgIGNhc2UgV0lORUQzREZNVF9BNFI0RzRCNDoKICAgICAgICAgICAgY2FzZSBXSU5FRDNERk1UX1g0UjRHNEI0OgogICAgICAgICAgICBjYXNlIFdJTkVEM0RGTVRfUjNHM0IyOgogICAgICAgICAgICBjYXNlIFdJTkVEM0RGTVRfQThSM0czQjI6CiAgICAgICAgICAgIGNhc2UgV0lORUQzREZNVF9BMkIxMEcxMFIxMDoKICAgICAgICAgICAgY2FzZSBXSU5FRDNERk1UX0E4QjhHOFI4OgogICAgICAgICAgICBjYXNlIFdJTkVEM0RGTVRfWDhCOEc4Ujg6CiAgICAgICAgICAgIGNhc2UgV0lORUQzREZNVF9BMlIxMEcxMEIxMDoKICAgICAgICAgICAgY2FzZSBXSU5FRDNERk1UX1I1RzZCNToKICAgICAgICAgICAgY2FzZSBXSU5FRDNERk1UX0ExNkIxNkcxNlIxNjoKICAgICAgICAgICAgICAgIHVzYWdlID0gMDsKICAgICAgICAgICAgICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpQ29tcHJlc3Npb24gPSBCSV9CSVRGSUVMRFM7CiAgICAgICAgICAgICAgICBtYXNrc1swXSA9IGZvcm1hdEVudHJ5LT5yZWRNYXNrOwogICAgICAgICAgICAgICAgbWFza3NbMV0gPSBmb3JtYXRFbnRyeS0+Z3JlZW5NYXNrOwogICAgICAgICAgICAgICAgbWFza3NbMl0gPSBmb3JtYXRFbnRyeS0+Ymx1ZU1hc2s7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAvKiBEb24ndCBrbm93IHBhbGV0dGUgKi8KICAgICAgICAgICAgICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpQ29tcHJlc3Npb24gPSBCSV9SR0I7CiAgICAgICAgICAgICAgICB1c2FnZSA9IDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGRkYyA9IEdldERDKDApOwogICAgICAgIGlmIChkZGMgPT0gMCkgewogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBiX2luZm8pOwogICAgICAgICAgICByZXR1cm4gSFJFU1VMVF9GUk9NX1dJTjMyKEdldExhc3RFcnJvcigpKTsKICAgICAgICB9CgogICAgICAgIFRSQUNFKCJDcmVhdGluZyBhIERJQiBzZWN0aW9uIHdpdGggc2l6ZSAlZHglZHglZCwgc2l6ZT0lZFxuIiwgYl9pbmZvLT5ibWlIZWFkZXIuYmlXaWR0aCwgYl9pbmZvLT5ibWlIZWFkZXIuYmlIZWlnaHQsIGJfaW5mby0+Ym1pSGVhZGVyLmJpQml0Q291bnQsIGJfaW5mby0+Ym1pSGVhZGVyLmJpU2l6ZUltYWdlKTsKICAgICAgICBUaGlzLT5kaWIuRElCc2VjdGlvbiA9IENyZWF0ZURJQlNlY3Rpb24oZGRjLCBiX2luZm8sIHVzYWdlLCAmVGhpcy0+ZGliLmJpdG1hcF9kYXRhLCAwIC8qIEhhbmRsZSAqLywgMCAvKiBPZmZzZXQgKi8pOwogICAgICAgIFJlbGVhc2VEQygwLCBkZGMpOwoKICAgICAgICBpZiAoIVRoaXMtPmRpYi5ESUJzZWN0aW9uKSB7CiAgICAgICAgICAgIEVSUigiQ3JlYXRlRElCU2VjdGlvbiBmYWlsZWQhXG4iKTsKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgYl9pbmZvKTsKICAgICAgICAgICAgcmV0dXJuIEhSRVNVTFRfRlJPTV9XSU4zMihHZXRMYXN0RXJyb3IoKSk7CiAgICAgICAgfQoKICAgICAgICBUUkFDRSgiRElCU2VjdGlvbiBhdCA6ICVwXG4iLCBUaGlzLT5kaWIuYml0bWFwX2RhdGEpOwoKICAgICAgICAvKiBjb3B5IHRoZSBleGlzdGluZyBzdXJmYWNlIHRvIHRoZSBkaWIgc2VjdGlvbiAqLwogICAgICAgIGlmKFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSkgewogICAgICAgICAgICBtZW1jcHkoVGhpcy0+ZGliLmJpdG1hcF9kYXRhLCBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnksIGJfaW5mby0+Ym1pSGVhZGVyLmJpU2l6ZUltYWdlKTsKICAgICAgICAgICAgLyogV2Ugd29uJ3QgbmVlZCB0aGF0IGFueSBtb3JlICovCiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLyogVGhpcyBpcyB0byBtYWtlIExvY2tSZWN0IHJlYWQgdGhlIGdsIFRleHR1cmUgYWx0aG91Z2ggbWVtb3J5IGlzIGFsbG9jYXRlZCAqLwogICAgICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19HTERJUlRZOwogICAgICAgIH0KCiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgYl9pbmZvKTsKCiAgICAgICAgLyogVXNlIHRoZSBkaWIgc2VjdGlvbiBmcm9tIG5vdyBvbiAqLwogICAgICAgIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IFRoaXMtPmRpYi5iaXRtYXBfZGF0YTsKCiAgICAgICAgLyogTm93IGFsbG9jYXRlIGEgSERDICovCiAgICAgICAgVGhpcy0+aERDID0gQ3JlYXRlQ29tcGF0aWJsZURDKDApOwogICAgICAgIFRoaXMtPmRpYi5ob2xkYml0bWFwID0gU2VsZWN0T2JqZWN0KFRoaXMtPmhEQywgVGhpcy0+ZGliLkRJQnNlY3Rpb24pOwogICAgICAgIFRSQUNFKCJ1c2luZyB3aW5lZDNkIHBhbGV0dGUgJXBcbiIsIFRoaXMtPnBhbGV0dGUpOwogICAgICAgIFNlbGVjdFBhbGV0dGUoVGhpcy0+aERDLAogICAgICAgICAgICAgICAgICAgICAgVGhpcy0+cGFsZXR0ZSA/IFRoaXMtPnBhbGV0dGUtPmhwYWwgOiAwLAogICAgICAgICAgICAgICAgICAgICAgRkFMU0UpOwoKICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19ESUJTRUNUSU9OOwogICAgfQoKICAgIC8qIExvY2sgdGhlIHN1cmZhY2UgKi8KICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX0xvY2tSZWN0KGlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmxvY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCk7CiAgICBpZihGQUlMRUQoaHIpKSB7CiAgICAgICAgRVJSKCJJV2luZUQzRFN1cmZhY2VfTG9ja1JlY3QgZmFpbGVkIHdpdGggaHIgPSAlMDh4XG4iLCBocik7CiAgICAgICAgLyoga2VlcCB0aGUgZGliIHNlY3Rpb24gKi8KICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgaWYoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfUDggfHwKICAgICAgICBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9BOFA4KSB7CiAgICAgICAgdW5zaWduZWQgaW50IG47CiAgICAgICAgaWYoVGhpcy0+cGFsZXR0ZSkgewogICAgICAgICAgICBQQUxFVFRFRU5UUlkgZW50WzI1Nl07CgogICAgICAgICAgICBHZXRQYWxldHRlRW50cmllcyhUaGlzLT5wYWxldHRlLT5ocGFsLCAwLCAyNTYsIGVudCk7CiAgICAgICAgICAgIGZvciAobj0wOyBuPDI1NjsgbisrKSB7CiAgICAgICAgICAgICAgICBjb2xbbl0ucmdiUmVkICAgPSBlbnRbbl0ucGVSZWQ7CiAgICAgICAgICAgICAgICBjb2xbbl0ucmdiR3JlZW4gPSBlbnRbbl0ucGVHcmVlbjsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JCbHVlICA9IGVudFtuXS5wZUJsdWU7CiAgICAgICAgICAgICAgICBjb2xbbl0ucmdiUmVzZXJ2ZWQgPSAwOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsICpkZXZpY2UgPSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOwoKICAgICAgICAgICAgZm9yIChuPTA7IG48MjU2OyBuKyspIHsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JSZWQgICA9IGRldmljZS0+cGFsZXR0ZXNbZGV2aWNlLT5jdXJyZW50UGFsZXR0ZV1bbl0ucGVSZWQ7CiAgICAgICAgICAgICAgICBjb2xbbl0ucmdiR3JlZW4gPSBkZXZpY2UtPnBhbGV0dGVzW2RldmljZS0+Y3VycmVudFBhbGV0dGVdW25dLnBlR3JlZW47CiAgICAgICAgICAgICAgICBjb2xbbl0ucmdiQmx1ZSAgPSBkZXZpY2UtPnBhbGV0dGVzW2RldmljZS0+Y3VycmVudFBhbGV0dGVdW25dLnBlQmx1ZTsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JSZXNlcnZlZCA9IDA7CiAgICAgICAgICAgIH0KCiAgICAgICAgfQogICAgICAgIFNldERJQkNvbG9yVGFibGUoVGhpcy0+aERDLCAwLCAyNTYsIGNvbCk7CiAgICB9CgogICAgKnBIREMgPSBUaGlzLT5oREM7CiAgICBUUkFDRSgicmV0dXJuaW5nICVwXG4iLCpwSERDKTsKICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX0RDSU5VU0U7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfUmVsZWFzZURDKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIEhEQyBoREMpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwoKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLFRoaXMsaERDKTsKCiAgICBpZiAoIShUaGlzLT5GbGFncyAmIFNGTEFHX0RDSU5VU0UpKQogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwoKICAgIC8qIHdlIGxvY2tlZCBmaXJzdCwgc28gdW5sb2NrIG5vdyAqLwogICAgSVdpbmVEM0RTdXJmYWNlX1VubG9ja1JlY3QoaWZhY2UpOwoKICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19EQ0lOVVNFOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICAgSVdpbmVEM0RTdXJmYWNlIEludGVybmFsIChObyBtYXBwaW5nIHRvIGRpcmVjdHggYXBpKSBwYXJ0cyBmb2xsb3cKICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovCgpIUkVTVUxUIGQzZGZtdF9nZXRfY29udihJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzLCBCT09MIG5lZWRfYWxwaGFfY2ssIEJPT0wgdXNlX3RleHR1cmluZywgR0xlbnVtICpmb3JtYXQsIEdMZW51bSAqaW50ZXJuYWwsIEdMZW51bSAqdHlwZSwgQ09OVkVSVF9UWVBFUyAqY29udmVydCwgaW50ICp0YXJnZXRfYnBwKSB7CiAgICBCT09MIGNvbG9ya2V5X2FjdGl2ZSA9IG5lZWRfYWxwaGFfY2sgJiYgKFRoaXMtPkNLZXlGbGFncyAmIEREU0RfQ0tTUkNCTFQpOwogICAgY29uc3QgUGl4ZWxGb3JtYXREZXNjICpmb3JtYXRFbnRyeSA9IGdldEZvcm1hdERlc2NFbnRyeShUaGlzLT5yZXNvdXJjZS5mb3JtYXQpOwoKICAgIC8qIERlZmF1bHQgdmFsdWVzOiBGcm9tIHRoZSBzdXJmYWNlICovCiAgICAqZm9ybWF0ID0gZm9ybWF0RW50cnktPmdsRm9ybWF0OwogICAgKmludGVybmFsID0gZm9ybWF0RW50cnktPmdsSW50ZXJuYWw7CiAgICAqdHlwZSA9IGZvcm1hdEVudHJ5LT5nbFR5cGU7CiAgICAqY29udmVydCA9IE5PX0NPTlZFUlNJT047CiAgICAqdGFyZ2V0X2JwcCA9IFRoaXMtPmJ5dGVzUGVyUGl4ZWw7CgogICAgLyogT2ssIG5vdyBsb29rIGlmIHdlIGhhdmUgdG8gZG8gYW55IGNvbnZlcnNpb24gKi8KICAgIHN3aXRjaChUaGlzLT5yZXNvdXJjZS5mb3JtYXQpIHsKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfUDg6CiAgICAgICAgICAgIC8qICoqKioqKioqKioqKioqKioKICAgICAgICAgICAgICAgIFBhbGV0dGVkIFRleHR1cmUKICAgICAgICAgICAgICAgICoqKioqKioqKioqKioqKiogKi8KICAgICAgICAgICAgLyogVXNlIGNvbnZlcnNpb24gd2hlbiB0aGUgcGFsZXR0ZWQgdGV4dHVyZSBleHRlbnNpb24gaXMgbm90IGF2YWlsYWJsZSwgb3Igd2hlbiBpdCBpcyBhdmFpbGFibGUgbWFrZSBzdXJlIGl0IGlzIHVzZWQKICAgICAgICAgICAgICogZm9yIHRleHR1cmluZyBhcyBpdCB3b24ndCB3b3JrIGZvciBjYWxscyBsaWtlIGdsRHJhdy0vZ2xSZWFkUGl4ZWxzIGFuZCBmdXJ0aGVyIGFsc28gdXNlIGNvbnZlcnNpb24gaW4gY2FzZSBvZiBjb2xvciBrZXlpbmcuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZighR0xfU1VQUE9SVChFWFRfUEFMRVRURURfVEVYVFVSRSkgfHwgY29sb3JrZXlfYWN0aXZlIHx8ICghdXNlX3RleHR1cmluZyAmJiBHTF9TVVBQT1JUKEVYVF9QQUxFVFRFRF9URVhUVVJFKSkgKSB7CiAgICAgICAgICAgICAgICAqZm9ybWF0ID0gR0xfUkdCQTsKICAgICAgICAgICAgICAgICppbnRlcm5hbCA9IEdMX1JHQkE7CiAgICAgICAgICAgICAgICAqdHlwZSA9IEdMX1VOU0lHTkVEX0JZVEU7CiAgICAgICAgICAgICAgICAqdGFyZ2V0X2JwcCA9IDQ7CiAgICAgICAgICAgICAgICBpZihjb2xvcmtleV9hY3RpdmUpIHsKICAgICAgICAgICAgICAgICAgICAqY29udmVydCA9IENPTlZFUlRfUEFMRVRURURfQ0s7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICpjb252ZXJ0ID0gQ09OVkVSVF9QQUxFVFRFRDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgV0lORUQzREZNVF9SM0czQjI6CiAgICAgICAgICAgIC8qICoqKioqKioqKioqKioqKioqKioqKioKICAgICAgICAgICAgICAgIEdMX1VOU0lHTkVEX0JZVEVfM18zXzIKICAgICAgICAgICAgICAgICoqKioqKioqKioqKioqKioqKioqKiogKi8KICAgICAgICAgICAgaWYgKGNvbG9ya2V5X2FjdGl2ZSkgewogICAgICAgICAgICAgICAgLyogVGhpcyB0ZXh0dXJlIGZvcm1hdCB3aWxsIG5ldmVyIGJlIHVzZWQuLiBTbyBkbyBub3QgY2FyZSBhYm91dCBjb2xvciBrZXlpbmcKICAgICAgICAgICAgICAgICAgICB1cCB1bnRpbCB0aGUgcG9pbnQgaW4gdGltZSBpdCB3aWxsIGJlIG5lZWRlZCA6LSkgKi8KICAgICAgICAgICAgICAgIEZJWE1FKCIgQ29sb3JLZXlpbmcgbm90IHN1cHBvcnRlZCBpbiB0aGUgUkdCIDMzMiBmb3JtYXQgIVxuIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgV0lORUQzREZNVF9SNUc2QjU6CiAgICAgICAgICAgIGlmIChjb2xvcmtleV9hY3RpdmUpIHsKICAgICAgICAgICAgICAgICpjb252ZXJ0ID0gQ09OVkVSVF9DS181NjU7CiAgICAgICAgICAgICAgICAqZm9ybWF0ID0gR0xfUkdCQTsKICAgICAgICAgICAgICAgICppbnRlcm5hbCA9IEdMX1JHQkE7CiAgICAgICAgICAgICAgICAqdHlwZSA9IEdMX1VOU0lHTkVEX1NIT1JUXzVfNV81XzE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgV0lORUQzREZNVF9SOEc4Qjg6CiAgICAgICAgICAgIGlmIChjb2xvcmtleV9hY3RpdmUpIHsKICAgICAgICAgICAgICAgICpjb252ZXJ0ID0gQ09OVkVSVF9DS19SR0IyNDsKICAgICAgICAgICAgICAgICpmb3JtYXQgPSBHTF9SR0JBOwogICAgICAgICAgICAgICAgKmludGVybmFsID0gR0xfUkdCQTsKICAgICAgICAgICAgICAgICp0eXBlID0gR0xfVU5TSUdORURfSU5UXzhfOF84Xzg7CiAgICAgICAgICAgICAgICAqdGFyZ2V0X2JwcCA9IDQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgV0lORUQzREZNVF9YOFI4RzhCODoKICAgICAgICAgICAgaWYgKGNvbG9ya2V5X2FjdGl2ZSkgewogICAgICAgICAgICAgICAgKmNvbnZlcnQgPSBDT05WRVJUX1JHQjMyXzg4ODsKICAgICAgICAgICAgICAgICpmb3JtYXQgPSBHTF9SR0JBOwogICAgICAgICAgICAgICAgKmludGVybmFsID0gR0xfUkdCQTsKICAgICAgICAgICAgICAgICp0eXBlID0gR0xfVU5TSUdORURfSU5UXzhfOF84Xzg7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgV0lORUQzREZNVF9WOFU4OgogICAgICAgICAgICAqY29udmVydCA9IENPTlZFUlRfVjhVODsKICAgICAgICAgICAgKmZvcm1hdCA9IEdMX0JHUjsKICAgICAgICAgICAgKmludGVybmFsID0gR0xfUkdCODsKICAgICAgICAgICAgKnR5cGUgPSBHTF9CWVRFOwogICAgICAgICAgICAqdGFyZ2V0X2JwcCA9IDM7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBicmVhazsKICAgIH0KCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBkM2RmbXRfY29udmVydF9zdXJmYWNlKEJZVEUgKnNyYywgQllURSAqZHN0LCBVSU5UIHBpdGNoLCBVSU5UIHdpZHRoLCBVSU5UIGhlaWdodCwgVUlOVCBvdXRwaXRjaCwgQ09OVkVSVF9UWVBFUyBjb252ZXJ0LCBJV2luZUQzRFN1cmZhY2VJbXBsICpzdXJmKSB7CiAgICBCWVRFICpzb3VyY2UsICpkZXN0OwogICAgVFJBQ0UoIiglcCktPiglcCksKCVkLCVkLCVkLCVkLCVwKVxuIiwgc3JjLCBkc3QsIHBpdGNoLCBoZWlnaHQsIG91dHBpdGNoLCBjb252ZXJ0LCBzdXJmKTsKCiAgICBzd2l0Y2ggKGNvbnZlcnQpIHsKICAgICAgICBjYXNlIE5PX0NPTlZFUlNJT046CiAgICAgICAgewogICAgICAgICAgICBtZW1jcHkoZHN0LCBzcmMsIHBpdGNoICogaGVpZ2h0KTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGNhc2UgQ09OVkVSVF9QQUxFVFRFRDoKICAgICAgICBjYXNlIENPTlZFUlRfUEFMRVRURURfQ0s6CiAgICAgICAgewogICAgICAgICAgICBJV2luZUQzRFBhbGV0dGVJbXBsKiBwYWwgPSBzdXJmLT5wYWxldHRlOwogICAgICAgICAgICBCWVRFIHRhYmxlWzI1Nl1bNF07CiAgICAgICAgICAgIHVuc2lnbmVkIGludCBpOwogICAgICAgICAgICB1bnNpZ25lZCBpbnQgeCwgeTsKCiAgICAgICAgICAgIGlmKCBwYWwgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgLyogVE9ETzogSWYgd2UgYXJlIGEgc3VibGV2ZWwsIHRyeSB0byBnZXQgdGhlIHBhbGV0dGUgZnJvbSBsZXZlbCAwICovCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChwYWwgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgLyogU3RpbGwgbm8gcGFsZXR0ZT8gVXNlIHRoZSBkZXZpY2UncyBwYWxldHRlICovCiAgICAgICAgICAgICAgICAvKiBHZXQgdGhlIHN1cmZhY2UncyBwYWxldHRlICovCiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgMjU2OyBpKyspIHsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZUltcGwgKmRldmljZSA9IHN1cmYtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CgogICAgICAgICAgICAgICAgICAgIHRhYmxlW2ldWzBdID0gZGV2aWNlLT5wYWxldHRlc1tkZXZpY2UtPmN1cnJlbnRQYWxldHRlXVtpXS5wZVJlZDsKICAgICAgICAgICAgICAgICAgICB0YWJsZVtpXVsxXSA9IGRldmljZS0+cGFsZXR0ZXNbZGV2aWNlLT5jdXJyZW50UGFsZXR0ZV1baV0ucGVHcmVlbjsKICAgICAgICAgICAgICAgICAgICB0YWJsZVtpXVsyXSA9IGRldmljZS0+cGFsZXR0ZXNbZGV2aWNlLT5jdXJyZW50UGFsZXR0ZV1baV0ucGVCbHVlOwogICAgICAgICAgICAgICAgICAgIGlmICgoY29udmVydCA9PSBDT05WRVJUX1BBTEVUVEVEX0NLKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAoaSA+PSBzdXJmLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUxvd1ZhbHVlKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAoaSA8PSBzdXJmLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUhpZ2hWYWx1ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogV2Ugc2hvdWxkIG1heWJlIGhlcmUgcHV0IGEgbW9yZSAnbmV1dHJhbCcgY29sb3IgdGhhbiB0aGUgc3RhbmRhcmQgYnJpZ2h0IHB1cnBsZQogICAgICAgICAgICAgICAgICAgICAgICAgIG9uZSBvZnRlbiB1c2VkIGJ5IGFwcGxpY2F0aW9uIHRvIHByZXZlbnQgdGhlIG5pY2UgcHVycGxlIGJvcmRlcnMgd2hlbiBiaS1saW5lYXIKICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXJpbmcgaXMgb24gKi8KICAgICAgICAgICAgICAgICAgICAgICAgdGFibGVbaV1bM10gPSAweDAwOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRhYmxlW2ldWzNdID0gMHhGRjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBUUkFDRSgiVXNpbmcgc3VyZmFjZSBwYWxldHRlICVwXG4iLCBwYWwpOwogICAgICAgICAgICAgICAgLyogR2V0IHRoZSBzdXJmYWNlJ3MgcGFsZXR0ZSAqLwogICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IDI1NjsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgdGFibGVbaV1bMF0gPSBwYWwtPnBhbGVudHNbaV0ucGVSZWQ7CiAgICAgICAgICAgICAgICAgICAgdGFibGVbaV1bMV0gPSBwYWwtPnBhbGVudHNbaV0ucGVHcmVlbjsKICAgICAgICAgICAgICAgICAgICB0YWJsZVtpXVsyXSA9IHBhbC0+cGFsZW50c1tpXS5wZUJsdWU7CiAgICAgICAgICAgICAgICAgICAgaWYgKChjb252ZXJ0ID09IENPTlZFUlRfUEFMRVRURURfQ0spICYmCiAgICAgICAgICAgICAgICAgICAgICAgIChpID49IHN1cmYtPlNyY0JsdENLZXkuZHdDb2xvclNwYWNlTG93VmFsdWUpICYmCiAgICAgICAgICAgICAgICAgICAgICAgIChpIDw9IHN1cmYtPlNyY0JsdENLZXkuZHdDb2xvclNwYWNlSGlnaFZhbHVlKSkgewogICAgICAgICAgICAgICAgICAgICAgICAvKiBXZSBzaG91bGQgbWF5YmUgaGVyZSBwdXQgYSBtb3JlICduZXV0cmFsJyBjb2xvciB0aGFuIHRoZSBzdGFuZGFyZCBicmlnaHQgcHVycGxlCiAgICAgICAgICAgICAgICAgICAgICAgICAgb25lIG9mdGVuIHVzZWQgYnkgYXBwbGljYXRpb24gdG8gcHJldmVudCB0aGUgbmljZSBwdXJwbGUgYm9yZGVycyB3aGVuIGJpLWxpbmVhcgogICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcmluZyBpcyBvbiAqLwogICAgICAgICAgICAgICAgICAgICAgICB0YWJsZVtpXVszXSA9IDB4MDA7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGFibGVbaV1bM10gPSAweEZGOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yICh5ID0gMDsgeSA8IGhlaWdodDsgeSsrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzb3VyY2UgPSBzcmMgKyBwaXRjaCAqIHk7CiAgICAgICAgICAgICAgICBkZXN0ID0gZHN0ICsgb3V0cGl0Y2ggKiB5OwogICAgICAgICAgICAgICAgLyogVGhpcyBpcyBhbiAxIGJwcCBmb3JtYXQsIHVzaW5nIHRoZSB3aWR0aCBoZXJlIGlzIGZpbmUgKi8KICAgICAgICAgICAgICAgIGZvciAoeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CiAgICAgICAgICAgICAgICAgICAgQllURSBjb2xvciA9ICpzb3VyY2UrKzsKICAgICAgICAgICAgICAgICAgICAqZGVzdCsrID0gdGFibGVbY29sb3JdWzBdOwogICAgICAgICAgICAgICAgICAgICpkZXN0KysgPSB0YWJsZVtjb2xvcl1bMV07CiAgICAgICAgICAgICAgICAgICAgKmRlc3QrKyA9IHRhYmxlW2NvbG9yXVsyXTsKICAgICAgICAgICAgICAgICAgICAqZGVzdCsrID0gdGFibGVbY29sb3JdWzNdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIENPTlZFUlRfQ0tfNTY1OgogICAgICAgIHsKICAgICAgICAgICAgLyogQ29udmVydGluZyB0aGUgNTY1IGZvcm1hdCBpbiA1NTUxIHBhY2tlZCB0byBlbXVsYXRlIGNvbG9yLWtleWluZy4KCiAgICAgICAgICAgICAgTm90ZSA6IGluIGFsbCB0aGVzZSBjb252ZXJzaW9uLCBpdCB3b3VsZCBiZSBiZXN0IHRvIGF2ZXJhZ2UgdGhlIGF2ZXJhZ2luZwogICAgICAgICAgICAgICAgICAgICAgcGl4ZWxzIHRvIGdldCB0aGUgY29sb3Igb2YgdGhlIHBpeGVsIHRoYXQgd2lsbCBiZSBjb2xvci1rZXllZCB0bwogICAgICAgICAgICAgICAgICAgICAgcHJldmVudCAnY29sb3IgYmxlZWRpbmcnLiBUaGlzIHdpbGwgYmUgZG9uZSBsYXRlciBvbiBpZiBldmVyIGl0IGlzCiAgICAgICAgICAgICAgICAgICAgICB0b28gdmlzaWJsZS4KCiAgICAgICAgICAgICAgTm90ZTI6IE52aWRpYSBkb2N1bWVudHMgc2F5IHRoYXQgdGhlaXIgZHJpdmVyIGRvZXMgbm90IHN1cHBvcnQgYWxwaGEgKyBjb2xvciBrZXlpbmcKICAgICAgICAgICAgICAgICAgICAgb24gdGhlIHNhbWUgc3VyZmFjZSBhbmQgZGlzYWJsZXMgY29sb3Iga2V5aW5nIGluIHN1Y2ggYSBjYXNlCiAgICAgICAgICAgICovCiAgICAgICAgICAgIHVuc2lnbmVkIGludCB4LCB5OwogICAgICAgICAgICBXT1JEICpTb3VyY2U7CiAgICAgICAgICAgIFdPUkQgKkRlc3Q7CgogICAgICAgICAgICBUUkFDRSgiQ29sb3Iga2V5ZWQgNTY1XG4iKTsKCiAgICAgICAgICAgIGZvciAoeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewogICAgICAgICAgICAgICAgU291cmNlID0gKFdPUkQgKikgKHNyYyArIHkgKiBwaXRjaCk7CiAgICAgICAgICAgICAgICBEZXN0ID0gKFdPUkQgKikgKGRzdCArIHkgKiBvdXRwaXRjaCk7CiAgICAgICAgICAgICAgICBmb3IgKHggPSAwOyB4IDwgd2lkdGg7IHgrKyApIHsKICAgICAgICAgICAgICAgICAgICBXT1JEIGNvbG9yID0gKlNvdXJjZSsrOwogICAgICAgICAgICAgICAgICAgICpEZXN0ID0gKChjb2xvciAmIDB4RkZDMCkgfCAoKGNvbG9yICYgMHgxRikgPDwgMSkpOwogICAgICAgICAgICAgICAgICAgIGlmICgoY29sb3IgPCBzdXJmLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUxvd1ZhbHVlKSB8fAogICAgICAgICAgICAgICAgICAgICAgICAoY29sb3IgPiBzdXJmLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUhpZ2hWYWx1ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgKkRlc3QgfD0gMHgwMDAxOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBEZXN0Kys7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgQ09OVkVSVF9WOFU4OgogICAgICAgIHsKICAgICAgICAgICAgdW5zaWduZWQgaW50IHgsIHk7CiAgICAgICAgICAgIHNob3J0ICpTb3VyY2U7CiAgICAgICAgICAgIGNoYXIgKkRlc3Q7CiAgICAgICAgICAgIGZvcih5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CiAgICAgICAgICAgICAgICBTb3VyY2UgPSAoc2hvcnQgKikgKHNyYyArIHkgKiBwaXRjaCk7CiAgICAgICAgICAgICAgICBEZXN0ID0gKGNoYXIgKikgKGRzdCArIHkgKiBvdXRwaXRjaCk7CiAgICAgICAgICAgICAgICBmb3IgKHggPSAwOyB4IDwgd2lkdGg7IHgrKyApIHsKICAgICAgICAgICAgICAgICAgICBsb25nIGNvbG9yID0gKCpTb3VyY2UrKyk7CiAgICAgICAgICAgICAgICAgICAgRGVzdFswXSA9IGNvbG9yID4+IDg7CiAgICAgICAgICAgICAgICAgICAgRGVzdFsxXSA9IGNvbG9yOwogICAgICAgICAgICAgICAgICAgIERlc3RbMl0gPSAweGZmOwogICAgICAgICAgICAgICAgICAgIERlc3QgKz0gMzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIEVSUigiVW5zdXBwb3J0ZWQgY29udmVyc2F0aW9uIHR5cGUgJWRcbiIsIGNvbnZlcnQpOwogICAgfQogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCBpbiBjYXNlIG9mIDhiaXQgcGFsZXR0ZWQgdGV4dHVyZXMgdG8gdXBsb2FkIHRoZSBwYWxldHRlLgogICBGb3Igbm93IGl0IG9ubHkgc3VwcG9ydHMgR0xfRVhUX3BhbGV0dGVkX3RleHR1cmUgZXh0ZW5zaW9uIGJ1dCBzdXBwb3J0IGZvciBvdGhlcgogICBleHRlbnNpb25zIGxpa2UgQVJCX2ZyYWdtZW50X3Byb2dyYW0gYW5kIEFUSV9mcmFnbWVudF9zaGFkZXJzIHdpbGwgYmUgYWRkZWQgYXMgd2VsbC4KKi8Kdm9pZCBkM2RmbXRfcDhfdXBsb2FkX3BhbGV0dGUoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgQ09OVkVSVF9UWVBFUyBjb252ZXJ0KSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEUGFsZXR0ZUltcGwqIHBhbCA9IFRoaXMtPnBhbGV0dGU7CiAgICBCWVRFIHRhYmxlWzI1Nl1bNF07CiAgICBpbnQgaTsKCiAgICBpZiAocGFsID09IE5VTEwpIHsKICAgICAgICAvKiBTdGlsbCBubyBwYWxldHRlPyBVc2UgdGhlIGRldmljZSdzIHBhbGV0dGUgKi8KICAgICAgICAvKiBHZXQgdGhlIHN1cmZhY2UncyBwYWxldHRlICovCiAgICAgICAgZm9yIChpID0gMDsgaSA8IDI1NjsgaSsrKSB7CiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlSW1wbCAqZGV2aWNlID0gVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZTsKCiAgICAgICAgICAgIHRhYmxlW2ldWzBdID0gZGV2aWNlLT5wYWxldHRlc1tkZXZpY2UtPmN1cnJlbnRQYWxldHRlXVtpXS5wZVJlZDsKICAgICAgICAgICAgdGFibGVbaV1bMV0gPSBkZXZpY2UtPnBhbGV0dGVzW2RldmljZS0+Y3VycmVudFBhbGV0dGVdW2ldLnBlR3JlZW47CiAgICAgICAgICAgIHRhYmxlW2ldWzJdID0gZGV2aWNlLT5wYWxldHRlc1tkZXZpY2UtPmN1cnJlbnRQYWxldHRlXVtpXS5wZUJsdWU7CiAgICAgICAgICAgIGlmICgoY29udmVydCA9PSBDT05WRVJUX1BBTEVUVEVEX0NLKSAmJgogICAgICAgICAgICAgICAgKGkgPj0gVGhpcy0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VMb3dWYWx1ZSkgJiYKICAgICAgICAgICAgICAgIChpIDw9IFRoaXMtPlNyY0JsdENLZXkuZHdDb2xvclNwYWNlSGlnaFZhbHVlKSkgewogICAgICAgICAgICAgICAgLyogV2Ugc2hvdWxkIG1heWJlIGhlcmUgcHV0IGEgbW9yZSAnbmV1dHJhbCcgY29sb3IgdGhhbiB0aGUgc3RhbmRhcmQgYnJpZ2h0IHB1cnBsZQogICAgICAgICAgICAgICAgICAgb25lIG9mdGVuIHVzZWQgYnkgYXBwbGljYXRpb24gdG8gcHJldmVudCB0aGUgbmljZSBwdXJwbGUgYm9yZGVycyB3aGVuIGJpLWxpbmVhcgogICAgICAgICAgICAgICAgICAgZmlsdGVyaW5nIGlzIG9uICovCiAgICAgICAgICAgICAgICB0YWJsZVtpXVszXSA9IDB4MDA7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0YWJsZVtpXVszXSA9IDB4RkY7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIFRSQUNFKCJVc2luZyBzdXJmYWNlIHBhbGV0dGUgJXBcbiIsIHBhbCk7CiAgICAgICAgLyogR2V0IHRoZSBzdXJmYWNlJ3MgcGFsZXR0ZSAqLwogICAgICAgIGZvciAoaSA9IDA7IGkgPCAyNTY7IGkrKykgewogICAgICAgICAgICB0YWJsZVtpXVswXSA9IHBhbC0+cGFsZW50c1tpXS5wZVJlZDsKICAgICAgICAgICAgdGFibGVbaV1bMV0gPSBwYWwtPnBhbGVudHNbaV0ucGVHcmVlbjsKICAgICAgICAgICAgdGFibGVbaV1bMl0gPSBwYWwtPnBhbGVudHNbaV0ucGVCbHVlOwogICAgICAgICAgICBpZiAoKGNvbnZlcnQgPT0gQ09OVkVSVF9QQUxFVFRFRF9DSykgJiYKICAgICAgICAgICAgICAgIChpID49IFRoaXMtPlNyY0JsdENLZXkuZHdDb2xvclNwYWNlTG93VmFsdWUpICYmCiAgICAgICAgICAgICAgICAoaSA8PSBUaGlzLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUhpZ2hWYWx1ZSkpIHsKICAgICAgICAgICAgICAgIC8qIFdlIHNob3VsZCBtYXliZSBoZXJlIHB1dCBhIG1vcmUgJ25ldXRyYWwnIGNvbG9yIHRoYW4gdGhlIHN0YW5kYXJkIGJyaWdodCBwdXJwbGUKICAgICAgICAgICAgICAgICAgIG9uZSBvZnRlbiB1c2VkIGJ5IGFwcGxpY2F0aW9uIHRvIHByZXZlbnQgdGhlIG5pY2UgcHVycGxlIGJvcmRlcnMgd2hlbiBiaS1saW5lYXIKICAgICAgICAgICAgICAgICAgIGZpbHRlcmluZyBpcyBvbiAqLwogICAgICAgICAgICAgICAgdGFibGVbaV1bM10gPSAweDAwOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdGFibGVbaV1bM10gPSAweEZGOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgR0xfRVhUQ0FMTChnbENvbG9yVGFibGVFWFQoR0xfVEVYVFVSRV8yRCxHTF9SR0JBLDI1NixHTF9SR0JBLEdMX1VOU0lHTkVEX0JZVEUsIHRhYmxlKSk7Cn0KCnN0YXRpYyBCT09MIHBhbGV0dGU5X2NoYW5nZWQoSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpkZXZpY2UgPSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOwoKICAgIGlmKFRoaXMtPnBhbGV0dGUgfHwgKFRoaXMtPnJlc291cmNlLmZvcm1hdCAhPSBXSU5FRDNERk1UX1A4ICYmIFRoaXMtPnJlc291cmNlLmZvcm1hdCAhPSBXSU5FRDNERk1UX0E4UDgpKSB7CiAgICAgICAgLyogSWYgYSBkZHJhdy1zdHlsZSBwYWxldHRlIGlzIGF0dGFjaGVkIGFzc3VtZSBubyBkM2Q5IHBhbGV0dGUgY2hhbmdlLgogICAgICAgICAqIEFsc28gdGhlIHBhbGV0dGUgaXNuJ3QgaW50ZXJlc3RpbmcgaWYgdGhlIHN1cmZhY2UgZm9ybWF0IGlzbid0IFA4IG9yIEE4UDgKICAgICAgICAgKi8KICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaWYoVGhpcy0+cGFsZXR0ZTkpIHsKICAgICAgICBpZihtZW1jbXAoVGhpcy0+cGFsZXR0ZTksICZkZXZpY2UtPnBhbGV0dGVzW2RldmljZS0+Y3VycmVudFBhbGV0dGVdLCBzaXplb2YoUEFMRVRURUVOVFJZKSAqIDI1NikgPT0gMCkgewogICAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICBUaGlzLT5wYWxldHRlOSA9IChQQUxFVFRFRU5UUlkgKikgSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZihQQUxFVFRFRU5UUlkpICogMjU2KTsKICAgIH0KICAgIG1lbWNweShUaGlzLT5wYWxldHRlOSwgJmRldmljZS0+cGFsZXR0ZXNbZGV2aWNlLT5jdXJyZW50UGFsZXR0ZV0sIHNpemVvZihQQUxFVFRFRU5UUlkpICogMjU2KTsKICAgIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9Mb2FkVGV4dHVyZShJV2luZUQzRFN1cmZhY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIEdMZW51bSBmb3JtYXQsIGludGVybmFsLCB0eXBlOwogICAgQ09OVkVSVF9UWVBFUyBjb252ZXJ0OwogICAgaW50IGJwcDsKICAgIGludCB3aWR0aCwgcGl0Y2gsIG91dHBpdGNoOwogICAgQllURSAqbWVtOwoKICAgIGlmIChUaGlzLT5GbGFncyAmIFNGTEFHX0lOVEVYVFVSRSkgewogICAgICAgIFRSQUNFKCJTdXJmYWNlIGFscmVhZHkgaW4gdGV4dHVyZVxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CiAgICBpZiAoVGhpcy0+RmxhZ3MgJiBTRkxBR19ESVJUWSkgewogICAgICAgIFRSQUNFKCJSZWxvYWRpbmcgYmVjYXVzZSBzdXJmYWNlIGlzIGRpcnR5XG4iKTsKICAgIH0gZWxzZSBpZigvKiBSZWxvYWQ6IGdsIHRleHR1cmUgaGFzIGNrLCBub3cgbm8gY2tleSBpcyBzZXQgT1IgKi8KICAgICAgICAgICAgICAoKFRoaXMtPkZsYWdzICYgU0ZMQUdfR0xDS0VZKSAmJiAoIShUaGlzLT5DS2V5RmxhZ3MgJiBERFNEX0NLU1JDQkxUKSkpIHx8CiAgICAgICAgICAgICAgLyogUmVsb2FkOiB2aWNlIHZlcnNhICBPUiAqLwogICAgICAgICAgICAgICgoIShUaGlzLT5GbGFncyAmIFNGTEFHX0dMQ0tFWSkpICYmIChUaGlzLT5DS2V5RmxhZ3MgJiBERFNEX0NLU1JDQkxUKSkgfHwKICAgICAgICAgICAgICAvKiBBbHNvIHJlbG9hZDogQ29sb3Iga2V5IGlzIGFjdGl2ZSBBTkQgdGhlIGNvbG9yIGtleSBoYXMgY2hhbmdlZCAqLwogICAgICAgICAgICAgICgoVGhpcy0+Q0tleUZsYWdzICYgRERTRF9DS1NSQ0JMVCkgJiYgKAogICAgICAgICAgICAgICAgKFRoaXMtPmdsQ0tleS5kd0NvbG9yU3BhY2VMb3dWYWx1ZSAhPSBUaGlzLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUxvd1ZhbHVlKSB8fAogICAgICAgICAgICAgICAgKFRoaXMtPmdsQ0tleS5kd0NvbG9yU3BhY2VIaWdoVmFsdWUgIT0gVGhpcy0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VIaWdoVmFsdWUpKSkpIHsKICAgICAgICBUUkFDRSgiUmVsb2FkaW5nIGJlY2F1c2Ugb2YgY29sb3Iga2V5aW5nXG4iKTsKICAgIH0gZWxzZSBpZihwYWxldHRlOV9jaGFuZ2VkKFRoaXMpKSB7CiAgICAgICAgVFJBQ0UoIlJlbG9hZGluZyBzdXJmYWNlIGJlY2F1c2UgdGhlIGQzZDgvOSBwYWxldHRlIHdhcyBjaGFuZ2VkXG4iKTsKICAgIH0gZWxzZSB7CiAgICAgICAgVFJBQ0UoInN1cmZhY2UgaXNuJ3QgZGlydHlcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19ESVJUWTsKCiAgICAvKiBSZXNvdXJjZXMgYXJlIHBsYWNlZCBpbiBzeXN0ZW0gUkFNIGFuZCBkbyBub3QgbmVlZCB0byBiZSByZWNyZWF0ZWQgd2hlbiBhIGRldmljZSBpcyBsb3N0LgogICAgKiAgVGhlc2UgcmVzb3VyY2VzIGFyZSBub3QgYm91bmQgYnkgZGV2aWNlIHNpemUgb3IgZm9ybWF0IHJlc3RyaWN0aW9ucy4gQmVjYXVzZSBvZiB0aGlzLAogICAgKiAgdGhlc2UgcmVzb3VyY2VzIGNhbm5vdCBiZSBhY2Nlc3NlZCBieSB0aGUgRGlyZWN0M0QgZGV2aWNlIG5vciBzZXQgYXMgdGV4dHVyZXMgb3IgcmVuZGVyIHRhcmdldHMuCiAgICAqICBIb3dldmVyLCB0aGVzZSByZXNvdXJjZXMgY2FuIGFsd2F5cyBiZSBjcmVhdGVkLCBsb2NrZWQsIGFuZCBjb3BpZWQuCiAgICAqLwogICAgaWYgKFRoaXMtPnJlc291cmNlLnBvb2wgPT0gV0lORUQzRFBPT0xfU0NSQVRDSCAmJiAhKFRoaXMtPkZsYWdzICYgU0ZMQUdfRk9SQ0VMT0FEKSApCiAgICB7CiAgICAgICAgRklYTUUoIiglcCkgT3BlcmF0aW9uIG5vdCBzdXBwb3J0ZWQgZm9yIHNjcmF0Y2ggdGV4dHVyZXNcbiIsVGhpcyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgaWYgKFRoaXMtPkZsYWdzICYgU0ZMQUdfSU5QQlVGRkVSKSB7CiAgICAgICAgaWYgKFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwgIT0gMCkKICAgICAgICAgICAgRklYTUUoIlN1cmZhY2UgaW4gdGV4dHVyZSBpcyBvbmx5IHN1cHBvcnRlZCBmb3IgbGV2ZWwgMFxuIik7CiAgICAgICAgZWxzZSBpZiAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfUDggfHwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfQThQOCB8fAogICAgICAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDEgfHwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMiB8fAogICAgICAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDMgfHwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNCB8fAogICAgICAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDUpCiAgICAgICAgICAgIEZJWE1FKCJGb3JtYXQgJWQgbm90IHN1cHBvcnRlZFxuIiwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0KTsKICAgICAgICBlbHNlIHsKICAgICAgICAgICAgR0xpbnQgcHJldlJlYWQ7CgogICAgICAgICAgICBFTlRFUl9HTCgpOwoKICAgICAgICAgICAgZ2xHZXRJbnRlZ2VydihHTF9SRUFEX0JVRkZFUiwgJnByZXZSZWFkKTsKICAgICAgICAgICAgdmNoZWNrR0xjYWxsKCJnbEdldEludGVnZXJ2Iik7CiAgICAgICAgICAgIGdsUmVhZEJ1ZmZlcihHTF9CQUNLKTsKICAgICAgICAgICAgdmNoZWNrR0xjYWxsKCJnbFJlYWRCdWZmZXIiKTsKCiAgICAgICAgICAgIGdsQ29weVRleEltYWdlMkQoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0SW50ZXJuYWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPmN1cnJlbnREZXNjLldpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwKTsKCiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbENvcHlUZXhJbWFnZTJEIik7CiAgICAgICAgICAgIGdsUmVhZEJ1ZmZlcihwcmV2UmVhZCk7CiAgICAgICAgICAgIHZjaGVja0dMY2FsbCgiZ2xSZWFkQnVmZmVyIik7CgogICAgICAgICAgICBMRUFWRV9HTCgpOwoKICAgICAgICAgICAgVFJBQ0UoIlVwZGF0aW5nIHRhcmdldCAlZFxuIiwgVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQpOwogICAgICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19JTlRFWFRVUkU7CiAgICAgICAgfQogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIGlmKFRoaXMtPkNLZXlGbGFncyAmIEREU0RfQ0tTUkNCTFQpIHsKICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19HTENLRVk7CiAgICAgICAgVGhpcy0+Z2xDS2V5ID0gVGhpcy0+U3JjQmx0Q0tleTsKICAgIH0KICAgIGVsc2UgVGhpcy0+RmxhZ3MgJj0gflNGTEFHX0dMQ0tFWTsKCiAgICBkM2RmbXRfZ2V0X2NvbnYoVGhpcywgVFJVRSAvKiBXZSBuZWVkIGNvbG9yIGtleWluZyAqLywgVFJVRSAvKiBXZSB3aWxsIHVzZSB0ZXh0dXJlcyAqLywgJmZvcm1hdCwgJmludGVybmFsLCAmdHlwZSwgJmNvbnZlcnQsICZicHApOwoKICAgIC8qIFRoZSB3aWR0aCBpcyBpbiAnbGVuZ3RoJyBub3QgaW4gYnl0ZXMgKi8KICAgIHdpZHRoID0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICBwaXRjaCA9IElXaW5lRDNEU3VyZmFjZV9HZXRQaXRjaChpZmFjZSk7CgogICAgaWYoKGNvbnZlcnQgIT0gTk9fQ09OVkVSU0lPTikgJiYgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KSB7CiAgICAgICAgaW50IGhlaWdodCA9IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodDsKCiAgICAgICAgLyogU3RpY2sgdG8gdGhlIGFsaWdubWVudCBmb3IgdGhlIGNvbnZlcnRlZCBzdXJmYWNlIHRvbywgbWFrZXMgaXQgZWFzaWVyIHRvIGxvYWQgdGhlIHN1cmZhY2UgKi8KICAgICAgICBvdXRwaXRjaCA9IHdpZHRoICogYnBwOwogICAgICAgIG91dHBpdGNoID0gKG91dHBpdGNoICsgU1VSRkFDRV9BTElHTk1FTlQgLSAxKSAmIH4oU1VSRkFDRV9BTElHTk1FTlQgLSAxKTsKCiAgICAgICAgbWVtID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIG91dHBpdGNoICogaGVpZ2h0KTsKICAgICAgICBpZighbWVtKSB7CiAgICAgICAgICAgIEVSUigiT3V0IG9mIG1lbW9yeSAlZCwgJWQhXG4iLCBvdXRwaXRjaCwgaGVpZ2h0KTsKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfT1VUT0ZWSURFT01FTU9SWTsKICAgICAgICB9CiAgICAgICAgZDNkZm10X2NvbnZlcnRfc3VyZmFjZShUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnksIG1lbSwgcGl0Y2gsIHdpZHRoLCBoZWlnaHQsIG91dHBpdGNoLCBjb252ZXJ0LCBUaGlzKTsKCiAgICAgICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfQ09OVkVSVEVEOwogICAgfSBlbHNlIGlmIChUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9QOCAmJiBHTF9TVVBQT1JUKEVYVF9QQUxFVFRFRF9URVhUVVJFKSkgewogICAgICAgIGQzZGZtdF9wOF91cGxvYWRfcGFsZXR0ZShpZmFjZSwgY29udmVydCk7CiAgICAgICAgVGhpcy0+RmxhZ3MgJj0gflNGTEFHX0NPTlZFUlRFRDsKICAgICAgICBtZW0gPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnk7CiAgICB9IGVsc2UgewogICAgICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19DT05WRVJURUQ7CiAgICAgICAgbWVtID0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5OwogICAgfQoKICAgIC8qIE1ha2Ugc3VyZSB0aGUgY29ycmVjdCBwaXRjaCBpcyB1c2VkICovCiAgICBnbFBpeGVsU3RvcmVpKEdMX1VOUEFDS19ST1dfTEVOR1RILCB3aWR0aCk7CgogICAgaWYgKChUaGlzLT5GbGFncyAmIFNGTEFHX05PTlBPVzIpICYmICEoVGhpcy0+RmxhZ3MgJiBTRkxBR19PVkVSU0laRSkpIHsKICAgICAgICBUUkFDRSgibm9uIHBvd2VyIG9mIHR3byBzdXBwb3J0XG4iKTsKICAgICAgICBzdXJmYWNlX2FsbG9jYXRlX3N1cmZhY2UoVGhpcywgaW50ZXJuYWwsIFRoaXMtPnBvdzJXaWR0aCwgVGhpcy0+cG93MkhlaWdodCwgZm9ybWF0LCB0eXBlKTsKICAgICAgICBpZiAobWVtKSB7CiAgICAgICAgICAgIHN1cmZhY2VfdXBsb2FkX2RhdGEoVGhpcywgVGhpcy0+Y3VycmVudERlc2MuV2lkdGgsIFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodCwgZm9ybWF0LCB0eXBlLCBtZW0pOwogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgc3VyZmFjZV9hbGxvY2F0ZV9zdXJmYWNlKFRoaXMsIGludGVybmFsLCBUaGlzLT5nbFJlY3QucmlnaHQgLSBUaGlzLT5nbFJlY3QubGVmdCwgVGhpcy0+Z2xSZWN0LmJvdHRvbSAtIFRoaXMtPmdsUmVjdC50b3AsIGZvcm1hdCwgdHlwZSk7CiAgICAgICAgaWYgKG1lbSkgewogICAgICAgICAgICBzdXJmYWNlX3VwbG9hZF9kYXRhKFRoaXMsIFRoaXMtPmdsUmVjdC5yaWdodCAtIFRoaXMtPmdsUmVjdC5sZWZ0LCBUaGlzLT5nbFJlY3QuYm90dG9tIC0gVGhpcy0+Z2xSZWN0LnRvcCwgZm9ybWF0LCB0eXBlLCBtZW0pOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBSZXN0b3JlIHRoZSBkZWZhdWx0IHBpdGNoICovCiAgICBnbFBpeGVsU3RvcmVpKEdMX1VOUEFDS19ST1dfTEVOR1RILCAwKTsKCiAgICBpZiAobWVtICE9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSkKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBtZW0pOwoKI2lmIDAKICAgIHsKICAgICAgICBzdGF0aWMgdW5zaWduZWQgaW50IGdlbiA9IDA7CiAgICAgICAgY2hhciBidWZmZXJbNDA5Nl07CiAgICAgICAgKytnZW47CiAgICAgICAgaWYgKChnZW4gJSAxMCkgPT0gMCkgewogICAgICAgICAgICBzbnByaW50ZihidWZmZXIsIHNpemVvZihidWZmZXIpLCAiL3RtcC9zdXJmYWNlJXBfdHlwZSV1X2xldmVsJXVfJXUucHBtIiwgVGhpcywgVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsIGdlbik7CiAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZUltcGxfU2F2ZVNuYXBzaG90KGlmYWNlLCBidWZmZXIpOwogICAgICAgIH0KICAgICAgICAvKgogICAgICAgICAqIGRlYnVnZ2luZyBjcmFzaCBjb2RlCiAgICAgICAgIGlmIChnZW4gPT0gMjUwKSB7CiAgICAgICAgIHZvaWQqKiB0ZXN0ID0gTlVMTDsKICAgICAgICAgKnRlc3QgPSAwOwogICAgICAgICB9CiAgICAgICAgICovCiAgICB9CiNlbmRpZgoKICAgIGlmICghKFRoaXMtPkZsYWdzICYgU0ZMQUdfRE9OT1RGUkVFKSkgewogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSk7CiAgICAgICAgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gTlVMTDsKICAgIH0KCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKI2luY2x1ZGUgPGVycm5vLmg+CiNpbmNsdWRlIDxzdGRpby5oPgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1NhdmVTbmFwc2hvdChJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBjb25zdCBjaGFyKiBmaWxlbmFtZSkgewogICAgRklMRSogZiA9IE5VTEw7CiAgICBVSU5UIGksIHk7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIGNoYXIgKmFsbG9jYXRlZE1lbW9yeTsKICAgIGNoYXIgKnRleHR1cmVSb3c7CiAgICBJV2luZUQzRFN3YXBDaGFpbiAqc3dhcENoYWluID0gTlVMTDsKICAgIGludCB3aWR0aCwgaGVpZ2h0OwogICAgR0x1aW50IHRtcFRleHR1cmUgPSAwOwogICAgRFdPUkQgY29sb3I7CiAgICAvKkZJWE1FOgogICAgVGV4dHVyZXMgbXkgbm90IGJlIHN0b3JlZCBpbiAtPmFsbG9jYXRlZGdNZW1vcnkgYW5kIGEgR2xUZXh0dXJlCiAgICBzbyB3ZSBzaG91bGQgbG9jayB0aGUgc3VyZmFjZSBiZWZvcmUgc2F2aW5nIGEgc25hcHNob3QsIG9yIGF0IGxlYXN0IGNoZWNrIHRoYXQKICAgICovCiAgICAvKiBUT0RPOiBDb21wcmVzc2VkIHRleHR1cmUgaW1hZ2VzIGNhbiBiZSBvYnRhaW5lZCBmcm9tIHRoZSBHTCBpbiB1bmNvbXByZXNzZWQgZm9ybQogICAgYnkgY2FsbGluZyBHZXRUZXhJbWFnZSBhbmQgaW4gY29tcHJlc3NlZCBmb3JtIGJ5IGNhbGxpbmcKICAgIEdldENvbXByZXNzZWRUZXhJbWFnZUFSQi4gIFF1ZXJpZWQgY29tcHJlc3NlZCBpbWFnZXMgY2FuIGJlIHNhdmVkIGFuZAogICAgbGF0ZXIgcmV1c2VkIGJ5IGNhbGxpbmcgQ29tcHJlc3NlZFRleEltYWdlWzEyM11EQVJCLiAgUHJlLWNvbXByZXNzZWQKICAgIHRleHR1cmUgaW1hZ2VzIGRvIG5vdCBuZWVkIHRvIGJlIHByb2Nlc3NlZCBieSB0aGUgR0wgYW5kIHNob3VsZAogICAgc2lnbmlmaWNhbnRseSBpbXByb3ZlIHRleHR1cmUgbG9hZGluZyBwZXJmb3JtYW5jZSByZWxhdGl2ZSB0byB1bmNvbXByZXNzZWQKICAgIGltYWdlcy4gKi8KCi8qIFNldHVwIHRoZSB3aWR0aCBhbmQgaGVpZ2h0IHRvIGJlIHRoZSBpbnRlcm5hbCB0ZXh0dXJlIHdpZHRoIGFuZCBoZWlnaHQuICovCiAgICB3aWR0aCAgPSBUaGlzLT5wb3cyV2lkdGg7CiAgICBoZWlnaHQgPSBUaGlzLT5wb3cySGVpZ2h0OwovKiBjaGVjayB0byBzZWUgaWYgd2VyZSBhICd2aXJ0dWFsJyB0ZXh0dXJlIGUuZy4gd2VyZSBub3QgYSBwYnVmZmVyIG9mIHRleHR1cmUgd2VyZSBhIGJhY2sgYnVmZmVyKi8KICAgIElXaW5lRDNEU3VyZmFjZV9HZXRDb250YWluZXIoaWZhY2UsICZJSURfSVdpbmVEM0RTd2FwQ2hhaW4sICh2b2lkICoqKSZzd2FwQ2hhaW4pOwoKICAgIGlmIChzd2FwQ2hhaW4gfHwgKFRoaXMtPkZsYWdzICYgU0ZMQUdfSU5QQlVGRkVSKSkgeyAvKiBpZiB3ZXJlIG5vdCBhIHJlYWwgdGV4dHVyZSB0aGVuIHJlYWQgdGhlIGJhY2sgYnVmZmVyIGludG8gYSByZWFsIHRleHR1cmUqLwovKiB3ZSBkb24ndCB3YW50IHRvIGludGVyZmVyZSB3aXRoIHRoZSBiYWNrIGJ1ZmZlciBzbyByZWFkIHRoZSBkYXRhIGludG8gYSB0ZW1wb3JhcnkgdGV4dHVyZSBhbmQgdGhlbiBzYXZlIHRoZSBkYXRhIG91dCBvZiB0aGUgdGVtcG9yYXJ5IHRleHR1cmUgKi8KICAgICAgICBHTGludCBwcmV2UmVhZDsKICAgICAgICBFTlRFUl9HTCgpOwogICAgICAgIEZJWE1FKCIoJXApIFRoaXMgc3VyZmFjZSBuZWVkcyB0byBiZSBsb2NrZWQgYmVmb3JlIGEgc25hcHNob3QgY2FuIGJlIHRha2VuXG4iLCBUaGlzKTsKICAgICAgICBnbEVuYWJsZShHTF9URVhUVVJFXzJEKTsKCiAgICAgICAgZ2xHZW5UZXh0dXJlcygxLCAmdG1wVGV4dHVyZSk7CiAgICAgICAgZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCB0bXBUZXh0dXJlKTsKCiAgICAgICAgZ2xUZXhJbWFnZTJEKEdMX1RFWFRVUkVfMkQsCiAgICAgICAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgICAgICAgIEdMX1JHQkEsCiAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgICAgIDAvKmJvcmRlciovLAogICAgICAgICAgICAgICAgICAgICAgICBHTF9SR0JBLAogICAgICAgICAgICAgICAgICAgICAgICBHTF9VTlNJR05FRF9JTlRfOF84XzhfOF9SRVYsCiAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwoKICAgICAgICBnbEdldEludGVnZXJ2KEdMX1JFQURfQlVGRkVSLCAmcHJldlJlYWQpOwogICAgICAgIHZjaGVja0dMY2FsbCgiZ2xHZXRJbnRlZ2VydiIpOwogICAgICAgIGdsUmVhZEJ1ZmZlcihHTF9CQUNLKTsKICAgICAgICB2Y2hlY2tHTGNhbGwoImdsUmVhZEJ1ZmZlciIpOwogICAgICAgIGdsQ29weVRleEltYWdlMkQoR0xfVEVYVFVSRV8yRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBHTF9SR0JBLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIDApOwoKICAgICAgICBjaGVja0dMY2FsbCgiZ2xDb3B5VGV4SW1hZ2UyRCIpOwogICAgICAgIGdsUmVhZEJ1ZmZlcihwcmV2UmVhZCk7CiAgICAgICAgTEVBVkVfR0woKTsKCiAgICB9IGVsc2UgeyAvKiBiaW5kIHRoZSByZWFsIHRleHR1cmUgKi8KICAgICAgICBJV2luZUQzRFN1cmZhY2VfUHJlTG9hZChpZmFjZSk7CiAgICB9CiAgICBhbGxvY2F0ZWRNZW1vcnkgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgd2lkdGggICogaGVpZ2h0ICogNCk7CiAgICBFTlRFUl9HTCgpOwogICAgRklYTUUoIlNhdmluZyB0ZXh0dXJlIGxldmVsICVkIHdpZHRoICVkIGhlaWdodCAlZFxuIiwgVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCwgd2lkdGgsIGhlaWdodCk7CiAgICBnbEdldFRleEltYWdlKEdMX1RFWFRVUkVfMkQsCiAgICAgICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLAogICAgICAgICAgICAgICAgR0xfUkdCQSwKICAgICAgICAgICAgICAgIEdMX1VOU0lHTkVEX0lOVF84XzhfOF84X1JFViwKICAgICAgICAgICAgICAgIGFsbG9jYXRlZE1lbW9yeSk7CiAgICBjaGVja0dMY2FsbCgiZ2xUZXhJbWFnZTJEIik7CiAgICBpZiAodG1wVGV4dHVyZSkgewogICAgICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgMCk7CiAgICAgICAgZ2xEZWxldGVUZXh0dXJlcygxLCAmdG1wVGV4dHVyZSk7CiAgICB9CiAgICBMRUFWRV9HTCgpOwoKICAgIGYgPSBmb3BlbihmaWxlbmFtZSwgIncrIik7CiAgICBpZiAoTlVMTCA9PSBmKSB7CiAgICAgICAgRVJSKCJvcGVuaW5nIG9mICVzIGZhaWxlZCB3aXRoOiAlc1xuIiwgZmlsZW5hbWUsIHN0cmVycm9yKGVycm5vKSk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9Ci8qIFNhdmUgdGhlIGRhdCBvdXQgdG8gYSBUR0EgZmlsZSBiZWNhdXNlIDE6IGl0J3MgYW4gZWFzeSByYXcgZm9ybWF0LCAyOiBpdCBzdXBwb3J0cyBhbiBhbHBoYSBjaGFuZWwqLwogICAgVFJBQ0UoIiglcCkgb3BlbmVkICVzIHdpdGggZm9ybWF0ICVzXG4iLCBUaGlzLCBmaWxlbmFtZSwgZGVidWdfZDNkZm9ybWF0KFRoaXMtPnJlc291cmNlLmZvcm1hdCkpOwovKiBUR0EgaGVhZGVyICovCiAgICBmcHV0YygwLGYpOwogICAgZnB1dGMoMCxmKTsKICAgIGZwdXRjKDIsZik7CiAgICBmcHV0YygwLGYpOwogICAgZnB1dGMoMCxmKTsKICAgIGZwdXRjKDAsZik7CiAgICBmcHV0YygwLGYpOwogICAgZnB1dGMoMCxmKTsKICAgIGZwdXRjKDAsZik7CiAgICBmcHV0YygwLGYpOwogICAgZnB1dGMoMCxmKTsKICAgIGZwdXRjKDAsZik7Ci8qIHNob3J0IHdpZHRoKi8KICAgIGZ3cml0ZSgmd2lkdGgsMiwxLGYpOwovKiBzaG9ydCBoZWlnaHQgKi8KICAgIGZ3cml0ZSgmaGVpZ2h0LDIsMSxmKTsKLyogZm9ybWF0IHJnYmEgKi8KICAgIGZwdXRjKDB4MjAsZik7CiAgICBmcHV0YygweDI4LGYpOwovKiByYXcgZGF0YSAqLwogICAgLyogaWYgIHRoZSBkYXRhIGlzIHVwc2lkZSBkb3duIGlmIHdlJ3ZlIGZldGNoZWQgaXQgZnJvbSBhIGJhY2sgYnVmZmVyLCBzbyBpdCBuZWVkcyBmbGlwcGluZyBhZ2FpbiB0byBtYWtlIGl0IHRoZSBjb3JyZWN0IHdheSB1cCovCiAgICBpZihzd2FwQ2hhaW4pCiAgICAgICAgdGV4dHVyZVJvdyA9IGFsbG9jYXRlZE1lbW9yeSArICh3aWR0aCAqIChoZWlnaHQgLSAxKSAqNCk7CiAgICBlbHNlCiAgICAgICAgdGV4dHVyZVJvdyA9IGFsbG9jYXRlZE1lbW9yeTsKICAgIGZvciAoeSA9IDAgOyB5IDwgaGVpZ2h0OyB5KyspIHsKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgd2lkdGg7ICBpKyspIHsKICAgICAgICAgICAgY29sb3IgPSAqKChEV09SRCopdGV4dHVyZVJvdyk7CiAgICAgICAgICAgIGZwdXRjKChjb2xvciA+PiAxNikgJiAweEZGLCBmKTsgLyogQiAqLwogICAgICAgICAgICBmcHV0YygoY29sb3IgPj4gIDgpICYgMHhGRiwgZik7IC8qIEcgKi8KICAgICAgICAgICAgZnB1dGMoKGNvbG9yID4+ICAwKSAmIDB4RkYsIGYpOyAvKiBSICovCiAgICAgICAgICAgIGZwdXRjKChjb2xvciA+PiAyNCkgJiAweEZGLCBmKTsgLyogQSAqLwogICAgICAgICAgICB0ZXh0dXJlUm93ICs9IDQ7CiAgICAgICAgfQogICAgICAgIC8qIHRha2UgdHdvIHJvd3Mgb2YgdGhlIHBvaW50ZXIgdG8gdGhlIHRleHR1cmUgbWVtb3J5ICovCiAgICAgICAgaWYoc3dhcENoYWluKQogICAgICAgICAgICAodGV4dHVyZVJvdy09IHdpZHRoIDw8IDMpOwoKICAgIH0KICAgIFRSQUNFKCJDbG9zaW5nIGZpbGVcbiIpOwogICAgZmNsb3NlKGYpOwoKICAgIGlmKHN3YXBDaGFpbikgewogICAgICAgIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2Uoc3dhcENoYWluKTsKICAgIH0KICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGFsbG9jYXRlZE1lbW9yeSk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9DbGVhbkRpcnR5UmVjdChJV2luZUQzRFN1cmZhY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19ESVJUWTsKICAgIFRoaXMtPmRpcnR5UmVjdC5sZWZ0ICAgPSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgIFRoaXMtPmRpcnR5UmVjdC50b3AgICAgPSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICBUaGlzLT5kaXJ0eVJlY3QucmlnaHQgID0gMDsKICAgIFRoaXMtPmRpcnR5UmVjdC5ib3R0b20gPSAwOwogICAgVFJBQ0UoIiglcCkgOiBEaXJ0eT8lZCwgUmVjdDooJWQsJWQsJWQsJWQpXG4iLCBUaGlzLCBUaGlzLT5GbGFncyAmIFNGTEFHX0RJUlRZID8gMSA6IDAsIFRoaXMtPmRpcnR5UmVjdC5sZWZ0LAogICAgICAgICAgVGhpcy0+ZGlydHlSZWN0LnRvcCwgVGhpcy0+ZGlydHlSZWN0LnJpZ2h0LCBUaGlzLT5kaXJ0eVJlY3QuYm90dG9tKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKioKICogICBTbGlnaHRseSBpbmVmZmljaWVudCB3YXkgdG8gaGFuZGxlIG11bHRpcGxlIGRpcnR5IHJlY3RzIGJ1dCBpdCB3b3JrcyA6KQogKi8KZXh0ZXJuIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfQWRkRGlydHlSZWN0KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIENPTlNUIFJFQ1QqIHBEaXJ0eVJlY3QpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RCYXNlVGV4dHVyZSAqYmFzZVRleHR1cmUgPSBOVUxMOwogICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfRElSVFk7CiAgICBpZiAoTlVMTCAhPSBwRGlydHlSZWN0KSB7CiAgICAgICAgVGhpcy0+ZGlydHlSZWN0LmxlZnQgICA9IG1pbihUaGlzLT5kaXJ0eVJlY3QubGVmdCwgICBwRGlydHlSZWN0LT5sZWZ0KTsKICAgICAgICBUaGlzLT5kaXJ0eVJlY3QudG9wICAgID0gbWluKFRoaXMtPmRpcnR5UmVjdC50b3AsICAgIHBEaXJ0eVJlY3QtPnRvcCk7CiAgICAgICAgVGhpcy0+ZGlydHlSZWN0LnJpZ2h0ICA9IG1heChUaGlzLT5kaXJ0eVJlY3QucmlnaHQsICBwRGlydHlSZWN0LT5yaWdodCk7CiAgICAgICAgVGhpcy0+ZGlydHlSZWN0LmJvdHRvbSA9IG1heChUaGlzLT5kaXJ0eVJlY3QuYm90dG9tLCBwRGlydHlSZWN0LT5ib3R0b20pOwogICAgfSBlbHNlIHsKICAgICAgICBUaGlzLT5kaXJ0eVJlY3QubGVmdCAgID0gMDsKICAgICAgICBUaGlzLT5kaXJ0eVJlY3QudG9wICAgID0gMDsKICAgICAgICBUaGlzLT5kaXJ0eVJlY3QucmlnaHQgID0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAgICAgVGhpcy0+ZGlydHlSZWN0LmJvdHRvbSA9IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgIH0KICAgIFRSQUNFKCIoJXApIDogRGlydHk/JWQsIFJlY3Q6KCVkLCVkLCVkLCVkKVxuIiwgVGhpcywgVGhpcy0+RmxhZ3MgJiBTRkxBR19ESVJUWSwgVGhpcy0+ZGlydHlSZWN0LmxlZnQsCiAgICAgICAgICBUaGlzLT5kaXJ0eVJlY3QudG9wLCBUaGlzLT5kaXJ0eVJlY3QucmlnaHQsIFRoaXMtPmRpcnR5UmVjdC5ib3R0b20pOwogICAgLyogaWYgdGhlIGNvbnRhaW5lciBpcyBhIGJhc2V0ZXh0dXJlIHRoZW4gbWFyayBpdCBkaXJ0eS4gKi8KICAgIGlmIChJV2luZUQzRFN1cmZhY2VfR2V0Q29udGFpbmVyKGlmYWNlLCAmSUlEX0lXaW5lRDNEQmFzZVRleHR1cmUsICh2b2lkICoqKSZiYXNlVGV4dHVyZSkgPT0gV0lORUQzRF9PSykgewogICAgICAgIFRSQUNFKCJQYXNzaW5nIHRvIGNvbmF0aW5lclxuIik7CiAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9TZXREaXJ0eShiYXNlVGV4dHVyZSwgVFJVRSk7CiAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9SZWxlYXNlKGJhc2VUZXh0dXJlKTsKICAgIH0KICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1NldENvbnRhaW5lcihJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBJV2luZUQzREJhc2UgKmNvbnRhaW5lcikgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CgogICAgVFJBQ0UoIlRoaXMgJXAsIGNvbnRhaW5lciAlcFxuIiwgVGhpcywgY29udGFpbmVyKTsKCiAgICAvKiBXZSBjYW4ndCBrZWVwIGEgcmVmZXJlbmNlIHRvIHRoZSBjb250YWluZXIsIHNpbmNlIHRoZSBjb250YWluZXIgYWxyZWFkeSBrZWVwcyBhIHJlZmVyZW5jZSB0byB1cy4gKi8KCiAgICBUUkFDRSgiU2V0dGluZyBjb250YWluZXIgdG8gJXAgZnJvbSAlcFxuIiwgY29udGFpbmVyLCBUaGlzLT5jb250YWluZXIpOwogICAgVGhpcy0+Y29udGFpbmVyID0gY29udGFpbmVyOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1NldEZvcm1hdChJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBXSU5FRDNERk9STUFUIGZvcm1hdCkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBjb25zdCBQaXhlbEZvcm1hdERlc2MgKmZvcm1hdEVudHJ5ID0gZ2V0Rm9ybWF0RGVzY0VudHJ5KGZvcm1hdCk7CgogICAgaWYgKFRoaXMtPnJlc291cmNlLmZvcm1hdCAhPSBXSU5FRDNERk1UX1VOS05PV04pIHsKICAgICAgICBGSVhNRSgiKCVwKSA6IFRoZSBmb3JhbXQgb2YgdGhlIHN1cmZhY2UgbXVzdCBiZSBXSU5FRDNERk9STUFUX1VOS05PV05cbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIFRSQUNFKCIoJXApIDogU2V0dGluZyB0ZXh0dXJlIGZvcmFtdCB0byAoJWQsJXMpXG4iLCBUaGlzLCBmb3JtYXQsIGRlYnVnX2QzZGZvcm1hdChmb3JtYXQpKTsKICAgIGlmIChmb3JtYXQgPT0gV0lORUQzREZNVF9VTktOT1dOKSB7CiAgICAgICAgVGhpcy0+cmVzb3VyY2Uuc2l6ZSA9IDA7CiAgICB9IGVsc2UgaWYgKGZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDEpIHsKICAgICAgICAvKiBEWFQxIGlzIGhhbGYgYnl0ZSBwZXIgcGl4ZWwgKi8KICAgICAgICBUaGlzLT5yZXNvdXJjZS5zaXplID0gKChtYXgoVGhpcy0+cG93MldpZHRoLCA0KSAqIGZvcm1hdEVudHJ5LT5icHApICogbWF4KFRoaXMtPnBvdzJIZWlnaHQsIDQpKSA+PiAxOwoKICAgIH0gZWxzZSBpZiAoZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMiB8fCBmb3JtYXQgPT0gV0lORUQzREZNVF9EWFQzIHx8CiAgICAgICAgICAgICAgIGZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDQgfHwgZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNSkgewogICAgICAgIFRoaXMtPnJlc291cmNlLnNpemUgPSAoKG1heChUaGlzLT5wb3cyV2lkdGgsIDQpICogZm9ybWF0RW50cnktPmJwcCkgKiBtYXgoVGhpcy0+cG93MkhlaWdodCwgNCkpOwogICAgfSBlbHNlIHsKICAgICAgICBUaGlzLT5yZXNvdXJjZS5zaXplID0gKChUaGlzLT5wb3cyV2lkdGggKiBmb3JtYXRFbnRyeS0+YnBwKSArIFNVUkZBQ0VfQUxJR05NRU5UIC0gMSkgJiB+KFNVUkZBQ0VfQUxJR05NRU5UIC0gMSk7CiAgICAgICAgVGhpcy0+cmVzb3VyY2Uuc2l6ZSAqPSBUaGlzLT5wb3cySGVpZ2h0OwogICAgfQoKCiAgICAvKiBTZXR1cCBzb21lIGdsZm9ybWF0IGRlZmF1bHRzICovCiAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0ICAgICAgICAgPSBmb3JtYXRFbnRyeS0+Z2xGb3JtYXQ7CiAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0SW50ZXJuYWwgPSBmb3JtYXRFbnRyeS0+Z2xJbnRlcm5hbDsKICAgIFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xUeXBlICAgICAgICAgICA9IGZvcm1hdEVudHJ5LT5nbFR5cGU7CgogICAgaWYgKGZvcm1hdCAhPSBXSU5FRDNERk1UX1VOS05PV04pIHsKICAgICAgICBUaGlzLT5ieXRlc1BlclBpeGVsID0gZm9ybWF0RW50cnktPmJwcDsKICAgIH0gZWxzZSB7CiAgICAgICAgVGhpcy0+Ynl0ZXNQZXJQaXhlbCA9IDA7CiAgICB9CgogICAgVGhpcy0+RmxhZ3MgfD0gKFdJTkVEM0RGTVRfRDE2X0xPQ0tBQkxFID09IGZvcm1hdCkgPyBTRkxBR19MT0NLQUJMRSA6IDA7CgogICAgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID0gZm9ybWF0OwoKICAgIFRSQUNFKCIoJXApIDogU2l6ZSAlZCwgYnl0ZXNQZXJQaXhlbCAlZCwgZ2xGb3JtYXQgJWQsIGdsRm90bWF0SW50ZXJuYWwgJWQsIGdsVHlwZSAlZFxuIiwgVGhpcywgVGhpcy0+cmVzb3VyY2Uuc2l6ZSwgVGhpcy0+Ynl0ZXNQZXJQaXhlbCwgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdCwgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdEludGVybmFsLCBUaGlzLT5nbERlc2NyaXB0aW9uLmdsVHlwZSk7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0TWVtKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIHZvaWQgKk1lbSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwoKICAgIC8qIFJlbmRlciB0YXJnZXRzIGRlcGVuZCBvbiB0aGVpciBoZGMsIGFuZCB3ZSBjYW4ndCBjcmVhdGUgYSBoZGMgb24gYSB1c2VyIHBvaW50ZXIgKi8KICAgIGlmKFRoaXMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkgewogICAgICAgIEVSUigiTm90IHN1cHBvcnRlZCBvbiByZW5kZXIgdGFyZ2V0c1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgaWYoVGhpcy0+RmxhZ3MgJiAoU0ZMQUdfTE9DS0VEIHwgU0ZMQUdfRENJTlVTRSkpIHsKICAgICAgICBXQVJOKCJTdXJmYWNlIGlzIGxvY2tlZCBvciB0aGUgSERDIGlzIGluIHVzZVxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgaWYoTWVtICYmIE1lbSAhPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpIHsKCiAgICAgICAgLyogRG8gSSBoYXZlIHRvIGNvcHkgdGhlIG9sZCBzdXJmYWNlIGNvbnRlbnQ/ICovCiAgICAgICAgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19ESUJTRUNUSU9OKSB7CiAgICAgICAgICAgICAgICAvKiBSZWxlYXNlIHRoZSBEQy4gTm8gbmVlZCB0byBob2xkIHRoZSBjcml0aWNhbCBzZWN0aW9uIGZvciB0aGUgdXBkYXRlCiAgICAgICAgICAgICAgICAgKiBUaHJlYWQgYmVjYXVzZSB0aGlzIHRocmVhZCBydW5zIG9ubHkgb24gZnJvbnQgYnVmZmVycywgYnV0IHRoaXMgbWV0aG9kCiAgICAgICAgICAgICAgICAgKiBmYWlscyBmb3IgcmVuZGVyIHRhcmdldHMgaW4gdGhlIGNoZWNrIGFib3ZlLgogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBTZWxlY3RPYmplY3QoVGhpcy0+aERDLCBUaGlzLT5kaWIuaG9sZGJpdG1hcCk7CiAgICAgICAgICAgICAgICBEZWxldGVEQyhUaGlzLT5oREMpOwogICAgICAgICAgICAgICAgLyogUmVsZWFzZSB0aGUgRElCIHNlY3Rpb24gKi8KICAgICAgICAgICAgICAgIERlbGV0ZU9iamVjdChUaGlzLT5kaWIuRElCc2VjdGlvbik7CiAgICAgICAgICAgICAgICBUaGlzLT5kaWIuYml0bWFwX2RhdGEgPSBOVUxMOwogICAgICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gTlVMTDsKICAgICAgICAgICAgICAgIFRoaXMtPmhEQyA9IE5VTEw7CiAgICAgICAgICAgICAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfRElCU0VDVElPTjsKICAgICAgICB9IGVsc2UgaWYoIShUaGlzLT5GbGFncyAmIFNGTEFHX1VTRVJQVFIpKSB7CiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSk7CiAgICAgICAgfQogICAgICAgIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IE1lbTsKICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19VU0VSUFRSOwogICAgfSBlbHNlIGlmKFRoaXMtPkZsYWdzICYgU0ZMQUdfVVNFUlBUUikgewogICAgICAgIC8qIExvY2tyZWN0IGFuZCBHZXREQyB3aWxsIHJlLWNyZWF0ZSB0aGUgZGliIHNlY3Rpb24gYW5kIGFsbG9jYXRlZCBtZW1vcnkgKi8KICAgICAgICBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgPSBOVUxMOwogICAgICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19VU0VSUFRSOwogICAgfQogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qIFRPRE86IHJlcGxhY2UgdGhpcyBmdW5jdGlvbiB3aXRoIGNvbnRleHQgbWFuYWdlbWVudCByb3V0aW5lcyAqLwpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1NldFBCdWZmZXJTdGF0ZShJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBCT09MIGluUEJ1ZmZlciwgQk9PTCAgaW5UZXh0dXJlKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKCiAgICBpZihpblBCdWZmZXIpIHsKICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19JTlBCVUZGRVI7CiAgICB9IGVsc2UgewogICAgICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19JTlBCVUZGRVI7CiAgICB9CgogICAgaWYoaW5UZXh0dXJlKSB7CiAgICAgICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfSU5URVhUVVJFOwogICAgfSBlbHNlIHsKICAgICAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfSU5URVhUVVJFOwogICAgfQoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9GbGlwKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIElXaW5lRDNEU3VyZmFjZSAqb3ZlcnJpZGUsIERXT1JEIEZsYWdzKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNERGV2aWNlICpEM0QgPSAoSVdpbmVEM0REZXZpY2UgKikgVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZTsKICAgIFRSQUNFKCIoJXApLT4oJXAsJXgpXG4iLCBUaGlzLCBvdmVycmlkZSwgRmxhZ3MpOwoKICAgIC8qIEZsaXBwaW5nIGlzIG9ubHkgc3VwcG9ydGVkIG9uIFJlbmRlclRhcmdldHMgKi8KICAgIGlmKCAhKFRoaXMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkgKSByZXR1cm4gRERFUlJfTk9URkxJUFBBQkxFOwoKICAgIGlmKG92ZXJyaWRlKSB7CiAgICAgICAgLyogRERyYXcgc2V0cyB0aGlzIGZvciB0aGUgWDExIHN1cmZhY2VzLCBzbyBkb24ndCBjb25mdXNlIHRoZSB1c2VyIAogICAgICAgICAqIEZJWE1FKCIoJXApIFRhcmdldCBvdmVycmlkZSBpcyBub3Qgc3VwcG9ydGVkIGJ5IG5vd1xuIiwgVGhpcyk7CiAgICAgICAgICogQWRkaXRpb25hbGx5LCBpdCBpc24ndCByZWFsbHkgcG9zc2libGUgdG8gc3VwcG9ydCB0cmlwbGUtYnVmZmVyaW5nCiAgICAgICAgICogcHJvcGVybHkgb24gb3BlbmdsIGF0IGFsbAogICAgICAgICAqLwogICAgfQoKICAgIC8qIEZsaXBwaW5nIGEgT3BlbkdMIHN1cmZhY2UgLT4gVXNlIFdpbmVEM0REZXZpY2U6OlByZXNlbnQgKi8KICAgIHJldHVybiBJV2luZUQzRERldmljZV9QcmVzZW50KEQzRCwgTlVMTCwgTlVMTCwgMCwgTlVMTCk7Cn0KCi8qIERvZXMgYSBkaXJlY3QgZnJhbWUgYnVmZmVyIC0+IHRleHR1cmUgY29weS4gU3RyZXRjaGluZyBpcyBkb25lCiAqIHdpdGggc2luZ2xlIHBpeGVsIGNvcHkgY2FsbHMKICovCnN0YXRpYyBpbmxpbmUgdm9pZCBmYl9jb3B5X3RvX3RleHR1cmVfZGlyZWN0KElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMsIElXaW5lRDNEU3VyZmFjZSAqU3JjU3VyZmFjZSwgSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICpzd2FwY2hhaW4sIFdJTkVEM0RSRUNUICpzcmVjdCwgV0lORUQzRFJFQ1QgKmRyZWN0LCBCT09MIHVwc2lkZWRvd24pIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqbXlEZXZpY2UgPSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOwogICAgZmxvYXQgeHJlbCwgeXJlbDsKICAgIFVJTlQgcm93OwogICAgQk9PTCB3YXJuZWQgPSBGQUxTRTsgLyogZGVsaWJlcmF0ZWx5IG5vdCBzdGF0aWMgKi8KICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlNyYyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIFNyY1N1cmZhY2U7CgogICAgRU5URVJfR0woKTsKCiAgICBBY3RpdmF0ZUNvbnRleHQobXlEZXZpY2UsIFNyY1N1cmZhY2UsIENUWFVTQUdFX0JMSVQpOwoKICAgIC8qIEJpbmQgdGhlIHRhcmdldCB0ZXh0dXJlICovCiAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIFRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpOwogICAgY2hlY2tHTGNhbGwoImdsQmluZFRleHR1cmUiKTsKICAgIGlmKCFzd2FwY2hhaW4gfHwgKHN3YXBjaGFpbi0+YmFja0J1ZmZlciAmJiBTcmNTdXJmYWNlID09IHN3YXBjaGFpbi0+YmFja0J1ZmZlclswXSkpIHsKICAgICAgICBnbFJlYWRCdWZmZXIoR0xfQkFDSyk7CiAgICB9IGVsc2UgewogICAgICAgIGdsUmVhZEJ1ZmZlcihHTF9GUk9OVCk7CiAgICB9CiAgICBjaGVja0dMY2FsbCgiZ2xSZWFkQnVmZmVyIik7CgogICAgeHJlbCA9IChmbG9hdCkgKHNyZWN0LT54MiAtIHNyZWN0LT54MSkgLyAoZmxvYXQpIChkcmVjdC0+eDIgLSBkcmVjdC0+eDEpOwogICAgeXJlbCA9IChmbG9hdCkgKHNyZWN0LT55MiAtIHNyZWN0LT55MSkgLyAoZmxvYXQpIChkcmVjdC0+eTIgLSBkcmVjdC0+eTEpOwoKICAgIGlmKCAoeHJlbCAtIDEuMCA8IC1lcHMpIHx8ICh4cmVsIC0gMS4wID4gZXBzKSkgewogICAgICAgIEZJWE1FKCJEb2luZyBhIHBpeGVsIGJ5IHBpeGVsIGNvcHkgZnJvbSB0aGUgZnJhbWVidWZmZXIgdG8gYSB0ZXh0dXJlLCBleHBlY3QgbWFqb3IgcGVyZm9ybWFuY2UgaXNzdWVzXG4iKTsKICAgIH0KCiAgICBpZih1cHNpZGVkb3duICYmCiAgICAgICAhKCh4cmVsIC0gMS4wIDwgLWVwcykgfHwgKHhyZWwgLSAxLjAgPiBlcHMpKSAmJgogICAgICAgISgoeXJlbCAtIDEuMCA8IC1lcHMpIHx8ICh5cmVsIC0gMS4wID4gZXBzKSkpIHsKICAgICAgICAvKiBVcHNpZGUgZG93biBjb3B5IHdpdGhvdXQgc3RyZXRjaGluZyBpcyBuaWNlLCBvbmUgZ2xDb3B5VGV4U3ViSW1hZ2UgY2FsbCB3aWxsIGRvICovCgogICAgICAgIGdsQ29weVRleFN1YkltYWdlMkQoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZHJlY3QtPngxLCBkcmVjdC0+eTEsIC8qIHhvZmZzZXQsIHlvZmZzZXQgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNyZWN0LT54MSwgU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQgLSBzcmVjdC0+eTIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcmVjdC0+eDIgLSBkcmVjdC0+eDEsIGRyZWN0LT55MiAtIGRyZWN0LT55MSk7CiAgICB9IGVsc2UgewogICAgICAgIFVJTlQgeW9mZnNldCA9IFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0IC0gc3JlY3QtPnkxICsgZHJlY3QtPnkxIC0gMTsKICAgICAgICAvKiBJIGhhdmUgdG8gcHJvY2VzcyB0aGlzIHJvdyBieSByb3cgdG8gc3dhcCB0aGUgaW1hZ2UsCiAgICAgICAgICogb3RoZXJ3aXNlIGl0IHdvdWxkIGJlIHVwc2lkZSBkb3duLCBzbyBzdHJlY2hpbmcgaW4geSBkaXJlY3Rpb24KICAgICAgICAgKiBkb2Vzbid0IGNvc3QgZXh0cmEgdGltZQogICAgICAgICAqCiAgICAgICAgICogSG93ZXZlciwgc3RyZWNoaW5nIGluIHggZGlyZWN0aW9uIGNhbiBiZSBhdm9pZGVkIGlmIG5vdCBuZWNlc3NhcnkKICAgICAgICAgKi8KICAgICAgICBmb3Iocm93ID0gZHJlY3QtPnkxOyByb3cgPCBkcmVjdC0+eTI7IHJvdysrKSB7CiAgICAgICAgICAgIGlmKCAoeHJlbCAtIDEuMCA8IC1lcHMpIHx8ICh4cmVsIC0gMS4wID4gZXBzKSkgewogICAgICAgICAgICAgICAgLyogV2VsbCwgdGhhdCBzdHVmZiB3b3JrcywgYnV0IGl0J3MgdmVyeSBzbG93LgogICAgICAgICAgICAgICAgICogZmluZCBhIGJldHRlciB3YXkgaW5zdGVhZAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBVSU5UIGNvbDsKCiAgICAgICAgICAgICAgICBpZighd2FybmVkKSB7CiAgICAgICAgICAgICAgICAgICAgd2FybmVkID0gVFJVRTsKICAgICAgICAgICAgICAgICAgICBGSVhNRSgiRG9pbmcgYSBwaXhlbCBieSBwaXhlbCByZW5kZXIgdGFyZ2V0IC0+IHRleHR1cmUgY29weSwgZXhwZWN0IHBlcmZvcm1hbmNlIGlzc3Vlc1xuIik7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgZm9yKGNvbCA9IGRyZWN0LT54MTsgY29sIDwgZHJlY3QtPngyOyBjb2wrKykgewogICAgICAgICAgICAgICAgICAgIGdsQ29weVRleFN1YkltYWdlMkQoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHJlY3QtPngxICsgY29sLCByb3csIC8qIHhvZmZzZXQsIHlvZmZzZXQgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNyZWN0LT54MSArIGNvbCAqIHhyZWwsIHlvZmZzZXQgLSAoaW50KSAocm93ICogeXJlbCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLCAxKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGdsQ29weVRleFN1YkltYWdlMkQoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRyZWN0LT54MSwgcm93LCAvKiB4b2Zmc2V0LCB5b2Zmc2V0ICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNyZWN0LT54MSwgeW9mZnNldCAtIChpbnQpIChyb3cgKiB5cmVsKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHJlY3QtPngyLWRyZWN0LT54MSwgMSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgdmNoZWNrR0xjYWxsKCJnbENvcHlUZXhTdWJJbWFnZTJEIik7CiAgICBMRUFWRV9HTCgpOwp9CgovKiBVc2VzIHRoZSBoYXJkd2FyZSB0byBzdHJldGNoIGFuZCBmbGlwIHRoZSBpbWFnZSAqLwpzdGF0aWMgaW5saW5lIHZvaWQgZmJfY29weV90b190ZXh0dXJlX2h3c3RyZXRjaChJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzLCBJV2luZUQzRFN1cmZhY2UgKlNyY1N1cmZhY2UsIElXaW5lRDNEU3dhcENoYWluSW1wbCAqc3dhcGNoYWluLCBXSU5FRDNEUkVDVCAqc3JlY3QsIFdJTkVEM0RSRUNUICpkcmVjdCwgQk9PTCB1cHNpZGVkb3duKSB7CiAgICBHTHVpbnQgYmFja3VwLCBzcmM7CiAgICBJV2luZUQzRERldmljZUltcGwgKm15RGV2aWNlID0gVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZTsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlNyYyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIFNyY1N1cmZhY2U7CiAgICBmbG9hdCBsZWZ0LCByaWdodCwgdG9wLCBib3R0b207IC8qIFRleHR1cmUgY29vcmRpbmF0ZXMgKi8KICAgIFVJTlQgZmJ3aWR0aCA9IFNyYy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICBVSU5UIGZiaGVpZ2h0ID0gU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQ7CgogICAgVFJBQ0UoIlVzaW5nIGh3c3RyZXRjaCBibGl0XG4iKTsKICAgIC8qIEFjdGl2YXRlIHRoZSBQcm9wZXIgY29udGV4dCBmb3IgcmVhZGluZyBmcm9tIHRoZSBzb3VyY2Ugc3VyZmFjZSwgc2V0IGl0IHVwIGZvciBibGl0dGluZyAqLwogICAgRU5URVJfR0woKTsKICAgIEFjdGl2YXRlQ29udGV4dChteURldmljZSwgU3JjU3VyZmFjZSwgQ1RYVVNBR0VfQkxJVCk7CgogICAgLyogQmFja3VwIHRoZSBiYWNrIGJ1ZmZlciBhbmQgY29weSB0aGUgc291cmNlIGJ1ZmZlciBpbnRvIGEgdGV4dHVyZSB0byBkcmF3IGFuIHVwc2lkZSBkb3duIHN0cmV0Y2hlZCBxdWFkLiBJZgogICAgICogd2UgYXJlIHJlYWRpbmcgZnJvbSB0aGUgYmFjayBidWZmZXIsIHRoZSBiYWNrdXAgY2FuIGJlIHVzZWQgYXMgc291cmNlIHRleHR1cmUKICAgICAqLwogICAgZ2xHZW5UZXh0dXJlcygxLCAmYmFja3VwKTsKICAgIGNoZWNrR0xjYWxsKCJnbEdlblRleHR1cmVzKDEsICZiYWNrdXApIik7CiAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIGJhY2t1cCk7CiAgICBjaGVja0dMY2FsbCgiZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCBiYWNrdXApIik7CgogICAgZ2xSZWFkQnVmZmVyKEdMX0JBQ0spOwogICAgY2hlY2tHTGNhbGwoImdsUmVhZEJ1ZmZlcihHTF9CQUNLKSIpOwoKICAgIC8qIFRPRE86IE9ubHkgYmFjayB1cCB0aGUgcGFydCB0aGF0IHdpbGwgYmUgb3ZlcndyaXR0ZW4gKi8KICAgIGdsVGV4SW1hZ2UyRChHTF9URVhUVVJFXzJELCAwLCBHTF9SR0JBLCBTcmMtPnBvdzJXaWR0aCwgU3JjLT5wb3cySGVpZ2h0LCAwLAogICAgICAgICAgICAgICAgIEdMX1JHQkEsIEdMX1VOU0lHTkVEX0JZVEUsIE5VTEwpOwogICAgY2hlY2tHTGNhbGwoImdsVGV4SW1hZ2UyRCIpOwoKICAgIGdsQ29weVRleFN1YkltYWdlMkQoR0xfVEVYVFVSRV8yRCwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCAvKiByZWFkIG9mZnNldHMgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgIGZid2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgIGZiaGVpZ2h0KTsKCiAgICBjaGVja0dMY2FsbCgiZ2xDb3B5VGV4U3ViSW1hZ2UyRCIpOwoKICAgIGdsVGV4UGFyYW1ldGVyaShHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX01BR19GSUxURVIsIEdMX05FQVJFU1QpOwogICAgY2hlY2tHTGNhbGwoImdsVGV4UGFyYW1ldGVyaSIpOwogICAgZ2xUZXhQYXJhbWV0ZXJpKEdMX1RFWFRVUkVfMkQsIEdMX1RFWFRVUkVfTUlOX0ZJTFRFUiwgR0xfTkVBUkVTVCk7CiAgICBjaGVja0dMY2FsbCgiZ2xUZXhQYXJhbWV0ZXJpIik7CgogICAgaWYoIXN3YXBjaGFpbiB8fCAoSVdpbmVEM0RTdXJmYWNlICopIFRoaXMgPT0gc3dhcGNoYWluLT5iYWNrQnVmZmVyWzBdKSB7CiAgICAgICAgc3JjID0gYmFja3VwOwogICAgfSBlbHNlIHsKICAgICAgICBnbFJlYWRCdWZmZXIoR0xfRlJPTlQpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbFJlYWRCdWZmZXIoR0xfRlJPTlQpIik7CgogICAgICAgIGdsR2VuVGV4dHVyZXMoMSwgJnNyYyk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsR2VuVGV4dHVyZXMoMSwgJnNyYykiKTsKICAgICAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIHNyYyk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgc3JjKSIpOwoKICAgICAgICAvKiBUT0RPOiBPbmx5IGNvcHkgdGhlIHBhcnQgdGhhdCB3aWxsIGJlIHJlYWQuIFVzZSBzcmVjdC0+eDEsIHNyZWN0LT55MiBhcyBvcmlnaW4sIGJ1dCB3aXRoIHRoZSB3aWR0aCB3YXRjaAogICAgICAgICAqIG91dCBmb3IgcG93ZXIgb2YgMiBzaXplcwogICAgICAgICAqLwogICAgICAgIGdsVGV4SW1hZ2UyRChHTF9URVhUVVJFXzJELCAwLCBHTF9SR0JBLCBTcmMtPnBvdzJXaWR0aCwgU3JjLT5wb3cySGVpZ2h0LCAwLAogICAgICAgICAgICAgICAgICAgIEdMX1JHQkEsIEdMX1VOU0lHTkVEX0JZVEUsIE5VTEwpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbFRleEltYWdlMkQiKTsKICAgICAgICBnbENvcHlUZXhTdWJJbWFnZTJEKEdMX1RFWFRVUkVfMkQsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAwIC8qIHJlYWQgb2Zmc2V0cyAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYndpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmJoZWlnaHQpOwoKICAgICAgICBnbFRleFBhcmFtZXRlcmkoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9NQUdfRklMVEVSLCBHTF9ORUFSRVNUKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xUZXhQYXJhbWV0ZXJpIik7CiAgICAgICAgZ2xUZXhQYXJhbWV0ZXJpKEdMX1RFWFRVUkVfMkQsIEdMX1RFWFRVUkVfTUlOX0ZJTFRFUiwgR0xfTkVBUkVTVCk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsVGV4UGFyYW1ldGVyaSIpOwoKICAgICAgICBnbFJlYWRCdWZmZXIoR0xfQkFDSyk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsUmVhZEJ1ZmZlcihHTF9CQUNLKSIpOwogICAgfQogICAgY2hlY2tHTGNhbGwoImdsRW5kIGFuZCBwcmV2aW91cyIpOwoKICAgIGxlZnQgPSAoZmxvYXQpIHNyZWN0LT54MSAvIChmbG9hdCkgU3JjLT5wb3cyV2lkdGg7CiAgICByaWdodCA9IChmbG9hdCkgc3JlY3QtPngyIC8gKGZsb2F0KSBTcmMtPnBvdzJXaWR0aDsKCiAgICBpZih1cHNpZGVkb3duKSB7CiAgICAgICAgdG9wID0gKGZsb2F0KSAoU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQgLSBzcmVjdC0+eTEpIC8gKGZsb2F0KSBTcmMtPnBvdzJIZWlnaHQ7CiAgICAgICAgYm90dG9tID0gKGZsb2F0KSAoU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQgLSBzcmVjdC0+eTIpIC8gKGZsb2F0KSBTcmMtPnBvdzJIZWlnaHQ7CiAgICB9IGVsc2UgewogICAgICAgIHRvcCA9IChmbG9hdCkgKFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0IC0gc3JlY3QtPnkyKSAvIChmbG9hdCkgU3JjLT5wb3cySGVpZ2h0OwogICAgICAgIGJvdHRvbSA9IChmbG9hdCkgKFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0IC0gc3JlY3QtPnkxKSAvIChmbG9hdCkgU3JjLT5wb3cySGVpZ2h0OwogICAgfQoKICAgIC8qIGRyYXcgdGhlIHNvdXJjZSB0ZXh0dXJlIHN0cmV0Y2hlZCBhbmQgdXBzaWRlIGRvd24uIFRoZSBjb3JyZWN0IHN1cmZhY2UgaXMgYm91bmQgYWxyZWFkeSAqLwogICAgZ2xUZXhQYXJhbWV0ZXJpKEdMX1RFWFRVUkVfMkQsIEdMX1RFWFRVUkVfV1JBUF9TLCBHTF9DTEFNUCk7CiAgICBnbFRleFBhcmFtZXRlcmkoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9XUkFQX1QsIEdMX0NMQU1QKTsKCiAgICBnbEJlZ2luKEdMX1FVQURTKTsKICAgICAgICAvKiBib3R0b20gbGVmdCAqLwogICAgICAgIGdsVGV4Q29vcmQyZihsZWZ0LCBib3R0b20pOwogICAgICAgIGdsVmVydGV4MmkoMCwgZmJoZWlnaHQpOwoKICAgICAgICAvKiB0b3AgbGVmdCAqLwogICAgICAgIGdsVGV4Q29vcmQyZihsZWZ0LCB0b3ApOwogICAgICAgIGdsVmVydGV4MmkoMCwgZmJoZWlnaHQgLSBkcmVjdC0+eTIgLSBkcmVjdC0+eTEpOwoKICAgICAgICAvKiB0b3AgcmlnaHQgKi8KICAgICAgICBnbFRleENvb3JkMmYocmlnaHQsIHRvcCk7CiAgICAgICAgZ2xWZXJ0ZXgyaShkcmVjdC0+eDIgLSBkcmVjdC0+eDEsIGZiaGVpZ2h0IC0gZHJlY3QtPnkyIC0gZHJlY3QtPnkxKTsKCiAgICAgICAgLyogYm90dG9tIHJpZ2h0ICovCiAgICAgICAgZ2xUZXhDb29yZDJmKHJpZ2h0LCBib3R0b20pOwogICAgICAgIGdsVmVydGV4MmkoZHJlY3QtPngyIC0gZHJlY3QtPngxLCBmYmhlaWdodCk7CiAgICBnbEVuZCgpOwogICAgY2hlY2tHTGNhbGwoImdsRW5kIGFuZCBwcmV2aW91cyIpOwoKICAgIC8qIE5vdyByZWFkIHRoZSBzdHJldGNoZWQgYW5kIHVwc2lkZSBkb3duIGltYWdlIGludG8gdGhlIGRlc3RpbmF0aW9uIHRleHR1cmUgKi8KICAgIGdsQmluZFRleHR1cmUoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsIFRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpOwogICAgY2hlY2tHTGNhbGwoImdsQmluZFRleHR1cmUiKTsKICAgIGdsQ29weVRleFN1YkltYWdlMkQoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgICAgICAgIGRyZWN0LT54MSwgZHJlY3QtPnkxLCAvKiB4b2Zmc2V0LCB5b2Zmc2V0ICovCiAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsIC8qIFdlIGJsaXR0ZWQgdGhlIGltYWdlIHRvIHRoZSBvcmlnaW4gKi8KICAgICAgICAgICAgICAgICAgICAgICAgZHJlY3QtPngyIC0gZHJlY3QtPngxLCBkcmVjdC0+eTIgLSBkcmVjdC0+eTEpOwogICAgY2hlY2tHTGNhbGwoImdsQ29weVRleFN1YkltYWdlMkQiKTsKCiAgICAvKiBXcml0ZSB0aGUgYmFjayBidWZmZXIgYmFja3VwIGJhY2sgKi8KICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgYmFja3VwKTsKICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIGJhY2t1cCkiKTsKCiAgICBnbEJlZ2luKEdMX1FVQURTKTsKICAgICAgICAvKiB0b3AgbGVmdCAqLwogICAgICAgIGdsVGV4Q29vcmQyZigwLjAsIChmbG9hdCkgZmJoZWlnaHQgLyAoZmxvYXQpIFNyYy0+cG93MkhlaWdodCk7CiAgICAgICAgZ2xWZXJ0ZXgyaSgwLCAwKTsKCiAgICAgICAgLyogYm90dG9tIGxlZnQgKi8KICAgICAgICBnbFRleENvb3JkMmYoMC4wLCAwLjApOwogICAgICAgIGdsVmVydGV4MmkoMCwgZmJoZWlnaHQpOwoKICAgICAgICAvKiBib3R0b20gcmlnaHQgKi8KICAgICAgICBnbFRleENvb3JkMmYoKGZsb2F0KSBmYndpZHRoIC8gKGZsb2F0KSBTcmMtPnBvdzJXaWR0aCwgMC4wKTsKICAgICAgICBnbFZlcnRleDJpKGZid2lkdGgsIFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0KTsKCiAgICAgICAgLyogdG9wIHJpZ2h0ICovCiAgICAgICAgZ2xUZXhDb29yZDJmKChmbG9hdCkgZmJ3aWR0aCAvIChmbG9hdCkgU3JjLT5wb3cyV2lkdGgsIChmbG9hdCkgZmJoZWlnaHQgLyAoZmxvYXQpIFNyYy0+cG93MkhlaWdodCk7CiAgICAgICAgZ2xWZXJ0ZXgyaShmYndpZHRoLCAwKTsKICAgIGdsRW5kKCk7CgogICAgLyogQ2xlYW51cCAqLwogICAgaWYoc3JjICE9IGJhY2t1cCkgewogICAgICAgIGdsRGVsZXRlVGV4dHVyZXMoMSwgJnNyYyk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRGVsZXRlVGV4dHVyZXMoMSwgJnNyYykiKTsKICAgIH0KICAgIGdsRGVsZXRlVGV4dHVyZXMoMSwgJmJhY2t1cCk7CiAgICBjaGVja0dMY2FsbCgiZ2xEZWxldGVUZXh0dXJlcygxLCAmYmFja3VwKSIpOwogICAgTEVBVkVfR0woKTsKfQoKLyogTm90IGNhbGxlZCBmcm9tIHRoZSBWVGFibGUgKi8Kc3RhdGljIEhSRVNVTFQgSVdpbmVEM0RTdXJmYWNlSW1wbF9CbHRPdmVycmlkZShJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzLCBSRUNUICpEZXN0UmVjdCwgSVdpbmVEM0RTdXJmYWNlICpTcmNTdXJmYWNlLCBSRUNUICpTcmNSZWN0LCBEV09SRCBGbGFncywgRERCTFRGWCAqRERCbHRGeCkgewogICAgV0lORUQzRFJFQ1QgcmVjdDsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqbXlEZXZpY2UgPSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOwogICAgSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICpzcmNTd2FwY2hhaW4gPSBOVUxMLCAqZHN0U3dhcGNoYWluID0gTlVMTDsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlNyYyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIFNyY1N1cmZhY2U7CiAgICBCT09MIFNyY09LID0gVFJVRTsKCiAgICBUUkFDRSgiKCVwKS0+KCVwLCVwLCVwLCUwOHgsJXApXG4iLCBUaGlzLCBEZXN0UmVjdCwgU3JjU3VyZmFjZSwgU3JjUmVjdCwgRmxhZ3MsIEREQmx0RngpOwoKICAgIC8qIEdldCB0aGUgc3dhcGNoYWluLiBPbmUgb2YgdGhlIHN1cmZhY2VzIGhhcyB0byBiZSBhIHByaW1hcnkgc3VyZmFjZSAqLwogICAgSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lciggKElXaW5lRDNEU3VyZmFjZSAqKSBUaGlzLCAmSUlEX0lXaW5lRDNEU3dhcENoYWluLCAodm9pZCAqKikmZHN0U3dhcGNoYWluKTsKICAgIGlmKGRzdFN3YXBjaGFpbikgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZSgoSVdpbmVEM0RTd2FwQ2hhaW4gKikgZHN0U3dhcGNoYWluKTsKICAgIGlmKFNyYykgewogICAgICAgIElXaW5lRDNEU3VyZmFjZV9HZXRDb250YWluZXIoIChJV2luZUQzRFN1cmZhY2UgKikgU3JjLCAmSUlEX0lXaW5lRDNEU3dhcENoYWluLCAodm9pZCAqKikmc3JjU3dhcGNoYWluKTsKICAgICAgICBpZihzcmNTd2FwY2hhaW4pIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2UoKElXaW5lRDNEU3dhcENoYWluICopIHNyY1N3YXBjaGFpbik7CiAgICB9CgogICAgLyogRWFybHkgc29ydCBvdXQgb2YgY2FzZXMgd2hlcmUgbm8gcmVuZGVyIHRhcmdldCBpcyB1c2VkICovCiAgICBpZighZHN0U3dhcGNoYWluICYmICFzcmNTd2FwY2hhaW4gJiYKICAgICAgICBTcmNTdXJmYWNlICE9IG15RGV2aWNlLT5yZW5kZXJfdGFyZ2V0c1swXSAmJiBUaGlzICE9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIG15RGV2aWNlLT5yZW5kZXJfdGFyZ2V0c1swXSkgewogICAgICAgIFRSQUNFKCJObyBzdXJmYWNlIGlzIHJlbmRlciB0YXJnZXQsIG5vdCB1c2luZyBoYXJkd2FyZSBibGl0LiBTcmMgPSAlcCwgZHN0ID0gJXBcbiIsIFNyYywgVGhpcyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgLyogTm8gZGVzdGluYXRpb24gY29sb3Iga2V5aW5nIHN1cHBvcnRlZCAqLwogICAgaWYoRmxhZ3MgJiAoRERCTFRfS0VZREVTVCB8IEREQkxUX0tFWURFU1RPVkVSUklERSkpIHsKICAgICAgICAvKiBDYW4gd2Ugc3VwcG9ydCB0aGF0IHdpdGggZ2xCbGVuZEZ1bmMgaWYgYmxpdHRpbmcgdG8gdGhlIGZyYW1lIGJ1ZmZlcj8gKi8KICAgICAgICBUUkFDRSgiRGVzdGluYXRpb24gY29sb3Iga2V5IG5vdCBzdXBwb3J0ZWQgaW4gYWNjZWxlcmF0ZWQgQmxpdCwgZmFsbGluZyBiYWNrIHRvIHNvZnR3YXJlXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBpZiAoRGVzdFJlY3QpIHsKICAgICAgICByZWN0LngxID0gRGVzdFJlY3QtPmxlZnQ7CiAgICAgICAgcmVjdC55MSA9IERlc3RSZWN0LT50b3A7CiAgICAgICAgcmVjdC54MiA9IERlc3RSZWN0LT5yaWdodDsKICAgICAgICByZWN0LnkyID0gRGVzdFJlY3QtPmJvdHRvbTsKICAgIH0gZWxzZSB7CiAgICAgICAgcmVjdC54MSA9IDA7CiAgICAgICAgcmVjdC55MSA9IDA7CiAgICAgICAgcmVjdC54MiA9IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoOwogICAgICAgIHJlY3QueTIgPSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICB9CgogICAgLyogVGhlIG9ubHkgY2FzZSB3aGVyZSBib3RoIHN1cmZhY2VzIG9uIGEgc3dhcGNoYWluIGFyZSBzdXBwb3J0ZWQgaXMgYSBiYWNrIGJ1ZmZlciAtPiBmcm9udCBidWZmZXIgYmxpdCBvbiB0aGUgc2FtZSBzd2FwY2hhaW4gKi8KICAgIGlmKGRzdFN3YXBjaGFpbiAmJiBkc3RTd2FwY2hhaW4gPT0gc3JjU3dhcGNoYWluKSB7CiAgICAgICAgLyogSGFsZi1saWZlIGRvZXMgYSBCbHQgZnJvbSB0aGUgYmFjayBidWZmZXIgdG8gdGhlIGZyb250IGJ1ZmZlciwKICAgICAgICAgKiBGdWxsIHN1cmZhY2Ugc2l6ZSwgbm8gZmxhZ3MuLi4gVXNlIHByZXNlbnQgaW5zdGVhZAogICAgICAgICAqLwoKICAgICAgICAvKiBDaGVjayByZWN0cyAtIElXaW5lRDNERGV2aWNlX1ByZXNlbnQgZG9lc24ndCBoYW5kbGUgdGhlbSAqLwogICAgICAgIGlmKCBTcmNSZWN0ICkgewogICAgICAgICAgICBpZiggKFNyY1JlY3QtPmxlZnQgPT0gMCkgJiYgKFNyY1JlY3QtPnRvcCA9PSAwKSAmJgogICAgICAgICAgICAgICAgKFNyY1JlY3QtPnJpZ2h0ID09IFNyYy0+Y3VycmVudERlc2MuV2lkdGgpICYmIChTcmNSZWN0LT5ib3R0b20gPT0gU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQpICkgewogICAgICAgICAgICAgICAgU3JjT0sgPSBUUlVFOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgU3JjT0sgPSBUUlVFOwogICAgICAgIH0KCiAgICAgICAgLyogQ2hlY2sgdGhlIERlc3RpbmF0aW9uIHJlY3QgYW5kIHRoZSBzdXJmYWNlIHNpemVzICovCiAgICAgICAgaWYoU3JjT0sgJiYKICAgICAgICAgICAocmVjdC54MSA9PSAwKSAmJiAocmVjdC55MSA9PSAwKSAmJgogICAgICAgICAgIChyZWN0LngyID09ICBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCkgJiYgKHJlY3QueTIgPT0gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0KSAmJgogICAgICAgICAgIChUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCA9PSBTcmMtPmN1cnJlbnREZXNjLldpZHRoKSAmJgogICAgICAgICAgIChUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQgPT0gU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQpKSB7CiAgICAgICAgICAgIC8qIFRoZXNlIGZsYWdzIGFyZSB1bmltcG9ydGFudCBmb3IgdGhlIGZsYWcgY2hlY2ssIHJlbW92ZSB0aGVtICovCgogICAgICAgICAgICBpZigoRmxhZ3MgJiB+KEREQkxUX0RPTk9UV0FJVCB8IEREQkxUX1dBSVQpKSA9PSAwKSB7CiAgICAgICAgICAgICAgICBpZiggZHN0U3dhcGNoYWluLT5iYWNrQnVmZmVyICYmICgoSVdpbmVEM0RTdXJmYWNlICopIFRoaXMgPT0gZHN0U3dhcGNoYWluLT5mcm9udEJ1ZmZlcikgJiYKICAgICAgICAgICAgICAgICAgICBTcmNTdXJmYWNlID09IGRzdFN3YXBjaGFpbi0+YmFja0J1ZmZlclswXSApIHsKCiAgICAgICAgICAgICAgICAgICAgV0lORUQzRFNXQVBFRkZFQ1Qgb3JpZ19zd2FwID0gZHN0U3dhcGNoYWluLT5wcmVzZW50UGFybXMuU3dhcEVmZmVjdDsKCiAgICAgICAgICAgICAgICAgICAgLyogVGhlIGlkZWEgYmVoaW5kIHRoaXMgaXMgdGhhdCBhIGdsUmVhZFBpeGVscyBhbmQgYSBnbERyYXdQaXhlbHMgY2FsbAogICAgICAgICAgICAgICAgICAgICAqIHRha2UgdmVyeSBsb25nLCB3aGlsZSBhIGZsaXAgaXMgZmFzdC4KICAgICAgICAgICAgICAgICAgICAgKiBUaGlzIGFwcGxpZXMgdG8gSGFsZi1MaWZlLCB3aGljaCBkb2VzIHN1Y2ggQmx0cyBldmVyeSB0aW1lIGl0IGZpbmlzaGVkCiAgICAgICAgICAgICAgICAgICAgICogYSBmcmFtZSwgYW5kIHRvIFByaW5jZSBvZiBQZXJzaWEgM0QsIHdoaWNoIHVzZXMgdGhpcyB0byBkcmF3IGF0IGxlYXN0IHRoZSBtYWluCiAgICAgICAgICAgICAgICAgICAgICogbWVudS4gVGhpcyBpcyBhbHNvIHVzZWQgYnkgYWxsIGFwcHMgd2hlbiB0aGV5IGRvIHdpbmRvd2VkIHJlbmRlcmluZwogICAgICAgICAgICAgICAgICAgICAqCiAgICAgICAgICAgICAgICAgICAgICogVGhlIHByb2JsZW0gaXMgdGhhdCBmbGlwcGluZyBpcyBub3QgcmVhbGx5IHRoZSBzYW1lIGFzIGNvcHlpbmcuIEFmdGVyIGEKICAgICAgICAgICAgICAgICAgICAgKiBCbHQgdGhlIGZyb250IGJ1ZmZlciBpcyBhIGNvcHkgb2YgdGhlIGJhY2sgYnVmZmVyLCBhbmQgdGhlIGJhY2sgYnVmZmVyIGlzCiAgICAgICAgICAgICAgICAgICAgICogdW50b3VjaGVkLiBUaGVyZWZvcmUgaXQncyBuZWNlc3NhcnkgdG8gb3ZlcnJpZGUgdGhlIHN3YXAgZWZmZWN0CiAgICAgICAgICAgICAgICAgICAgICogYW5kIHRvIHNldCBpdCBiYWNrIGFmdGVyIHRoZSBmbGlwLgogICAgICAgICAgICAgICAgICAgICAqLwoKICAgICAgICAgICAgICAgICAgICBkc3RTd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5Td2FwRWZmZWN0ID0gV0lORUQzRFNXQVBFRkZFQ1RfQ09QWTsKCiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIkZ1bGwgc2NyZWVuIGJhY2sgYnVmZmVyIC0+IGZyb250IGJ1ZmZlciBibHQsIHBlcmZvcm1pbmcgYSBmbGlwIGluc3RlYWRcbiIpOwogICAgICAgICAgICAgICAgICAgIElXaW5lRDNERGV2aWNlX1ByZXNlbnQoKElXaW5lRDNERGV2aWNlICopIFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgTlVMTCwgMCwgTlVMTCk7CgogICAgICAgICAgICAgICAgICAgIGRzdFN3YXBjaGFpbi0+cHJlc2VudFBhcm1zLlN3YXBFZmZlY3QgPSBvcmlnX3N3YXA7CgogICAgICAgICAgICAgICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBUUkFDRSgiVW5zdXBwb3J0ZWQgYmxpdCBiZXR3ZWVuIGJ1ZmZlcnMgb24gdGhlIHNhbWUgc3dhcGNoYWluXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0gZWxzZSBpZigoZHN0U3dhcGNoYWluIHx8IFRoaXMgPT0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgbXlEZXZpY2UtPnJlbmRlcl90YXJnZXRzWzBdKSAmJgogICAgICAgICAgICAgIChzcmNTd2FwY2hhaW4gfHwgU3JjU3VyZmFjZSA9PSBteURldmljZS0+cmVuZGVyX3RhcmdldHNbMF0pICkgewogICAgICAgIEVSUigiQ2FuJ3QgcGVyZm9ybSBoYXJkd2FyZSBibGl0IGJldHdlZW4gMiBkaWZmZXJlbnQgc3dhcGNoYWlucywgZmFsbGluZyBiYWNrIHRvIHNvZnR3YXJlXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBpZihzcmNTd2FwY2hhaW4gfHwgU3JjU3VyZmFjZSA9PSBteURldmljZS0+cmVuZGVyX3RhcmdldHNbMF0pIHsKICAgICAgICAvKiBCbGl0IGZyb20gcmVuZGVyIHRhcmdldCB0byB0ZXh0dXJlICovCiAgICAgICAgV0lORUQzRFJFQ1Qgc3JlY3Q7CiAgICAgICAgQk9PTCB1cHNpZGVEb3duLCBzdHJldGNoeDsKCiAgICAgICAgaWYoRmxhZ3MgJiAoRERCTFRfS0VZU1JDIHwgRERCTFRfS0VZU1JDT1ZFUlJJREUpKSB7CiAgICAgICAgICAgIFRSQUNFKCJDb2xvciBrZXlpbmcgbm90IHN1cHBvcnRlZCBieSBmcmFtZSBidWZmZXIgdG8gdGV4dHVyZSBibGl0XG4iKTsKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICAgICAgICAgIC8qIERlc3RpbmF0aW9uIGNvbG9yIGtleSBpcyBjaGVja2VkIGFib3ZlICovCiAgICAgICAgfQoKICAgICAgICAvKiBDYWxsIHByZWxvYWQgZm9yIHRoZSBzdXJmYWNlIHRvIG1ha2Ugc3VyZSBpdCBpc24ndCBkaXJ0eSAqLwogICAgICAgIElXaW5lRDNEU3VyZmFjZV9QcmVMb2FkKChJV2luZUQzRFN1cmZhY2UgKikgVGhpcyk7CgogICAgICAgIC8qIE1ha2Ugc3VyZSB0aGF0IHRoZSB0b3AgcGl4ZWwgaXMgYWx3YXlzIGFib3ZlIHRoZSBib3R0b20gcGl4ZWwsIGFuZCBrZWVwIGEgc2VwZXJhdGUgdXBzaWRlIGRvd24gZmxhZwogICAgICAgICAgICAqIGdsQ29weVRleFN1YkltYWdlIGlzIGEgYml0IHBpY2t5IGFib3V0IHRoZSBwYXJhbWV0ZXJzIHdlIHBhc3MgdG8gaXQKICAgICAgICAgICAgKi8KICAgICAgICBpZihTcmNSZWN0KSB7CiAgICAgICAgICAgIGlmKFNyY1JlY3QtPnRvcCA8IFNyY1JlY3QtPmJvdHRvbSkgewogICAgICAgICAgICAgICAgc3JlY3QueTEgPSBTcmNSZWN0LT50b3A7CiAgICAgICAgICAgICAgICBzcmVjdC55MiA9IFNyY1JlY3QtPmJvdHRvbTsKICAgICAgICAgICAgICAgIHVwc2lkZURvd24gPSBGQUxTRTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHNyZWN0LnkxID0gU3JjUmVjdC0+Ym90dG9tOwogICAgICAgICAgICAgICAgc3JlY3QueTIgPSBTcmNSZWN0LT50b3A7CiAgICAgICAgICAgICAgICB1cHNpZGVEb3duID0gVFJVRTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzcmVjdC54MSA9IFNyY1JlY3QtPmxlZnQ7CiAgICAgICAgICAgIHNyZWN0LngyID0gU3JjUmVjdC0+cmlnaHQ7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3JlY3QueDEgPSAwOwogICAgICAgICAgICBzcmVjdC55MSA9IDA7CiAgICAgICAgICAgIHNyZWN0LngyID0gU3JjLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICAgICAgc3JlY3QueTIgPSBTcmMtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgICAgICAgICAgdXBzaWRlRG93biA9IEZBTFNFOwogICAgICAgIH0KICAgICAgICBpZihyZWN0LngxID4gcmVjdC54MikgewogICAgICAgICAgICBVSU5UIHRtcCA9IHJlY3QueDI7CiAgICAgICAgICAgIHJlY3QueDIgPSByZWN0LngxOwogICAgICAgICAgICByZWN0LngxID0gdG1wOwogICAgICAgICAgICB1cHNpZGVEb3duID0gIXVwc2lkZURvd247CiAgICAgICAgfQogICAgICAgIGlmKCFzcmNTd2FwY2hhaW4pIHsKICAgICAgICAgICAgVFJBQ0UoIlJlYWRpbmcgZnJvbSBhbiBvZmZzY3JlZW4gdGFyZ2V0XG4iKTsKICAgICAgICAgICAgdXBzaWRlRG93biA9ICF1cHNpZGVEb3duOwogICAgICAgIH0KCiAgICAgICAgaWYocmVjdC54MiAtIHJlY3QueDEgIT0gc3JlY3QueDIgLSBzcmVjdC54MSkgewogICAgICAgICAgICBzdHJldGNoeCA9IFRSVUU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3RyZXRjaHggPSBGQUxTRTsKICAgICAgICB9CgogICAgICAgIC8qIEJsdCBpcyBhIHByZXR0eSBwb3dlcmZ1bCBjYWxsLCB3aGlsZSBnbENvcHlUZXhTdWJJbWFnZTJEIGlzIG5vdC4gZ2xDb3B5VGV4U3ViSW1hZ2UgY2Fubm90CiAgICAgICAgICogZmxpcCB0aGUgaW1hZ2Ugbm9yIHNjYWxlIGl0LiBJZiBHTF9FWFRfZnJhbWVidWZmZXJfYmxpdCBpcyBhdmFpbGFibGUgaXQgY2FuIGJlIHVzZWQoaG9wZWZ1bGx5LAogICAgICAgICAqIG5vdCBpbXBsZW1lbnRlZCBieSBub3cpLiBPdGhlcndpc2U6CiAgICAgICAgICoKICAgICAgICAgKiAtPiBJZiB0aGUgYXBwIGFza3MgZm9yIGEgdW5zY2FsZWQsIHVwc2lkZSBkb3duIGNvcHksIGp1c3QgcGVyZm9ybSBvbmUgZ2xDb3B5VGV4U3ViSW1hZ2UyRCBjYWxsCiAgICAgICAgICogLT4gSWYgdGhlIGFwcCB3YW50cyBhIGltYWdlIHdpZHRoIGFuIHVuc2NhbGVkIHdpZHRoLCBjb3B5IGl0IGxpbmUgcGVyIGxpbmUKICAgICAgICAgKiAtPiBJZiB0aGUgYXBwIHdhbnRzIGEgaW1hZ2UgdGhhdCBpcyBzY2FsZWQgb24gdGhlIHggYXhpcywgYW5kIHRoZSBkZXN0aW5hdGlvbiByZWN0YW5nbGUgaXMgc21hbGxlcgogICAgICAgICAqICAgIHRoYW4gdGhlIGZyYW1lIGJ1ZmZlciwgZHJhdyBhbiB1cHNpZGUgZG93biBzY2FsZWQgaW1hZ2Ugb250byB0aGUgZmIsIHJlYWQgaXQgYmFjayBhbmQgcmVzdG9yZSB0aGUKICAgICAgICAgKiAgICBiYWNrIGJ1ZmZlci4gVGhpcyBpcyBzbG93ZXIgdGhhbiByZWFkaW5nIGxpbmUgcGVyIGxpbmUsIHRodXMgbm90IHVzZWQgZm9yIGZsaXBwaW5nCiAgICAgICAgICogLT4gSWYgdGhlIGFwcCB3YW50cyBhIHNjYWxlZCBpbWFnZSB3aXRoIGEgZGVzdCByZWN0IHRoYXQgaXMgYmlnZ2VyIHRoYW4gdGhlIGZiLCBpdCBoYXMgdG8gYmUgY29waWVkCiAgICAgICAgICogICAgcGl4ZWwgYnkgcGl4ZWwKICAgICAgICAgKi8KICAgICAgICBpZihGQUxTRSAvKiBHTF9TVVBQT1JUKEVYVF9GUkFNRUJVRkZFUl9CTElUKSAqLykgewogICAgICAgICAgICBUUkFDRSgiVXNpbmcgR0xfRVhUX2ZyYW1lYnVmZmVyX2JsaXQgZm9yIGNvcHlpbmdcbiIpOwogICAgICAgIH0gZWxzZSBpZigoIXN0cmV0Y2h4KSB8fCByZWN0LngyIC0gcmVjdC54MSA+IFNyYy0+Y3VycmVudERlc2MuV2lkdGggfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVjdC55MiAtIHJlY3QueTEgPiBTcmMtPmN1cnJlbnREZXNjLkhlaWdodCkgewogICAgICAgICAgICBUUkFDRSgiTm8gc3RyZXRjaGluZyBpbiB4IGRpcmVjdGlvbiwgdXNpbmcgZGlyZWN0IGZyYW1lYnVmZmVyIC0+IHRleHR1cmUgY29weVxuIik7CiAgICAgICAgICAgIGZiX2NvcHlfdG9fdGV4dHVyZV9kaXJlY3QoVGhpcywgU3JjU3VyZmFjZSwgc3JjU3dhcGNoYWluLCAmc3JlY3QsICZyZWN0LCB1cHNpZGVEb3duKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBUUkFDRSgiVXNpbmcgaGFyZHdhcmUgc3RyZXRjaGluZyB0byBmbGlwIC8gc3RyZXRjaCB0aGUgdGV4dHVyZVxuIik7CiAgICAgICAgICAgIGZiX2NvcHlfdG9fdGV4dHVyZV9od3N0cmV0Y2goVGhpcywgU3JjU3VyZmFjZSwgc3JjU3dhcGNoYWluLCAmc3JlY3QsICZyZWN0LCB1cHNpZGVEb3duKTsKICAgICAgICB9CgogICAgICAgIGlmKCEoVGhpcy0+RmxhZ3MgJiBTRkxBR19ET05PVEZSRUUpKSB7CiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSk7CiAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IE5VTEw7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfR0xESVJUWTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfSBlbHNlIGlmKFNyYykgewogICAgICAgIC8qIEJsaXQgZnJvbSBvZmZzY3JlZW4gc3VyZmFjZSB0byByZW5kZXIgdGFyZ2V0ICovCiAgICAgICAgZmxvYXQgZ2xUZXhDb29yZFs0XTsKICAgICAgICBEV09SRCBvbGRDS2V5RmxhZ3MgPSBTcmMtPkNLZXlGbGFnczsKICAgICAgICBERENPTE9SS0VZIG9sZEJsdENLZXkgPSBUaGlzLT5TcmNCbHRDS2V5OwogICAgICAgIFJFQ1QgU291cmNlUmVjdGFuZ2xlOwogICAgICAgIEdMaW50IG9sZERyYXc7CgogICAgICAgIFRSQUNFKCJCbHQgZnJvbSBzdXJmYWNlICVwIHRvIHJlbmRlcnRhcmdldCAlcFxuIiwgU3JjLCBUaGlzKTsKCiAgICAgICAgaWYoU3JjUmVjdCkgewogICAgICAgICAgICBTb3VyY2VSZWN0YW5nbGUubGVmdCA9IFNyY1JlY3QtPmxlZnQ7CiAgICAgICAgICAgIFNvdXJjZVJlY3RhbmdsZS5yaWdodCA9IFNyY1JlY3QtPnJpZ2h0OwogICAgICAgICAgICBTb3VyY2VSZWN0YW5nbGUudG9wID0gU3JjUmVjdC0+dG9wOwogICAgICAgICAgICBTb3VyY2VSZWN0YW5nbGUuYm90dG9tID0gU3JjUmVjdC0+Ym90dG9tOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIFNvdXJjZVJlY3RhbmdsZS5sZWZ0ID0gMDsKICAgICAgICAgICAgU291cmNlUmVjdGFuZ2xlLnJpZ2h0ID0gU3JjLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICAgICAgU291cmNlUmVjdGFuZ2xlLnRvcCA9IDA7CiAgICAgICAgICAgIFNvdXJjZVJlY3RhbmdsZS5ib3R0b20gPSBTcmMtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgICAgICB9CgogICAgICAgIGlmKCFDYWxjdWxhdGVUZXhSZWN0KFNyYywgJlNvdXJjZVJlY3RhbmdsZSwgZ2xUZXhDb29yZCkpIHsKICAgICAgICAgICAgLyogRmFsbCBiYWNrIHRvIHNvZnR3YXJlICovCiAgICAgICAgICAgIFdBUk4oIiglcCkgU291cmNlIHRleHR1cmUgYXJlYSAoJWQsJWQpLSglZCwlZCkgaXMgdG9vIGJpZ1xuIiwgU3JjLAogICAgICAgICAgICAgICAgICAgIFNvdXJjZVJlY3RhbmdsZS5sZWZ0LCBTb3VyY2VSZWN0YW5nbGUudG9wLAogICAgICAgICAgICAgICAgICAgIFNvdXJjZVJlY3RhbmdsZS5yaWdodCwgU291cmNlUmVjdGFuZ2xlLmJvdHRvbSk7CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgICAgIH0KCiAgICAgICAgLyogQ29sb3Iga2V5aW5nOiBDaGVjayBpZiB3ZSBoYXZlIHRvIGRvIGEgY29sb3Iga2V5ZWQgYmx0LAogICAgICAgICAqIGFuZCBpZiBub3QgY2hlY2sgaWYgYSBjb2xvciBrZXkgaXMgYWN0aXZhdGVkLgogICAgICAgICAqCiAgICAgICAgICogSnVzdCBtb2RpZnkgdGhlIGNvbG9yIGtleWluZyBwYXJhbWV0ZXJzIGluIHRoZSBzdXJmYWNlIGFuZCByZXN0b3JlIHRoZW0gYWZ0ZXJ3YXJkcwogICAgICAgICAqIFRoZSBzdXJmYWNlIGtlZXBzIHRyYWNrIG9mIHRoZSBjb2xvciBrZXkgbGFzdCB1c2VkIHRvIGxvYWQgdGhlIG9wZW5nbCBzdXJmYWNlLgogICAgICAgICAqIFByZUxvYWQgd2lsbCBjYXRjaCB0aGUgY2hhbmdlIHRvIHRoZSBmbGFncyBhbmQgY29sb3Iga2V5IGFuZCByZWxvYWQgaWYgbmVjY2Vzc2FyeS4KICAgICAgICAgKi8KICAgICAgICBpZihGbGFncyAmIEREQkxUX0tFWVNSQykgewogICAgICAgICAgICAvKiBVc2UgY29sb3Iga2V5IGZyb20gc3VyZmFjZSAqLwogICAgICAgIH0gZWxzZSBpZihGbGFncyAmIEREQkxUX0tFWVNSQ09WRVJSSURFKSB7CiAgICAgICAgICAgIC8qIFVzZSBjb2xvciBrZXkgZnJvbSBEREJsdEZ4ICovCiAgICAgICAgICAgIFNyYy0+Q0tleUZsYWdzIHw9IEREU0RfQ0tTUkNCTFQ7CiAgICAgICAgICAgIFRoaXMtPlNyY0JsdENLZXkgPSBEREJsdEZ4LT5kZGNrU3JjQ29sb3JrZXk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLyogRG8gbm90IHVzZSBjb2xvciBrZXkgKi8KICAgICAgICAgICAgU3JjLT5DS2V5RmxhZ3MgJj0gfkREU0RfQ0tTUkNCTFQ7CiAgICAgICAgfQoKICAgICAgICAvKiBOb3cgbG9hZCB0aGUgc3VyZmFjZSAqLwogICAgICAgIElXaW5lRDNEU3VyZmFjZV9QcmVMb2FkKChJV2luZUQzRFN1cmZhY2UgKikgU3JjKTsKCiAgICAgICAgRU5URVJfR0woKTsKCiAgICAgICAgLyogQWN0aXZhdGUgdGhlIGRlc3RpbmF0aW9uIGNvbnRleHQsIHNldCBpdCB1cCBmb3IgYmxpdHRpbmcgKi8KICAgICAgICBBY3RpdmF0ZUNvbnRleHQobXlEZXZpY2UsIChJV2luZUQzRFN1cmZhY2UgKikgVGhpcywgQ1RYVVNBR0VfQkxJVCk7CgogICAgICAgIGdsR2V0SW50ZWdlcnYoR0xfRFJBV19CVUZGRVIsICZvbGREcmF3KTsKICAgICAgICBpZihUaGlzID09IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGRzdFN3YXBjaGFpbi0+ZnJvbnRCdWZmZXIpIHsKICAgICAgICAgICAgVFJBQ0UoIkRyYXdpbmcgdG8gZnJvbnQgYnVmZmVyXG4iKTsKICAgICAgICAgICAgZ2xEcmF3QnVmZmVyKEdMX0ZST05UKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlciBHTF9GUk9OVCIpOwogICAgICAgIH0KCiAgICAgICAgLyogQmluZCB0aGUgdGV4dHVyZSAqLwogICAgICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgU3JjLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xCaW5kVGV4dHVyZSIpOwoKICAgICAgICAvKiBObyBmaWx0ZXJpbmcgZm9yIGJsdHMgKi8KICAgICAgICBnbFRleFBhcmFtZXRlcmkoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9NQUdfRklMVEVSLAogICAgICAgICAgICAgICAgICAgICAgICBHTF9ORUFSRVNUKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xUZXhQYXJhbWV0ZXJpIik7CiAgICAgICAgZ2xUZXhQYXJhbWV0ZXJpKEdMX1RFWFRVUkVfMkQsIEdMX1RFWFRVUkVfTUlOX0ZJTFRFUiwKICAgICAgICAgICAgICAgICAgICAgICAgR0xfTkVBUkVTVCk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsVGV4UGFyYW1ldGVyaSIpOwogICAgICAgIGdsVGV4UGFyYW1ldGVyaShHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX1dSQVBfUywgR0xfQ0xBTVApOwogICAgICAgIGdsVGV4UGFyYW1ldGVyaShHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX1dSQVBfVCwgR0xfQ0xBTVApOwogICAgICAgIGdsVGV4RW52aShHTF9URVhUVVJFX0VOViwgR0xfVEVYVFVSRV9FTlZfTU9ERSwgR0xfUkVQTEFDRSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsVGV4RW52aSIpOwoKICAgICAgICAvKiBUaGlzIGlzIGZvciBjb2xvciBrZXlpbmcgKi8KICAgICAgICBpZihGbGFncyAmIChEREJMVF9LRVlTUkMgfCBEREJMVF9LRVlTUkNPVkVSUklERSkpIHsKICAgICAgICAgICAgZ2xFbmFibGUoR0xfQUxQSEFfVEVTVCk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZSBHTF9BTFBIQV9URVNUIik7CiAgICAgICAgICAgIGdsQWxwaGFGdW5jKEdMX05PVEVRVUFMLCAwLjApOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xBbHBoYUZ1bmNcbiIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGdsRGlzYWJsZShHTF9BTFBIQV9URVNUKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9BTFBIQV9URVNUIik7CiAgICAgICAgfQoKICAgICAgICAvKiBEcmF3IGEgdGV4dHVyZWQgcXVhZAogICAgICAgICAgICAqLwogICAgICAgIGdsQmVnaW4oR0xfUVVBRFMpOwoKICAgICAgICBnbENvbG9yM2QoMS4wZiwgMS4wZiwgMS4wZik7CiAgICAgICAgZ2xUZXhDb29yZDJmKGdsVGV4Q29vcmRbMF0sIGdsVGV4Q29vcmRbMl0pOwogICAgICAgIGdsVmVydGV4M2YocmVjdC54MSwKICAgICAgICAgICAgICAgICAgICByZWN0LnkxLAogICAgICAgICAgICAgICAgICAgIDAuMCk7CgogICAgICAgIGdsVGV4Q29vcmQyZihnbFRleENvb3JkWzBdLCBnbFRleENvb3JkWzNdKTsKICAgICAgICBnbFZlcnRleDNmKHJlY3QueDEsIHJlY3QueTIsIDAuMCk7CgogICAgICAgIGdsVGV4Q29vcmQyZihnbFRleENvb3JkWzFdLCBnbFRleENvb3JkWzNdKTsKICAgICAgICBnbFZlcnRleDNmKHJlY3QueDIsCiAgICAgICAgICAgICAgICAgICAgcmVjdC55MiwKICAgICAgICAgICAgICAgICAgICAwLjApOwoKICAgICAgICBnbFRleENvb3JkMmYoZ2xUZXhDb29yZFsxXSwgZ2xUZXhDb29yZFsyXSk7CiAgICAgICAgZ2xWZXJ0ZXgzZihyZWN0LngyLAogICAgICAgICAgICAgICAgICAgIHJlY3QueTEsCiAgICAgICAgICAgICAgICAgICAgMC4wKTsKICAgICAgICBnbEVuZCgpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEVuZCIpOwoKICAgICAgICBpZihGbGFncyAmIChEREJMVF9LRVlTUkMgfCBEREJMVF9LRVlTUkNPVkVSUklERSkpIHsKICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX0FMUEhBX1RFU1QpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlKEdMX0FMUEhBX1RFU1QpIik7CiAgICAgICAgfQoKICAgICAgICAvKiBVbmJpbmQgdGhlIHRleHR1cmUgKi8KICAgICAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIDApOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZSBnbEJpbmRUZXh0dXJlIik7CgogICAgICAgIGlmKFRoaXMgPT0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgZHN0U3dhcGNoYWluLT5mcm9udEJ1ZmZlciAmJiBvbGREcmF3ID09IEdMX0JBQ0spIHsKICAgICAgICAgICAgZ2xEcmF3QnVmZmVyKG9sZERyYXcpOwogICAgICAgIH0KICAgICAgICAvKiBSZXN0b3JlIHRoZSBjb2xvciBrZXkgcGFyYW1ldGVycyAqLwogICAgICAgIFNyYy0+Q0tleUZsYWdzID0gb2xkQ0tleUZsYWdzOwogICAgICAgIFRoaXMtPlNyY0JsdENLZXkgPSBvbGRCbHRDS2V5OwoKICAgICAgICBMRUFWRV9HTCgpOwoKICAgICAgICAvKiBUT0RPOiBJZiB0aGUgc3VyZmFjZSBpcyBsb2NrZWQgb2Z0ZW4sIHBlcmZvcm0gdGhlIEJsdCBpbiBzb2Z0d2FyZSBvbiB0aGUgbWVtb3J5IGluc3RlYWQgKi8KICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19HTERJUlRZOwoKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0gZWxzZSB7CiAgICAgICAgLyogU291cmNlLUxlc3MgQmxpdCB0byByZW5kZXIgdGFyZ2V0ICovCiAgICAgICAgaWYgKEZsYWdzICYgRERCTFRfQ09MT1JGSUxMKSB7CiAgICAgICAgICAgIC8qIFRoaXMgaXMgZWFzeSB0byBoYW5kbGUgZm9yIHRoZSBEM0QgRGV2aWNlLi4uICovCiAgICAgICAgICAgIERXT1JEIGNvbG9yOwoKICAgICAgICAgICAgVFJBQ0UoIkNvbG9yZmlsbFxuIik7CgogICAgICAgICAgICAvKiBUaGUgY29sb3IgYXMgZ2l2ZW4gaW4gdGhlIEJsdCBmdW5jdGlvbiBpcyBpbiB0aGUgZm9ybWF0IG9mIHRoZSBmcmFtZS1idWZmZXIuLi4KICAgICAgICAgICAgICogJ2NsZWFyJyBleHBlY3QgaXQgaW4gQVJHQiBmb3JtYXQgPT4gd2UgbmVlZCB0byBkbyBzb21lIGNvbnZlcnNpb24gOi0pCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfUDgpIHsKICAgICAgICAgICAgICAgIGlmIChUaGlzLT5wYWxldHRlKSB7CiAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAoKDB4RkYwMDAwMDApIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIChUaGlzLT5wYWxldHRlLT5wYWxlbnRzW0REQmx0RngtPnU1LmR3RmlsbENvbG9yXS5wZVJlZCA8PCAxNikgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKFRoaXMtPnBhbGV0dGUtPnBhbGVudHNbRERCbHRGeC0+dTUuZHdGaWxsQ29sb3JdLnBlR3JlZW4gPDwgOCkgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKFRoaXMtPnBhbGV0dGUtPnBhbGVudHNbRERCbHRGeC0+dTUuZHdGaWxsQ29sb3JdLnBlQmx1ZSkpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBjb2xvciA9IDB4RkYwMDAwMDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfUjVHNkI1KSB7CiAgICAgICAgICAgICAgICBpZiAoRERCbHRGeC0+dTUuZHdGaWxsQ29sb3IgPT0gMHhGRkZGKSB7CiAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAweEZGRkZGRkZGOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBjb2xvciA9ICgoMHhGRjAwMDAwMCkgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKChEREJsdEZ4LT51NS5kd0ZpbGxDb2xvciAmIDB4RjgwMCkgPDwgOCkgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKChEREJsdEZ4LT51NS5kd0ZpbGxDb2xvciAmIDB4MDdFMCkgPDwgNSkgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKChEREJsdEZ4LT51NS5kd0ZpbGxDb2xvciAmIDB4MDAxRikgPDwgMykpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKChUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9SOEc4QjgpIHx8CiAgICAgICAgICAgICAgICAgICAgKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX1g4UjhHOEI4KSApIHsKICAgICAgICAgICAgICAgIGNvbG9yID0gMHhGRjAwMDAwMCB8IEREQmx0RngtPnU1LmR3RmlsbENvbG9yOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0E4UjhHOEI4KSB7CiAgICAgICAgICAgICAgICBjb2xvciA9IEREQmx0RngtPnU1LmR3RmlsbENvbG9yOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgRVJSKCJXcm9uZyBzdXJmYWNlIHR5cGUgZm9yIEJMVCBvdmVycmlkZShGb3JtYXQgZG9lc24ndCBtYXRjaCkgIVxuIik7CiAgICAgICAgICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgVFJBQ0UoIkNhbGxpbmcgR2V0U3dhcENoYWluIHdpdGggbXlkZXZpY2UgPSAlcFxuIiwgbXlEZXZpY2UpOwogICAgICAgICAgICBpZihkc3RTd2FwY2hhaW4gJiYgZHN0U3dhcGNoYWluLT5iYWNrQnVmZmVyICYmIFRoaXMgPT0gKElXaW5lRDNEU3VyZmFjZUltcGwqKSBkc3RTd2FwY2hhaW4tPmJhY2tCdWZmZXJbMF0pIHsKICAgICAgICAgICAgICAgIGdsRHJhd0J1ZmZlcihHTF9CQUNLKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERyYXdCdWZmZXIoR0xfQkFDSykiKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChkc3RTd2FwY2hhaW4gJiYgVGhpcyA9PSAoSVdpbmVEM0RTdXJmYWNlSW1wbCopIGRzdFN3YXBjaGFpbi0+ZnJvbnRCdWZmZXIpIHsKICAgICAgICAgICAgICAgIGdsRHJhd0J1ZmZlcihHTF9GUk9OVCk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEcmF3QnVmZmVyKEdMX0ZST05UKSIpOwogICAgICAgICAgICB9IGVsc2UgaWYoVGhpcyA9PSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBteURldmljZS0+cmVuZGVyX3RhcmdldHNbMF0pIHsKICAgICAgICAgICAgICAgIGdsRHJhd0J1ZmZlcihHTF9CQUNLKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERyYXdCdWZmZXIoR0xfQkFDSykiKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIFRSQUNFKCJTdXJmYWNlIGlzIGhpZ2hlciBiYWNrIGJ1ZmZlciwgZmFsbGluZyBiYWNrIHRvIHNvZnR3YXJlXG4iKTsKICAgICAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgICAgICAgICB9CgogICAgICAgICAgICBUUkFDRSgiKCVwKSBleGVjdXRpbmcgUmVuZGVyIFRhcmdldCBvdmVycmlkZSwgY29sb3IgPSAleFxuIiwgVGhpcywgY29sb3IpOwoKICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfQ2xlYXIoIChJV2luZUQzRERldmljZSAqKSBteURldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxIC8qIE51bWJlciBvZiByZWN0YW5nbGVzICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZyZWN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RDTEVBUl9UQVJHRVQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMC4wIC8qIFogKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCAvKiBTdGVuY2lsICovKTsKCiAgICAgICAgICAgIC8qIFJlc3RvcmUgdGhlIG9yaWdpbmFsIGRyYXcgYnVmZmVyICovCiAgICAgICAgICAgIGlmKCFkc3RTd2FwY2hhaW4gfHwgKGRzdFN3YXBjaGFpbi0+YmFja0J1ZmZlciAmJiBkc3RTd2FwY2hhaW4tPmJhY2tCdWZmZXJbMF0pKSB7CiAgICAgICAgICAgICAgICBnbERyYXdCdWZmZXIoR0xfQkFDSyk7CiAgICAgICAgICAgICAgICB2Y2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlciIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgICAgICB9CiAgICB9CgogICAgLyogRGVmYXVsdDogRmFsbCBiYWNrIHRvIHRoZSBnZW5lcmljIGJsdC4gTm90IGFuIGVycm9yLCBhIFRSQUNFIGlzIGVub3VnaCAqLwogICAgVFJBQ0UoIkRpZG4ndCBmaW5kIGFueSB1c2FibGUgcmVuZGVyIHRhcmdldCBzZXR1cCBmb3IgaHcgYmxpdCwgZmFsbGluZyBiYWNrIHRvIHNvZnR3YXJlXG4iKTsKICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9CbHQoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgUkVDVCAqRGVzdFJlY3QsIElXaW5lRDNEU3VyZmFjZSAqU3JjU3VyZmFjZSwgUkVDVCAqU3JjUmVjdCwgRFdPUkQgRmxhZ3MsIEREQkxURlggKkREQmx0RngpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqU3JjID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgU3JjU3VyZmFjZTsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqbXlEZXZpY2UgPSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOwogICAgVFJBQ0UoIiglcCktPiglcCwlcCwlcCwleCwlcClcbiIsIFRoaXMsIERlc3RSZWN0LCBTcmNTdXJmYWNlLCBTcmNSZWN0LCBGbGFncywgRERCbHRGeCk7CiAgICBUUkFDRSgiKCVwKTogVXNhZ2UgaXMgJXNcbiIsIFRoaXMsIGRlYnVnX2QzZHVzYWdlKFRoaXMtPnJlc291cmNlLnVzYWdlKSk7CgogICAgLyogQWNjZXNzaW5nIHRoZSBkZXB0aCBzdGVuY2lsIGlzIHN1cHBvc2VkIHRvIGZhaWwgYmV0d2VlbiBhIEJlZ2luU2NlbmUgYW5kIEVuZFNjZW5lIHBhaXIgKi8KICAgIGlmKG15RGV2aWNlLT5pblNjZW5lICYmCiAgICAgICAoaWZhY2UgPT0gbXlEZXZpY2UtPnN0ZW5jaWxCdWZmZXJUYXJnZXQgfHwKICAgICAgIChTcmNTdXJmYWNlICYmIFNyY1N1cmZhY2UgPT0gbXlEZXZpY2UtPnN0ZW5jaWxCdWZmZXJUYXJnZXQpKSkgewogICAgICAgIFRSQUNFKCJBdHRlbXB0IHRvIGFjY2VzcyB0aGUgZGVwdGggc3RlbmNpbCBzdXJmYWNlIGluIGEgQmVnaW5TY2VuZSAvIEVuZFNjZW5lIHBhaXIsIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICAvKiBTcGVjaWFsIGNhc2VzIGZvciBSZW5kZXJUYXJnZXRzICovCiAgICBpZiggKFRoaXMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkgfHwKICAgICAgICAoIFNyYyAmJiAoU3JjLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQpICkpIHsKICAgICAgICBpZihJV2luZUQzRFN1cmZhY2VJbXBsX0JsdE92ZXJyaWRlKFRoaXMsIERlc3RSZWN0LCBTcmNTdXJmYWNlLCBTcmNSZWN0LCBGbGFncywgRERCbHRGeCkgPT0gV0lORUQzRF9PSykgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgLyogRm9yIHRoZSByZXN0IGNhbGwgdGhlIFgxMSBzdXJmYWNlIGltcGxlbWVudGF0aW9uLgogICAgICogRm9yIFJlbmRlclRhcmdldHMgdGhpcyBzaG91bGQgYmUgaW1wbGVtZW50ZWQgT3BlbkdMIGFjY2VsZXJhdGVkIGluIEJsdE92ZXJyaWRlLAogICAgICogb3RoZXIgQmx0cyBhcmUgcmF0aGVyIHJhcmUKICAgICAqLwogICAgcmV0dXJuIElXaW5lR0RJU3VyZmFjZUltcGxfQmx0KGlmYWNlLCBEZXN0UmVjdCwgU3JjU3VyZmFjZSwgU3JjUmVjdCwgRmxhZ3MsIEREQmx0RngpOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0dldEJsdFN0YXR1cyhJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBEV09SRCBGbGFncykgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKS0+KCV4KVxuIiwgVGhpcywgRmxhZ3MpOwoKICAgIHN3aXRjaCAoRmxhZ3MpCiAgICB7CiAgICBjYXNlIERER0JTX0NBTkJMVDoKICAgIGNhc2UgRERHQlNfSVNCTFRET05FOgogICAgICAgIHJldHVybiBERF9PSzsKCiAgICBkZWZhdWx0OgogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgfQp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0dldEZsaXBTdGF0dXMoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgRFdPUkQgRmxhZ3MpIHsKICAgIC8qIFhYWDogRERFUlJfSU5WQUxJRFNVUkZBQ0VUWVBFICovCgogICAgVFJBQ0UoIiglcCktPiglMDh4KVxuIixpZmFjZSxGbGFncyk7CiAgICBzd2l0Y2ggKEZsYWdzKSB7CiAgICBjYXNlIERER0ZTX0NBTkZMSVA6CiAgICBjYXNlIERER0ZTX0lTRkxJUERPTkU6CiAgICAgICAgcmV0dXJuIEREX09LOwoKICAgIGRlZmF1bHQ6CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfSXNMb3N0KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBpZmFjZTsKICAgIFRSQUNFKCIoJXApXG4iLCBUaGlzKTsKCiAgICByZXR1cm4gVGhpcy0+RmxhZ3MgJiBTRkxBR19MT1NUID8gRERFUlJfU1VSRkFDRUxPU1QgOiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1Jlc3RvcmUoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwoKICAgIC8qIFNvIGZhciB3ZSBkb24ndCBsb3NlIGFueXRoaW5nIDopICovCiAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfTE9TVDsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0JsdEZhc3QoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgRFdPUkQgZHN0eCwgRFdPUkQgZHN0eSwgSVdpbmVEM0RTdXJmYWNlICpTb3VyY2UsIFJFQ1QgKnJzcmMsIERXT1JEIHRyYW5zKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpzcmNJbXBsID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgU291cmNlOwogICAgSVdpbmVEM0REZXZpY2VJbXBsICpteURldmljZSA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CiAgICBUUkFDRSgiKCVwKS0+KCVkLCAlZCwgJXAsICVwLCAlMDh4XG4iLCBpZmFjZSwgZHN0eCwgZHN0eSwgU291cmNlLCByc3JjLCB0cmFucyk7CgogICAgaWYobXlEZXZpY2UtPmluU2NlbmUgJiYKICAgICAgIChpZmFjZSA9PSBteURldmljZS0+c3RlbmNpbEJ1ZmZlclRhcmdldCB8fAogICAgICAgKFNvdXJjZSAmJiBTb3VyY2UgPT0gbXlEZXZpY2UtPnN0ZW5jaWxCdWZmZXJUYXJnZXQpKSkgewogICAgICAgIFRSQUNFKCJBdHRlbXB0IHRvIGFjY2VzcyB0aGUgZGVwdGggc3RlbmNpbCBzdXJmYWNlIGluIGEgQmVnaW5TY2VuZSAvIEVuZFNjZW5lIHBhaXIsIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICAvKiBTcGVjaWFsIGNhc2VzIGZvciBSZW5kZXJUYXJnZXRzICovCiAgICBpZiggKFRoaXMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkgfHwKICAgICAgICAoIHNyY0ltcGwgJiYgKHNyY0ltcGwtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkgKSkgewoKICAgICAgICBSRUNUIFNyY1JlY3QsIERzdFJlY3Q7CiAgICAgICAgRFdPUkQgRmxhZ3M9MDsKCiAgICAgICAgaWYocnNyYykgewogICAgICAgICAgICBTcmNSZWN0LmxlZnQgPSByc3JjLT5sZWZ0OwogICAgICAgICAgICBTcmNSZWN0LnRvcD0gcnNyYy0+dG9wOwogICAgICAgICAgICBTcmNSZWN0LmJvdHRvbSA9IHJzcmMtPmJvdHRvbTsKICAgICAgICAgICAgU3JjUmVjdC5yaWdodCA9IHJzcmMtPnJpZ2h0OwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIFNyY1JlY3QubGVmdCA9IDA7CiAgICAgICAgICAgIFNyY1JlY3QudG9wID0gMDsKICAgICAgICAgICAgU3JjUmVjdC5yaWdodCA9IHNyY0ltcGwtPmN1cnJlbnREZXNjLldpZHRoOwogICAgICAgICAgICBTcmNSZWN0LmJvdHRvbSA9IHNyY0ltcGwtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgICAgICB9CgogICAgICAgIERzdFJlY3QubGVmdCA9IGRzdHg7CiAgICAgICAgRHN0UmVjdC50b3A9ZHN0eTsKICAgICAgICBEc3RSZWN0LnJpZ2h0ID0gZHN0eCArIFNyY1JlY3QucmlnaHQgLSBTcmNSZWN0LmxlZnQ7CiAgICAgICAgRHN0UmVjdC5ib3R0b20gPSBkc3R5ICsgU3JjUmVjdC5ib3R0b20gLSBTcmNSZWN0LnRvcDsKCiAgICAgICAgLyogQ29udmVydCBCbHRGYXN0IGZsYWdzIGludG8gQnRsIG9uZXMgYmVjYXVzZSBpdCBpcyBjYWxsZWQgZnJvbSBTdXJmYWNlSW1wbF9CbHQgYXMgd2VsbCAqLwogICAgICAgIGlmKHRyYW5zICYgRERCTFRGQVNUX1NSQ0NPTE9SS0VZKQogICAgICAgICAgICBGbGFncyB8PSBEREJMVF9LRVlTUkM7CiAgICAgICAgaWYodHJhbnMgJiBEREJMVEZBU1RfREVTVENPTE9SS0VZKQogICAgICAgICAgICBGbGFncyB8PSBEREJMVF9LRVlERVNUOwogICAgICAgIGlmKHRyYW5zICYgRERCTFRGQVNUX1dBSVQpCiAgICAgICAgICAgIEZsYWdzIHw9IEREQkxUX1dBSVQ7CiAgICAgICAgaWYodHJhbnMgJiBEREJMVEZBU1RfRE9OT1RXQUlUKQogICAgICAgICAgICBGbGFncyB8PSBEREJMVF9ET05PVFdBSVQ7CgogICAgICAgIGlmKElXaW5lRDNEU3VyZmFjZUltcGxfQmx0T3ZlcnJpZGUoVGhpcywgJkRzdFJlY3QsIFNvdXJjZSwgJlNyY1JlY3QsIEZsYWdzLCBOVUxMKSA9PSBXSU5FRDNEX09LKSByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCgogICAgcmV0dXJuIElXaW5lR0RJU3VyZmFjZUltcGxfQmx0RmFzdChpZmFjZSwgZHN0eCwgZHN0eSwgU291cmNlLCByc3JjLCB0cmFucyk7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0UGFsZXR0ZShJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBJV2luZUQzRFBhbGV0dGUgKipQYWwpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBpZmFjZTsKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLCBUaGlzLCBQYWwpOwoKICAgICpQYWwgPSAoSVdpbmVEM0RQYWxldHRlICopIFRoaXMtPnBhbGV0dGU7CiAgICByZXR1cm4gRERfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfUmVhbGl6ZVBhbGV0dGUoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwogICAgUkdCUVVBRCBjb2xbMjU2XTsKICAgIElXaW5lRDNEUGFsZXR0ZUltcGwgKnBhbCA9IFRoaXMtPnBhbGV0dGU7CiAgICB1bnNpZ25lZCBpbnQgbjsKICAgIFRSQUNFKCIoJXApXG4iLCBUaGlzKTsKCiAgICBpZihUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9QOCB8fAogICAgICAgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfQThQOCkKICAgIHsKICAgICAgICBUUkFDRSgiRGlydGlmeWluZyBzdXJmYWNlXG4iKTsKICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19ESVJUWTsKICAgIH0KCiAgICBpZihUaGlzLT5GbGFncyAmIFNGTEFHX0RJQlNFQ1RJT04pIHsKICAgICAgICBUUkFDRSgiKCVwKTogVXBkYXRpbmcgdGhlIGhkYydzIHBhbGV0dGVcbiIsIFRoaXMpOwogICAgICAgIGZvciAobj0wOyBuPDI1NjsgbisrKSB7CiAgICAgICAgICAgIGlmKHBhbCkgewogICAgICAgICAgICAgICAgY29sW25dLnJnYlJlZCAgID0gcGFsLT5wYWxlbnRzW25dLnBlUmVkOwogICAgICAgICAgICAgICAgY29sW25dLnJnYkdyZWVuID0gcGFsLT5wYWxlbnRzW25dLnBlR3JlZW47CiAgICAgICAgICAgICAgICBjb2xbbl0ucmdiQmx1ZSAgPSBwYWwtPnBhbGVudHNbbl0ucGVCbHVlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsICpkZXZpY2UgPSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOwogICAgICAgICAgICAgICAgLyogVXNlIHRoZSBkZWZhdWx0IGRldmljZSBwYWxldHRlICovCiAgICAgICAgICAgICAgICBjb2xbbl0ucmdiUmVkICAgPSBkZXZpY2UtPnBhbGV0dGVzW2RldmljZS0+Y3VycmVudFBhbGV0dGVdW25dLnBlUmVkOwogICAgICAgICAgICAgICAgY29sW25dLnJnYkdyZWVuID0gZGV2aWNlLT5wYWxldHRlc1tkZXZpY2UtPmN1cnJlbnRQYWxldHRlXVtuXS5wZUdyZWVuOwogICAgICAgICAgICAgICAgY29sW25dLnJnYkJsdWUgID0gZGV2aWNlLT5wYWxldHRlc1tkZXZpY2UtPmN1cnJlbnRQYWxldHRlXVtuXS5wZUJsdWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY29sW25dLnJnYlJlc2VydmVkID0gMDsKICAgICAgICB9CiAgICAgICAgU2V0RElCQ29sb3JUYWJsZShUaGlzLT5oREMsIDAsIDI1NiwgY29sKTsKICAgIH0KCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRQYWxldHRlKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIElXaW5lRDNEUGFsZXR0ZSAqUGFsKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CiAgICBJV2luZUQzRFBhbGV0dGVJbXBsICpQYWxJbXBsID0gKElXaW5lRDNEUGFsZXR0ZUltcGwgKikgUGFsOwogICAgVFJBQ0UoIiglcCktPiglcClcbiIsIFRoaXMsIFBhbCk7CgogICAgaWYoVGhpcy0+cGFsZXR0ZSAhPSBOVUxMKSAKICAgICAgICBpZihUaGlzLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQpCiAgICAgICAgICAgIFRoaXMtPnBhbGV0dGUtPkZsYWdzICY9IH5ERFBDQVBTX1BSSU1BUllTVVJGQUNFOwoKICAgIGlmKFBhbEltcGwgIT0gTlVMTCkgewogICAgICAgIGlmKFRoaXMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkgewogICAgICAgICAgICAvKiBTZXQgdGhlIGRldmljZSdzIG1haW4gcGFsZXR0ZSBpZiB0aGUgcGFsZXR0ZQogICAgICAgICAgICAgKiB3YXNuJ3QgYSBwcmltYXJ5IHBhbGV0dGUgYmVmb3JlCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZighKFBhbEltcGwtPkZsYWdzICYgRERQQ0FQU19QUklNQVJZU1VSRkFDRSkpIHsKICAgICAgICAgICAgICAgIElXaW5lRDNERGV2aWNlSW1wbCAqZGV2aWNlID0gVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZTsKICAgICAgICAgICAgICAgIHVuc2lnbmVkIGludCBpOwoKICAgICAgICAgICAgICAgIGZvcihpPTA7IGkgPCAyNTY7IGkrKykgewogICAgICAgICAgICAgICAgICAgIGRldmljZS0+cGFsZXR0ZXNbZGV2aWNlLT5jdXJyZW50UGFsZXR0ZV1baV0gPSBQYWxJbXBsLT5wYWxlbnRzW2ldOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAoUGFsSW1wbCktPkZsYWdzIHw9IEREUENBUFNfUFJJTUFSWVNVUkZBQ0U7CiAgICAgICAgfQogICAgfQogICAgVGhpcy0+cGFsZXR0ZSA9IFBhbEltcGw7CgogICAgcmV0dXJuIElXaW5lRDNEU3VyZmFjZV9SZWFsaXplUGFsZXR0ZShpZmFjZSk7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0Q29sb3JLZXkoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgRFdPUkQgRmxhZ3MsIEREQ09MT1JLRVkgKkNLZXkpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBpZmFjZTsKICAgIFRSQUNFKCIoJXApLT4oJTA4eCwlcClcbiIsIFRoaXMsIEZsYWdzLCBDS2V5KTsKCiAgICBpZiAoKEZsYWdzICYgRERDS0VZX0NPTE9SU1BBQ0UpICE9IDApIHsKICAgICAgICBGSVhNRSgiIGNvbG9ya2V5IHZhbHVlIG5vdCBzdXBwb3J0ZWQgKCUwOHgpICFcbiIsIEZsYWdzKTsKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgIH0KCiAgICAvKiBEaXJ0aWZ5IHRoZSBzdXJmYWNlLCBidXQgb25seSBpZiBhIGtleSB3YXMgY2hhbmdlZCAqLwogICAgaWYoQ0tleSkgewogICAgICAgIHN3aXRjaCAoRmxhZ3MgJiB+RERDS0VZX0NPTE9SU1BBQ0UpIHsKICAgICAgICAgICAgY2FzZSBERENLRVlfREVTVEJMVDoKICAgICAgICAgICAgICAgIFRoaXMtPkRlc3RCbHRDS2V5ID0gKkNLZXk7CiAgICAgICAgICAgICAgICBUaGlzLT5DS2V5RmxhZ3MgfD0gRERTRF9DS0RFU1RCTFQ7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgRERDS0VZX0RFU1RPVkVSTEFZOgogICAgICAgICAgICAgICAgVGhpcy0+RGVzdE92ZXJsYXlDS2V5ID0gKkNLZXk7CiAgICAgICAgICAgICAgICBUaGlzLT5DS2V5RmxhZ3MgfD0gRERTRF9DS0RFU1RPVkVSTEFZOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIEREQ0tFWV9TUkNPVkVSTEFZOgogICAgICAgICAgICAgICAgVGhpcy0+U3JjT3ZlcmxheUNLZXkgPSAqQ0tleTsKICAgICAgICAgICAgICAgIFRoaXMtPkNLZXlGbGFncyB8PSBERFNEX0NLU1JDT1ZFUkxBWTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBERENLRVlfU1JDQkxUOgogICAgICAgICAgICAgICAgVGhpcy0+U3JjQmx0Q0tleSA9ICpDS2V5OwogICAgICAgICAgICAgICAgVGhpcy0+Q0tleUZsYWdzIHw9IEREU0RfQ0tTUkNCTFQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CiAgICBlbHNlIHsKICAgICAgICBzd2l0Y2ggKEZsYWdzICYgfkREQ0tFWV9DT0xPUlNQQUNFKSB7CiAgICAgICAgICAgIGNhc2UgRERDS0VZX0RFU1RCTFQ6CiAgICAgICAgICAgICAgICBUaGlzLT5DS2V5RmxhZ3MgJj0gfkREU0RfQ0tERVNUQkxUOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIEREQ0tFWV9ERVNUT1ZFUkxBWToKICAgICAgICAgICAgICAgIFRoaXMtPkNLZXlGbGFncyAmPSB+RERTRF9DS0RFU1RPVkVSTEFZOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIEREQ0tFWV9TUkNPVkVSTEFZOgogICAgICAgICAgICAgICAgVGhpcy0+Q0tleUZsYWdzICY9IH5ERFNEX0NLU1JDT1ZFUkxBWTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBERENLRVlfU1JDQkxUOgogICAgICAgICAgICAgICAgVGhpcy0+Q0tleUZsYWdzICY9IH5ERFNEX0NLU1JDQkxUOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9Qcml2YXRlU2V0dXAoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgLyoqIENoZWNrIGFnYWluc3QgdGhlIG1heGltdW0gdGV4dHVyZSBzaXplcyBzdXBwb3J0ZWQgYnkgdGhlIHZpZGVvIGNhcmQgKiovCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CgogICAgVFJBQ0UoIiVwXG4iLCBUaGlzKTsKICAgIGlmICgoVGhpcy0+cG93MldpZHRoID4gR0xfTElNSVRTKHRleHR1cmVfc2l6ZSkgfHwgVGhpcy0+cG93MkhlaWdodCA+IEdMX0xJTUlUUyh0ZXh0dXJlX3NpemUpKSAmJiAhKFRoaXMtPnJlc291cmNlLnVzYWdlICYgKFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQgfCBXSU5FRDNEVVNBR0VfREVQVEhTVEVOQ0lMKSkpIHsKICAgICAgICAvKiBvbmUgb2YgdGhyZWUgb3B0aW9ucwogICAgICAgIDE6IERvIHRoZSBzYW1lIGFzIHdlIGRvIHdpdGggbm9ucG93IDIgYW5kIHNjYWxlIHRoZSB0ZXh0dXJlLCAoYW55IHRleHR1cmUgb3BzIHdvdWxkIHJlcXVpcmUgdGhlIHRleHR1cmUgdG8gYmUgc2NhbGVkIHdoaWNoIGlzIHBvdGVudGlhbGx5IHNsb3cpCiAgICAgICAgMjogU2V0IHRoZSB0ZXh0dXJlIHRvIHRoZSBtYXhpdW0gc2l6ZSAoYmFkIGlkZWEpCiAgICAgICAgMzogICAgV0FSTiBhbmQgcmV0dXJuIFdJTkVEM0RFUlJfTk9UQVZBSUxBQkxFOwogICAgICAgIDQ6IENyZWF0ZSB0aGUgc3VyZmFjZSwgYnV0IGFsbG93IGl0IHRvIGJlIHVzZWQgb25seSBmb3IgRGlyZWN0RHJhdyBCbHRzLiBTb21lIGFwcHMoZS5nLiBTd2F0IDMpIGNyZWF0ZSB0ZXh0dXJlcyB3aXRoIGEgSGVpZ2h0IG9mIDE2IGFuZCBhIFdpZHRoID4gMzAwMCBhbmQgYmx0IDE2eDE2IGxldHRlciBhcmVhcyBmcm9tIHRoZW0gdG8gdGhlIHJlbmRlciB0YXJnZXQuCiAgICAgICAgKi8KICAgICAgICBXQVJOKCIoJXApIENyZWF0aW5nIGFuIG92ZXJzaXplZCBzdXJmYWNlXG4iLCBUaGlzKTsKICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19PVkVSU0laRTsKCiAgICAgICAgLyogVGhpcyB3aWxsIGJlIGluaXRpYWxpemVkIG9uIHRoZSBmaXJzdCBibHQgKi8KICAgICAgICBUaGlzLT5nbFJlY3QubGVmdCA9IDA7CiAgICAgICAgVGhpcy0+Z2xSZWN0LnRvcCA9IDA7CiAgICAgICAgVGhpcy0+Z2xSZWN0LnJpZ2h0ID0gMDsKICAgICAgICBUaGlzLT5nbFJlY3QuYm90dG9tID0gMDsKICAgIH0gZWxzZSB7CiAgICAgICAgLyogTm8gb3ZlcnNpemUsIGdsIHJlY3QgaXMgdGhlIGZ1bGwgdGV4dHVyZSBzaXplICovCiAgICAgICAgVGhpcy0+RmxhZ3MgJj0gflNGTEFHX09WRVJTSVpFOwogICAgICAgIFRoaXMtPmdsUmVjdC5sZWZ0ID0gMDsKICAgICAgICBUaGlzLT5nbFJlY3QudG9wID0gMDsKICAgICAgICBUaGlzLT5nbFJlY3QucmlnaHQgPSBUaGlzLT5wb3cyV2lkdGg7CiAgICAgICAgVGhpcy0+Z2xSZWN0LmJvdHRvbSA9IFRoaXMtPnBvdzJIZWlnaHQ7CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkRXT1JEIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0dldFBpdGNoKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBpZmFjZTsKICAgIERXT1JEIHJldDsKICAgIFRSQUNFKCIoJXApXG4iLCBUaGlzKTsKCiAgICAvKiBEWFRuIGZvcm1hdHMgZG9uJ3QgaGF2ZSBleGFjdCBwaXRjaGVzIGFzIHRoZXkgYXJlIHRvIHRoZSBuZXcgcm93IG9mIGJsb2NrcywKICAgICAgICAgd2hlcmUgZWFjaCBibG9jayBpcyA0eDQgcGl4ZWxzLCA4IGJ5dGVzIChkeHQxKSBhbmQgMTYgYnl0ZXMgKGR4dDIvMy80LzUpCiAgICAgICAgICBpZSBwaXRjaCA9ICh3aWR0aC80KSAqIGJ5dGVzIHBlciBibG9jayAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwogICAgaWYgKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDEpIC8qIERYVDEgaXMgOCBieXRlcyBwZXIgYmxvY2sgKi8KICAgICAgICByZXQgPSAoKFRoaXMtPmN1cnJlbnREZXNjLldpZHRoICsgMykgPj4gMikgPDwgMzsKICAgIGVsc2UgaWYgKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDIgfHwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMyB8fAogICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNCB8fCBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQ1KSAvKiBEWFQyLzMvNC81IGlzIDE2IGJ5dGVzIHBlciBibG9jayAqLwogICAgICAgIHJldCA9ICgoVGhpcy0+Y3VycmVudERlc2MuV2lkdGggKyAzKSA+PiAyKSA8PCA0OwogICAgZWxzZSB7CiAgICAgICAgcmV0ID0gVGhpcy0+Ynl0ZXNQZXJQaXhlbCAqIFRoaXMtPmN1cnJlbnREZXNjLldpZHRoOyAgLyogQnl0ZXMgLyByb3cgKi8KICAgICAgICAvKiBTdXJmYWNlcyBhcmUgMzIgYml0IGFsaWduZWQgKi8KICAgICAgICByZXQgPSAocmV0ICsgU1VSRkFDRV9BTElHTk1FTlQgLSAxKSAmIH4oU1VSRkFDRV9BTElHTk1FTlQgLSAxKTsKICAgIH0KICAgIFRSQUNFKCIoJXApIFJldHVybmluZyAlZFxuIiwgVGhpcywgcmV0KTsKICAgIHJldHVybiByZXQ7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0T3ZlcmxheVBvc2l0aW9uKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIExPTkcgWCwgTE9ORyBZKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CgogICAgRklYTUUoIiglcCktPiglZCwlZCkgU3R1YiFcbiIsIFRoaXMsIFgsIFkpOwoKICAgIGlmKCEoVGhpcy0+cmVzb3VyY2UudXNhZ2UgJiBXSU5FRDNEVVNBR0VfT1ZFUkxBWSkpCiAgICB7CiAgICAgICAgVFJBQ0UoIiglcCk6IE5vdCBhbiBvdmVybGF5IHN1cmZhY2VcbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBEREVSUl9OT1RBT1ZFUkxBWVNVUkZBQ0U7CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0T3ZlcmxheVBvc2l0aW9uKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIExPTkcgKlgsIExPTkcgKlkpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBpZmFjZTsKCiAgICBGSVhNRSgiKCVwKS0+KCVwLCVwKSBTdHViIVxuIiwgVGhpcywgWCwgWSk7CgogICAgaWYoIShUaGlzLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9PVkVSTEFZKSkKICAgIHsKICAgICAgICBUUkFDRSgiKCVwKTogTm90IGFuIG92ZXJsYXkgc3VyZmFjZVxuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIERERVJSX05PVEFPVkVSTEFZU1VSRkFDRTsKICAgIH0KCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9VcGRhdGVPdmVybGF5Wk9yZGVyKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIERXT1JEIEZsYWdzLCBJV2luZUQzRFN1cmZhY2UgKlJlZikgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqUmVmSW1wbCA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIFJlZjsKCiAgICBGSVhNRSgiKCVwKS0+KCUwOHgsJXApIFN0dWIhXG4iLCBUaGlzLCBGbGFncywgUmVmSW1wbCk7CgogICAgaWYoIShUaGlzLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9PVkVSTEFZKSkKICAgIHsKICAgICAgICBUUkFDRSgiKCVwKTogTm90IGFuIG92ZXJsYXkgc3VyZmFjZVxuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIERERVJSX05PVEFPVkVSTEFZU1VSRkFDRTsKICAgIH0KCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9VcGRhdGVPdmVybGF5KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIFJFQ1QgKlNyY1JlY3QsIElXaW5lRDNEU3VyZmFjZSAqRHN0U3VyZmFjZSwgUkVDVCAqRHN0UmVjdCwgRFdPUkQgRmxhZ3MsIFdJTkVERE9WRVJMQVlGWCAqRlgpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBpZmFjZTsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKkRzdCA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIERzdFN1cmZhY2U7CiAgICBGSVhNRSgiKCVwKS0+KCVwLCAlcCwgJXAsICUwOHgsICVwKVxuIiwgVGhpcywgU3JjUmVjdCwgRHN0LCBEc3RSZWN0LCBGbGFncywgRlgpOwoKICAgIGlmKCEoVGhpcy0+cmVzb3VyY2UudXNhZ2UgJiBXSU5FRDNEVVNBR0VfT1ZFUkxBWSkpCiAgICB7CiAgICAgICAgVFJBQ0UoIiglcCk6IE5vdCBhbiBvdmVybGF5IHN1cmZhY2VcbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBEREVSUl9OT1RBT1ZFUkxBWVNVUkZBQ0U7CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCmNvbnN0IElXaW5lRDNEU3VyZmFjZVZ0YmwgSVdpbmVEM0RTdXJmYWNlX1Z0YmwgPQp7CiAgICAvKiBJVW5rbm93biAqLwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9RdWVyeUludGVyZmFjZSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfQWRkUmVmLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9SZWxlYXNlLAogICAgLyogSVdpbmVEM0RSZXNvdXJjZSAqLwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRQYXJlbnQsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldERldmljZSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0UHJpdmF0ZURhdGEsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldFByaXZhdGVEYXRhLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9GcmVlUHJpdmF0ZURhdGEsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1NldFByaW9yaXR5LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRQcmlvcml0eSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfUHJlTG9hZCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0VHlwZSwKICAgIC8qIElXaW5lRDNEU3VyZmFjZSAqLwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRDb250YWluZXIsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldERlc2MsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0xvY2tSZWN0LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9VbmxvY2tSZWN0LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXREQywKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfUmVsZWFzZURDLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9GbGlwLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9CbHQsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldEJsdFN0YXR1cywKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0RmxpcFN0YXR1cywKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfSXNMb3N0LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9SZXN0b3JlLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9CbHRGYXN0LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRQYWxldHRlLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRQYWxldHRlLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9SZWFsaXplUGFsZXR0ZSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0Q29sb3JLZXksCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldFBpdGNoLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRNZW0sCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1NldE92ZXJsYXlQb3NpdGlvbiwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0T3ZlcmxheVBvc2l0aW9uLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9VcGRhdGVPdmVybGF5Wk9yZGVyLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9VcGRhdGVPdmVybGF5LAogICAgLyogSW50ZXJuYWwgdXNlOiAqLwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9DbGVhbkRpcnR5UmVjdCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfQWRkRGlydHlSZWN0LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9Mb2FkVGV4dHVyZSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfU2F2ZVNuYXBzaG90LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRDb250YWluZXIsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1NldFBCdWZmZXJTdGF0ZSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0R2xUZXh0dXJlRGVzYywKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0R2xEZXNjLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXREYXRhLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRGb3JtYXQsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1ByaXZhdGVTZXR1cAp9Owo=