LyoKICogSVdpbmVEM0RTdXJmYWNlIEltcGxlbWVudGF0aW9uCiAqCiAqIENvcHlyaWdodCAxOTk4IExpb25lbCBVbG1lcgogKiBDb3B5cmlnaHQgMjAwMC0yMDAxIFRyYW5zR2FtaW5nIFRlY2hub2xvZ2llcyBJbmMuCiAqIENvcHlyaWdodCAyMDAyLTIwMDUgSmFzb24gRWRtZWFkZXMKICogQ29weXJpZ2h0IDIwMDItMjAwMyBSYXBoYWVsIEp1bnF1ZWlyYQogKiBDb3B5cmlnaHQgMjAwNCBDaHJpc3RpYW4gQ29zdGEKICogQ29weXJpZ2h0IDIwMDUgT2xpdmVyIFN0aWViZXIKICogQ29weXJpZ2h0IDIwMDYgU3RlZmFuIET2c2luZ2VyIGZvciBDb2RlV2VhdmVycwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCiNpbmNsdWRlICJ3aW5lL3BvcnQuaCIKI2luY2x1ZGUgIndpbmVkM2RfcHJpdmF0ZS5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoZDNkX3N1cmZhY2UpOwojZGVmaW5lIEdMSU5GT19MT0NBVElPTiAoKElXaW5lRDNESW1wbCAqKSgoKElXaW5lRDNERGV2aWNlSW1wbCAqKVRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2UpLT53aW5lRDNEKSktPmdsX2luZm8KCnR5cGVkZWYgZW51bSB7CiAgICBOT19DT05WRVJTSU9OLAogICAgQ09OVkVSVF9QQUxFVFRFRCwKICAgIENPTlZFUlRfUEFMRVRURURfQ0ssCiAgICBDT05WRVJUX0NLXzU2NSwKICAgIENPTlZFUlRfQ0tfNTU1MSwKICAgIENPTlZFUlRfQ0tfNDQ0NCwKICAgIENPTlZFUlRfQ0tfNDQ0NF9BUkdCLAogICAgQ09OVkVSVF9DS18xNTU1LAogICAgQ09OVkVSVF81NTUsCiAgICBDT05WRVJUX0NLX1JHQjI0LAogICAgQ09OVkVSVF9DS184ODg4LAogICAgQ09OVkVSVF9DS184ODg4X0FSR0IsCiAgICBDT05WRVJUX1JHQjMyXzg4OAp9IENPTlZFUlRfVFlQRVM7CgpIUkVTVUxUIGQzZGZtdF9jb252ZXJ0X3N1cmZhY2UoQllURSAqc3JjLCBCWVRFICpkc3QsIHVuc2lnbmVkIGxvbmcgbGVuLCBDT05WRVJUX1RZUEVTIGNvbnZlcnQsIElXaW5lRDNEU3VyZmFjZUltcGwgKnN1cmYpOwoKc3RhdGljIHZvaWQgc3VyZmFjZV9kb3dubG9hZF9kYXRhKElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMpIHsKICAgIGlmIChUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQxIHx8CiAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDIgfHwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMyB8fAogICAgICAgICAgICBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQ0IHx8IFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDUpIHsKICAgICAgICBpZiAoIUdMX1NVUFBPUlQoRVhUX1RFWFRVUkVfQ09NUFJFU1NJT05fUzNUQykpIHsgLyogV2UgY2FuIGFzc3VtZSB0aGlzIGFzIHRoZSB0ZXh0dXJlIHdvdWxkIG5vdCBoYXZlIGJlZW4gY3JlYXRlZCBvdGhlcndpc2UgKi8KICAgICAgICAgICAgRklYTUUoIiglcCkgOiBBdHRlbXB0aW5nIHRvIGxvY2sgYSBjb21wcmVzc2VkIHRleHR1cmUgd2hlbiB0ZXh0dXJlIGNvbXByZXNzaW9uIGlzbid0IHN1cHBvcnRlZCBieSBvcGVuZ2xcbiIsIFRoaXMpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIFRSQUNFKCIoJXApIDogQ2FsbGluZyBnbEdldENvbXByZXNzZWRUZXhJbWFnZUFSQiBsZXZlbCAlZCwgZm9ybWF0ICUjeCwgdHlwZSAlI3gsIGRhdGEgJXBcbiIsIFRoaXMsIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsCiAgICAgICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0LCBUaGlzLT5nbERlc2NyaXB0aW9uLmdsVHlwZSwgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKCiAgICAgICAgICAgIEVOVEVSX0dMKCk7CgogICAgICAgICAgICBHTF9FWFRDQUxMKGdsR2V0Q29tcHJlc3NlZFRleEltYWdlQVJCKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLCBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsR2V0Q29tcHJlc3NlZFRleEltYWdlQVJCKCkiKTsKCiAgICAgICAgICAgIExFQVZFX0dMKCk7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICBUUkFDRSgiKCVwKSA6IENhbGxpbmcgZ2xHZXRUZXhJbWFnZSBsZXZlbCAlZCwgZm9ybWF0ICUjeCwgdHlwZSAlI3gsIGRhdGEgJXBcbiIsIFRoaXMsIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsCiAgICAgICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0LCBUaGlzLT5nbERlc2NyaXB0aW9uLmdsVHlwZSwgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKCiAgICAgICAgRU5URVJfR0woKTsKCiAgICAgICAgZ2xHZXRUZXhJbWFnZShUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCwgVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCwgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdCwKICAgICAgICAgICAgICAgIFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xUeXBlLCBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEdldFRleEltYWdlKCkiKTsKCiAgICAgICAgTEVBVkVfR0woKTsKCiAgICAgICAgaWYgKHdpbmVkM2Rfc2V0dGluZ3Mubm9ucG93ZXIyX21vZGUgPT0gTlAyX1JFUEFDSykgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBTb21lIGdhbWVzIChlLmcuIHdhcmhhbW1lciA0MGspIGRvbid0IHdvcmsgcHJvcGVybHkgd2l0aCB0aGUgb2RkIHBpdGNoZXMsIHByZXZlbnRpbmcKICAgICAgICAgICAgICogdGhlIHN1cmZhY2UgcGl0Y2ggZnJvbSBiZWluZyB1c2VkIHRvIGJveCBub24tcG93ZXIyIHRleHR1cmVzLiBJbnN0ZWFkIHdlIGhhdmUgdG8gdXNlIGEgaGFjayB0bwogICAgICAgICAgICAgKiByZXBhY2sgdGhlIHRleHR1cmUgc28gdGhhdCB0aGUgYnBwICogd2lkdGggcGl0Y2ggY2FuIGJlIHVzZWQgaW5zdGVhZCBvZiBicHAgKiBwb3cyd2lkdGguCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIFdlJ3JlIGRvaW5nIHRoaXMuLi4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogaW5zdGVhZCBvZiBib3hpbmcgdGhlIHRleHR1cmUgOgogICAgICAgICAgICAgKiB8PC10ZXh0dXJlIHdpZHRoIC0+fCAgLS0+cG93MndpZHRofCAgIC9cCiAgICAgICAgICAgICAqIHwxMTExMTExMTExMTExMTExMTF8ICAgICAgICAgICAgICB8ICAgfAogICAgICAgICAgICAgKiB8MjIyIFRleHR1cmUgMjIyMjIyfCBib3hlZCBlbXB0eSAgfCB0ZXh0dXJlIGhlaWdodAogICAgICAgICAgICAgKiB8MzMzMyBEYXRhIDMzMzMzMzMzfCAgICAgICAgICAgICAgfCAgIHwKICAgICAgICAgICAgICogfDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NHwgICAgICAgICAgICAgIHwgICBcLwogICAgICAgICAgICAgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAgIHwKICAgICAgICAgICAgICogfCAgICAgYm94ZWQgIGVtcHR5IHwgYm94ZWQgZW1wdHkgIHwgcG93MmhlaWdodAogICAgICAgICAgICAgKiB8ICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgfCAgIFwvCiAgICAgICAgICAgICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIHdlJ3JlIHJlcGFja2luZyB0aGUgZGF0YSB0byB0aGUgZXhwZWN0ZWQgdGV4dHVyZSB3aWR0aAogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiB8PC10ZXh0dXJlIHdpZHRoIC0+fCAgLS0+cG93MndpZHRofCAgIC9cCiAgICAgICAgICAgICAqIHwxMTExMTExMTExMTExMTExMTEyMjIyMjIyMjIyMjIyMjJ8ICAgfAogICAgICAgICAgICAgKiB8MjIyMzMzMzMzMzMzMzMzMzMzMzMzNDQ0NDQ0NDQ0NDQ0fCB0ZXh0dXJlIGhlaWdodAogICAgICAgICAgICAgKiB8NDQ0NDQ0ICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgIHwKICAgICAgICAgICAgICogfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICBcLwogICAgICAgICAgICAgKiB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgIHwKICAgICAgICAgICAgICogfCAgICAgICAgICAgIGVtcHR5ICAgICAgICAgICAgICAgIHwgcG93MmhlaWdodAogICAgICAgICAgICAgKiB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgIFwvCiAgICAgICAgICAgICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqID09IGlzIHRoZSBzYW1lIGFzCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIHw8LXRleHR1cmUgd2lkdGggLT58ICAgIC9cCiAgICAgICAgICAgICAqIHwxMTExMTExMTExMTExMTExMTF8CiAgICAgICAgICAgICAqIHwyMjIyMjIyMjIyMjIyMjIyMjJ8dGV4dHVyZSBoZWlnaHQKICAgICAgICAgICAgICogfDMzMzMzMzMzMzMzMzMzMzMzM3wKICAgICAgICAgICAgICogfDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NHwgICAgXC8KICAgICAgICAgICAgICogLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogdGhpcyBhbHNvIG1lYW5zIHRoYXQgYW55IHJlZmVyZW5jZXMgdG8gYWxsb2NhdGVkTWVtb3J5IHNob3VsZCB3b3JrIHdpdGggdGhlIGRhdGEgYXMgaWYgd2VyZSBhCiAgICAgICAgICAgICAqIHN0YW5kYXJkIHRleHR1cmUgd2l0aCBhIG5vbi1wb3dlcjIgd2lkdGggaW5zdGVhZCBvZiB0ZXh0dXJlIGJveGVkIHVwIHRvIGJlIGEgcG93ZXIyIHRleHR1cmUuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIGludGVybmFsbHkgdGhlIHRleHR1cmUgaXMgc3RpbGwgc3RvcmVkIGluIGEgYm94ZWQgZm9ybWF0IHNvIGFueSByZWZlcmVuY2VzIHRvIHRleHR1cmVOYW1lIHdpbGwKICAgICAgICAgICAgICogZ2V0IGEgYm94ZWQgdGV4dHVyZSB3aXRoIHdpZHRoIHBvdzJ3aWR0aCBhbmQgbm90IGEgdGV4dHVyZSBvZiB3aWR0aCBjdXJyZW50RGVzYy5XaWR0aC4KICAgICAgICAgICAgICovCgogICAgICAgICAgICBpZiAoVGhpcy0+RmxhZ3MgJiBTRkxBR19OT05QT1cyKSB7CiAgICAgICAgICAgICAgICBMUEJZVEUgc3JjX2RhdGEsIGRzdF9kYXRhOwogICAgICAgICAgICAgICAgaW50IHNyY19waXRjaCA9IFRoaXMtPmJ5dGVzUGVyUGl4ZWwgKiBUaGlzLT5wb3cyV2lkdGg7CiAgICAgICAgICAgICAgICBpbnQgZHN0X3BpdGNoID0gVGhpcy0+Ynl0ZXNQZXJQaXhlbCAqIFRoaXMtPmN1cnJlbnREZXNjLldpZHRoOwogICAgICAgICAgICAgICAgaW50IHk7CgogICAgICAgICAgICAgICAgc3JjX2RhdGEgPSBkc3RfZGF0YSA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeTsKICAgICAgICAgICAgICAgIEZJWE1FKCIoJXApIDogUmVwYWNraW5nIHRoZSBzdXJmYWNlIGRhdGEgZnJvbSBwaXRjaCAlZCB0byBwaXRjaCAlZFxuIiwgVGhpcywgc3JjX3BpdGNoLCBkc3RfcGl0Y2gpOwogICAgICAgICAgICAgICAgZm9yICh5ID0gMSA7IHkgPCBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQ7IHkrKykgewogICAgICAgICAgICAgICAgICAgIC8qIHNraXAgdGhlIGZpcnN0IHJvdyAqLwogICAgICAgICAgICAgICAgICAgIHNyY19kYXRhICs9IHNyY19waXRjaDsKICAgICAgICAgICAgICAgICAgICBkc3RfZGF0YSArPSBkc3RfcGl0Y2g7CiAgICAgICAgICAgICAgICAgICAgbWVtY3B5KGRzdF9kYXRhLCBzcmNfZGF0YSwgZHN0X3BpdGNoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfQoKc3RhdGljIHZvaWQgc3VyZmFjZV91cGxvYWRfZGF0YShJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzLCBHTHNpemVpIHdpZHRoLCBHTHNpemVpIGhlaWdodCwgR0xlbnVtIGZvcm1hdCwgR0xlbnVtIHR5cGUsIGNvbnN0IEdMdm9pZCAqZGF0YSkgewogICAgaWYgKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDEgfHwKICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMiB8fCBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQzIHx8CiAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDQgfHwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNSkgewogICAgICAgIGlmICghR0xfU1VQUE9SVChFWFRfVEVYVFVSRV9DT01QUkVTU0lPTl9TM1RDKSkgewogICAgICAgICAgICBGSVhNRSgiVXNpbmcgRFhUMS8zLzUgd2l0aG91dCBhZHZlcnRpemVkIHN1cHBvcnRcbiIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIFRSQUNFKCIoJXApIDogQ2FsbGluZyBnbENvbXByZXNzZWRUZXhTdWJJbWFnZTJEIHcgJWQsIGggJWQsIGRhdGEgJXBcbiIsIFRoaXMsIHdpZHRoLCBoZWlnaHQsIGRhdGEpOwogICAgICAgICAgICBFTlRFUl9HTCgpOwogICAgICAgICAgICBHTF9FWFRDQUxMKGdsQ29tcHJlc3NlZFRleFN1YkltYWdlMkRBUkIoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsIDAsIDAsIHdpZHRoLCBoZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdEludGVybmFsLCBUaGlzLT5yZXNvdXJjZS5zaXplLCBkYXRhKSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbENvbXByZXNzZWRUZXhTdWJJbWFnZTJEIik7CiAgICAgICAgICAgIExFQVZFX0dMKCk7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICBUUkFDRSgiKCVwKSA6IENhbGxpbmcgZ2xUZXhTdWJJbWFnZTJEIHcgJWQsICBoICVkLCBkYXRhLCAlcFxuIiwgVGhpcywgd2lkdGgsIGhlaWdodCwgZGF0YSk7CiAgICAgICAgRU5URVJfR0woKTsKICAgICAgICBnbFRleFN1YkltYWdlMkQoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsIDAsIDAsIHdpZHRoLCBoZWlnaHQsIGZvcm1hdCwgdHlwZSwgZGF0YSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsVGV4U3ViSW1hZ2UyRCIpOwogICAgICAgIExFQVZFX0dMKCk7CiAgICB9Cn0KCnN0YXRpYyB2b2lkIHN1cmZhY2VfYWxsb2NhdGVfc3VyZmFjZShJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzLCBHTGVudW0gaW50ZXJuYWwsIEdMc2l6ZWkgd2lkdGgsIEdMc2l6ZWkgaGVpZ2h0LCBHTGVudW0gZm9ybWF0LCBHTGVudW0gdHlwZSkgewogICAgVFJBQ0UoIiglcCkgOiBDcmVhdGluZyBzdXJmYWNlICh0YXJnZXQgJSN4KSAgbGV2ZWwgJWQsIGQzZCBmb3JtYXQgJXMsIGludGVybmFsIGZvcm1hdCAlI3gsIHdpZHRoICVkLCBoZWlnaHQgJWQsIGdsIGZvcm1hdCAlI3gsIGdsIHR5cGU9JSN4XG4iLCBUaGlzLAogICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCwgVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCwgZGVidWdfZDNkZm9ybWF0KFRoaXMtPnJlc291cmNlLmZvcm1hdCksIGludGVybmFsLCB3aWR0aCwgaGVpZ2h0LCBmb3JtYXQsIHR5cGUpOwoKICAgIEVOVEVSX0dMKCk7CgogICAgZ2xUZXhJbWFnZTJEKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLCBpbnRlcm5hbCwgd2lkdGgsIGhlaWdodCwgMCwgZm9ybWF0LCB0eXBlLCBOVUxMKTsKICAgIGNoZWNrR0xjYWxsKCJnbFRleEltYWdlMkQiKTsKCiAgICBMRUFWRV9HTCgpOwp9CgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgIElXaW5lRDNEU3VyZmFjZSBJVW5rbm93biBwYXJ0cyBmb2xsb3cKICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqLwpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1F1ZXJ5SW50ZXJmYWNlKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIFJFRklJRCByaWlkLCBMUFZPSUQgKnBwb2JqKQp7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIC8qIFdhcm4gLGJ1dCBiZSBuaWNlIGFib3V0IHRoaW5ncyAqLwogICAgVFJBQ0UoIiglcCktPiglcywlcClcbiIsIFRoaXMsZGVidWdzdHJfZ3VpZChyaWlkKSxwcG9iaik7CiAgICBpZiAocmlpZCA9PSBOVUxMKSB7CiAgICAgICAgRVJSKCJQcm9iYWJseSBGSVhNRTogQ2FsbGluZyBxdWVyeSBpbnRlcmZhY2Ugd2l0aCBOVUxMIHJpaWRcbiIpOwogICAgfQogICAgaWYgKElzRXF1YWxHVUlEKHJpaWQsICZJSURfSVVua25vd24pCiAgICAgICAgfHwgSXNFcXVhbEdVSUQocmlpZCwgJklJRF9JV2luZUQzREJhc2UpCiAgICAgICAgfHwgSXNFcXVhbEdVSUQocmlpZCwgJklJRF9JV2luZUQzRFJlc291cmNlKQogICAgICAgIHx8IElzRXF1YWxHVUlEKHJpaWQsICZJSURfSVdpbmVEM0RTdXJmYWNlKSkgewogICAgICAgIElVbmtub3duX0FkZFJlZigoSVVua25vd24qKWlmYWNlKTsKICAgICAgICAqcHBvYmogPSBUaGlzOwogICAgICAgIHJldHVybiBTX09LOwogICAgfQogICAgKnBwb2JqID0gTlVMTDsKICAgIHJldHVybiBFX05PSU5URVJGQUNFOwp9CgpVTE9ORyBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9BZGRSZWYoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVzb3VyY2UucmVmKTsKICAgIFRSQUNFKCIoJXApIDogQWRkUmVmIGluY3JlYXNpbmcgZnJvbSAlbGRcbiIsIFRoaXMscmVmIC0gMSk7CiAgICByZXR1cm4gcmVmOwp9CgpVTE9ORyBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9SZWxlYXNlKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgVUxPTkcgcmVmID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJlRoaXMtPnJlc291cmNlLnJlZik7CiAgICBUUkFDRSgiKCVwKSA6IFJlbGVhc2luZyBmcm9tICVsZFxuIiwgVGhpcywgcmVmICsgMSk7CiAgICBpZiAocmVmID09IDApIHsKICAgICAgICBJV2luZUQzRERldmljZUltcGwgKmRldmljZSA9IChJV2luZUQzRERldmljZUltcGwgKikgVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZTsKICAgICAgICBUUkFDRSgiKCVwKSA6IGNsZWFuaW5nIHVwXG4iLCBUaGlzKTsKICAgICAgICBpZiAoVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSAhPSAwKSB7IC8qIHJlbGVhc2UgdGhlIG9wZW5HTCB0ZXh0dXJlLi4gKi8KICAgICAgICAgICAgRU5URVJfR0woKTsKICAgICAgICAgICAgVFJBQ0UoIkRlbGV0aW5nIHRleHR1cmUgJWRcbiIsIFRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpOwogICAgICAgICAgICBnbERlbGV0ZVRleHR1cmVzKDEsICZUaGlzLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lKTsKICAgICAgICAgICAgTEVBVkVfR0woKTsKICAgICAgICB9CgogICAgICAgIGlmKFRoaXMtPkZsYWdzICYgU0ZMQUdfRElCU0VDVElPTikgewogICAgICAgICAgICAvKiBSZWxlYXNlIHRoZSBEQyAqLwogICAgICAgICAgICBTZWxlY3RPYmplY3QoVGhpcy0+aERDLCBUaGlzLT5kaWIuaG9sZGJpdG1hcCk7CiAgICAgICAgICAgIERlbGV0ZURDKFRoaXMtPmhEQyk7CiAgICAgICAgICAgIC8qIFJlbGVhc2UgdGhlIERJQiBzZWN0aW9uICovCiAgICAgICAgICAgIERlbGV0ZU9iamVjdChUaGlzLT5kaWIuRElCc2VjdGlvbik7CiAgICAgICAgICAgIFRoaXMtPmRpYi5iaXRtYXBfZGF0YSA9IE5VTEw7CiAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IE5VTEw7CiAgICAgICAgfQogICAgICAgIGlmKFRoaXMtPkZsYWdzICYgU0ZMQUdfVVNFUlBUUikgSVdpbmVEM0RTdXJmYWNlX1NldE1lbShpZmFjZSwgTlVMTCk7CgogICAgICAgIElXaW5lRDNEUmVzb3VyY2VJbXBsX0NsZWFuVXAoKElXaW5lRDNEUmVzb3VyY2UgKilpZmFjZSk7CiAgICAgICAgaWYoaWZhY2UgPT0gZGV2aWNlLT5kZHJhd19wcmltYXJ5KQogICAgICAgICAgICBkZXZpY2UtPmRkcmF3X3ByaW1hcnkgPSBOVUxMOwoKICAgICAgICBUUkFDRSgiKCVwKSBSZWxlYXNlZFxuIiwgVGhpcyk7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcyk7CgogICAgfQogICAgcmV0dXJuIHJlZjsKfQoKLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogICBJV2luZUQzRFN1cmZhY2UgSVdpbmVEM0RSZXNvdXJjZSBwYXJ0cyBmb2xsb3cKICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqLwpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0dldERldmljZShJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBJV2luZUQzRERldmljZSoqIHBwRGV2aWNlKSB7CiAgICByZXR1cm4gSVdpbmVEM0RSZXNvdXJjZUltcGxfR2V0RGV2aWNlKChJV2luZUQzRFJlc291cmNlICopaWZhY2UsIHBwRGV2aWNlKTsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRQcml2YXRlRGF0YShJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBSRUZHVUlEIHJlZmd1aWQsIENPTlNUIHZvaWQqIHBEYXRhLCBEV09SRCBTaXplT2ZEYXRhLCBEV09SRCBGbGFncykgewogICAgcmV0dXJuIElXaW5lRDNEUmVzb3VyY2VJbXBsX1NldFByaXZhdGVEYXRhKChJV2luZUQzRFJlc291cmNlICopaWZhY2UsIHJlZmd1aWQsIHBEYXRhLCBTaXplT2ZEYXRhLCBGbGFncyk7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0UHJpdmF0ZURhdGEoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgUkVGR1VJRCByZWZndWlkLCB2b2lkKiBwRGF0YSwgRFdPUkQqIHBTaXplT2ZEYXRhKSB7CiAgICByZXR1cm4gSVdpbmVEM0RSZXNvdXJjZUltcGxfR2V0UHJpdmF0ZURhdGEoKElXaW5lRDNEUmVzb3VyY2UgKilpZmFjZSwgcmVmZ3VpZCwgcERhdGEsIHBTaXplT2ZEYXRhKTsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9GcmVlUHJpdmF0ZURhdGEoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgUkVGR1VJRCByZWZndWlkKSB7CiAgICByZXR1cm4gSVdpbmVEM0RSZXNvdXJjZUltcGxfRnJlZVByaXZhdGVEYXRhKChJV2luZUQzRFJlc291cmNlICopaWZhY2UsIHJlZmd1aWQpOwp9CgpEV09SRCAgIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1NldFByaW9yaXR5KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIERXT1JEIFByaW9yaXR5TmV3KSB7CiAgICByZXR1cm4gSVdpbmVEM0RSZXNvdXJjZUltcGxfU2V0UHJpb3JpdHkoKElXaW5lRDNEUmVzb3VyY2UgKilpZmFjZSwgUHJpb3JpdHlOZXcpOwp9CgpEV09SRCAgIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0dldFByaW9yaXR5KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpIHsKICAgIHJldHVybiBJV2luZUQzRFJlc291cmNlSW1wbF9HZXRQcmlvcml0eSgoSVdpbmVEM0RSZXNvdXJjZSAqKWlmYWNlKTsKfQoKdm9pZCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9QcmVMb2FkKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpIHsKICAgIC8qIFRPRE86IHJlLXdyaXRlIHRoZSB3YXkgdGV4dHVyZXMgYW5kIG1hbmFnZWQsCiAgICAqICB1c2UgYSAnb3BlbmdsIGNvbnRleHQgbWFuYWdlcicgdG8gbWFuYWdlIFJlbmRlclRhcmdldCBzdXJmYWNlcwogICAgKiogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICAgIC8qIFRPRE86IGNoZWNrIGZvciBsb2NrcyAqLwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzREJhc2VUZXh0dXJlICpiYXNlVGV4dHVyZSA9IE5VTEw7CiAgICBUUkFDRSgiKCVwKUNoZWNraW5nIHRvIHNlZSBpZiB0aGUgY29udGFpbmVyIGlzIGEgYmFzZSB0ZXh0dXJlXG4iLCBUaGlzKTsKICAgIGlmIChJV2luZUQzRFN1cmZhY2VfR2V0Q29udGFpbmVyKGlmYWNlLCAmSUlEX0lXaW5lRDNEQmFzZVRleHR1cmUsICh2b2lkICoqKSZiYXNlVGV4dHVyZSkgPT0gV0lORUQzRF9PSykgewogICAgICAgIFRSQUNFKCJQYXNzaW5nIHRvIGNvbmF0aW5lclxuIik7CiAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9QcmVMb2FkKGJhc2VUZXh0dXJlKTsKICAgICAgICBJV2luZUQzREJhc2VUZXh0dXJlX1JlbGVhc2UoYmFzZVRleHR1cmUpOwogICAgfSBlbHNlIHsKICAgIFRSQUNFKCIoJXApIDogQWJvdXQgdG8gbG9hZCBzdXJmYWNlXG4iLCBUaGlzKTsKICAgIEVOVEVSX0dMKCk7CiNpZiAwIC8qIFRPRE86IGNvbnRleHQgbWFuYWdlciBzdXBwb3J0ICovCiAgICAgSVdpbmVEM0RDb250ZXh0TWFuYWdlcl9QdXNoU3RhdGUoVGhpcy0+Y29udGV4dE1hbmFnZXIsIEdMX1RFWFRVUkVfMkQsIEVOQUJMRUQsIE5PVyAvKiBtYWtlIHN1cmUgdGhlIHN0YXRlIGlzIGFwcGxpZWQgbm93ICovKTsKI2VuZGlmCiAgICBnbEVuYWJsZShUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCk7LyogbWFrZSBzdXJlIHRleHR1cmUgc3VwcG9ydCBpcyBlbmFibGVkIGluIHRoaXMgY29udGV4dCAqLwogICAgaWYgKCFUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsKSB7CiAgICAgICAgaWYgKCFUaGlzLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lKSB7CiAgICAgICAgICAgIGdsR2VuVGV4dHVyZXMoMSwgJlRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xHZW5UZXh0dXJlcyIpOwogICAgICAgICAgICBUUkFDRSgiU3VyZmFjZSAlcCBnaXZlbiBuYW1lICVkXG4iLCBUaGlzLCBUaGlzLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lKTsKICAgICAgICB9CiAgICAgICAgZ2xCaW5kVGV4dHVyZShUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCwgVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQmluZFRleHR1cmUiKTsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfTG9hZFRleHR1cmUoaWZhY2UpOwogICAgICAgIC8qIFRoaXMgaXMgd2hlcmUgd2Ugc2hvdWxkIGJlIHJlZHVjaW5nIHRoZSBhbW91bnQgb2YgR0xNZW1vcnlVc2VkICovCiAgICB9IGVsc2UgaWYgKFRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpIHsgLyogTk9URTogdGhlIGxldmVsIDAgc3VyZmFjZSBvZiBhIG1wbWFwcGVkIHRleHR1cmUgbXVzdCBiZSBsb2FkZWQgZmlyc3QhICovCiAgICAgICAgLyogYXNzdW1lIHRoaXMgaXMgYSBjb2RpbmcgZXJyb3Igbm90IGEgcmVhbCBlcnJvciBmb3Igbm93ICovCiAgICAgICAgRklYTUUoIk1pcG1hcCBzdXJmYWNlIGhhcyBhIGdsVGV4dHVyZSBib3VuZCB0byBpdCFcbiIpOwogICAgfQogICAgaWYgKFRoaXMtPnJlc291cmNlLnBvb2wgPT0gV0lORUQzRFBPT0xfREVGQVVMVCkgewogICAgICAgLyogVGVsbCBvcGVuZ2wgdG8gdHJ5IGFuZCBrZWVwIHRoaXMgdGV4dHVyZSBpbiB2aWRlbyByYW0gKHdlbGwgbW9zdGx5KSAqLwogICAgICAgR0xjbGFtcGYgdG1wOwogICAgICAgdG1wID0gMC45ZjsKICAgICAgICBnbFByaW9yaXRpemVUZXh0dXJlcygxLCAmVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSwgJnRtcCk7CiAgICB9CiAgICAvKiBUT0RPOiBkaXNhYmxlIHRleHR1cmUgc3VwcG9ydCwgaWYgaXQgd2FzdG4ndCBlbmFibGVkIHdoZW4gd2UgZW50ZXJlZC4gKi8KI2lmIDAgLyogVE9ETzogY29udGV4dCBtYW5hZ2VyIHN1cHBvcnQgKi8KICAgICBJV2luZUQzRENvbnRleHRNYW5hZ2VyX1BvcFN0YXRlKFRoaXMtPmNvbnRleHRNYW5hZ2VyLCBHTF9URVhUVVJFXzJELCBESVNBQkxFRCxERUxBWUVECiAgICAgICAgICAgICAgLyogd2UgZG9uJ3QgY2FyZSB3aGVuIHRoZSBzdGF0ZSBpcyBkaXNhYmxlZChpZiBhdGFsbCkgKi8pOwojZW5kaWYKICAgIExFQVZFX0dMKCk7CiAgICB9CiAgICByZXR1cm47Cn0KCldJTkVEM0RSRVNPVVJDRVRZUEUgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0VHlwZShJV2luZUQzRFN1cmZhY2UgKmlmYWNlKSB7CiAgICBUUkFDRSgiKCVwKSA6IGNhbGxpbmcgcmVzb3VyY2VpbXBsX0dldFR5cGVcbiIsIGlmYWNlKTsKICAgIHJldHVybiBJV2luZUQzRFJlc291cmNlSW1wbF9HZXRUeXBlKChJV2luZUQzRFJlc291cmNlICopaWZhY2UpOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0dldFBhcmVudChJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBJVW5rbm93biAqKnBQYXJlbnQpIHsKICAgIFRSQUNFKCIoJXApIDogY2FsbGluZyByZXNvdXJjZWltcGxfR2V0UGFyZW50XG4iLCBpZmFjZSk7CiAgICByZXR1cm4gSVdpbmVEM0RSZXNvdXJjZUltcGxfR2V0UGFyZW50KChJV2luZUQzRFJlc291cmNlICopaWZhY2UsIHBQYXJlbnQpOwp9CgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICAgSVdpbmVEM0RTdXJmYWNlIElXaW5lRDNEU3VyZmFjZSBwYXJ0cyBmb2xsb3cKICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovCgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0dldENvbnRhaW5lclBhcmVudChJV2luZUQzRFN1cmZhY2UqIGlmYWNlLCBJVW5rbm93biAqKnBwQ29udGFpbmVyUGFyZW50KSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKCiAgICBUUkFDRSgiKCVwKSA6IHBwQ29udGFpbmVyUGFyZW50ICVwKVxuIiwgVGhpcywgcHBDb250YWluZXJQYXJlbnQpOwoKICAgIGlmICghcHBDb250YWluZXJQYXJlbnQpIHsKICAgICAgICBFUlIoIiglcCkgOiBDYWxsZWQgd2l0aG91dCBhIHZhbGlkIHBwQ29udGFpbmVyUGFyZW50LlxuIiwgVGhpcyk7CiAgICB9CgogICAgaWYgKFRoaXMtPmNvbnRhaW5lcikgewogICAgICAgIElXaW5lRDNEQmFzZV9HZXRQYXJlbnQoVGhpcy0+Y29udGFpbmVyLCBwcENvbnRhaW5lclBhcmVudCk7CiAgICAgICAgaWYgKCFwcENvbnRhaW5lclBhcmVudCkgewogICAgICAgICAgICAvKiBXaW5lRDNEIG9iamVjdHMgc2hvdWxkIGFsd2F5cyBoYXZlIGEgcGFyZW50ICovCiAgICAgICAgICAgIEVSUigiKCVwKSA6IEdldFBhcmVudCByZXR1cm5lZCBOVUxMXG4iLCBUaGlzKTsKICAgICAgICB9CiAgICAgICAgSVVua25vd25fUmVsZWFzZSgqcHBDb250YWluZXJQYXJlbnQpOyAvKiBHZXRQYXJlbnQgYWRkcyBhIHJlZmVyZW5jZTsgd2Ugd2FudCBqdXN0IHRoZSBwb2ludGVyICovCiAgICB9IGVsc2UgewogICAgICAgICpwcENvbnRhaW5lclBhcmVudCA9IE5VTEw7CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0Q29udGFpbmVyKElXaW5lRDNEU3VyZmFjZSogaWZhY2UsIFJFRklJRCByaWlkLCB2b2lkKiogcHBDb250YWluZXIpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RCYXNlICpjb250YWluZXIgPSAwOwoKICAgIFRSQUNFKCIoVGhpcyAlcCwgcmlpZCAlcywgcHBDb250YWluZXIgJXApXG4iLCBUaGlzLCBkZWJ1Z3N0cl9ndWlkKHJpaWQpLCBwcENvbnRhaW5lcik7CgogICAgaWYgKCFwcENvbnRhaW5lcikgewogICAgICAgIEVSUigiQ2FsbGVkIHdpdGhvdXQgYSB2YWxpZCBwcENvbnRhaW5lci5cbiIpOwogICAgfQoKICAgIC8qKiBGcm9tIE1TRE46CiAgICAgKiBJZiB0aGUgc3VyZmFjZSBpcyBjcmVhdGVkIHVzaW5nIENyZWF0ZUltYWdlU3VyZmFjZS9DcmVhdGVPZmZzY3JlZW5QbGFpblN1cmZhY2UsIENyZWF0ZVJlbmRlclRhcmdldCwKICAgICAqIG9yIENyZWF0ZURlcHRoU3RlbmNpbFN1cmZhY2UsIHRoZSBzdXJmYWNlIGlzIGNvbnNpZGVyZWQgc3RhbmQgYWxvbmUuIEluIHRoaXMgY2FzZSwKICAgICAqIEdldENvbnRhaW5lciB3aWxsIHJldHVybiB0aGUgRGlyZWN0M0QgZGV2aWNlIHVzZWQgdG8gY3JlYXRlIHRoZSBzdXJmYWNlLgogICAgICovCiAgICBpZiAoVGhpcy0+Y29udGFpbmVyKSB7CiAgICAgICAgY29udGFpbmVyID0gVGhpcy0+Y29udGFpbmVyOwogICAgfSBlbHNlIHsKICAgICAgICBjb250YWluZXIgPSAoSVdpbmVEM0RCYXNlICopVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZTsKICAgIH0KCiAgICBUUkFDRSgiUmVsYXlpbmcgdG8gUXVlcnlJbnRlcmZhY2VcbiIpOwogICAgcmV0dXJuIElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGNvbnRhaW5lciwgcmlpZCwgcHBDb250YWluZXIpOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0dldERlc2MoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgV0lORUQzRFNVUkZBQ0VfREVTQyAqcERlc2MpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwoKICAgIFRSQUNFKCIoJXApIDogY29weWluZyBpbnRvICVwXG4iLCBUaGlzLCBwRGVzYyk7CiAgICBpZihwRGVzYy0+Rm9ybWF0ICE9IE5VTEwpICAgICAgICAgICAgICoocERlc2MtPkZvcm1hdCkgPSBUaGlzLT5yZXNvdXJjZS5mb3JtYXQ7CiAgICBpZihwRGVzYy0+VHlwZSAhPSBOVUxMKSAgICAgICAgICAgICAgICoocERlc2MtPlR5cGUpICAgPSBUaGlzLT5yZXNvdXJjZS5yZXNvdXJjZVR5cGU7CiAgICBpZihwRGVzYy0+VXNhZ2UgIT0gTlVMTCkgICAgICAgICAgICAgICoocERlc2MtPlVzYWdlKSAgICAgICAgICAgICAgPSBUaGlzLT5yZXNvdXJjZS51c2FnZTsKICAgIGlmKHBEZXNjLT5Qb29sICE9IE5VTEwpICAgICAgICAgICAgICAgKihwRGVzYy0+UG9vbCkgICAgICAgICAgICAgICA9IFRoaXMtPnJlc291cmNlLnBvb2w7CiAgICBpZihwRGVzYy0+U2l6ZSAhPSBOVUxMKSAgICAgICAgICAgICAgICoocERlc2MtPlNpemUpICAgICAgICAgICAgICAgPSBUaGlzLT5yZXNvdXJjZS5zaXplOyAgIC8qIGR4OCBvbmx5ICovCiAgICBpZihwRGVzYy0+TXVsdGlTYW1wbGVUeXBlICE9IE5VTEwpICAgICoocERlc2MtPk11bHRpU2FtcGxlVHlwZSkgICAgPSBUaGlzLT5jdXJyZW50RGVzYy5NdWx0aVNhbXBsZVR5cGU7CiAgICBpZihwRGVzYy0+TXVsdGlTYW1wbGVRdWFsaXR5ICE9IE5VTEwpICoocERlc2MtPk11bHRpU2FtcGxlUXVhbGl0eSkgPSBUaGlzLT5jdXJyZW50RGVzYy5NdWx0aVNhbXBsZVF1YWxpdHk7CiAgICBpZihwRGVzYy0+V2lkdGggIT0gTlVMTCkgICAgICAgICAgICAgICoocERlc2MtPldpZHRoKSAgICAgICAgICAgICAgPSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgIGlmKHBEZXNjLT5IZWlnaHQgIT0gTlVMTCkgICAgICAgICAgICAgKihwRGVzYy0+SGVpZ2h0KSAgICAgICAgICAgICA9IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9Cgp2b2lkIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1NldEdsVGV4dHVyZURlc2MoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgVUlOVCB0ZXh0dXJlTmFtZSwgaW50IHRhcmdldCkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKSA6IHNldHRpbmcgdGV4dHVyZU5hbWUgJXUsIHRhcmdldCAlaVxuIiwgVGhpcywgdGV4dHVyZU5hbWUsIHRhcmdldCk7CiAgICBpZiAoVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSA9PSAwICYmIHRleHR1cmVOYW1lICE9IDApIHsKICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19ESVJUWTsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfQWRkRGlydHlSZWN0KGlmYWNlLCBOVUxMKTsKICAgIH0KICAgIFRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUgPSB0ZXh0dXJlTmFtZTsKICAgIFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0ICAgICAgPSB0YXJnZXQ7Cn0KCnZvaWQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0R2xEZXNjKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIGdsRGVzY3JpcHRvciAqKmdsRGVzY3JpcHRpb24pIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCkgOiByZXR1cm5pbmcgJXBcbiIsIFRoaXMsICZUaGlzLT5nbERlc2NyaXB0aW9uKTsKICAgICpnbERlc2NyaXB0aW9uID0gJlRoaXMtPmdsRGVzY3JpcHRpb247Cn0KCi8qIFRPRE86IHRoaW5rIGFib3V0IG1vdmluZyB0aGlzIGRvd24gdG8gcmVzb3VyY2U/ICovCmNvbnN0IHZvaWQgKldJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0dldERhdGEoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICAvKiBUaGlzIHNob3VsZCBvbmx5IGJlIGNhbGxlZCBmb3Igc3lzbWVtIHRleHR1cmVzLCBpdCBtYXkgYmUgYSBnb29kIGlkZWEgdG8gZXh0ZW5kIHRoaXMgdG8gYWxsIHBvb2xzIGF0IHNvbWUgcG9pbnQgaW4gdGhlIGZ1dHR1cmUgICovCiAgICBpZiAoVGhpcy0+cmVzb3VyY2UucG9vbCAhPSBXSU5FRDNEUE9PTF9TWVNURU1NRU0pIHsKICAgICAgICBGSVhNRSgiICglcClBdHRlbXB0aW5nIHRvIGdldCBzeXN0ZW0gbWVtb3J5IGZvciBhIG5vbi1zeXN0ZW0gbWVtb3J5IHRleHR1cmVcbiIsIGlmYWNlKTsKICAgIH0KICAgIHJldHVybiAoQ09OU1Qgdm9pZCopKFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSk7Cn0KCnN0YXRpYyB2b2lkIHJlYWRfZnJvbV9mcmFtZWJ1ZmZlcihJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzLCBDT05TVCBSRUNUICpyZWN0LCB2b2lkICpkZXN0LCBVSU5UIHBpdGNoKSB7CiAgICBsb25nIGo7CiAgICB2b2lkICptZW07CiAgICBHTGludCBmbXQ7CiAgICBHTGludCB0eXBlOwoKICAgIHN3aXRjaChUaGlzLT5yZXNvdXJjZS5mb3JtYXQpCiAgICB7CiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1A4OgogICAgICAgIHsKICAgICAgICAgICAgLyogR0wgY2FuJ3QgcmV0dXJuIHBhbGV0dGl6ZWQgZGF0YSwgc28gcmVhZCBBUkdCIHBpeGVscyBpbnRvIGEKICAgICAgICAgICAgICogc2VwYXJhdGUgYmxvY2sgb2YgbWVtb3J5IGFuZCBjb252ZXJ0IHRoZW0gaW50byBwYWxldHRpemVkIGZvcm1hdAogICAgICAgICAgICAgKiBpbiBzb2Z0d2FyZS4gU2xvdywgYnV0IGlmIHRoZSBhcHAgbWVhbnMgdG8gdXNlIHBhbGV0dGl6ZWQgcmVuZGVyCiAgICAgICAgICAgICAqIHRhcmdldHMgYW5kIGxvY2tzIGl0Li4uCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIFVzZSBHTF9SR0IsIEdMX1VOU0lHTkVEX0JZVEUgdG8gcmVhZCB0aGUgc3VyZmFjZSBmb3IgcGVyZm9ybWFuY2UgcmVhc29ucwogICAgICAgICAgICAgKiBEb24ndCB1c2UgR0xfQkdSIGFzIGluIHRoZSBXSU5FRDNERk1UX1I4RzhCOCBjYXNlLCBpbnN0ZWFkIHdhdGNoIG91dAogICAgICAgICAgICAgKiBmb3IgdGhlIGNvbG9yIGNoYW5uZWxzIHdoZW4gcGFsZXR0aXppbmcgdGhlIGNvbG9ycy4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGZtdCA9IEdMX1JHQjsKICAgICAgICAgICAgdHlwZSA9IEdMX1VOU0lHTkVEX0JZVEU7CiAgICAgICAgICAgIHBpdGNoICo9IDM7CiAgICAgICAgICAgIG1lbSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCAocmVjdC0+Ym90dG9tIC0gcmVjdC0+dG9wKSAqIHBpdGNoKTsKICAgICAgICAgICAgaWYoIW1lbSkgewogICAgICAgICAgICAgICAgRVJSKCJPdXQgb2YgbWVtb3J5XG4iKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgbWVtID0gZGVzdDsKICAgICAgICAgICAgZm10ID0gVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdDsKICAgICAgICAgICAgdHlwZSA9IFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xUeXBlOwogICAgfQoKICAgIGlmIChyZWN0LT5sZWZ0ID09IDAgJiYKICAgICAgICByZWN0LT5yaWdodCA9PSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCApIHsKICAgICAgICBCWVRFICpyb3csICp0b3AsICpib3R0b207CiAgICAgICAgaW50IGk7CgogICAgICAgIGdsUmVhZFBpeGVscygwLCByZWN0LT50b3AsCiAgICAgICAgICAgICAgICAgICAgIFRoaXMtPmN1cnJlbnREZXNjLldpZHRoLAogICAgICAgICAgICAgICAgICAgICByZWN0LT5ib3R0b20gLSByZWN0LT50b3AsCiAgICAgICAgICAgICAgICAgICAgIGZtdCwKICAgICAgICAgICAgICAgICAgICAgdHlwZSwKICAgICAgICAgICAgICAgICAgICAgbWVtKTsKCiAgICAgICAvKiBnbFJlYWRQaXhlbHMgcmV0dXJucyB0aGUgaW1hZ2UgdXBzaWRlIGRvd24sIGFuZCB0aGVyZSBpcyBubyB3YXkgdG8gcHJldmVudCB0aGlzLgogICAgICAgICAgRmxpcCB0aGUgbGluZXMgaW4gc29mdHdhcmUgKi8KICAgICAgICByb3cgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcGl0Y2gpOwogICAgICAgIGlmKCFyb3cpIHsKICAgICAgICAgICAgRVJSKCJPdXQgb2YgbWVtb3J5XG4iKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICB0b3AgPSBtZW07CiAgICAgICAgYm90dG9tID0gKChCWVRFICopIG1lbSkgKyBwaXRjaCAqICggcmVjdC0+Ym90dG9tIC0gcmVjdC0+dG9wIC0gMSk7CiAgICAgICAgZm9yKGkgPSAwOyBpIDwgKHJlY3QtPmJvdHRvbSAtIHJlY3QtPnRvcCkgLyAyOyBpKyspIHsKICAgICAgICAgICAgbWVtY3B5KHJvdywgdG9wLCBwaXRjaCk7CiAgICAgICAgICAgIG1lbWNweSh0b3AsIGJvdHRvbSwgcGl0Y2gpOwogICAgICAgICAgICBtZW1jcHkoYm90dG9tLCByb3csIHBpdGNoKTsKICAgICAgICAgICAgdG9wICs9IHBpdGNoOwogICAgICAgICAgICBib3R0b20gLT0gcGl0Y2g7CiAgICAgICAgfQogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHJvdyk7CgogICAgICAgIGlmKFRoaXMtPmxvY2tlZFJlY3QudG9wID09IDAgJiYgVGhpcy0+bG9ja2VkUmVjdC5ib3R0b20gPT0gIFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodCkgewogICAgICAgICAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfR0xESVJUWTsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIGZvciAoaiA9IFRoaXMtPmxvY2tlZFJlY3QudG9wOyBqIDwgVGhpcy0+bG9ja2VkUmVjdC5ib3R0b20gLSBUaGlzLT5sb2NrZWRSZWN0LnRvcDsgKytqKSB7CiAgICAgICAgICAgIGdsUmVhZFBpeGVscyhyZWN0LT5sZWZ0LAogICAgICAgICAgICAgICAgICAgICAgICAgcmVjdC0+Ym90dG9tIC0gaiAtIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICByZWN0LT5yaWdodCAtIHJlY3QtPmxlZnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAxLAogICAgICAgICAgICAgICAgICAgICAgICAgZm10LAogICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgIChjaGFyICopbWVtICsgKHBpdGNoICogKGotcmVjdC0+dG9wKSkpOwogICAgICAgIH0KICAgIH0KCiAgICB2Y2hlY2tHTGNhbGwoImdsUmVhZFBpeGVscyIpOwoKICAgIGlmKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX1A4KSB7CiAgICAgICAgUEFMRVRURUVOVFJZICpwYWw7CiAgICAgICAgRFdPUkQgd2lkdGggPSBwaXRjaCAvIDM7CiAgICAgICAgaW50IHgsIHksIGM7CiAgICAgICAgaWYoVGhpcy0+cGFsZXR0ZSkgewogICAgICAgICAgICBwYWwgPSBUaGlzLT5wYWxldHRlLT5wYWxlbnRzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHBhbCA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2UtPnBhbGV0dGVzW1RoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2UtPmN1cnJlbnRQYWxldHRlXTsKICAgICAgICB9CgogICAgICAgIGZvcih5ID0gcmVjdC0+dG9wOyB5IDwgcmVjdC0+Ym90dG9tOyB5KyspIHsKICAgICAgICAgICAgZm9yKHggPSByZWN0LT5sZWZ0OyB4IDwgcmVjdC0+cmlnaHQ7IHgrKykgewogICAgICAgICAgICAgICAgLyogICAgICAgICAgICAgICAgICAgICAgc3RhcnQgICAgICAgICAgICAgIGxpbmVzICAgICAgICAgICAgcGl4ZWxzICAgICAgKi8KICAgICAgICAgICAgICAgIEJZVEUgKmJsdWUgPSAgKEJZVEUgKikgKChCWVRFICopIG1lbSkgKyB5ICogcGl0Y2ggKyB4ICogKHNpemVvZihCWVRFKSAqIDMpOwogICAgICAgICAgICAgICAgQllURSAqZ3JlZW4gPSBibHVlICArIDE7CiAgICAgICAgICAgICAgICBCWVRFICpyZWQgPSAgIGdyZWVuICsgMTsKCiAgICAgICAgICAgICAgICBmb3IoYyA9IDA7IGMgPCAyNTY7IGMrKykgewogICAgICAgICAgICAgICAgICAgIGlmKCpyZWQgICA9PSBwYWxbY10ucGVSZWQgICAmJgogICAgICAgICAgICAgICAgICAgICAgICpncmVlbiA9PSBwYWxbY10ucGVHcmVlbiAmJgogICAgICAgICAgICAgICAgICAgICAgICpibHVlICA9PSBwYWxbY10ucGVCbHVlKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgKigoQllURSAqKSBkZXN0ICsgeSAqIHdpZHRoICsgeCkgPSBjOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbWVtKTsKICAgIH0KfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfTG9ja1JlY3QoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgV0lORUQzRExPQ0tFRF9SRUNUKiBwTG9ja2VkUmVjdCwgQ09OU1QgUkVDVCogcFJlY3QsIERXT1JEIEZsYWdzKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAgKm15RGV2aWNlID0gVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZTsKICAgIElXaW5lRDNEU3dhcENoYWluSW1wbCAqc3dhcGNoYWluID0gTlVMTDsKICAgIHN0YXRpYyBVSU5UIG1lc3NhZ2VzID0gMDsgLyogaG9sZHMgZmxhZ3MgdG8gZGlzYWJsZSBmaXhtZSBtZXNzYWdlcyAqLwogICAgQk9PTCBiYWNrYnVmID0gRkFMU0U7CgogICAgLyogZml4bWU6IHNob3VsZCB3ZSByZWFsbHkgbG9jayBhcyBzdWNoPyAqLwogICAgaWYoKFRoaXMtPkZsYWdzICYgKFNGTEFHX0lOVEVYVFVSRSB8IFNGTEFHX0lOUEJVRkZFUikpID09CiAgICAgICAgICAgICAgICAgICAgICAoU0ZMQUdfSU5URVhUVVJFIHwgU0ZMQUdfSU5QQlVGRkVSKSApIHsKICAgICAgICBGSVhNRSgiV2FybmluZzogU3VyZmFjZSBpcyBpbiB0ZXh0dXJlIG1lbW9yeSBvciBwYnVmZmVyXG4iKTsKICAgICAgICBUaGlzLT5GbGFncyAmPSB+KFNGTEFHX0lOVEVYVFVSRSB8IFNGTEFHX0lOUEJVRkZFUik7CiAgICB9CgogICAgaWYgKCEoVGhpcy0+RmxhZ3MgJiBTRkxBR19MT0NLQUJMRSkpIHsKICAgICAgICAvKiBOb3RlOiBVcGRhdGVUZXh0dXJlcyBjYWxscyBDb3B5UmVjdHMgd2hpY2ggY2FsbHMgdGhpcyByb3V0aW5lIHRvIHBvcHVsYXRlIHRoZQogICAgICAgICAgICAgIHRleHR1cmUgcmVnaW9ucywgYW5kIHNpbmNlIHRoZSBkZXN0aW5hdGlvbiBpcyBhbiB1bmxvY2thYmxlIHJlZ2lvbiB3ZSBuZWVkCiAgICAgICAgICAgICAgdG8gdG9sZXJhdGUgdGhpcyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICBUUkFDRSgiV2FybmluZzogdHJ5aW5nIHRvIGxvY2sgdW5sb2NrYWJsZSBzdXJmQCVwXG4iLCBUaGlzKTsKICAgICAgICAvKnJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOyAqLwogICAgfQoKICAgIGlmIChUaGlzLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQpIHsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfR2V0Q29udGFpbmVyKGlmYWNlLCAmSUlEX0lXaW5lRDNEU3dhcENoYWluLCAodm9pZCAqKikmc3dhcGNoYWluKTsKCiAgICAgICAgaWYgKHN3YXBjaGFpbiAhPSBOVUxMIHx8ICBpZmFjZSA9PSBteURldmljZS0+cmVuZGVyVGFyZ2V0IHx8IGlmYWNlID09IG15RGV2aWNlLT5kZXB0aFN0ZW5jaWxCdWZmZXIpIHsKICAgICAgICAgICAgaWYoc3dhcGNoYWluICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgIGludCBpOwogICAgICAgICAgICAgICAgZm9yKGkgPSAwOyBpIDwgc3dhcGNoYWluLT5wcmVzZW50UGFybXMuQmFja0J1ZmZlckNvdW50OyBpKyspIHsKICAgICAgICAgICAgICAgICAgICBpZihpZmFjZSA9PSBzd2FwY2hhaW4tPmJhY2tCdWZmZXJbaV0pIHsKICAgICAgICAgICAgICAgICAgICAgICAgYmFja2J1ZiA9IFRSVUU7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoYmFja2J1ZikgewogICAgICAgICAgICAgICAgVFJBQ0UoIiglcCwgYmFja0J1ZmZlcikgOiByZWN0QCVwIGZsYWdzKCUwOGx4KSwgb3V0cHV0IGxvY2tlZFJlY3RAJXAsIG1lbW9yeUAlcFxuIiwgVGhpcywgcFJlY3QsIEZsYWdzLCBwTG9ja2VkUmVjdCwgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKICAgICAgICAgICAgfSBlbHNlIGlmIChzd2FwY2hhaW4gIT0gTlVMTCAmJiBpZmFjZSA9PSAgc3dhcGNoYWluLT5mcm9udEJ1ZmZlcikgewogICAgICAgICAgICAgICAgVFJBQ0UoIiglcCwgZnJvbnRCdWZmZXIpIDogcmVjdEAlcCBmbGFncyglMDhseCksIG91dHB1dCBsb2NrZWRSZWN0QCVwLCBtZW1vcnlAJXBcbiIsIFRoaXMsIHBSZWN0LCBGbGFncywgcExvY2tlZFJlY3QsIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoaWZhY2UgPT0gbXlEZXZpY2UtPnJlbmRlclRhcmdldCkgewogICAgICAgICAgICAgICAgVFJBQ0UoIiglcCwgcmVuZGVyVGFyZ2V0KSA6IHJlY3RAJXAgZmxhZ3MoJTA4bHgpLCBvdXRwdXQgbG9ja2VkUmVjdEAlcCwgbWVtb3J5QCVwXG4iLCBUaGlzLCBwUmVjdCwgRmxhZ3MsIHBMb2NrZWRSZWN0LCBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpOwogICAgICAgICAgICB9IGVsc2UgaWYgKGlmYWNlID09IG15RGV2aWNlLT5kZXB0aFN0ZW5jaWxCdWZmZXIpIHsKICAgICAgICAgICAgICAgIFRSQUNFKCIoJXAsIHN0ZW5jaWxCdWZmZXIpIDogcmVjdEAlcCBmbGFncyglMDhseCksIG91dHB1dCBsb2NrZWRSZWN0QCVwLCBtZW1vcnlAJXBcbiIsIFRoaXMsIHBSZWN0LCBGbGFncywgcExvY2tlZFJlY3QsIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChOVUxMICE9IHN3YXBjaGFpbikgewogICAgICAgICAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZSgoSVdpbmVEM0RTd2FwQ2hhaW4gKilzd2FwY2hhaW4pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHN3YXBjaGFpbiA9IE5VTEw7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICBUUkFDRSgiKCVwKSA6IHJlY3RAJXAgZmxhZ3MoJTA4bHgpLCBvdXRwdXQgbG9ja2VkUmVjdEAlcCwgbWVtb3J5QCVwXG4iLCBUaGlzLCBwUmVjdCwgRmxhZ3MsIHBMb2NrZWRSZWN0LCBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpOwogICAgfQoKICAgIHBMb2NrZWRSZWN0LT5QaXRjaCA9IElXaW5lRDNEU3VyZmFjZV9HZXRQaXRjaChpZmFjZSk7CgogICAgaWYgKE5VTEwgPT0gcFJlY3QpIHsKICAgICAgICBwTG9ja2VkUmVjdC0+cEJpdHMgPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnk7CiAgICAgICAgVGhpcy0+bG9ja2VkUmVjdC5sZWZ0ICAgPSAwOwogICAgICAgIFRoaXMtPmxvY2tlZFJlY3QudG9wICAgID0gMDsKICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LnJpZ2h0ICA9IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoOwogICAgICAgIFRoaXMtPmxvY2tlZFJlY3QuYm90dG9tID0gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0OwogICAgICAgIFRSQUNFKCJMb2NrZWQgUmVjdCAoJXApID0gbCAlbGQsIHQgJWxkLCByICVsZCwgYiAlbGRcbiIsICZUaGlzLT5sb2NrZWRSZWN0LCBUaGlzLT5sb2NrZWRSZWN0LmxlZnQsIFRoaXMtPmxvY2tlZFJlY3QudG9wLCBUaGlzLT5sb2NrZWRSZWN0LnJpZ2h0LCBUaGlzLT5sb2NrZWRSZWN0LmJvdHRvbSk7CiAgICB9IGVsc2UgewogICAgICAgIFRSQUNFKCJMb2NrIFJlY3QgKCVwKSA9IGwgJWxkLCB0ICVsZCwgciAlbGQsIGIgJWxkXG4iLCBwUmVjdCwgcFJlY3QtPmxlZnQsIHBSZWN0LT50b3AsIHBSZWN0LT5yaWdodCwgcFJlY3QtPmJvdHRvbSk7CgogICAgICAgIGlmICgocFJlY3QtPnRvcCA8IDApIHx8CiAgICAgICAgICAgICAocFJlY3QtPmxlZnQgPCAwKSB8fAogICAgICAgICAgICAgKHBSZWN0LT5sZWZ0ID49IHBSZWN0LT5yaWdodCkgfHwKICAgICAgICAgICAgIChwUmVjdC0+dG9wID49IHBSZWN0LT5ib3R0b20pIHx8CiAgICAgICAgICAgICAocFJlY3QtPnJpZ2h0ID4gVGhpcy0+Y3VycmVudERlc2MuV2lkdGgpIHx8CiAgICAgICAgICAgICAocFJlY3QtPmJvdHRvbSA+IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodCkpCiAgICAgICAgewogICAgICAgICAgICBXQVJOKCIgSW52YWxpZCB2YWx1ZXMgaW4gcFJlY3QgISEhXG4iKTsKICAgICAgICAgICAgcmV0dXJuIEQzREVSUl9JTlZBTElEQ0FMTDsKICAgICAgICB9CgogICAgICAgIGlmIChUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQxKSB7IC8qIERYVDEgaXMgaGFsZiBieXRlIHBlciBwaXhlbCAqLwogICAgICAgICAgICBwTG9ja2VkUmVjdC0+cEJpdHMgPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgKyAocExvY2tlZFJlY3QtPlBpdGNoICogcFJlY3QtPnRvcCkgKyAoKHBSZWN0LT5sZWZ0ICogVGhpcy0+Ynl0ZXNQZXJQaXhlbCAvIDIpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBwTG9ja2VkUmVjdC0+cEJpdHMgPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgKyAocExvY2tlZFJlY3QtPlBpdGNoICogcFJlY3QtPnRvcCkgKyAocFJlY3QtPmxlZnQgKiBUaGlzLT5ieXRlc1BlclBpeGVsKTsKICAgICAgICB9CiAgICAgICAgVGhpcy0+bG9ja2VkUmVjdC5sZWZ0ICAgPSBwUmVjdC0+bGVmdDsKICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LnRvcCAgICA9IHBSZWN0LT50b3A7CiAgICAgICAgVGhpcy0+bG9ja2VkUmVjdC5yaWdodCAgPSBwUmVjdC0+cmlnaHQ7CiAgICAgICAgVGhpcy0+bG9ja2VkUmVjdC5ib3R0b20gPSBwUmVjdC0+Ym90dG9tOwogICAgfQoKICAgIGlmIChUaGlzLT5GbGFncyAmIFNGTEFHX05PTlBPVzIpIHsKICAgICAgICBUUkFDRSgiTG9ja2luZyBub24tcG93ZXIgMiB0ZXh0dXJlXG4iKTsKICAgIH0KCiAgICBpZiAoMCA9PSBUaGlzLT5yZXNvdXJjZS51c2FnZSB8fCBUaGlzLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9EWU5BTUlDKSB7CiAgICAgICAgLyogY2xhc3NpYyBzdXJmYWNlICBUT0RPOiBub24gMmQgc3VyZmFjZXM/CiAgICAgICAgVGhlc2UgcmVzb3VyY2VzIG1heSBiZSBQT09MX1NZU1RFTU1FTSwgc28gdGhleSBtdXN0IG5vdCBhY2Nlc3MgdGhlIGRldmljZSAqLwogICAgICAgIFRSQUNFKCJsb2NraW5nIGFuIG9yZGluYXJhcnkgc3VyZmFjZVxuIik7CiAgICAgICAgLyogQ2hlY2sgdG8gc2VlIGlmIG1lbW9yeSBoYXMgYWxyZWFkeSBiZWVuIGFsbG9jYXRlZCBmcm9tIHRoZSBzdXJmYWNlKi8KICAgICAgICBpZiAoKE5VTEwgPT0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KSB8fAogICAgICAgICAgICAoVGhpcy0+RmxhZ3MgJiBTRkxBR19HTERJUlRZKSApeyAvKiBUT0RPOiBjaGVjayB0byBzZWUgaWYgYW4gdXBkYXRlIGhhcyBiZWVuIHBlcmZvcm1lZCBvbiB0aGUgc3VyZmFjZSAoYW4gdXBkYXRlIGNvdWxkIGp1c3QgY2xvYmJlciBhbGxvY2F0ZWRNZW1vcnkgKi8KICAgICAgICAgICAgLyogTm9uLXN5c3RlbSBtZW1vcnkgc3VyZmFjZXMgKi8KCiAgICAgICAgICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19HTERJUlRZOwoKICAgICAgICAgICAgLypTdXJmYWNlIGhhcyBubyBtZW1vcnkgY3VycmVudGx5IGFsbG9jYXRlZCB0byBpdCEqLwogICAgICAgICAgICBUUkFDRSgiKCVwKSBMb2NraW5nIHJlY3RcbiIgLCBUaGlzKTsKICAgICAgICAgICAgaWYoIVRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSkgewogICAgICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCkgLDAgLCBUaGlzLT5wb3cyU2l6ZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKDAgIT0gVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSkgewogICAgICAgICAgICAgICAgLyogTm93IEkgaGF2ZSB0byBjb3B5IHRoaW5nIGJpdHMgYmFjayAqLwogICAgICAgICAgICAgICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfQUNUSVZFTE9DSzsgLyogV2hlbiB0aGlzIGZsYWcgaXMgc2V0IHRvIHRydWUsIGxvYWRpbmcgdGhlIHN1cmZhY2UgYWdhaW4gd29uJ3QgZnJlZSBUSGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgKi8KICAgICAgICAgICAgICAgIC8qIFRPRE86IG1ha2UgYWN0aXZlTG9jayBhIGJpdCBtb3JlIGludGVsbGlnZW50LCBtYXliZSBpbXBsZW1lbnQgYSBtZXRob2QgdG8gcHVyZ2UgdGhlIHRleHR1cmUgbWVtb3J5LiAqLwoKICAgICAgICAgICAgICAgIC8qIE1ha2Ugc3VyZSB0aGF0IHRoZSB0ZXh0dXJlIGlzIGxvYWRlZCAqLwogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1ByZUxvYWQoaWZhY2UpOyAvKiBNYWtlIHN1cmUgdGhlcmUgaXMgYSB0ZXh0dXJlIHRvIGJpbmQhICovCgogICAgICAgICAgICAgICAgc3VyZmFjZV9kb3dubG9hZF9kYXRhKFRoaXMpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsgLyogTm90aGluZyB0byBkbyAqLwogICAgICAgICAgICBUUkFDRSgiTWVtb3J5ICVwIGFscmVhZHkgYWxsb2N0ZWQgZm9yIHRleHR1cmVcbiIsICBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpOwogICAgICAgIH0KCiAgICAgICAgaWYgKE5VTEwgPT0gcFJlY3QpIHsKICAgICAgICAgICAgcExvY2tlZFJlY3QtPnBCaXRzID0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5OwogICAgICAgIH0gIGVsc2V7CiAgICAgICAgICAgIGlmIChUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gRDNERk1UX0RYVDEpIHsgLyogRFhUMSBpcyBoYWxmIGJ5dGUgcGVyIHBpeGVsICovCiAgICAgICAgICAgICAgICBwTG9ja2VkUmVjdC0+cEJpdHMgPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgKyAocExvY2tlZFJlY3QtPlBpdGNoICogcFJlY3QtPnRvcCkgKyAoKHBSZWN0LT5sZWZ0ICogVGhpcy0+Ynl0ZXNQZXJQaXhlbCAvIDIpKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHBMb2NrZWRSZWN0LT5wQml0cyA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSArIChwTG9ja2VkUmVjdC0+UGl0Y2ggKiBwUmVjdC0+dG9wKSArIChwUmVjdC0+bGVmdCAqIFRoaXMtPmJ5dGVzUGVyUGl4ZWwpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIH0gZWxzZSBpZiAoV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCAmIFRoaXMtPnJlc291cmNlLnVzYWdlICl7IC8qIHJlbmRlciBzdXJmYWNlcyAqLwogICAgICAgIGlmKCghKEZsYWdzJldJTkVEM0RMT0NLX0RJU0NBUkQpICYmIChUaGlzLT5GbGFncyAmIFNGTEFHX0dMRElSVFkpKSB8fCAhVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KSB7CiAgICAgICAgICAgIEdMaW50ICBwcmV2X3N0b3JlOwogICAgICAgICAgICBHTGludCAgcHJldl9yZWFkOwogICAgICAgICAgICBCT09MIG5vdEluQ29udGV4dCA9IEZBTFNFOwogICAgICAgICAgICBJV2luZUQzRFN3YXBDaGFpbkltcGwgKnRhcmdldFN3YXBDaGFpbiA9IE5VTEw7CgoKICAgICAgICAgICAgRU5URVJfR0woKTsKCiAgICAgICAgICAgICAgICAvKioKICAgICAgICAgICAgICAgICogZm9yIHJlbmRlci0+c3VyZmFjZSBjb3B5IGJlZ2luIHRvIGJlZ2luIG9mIGFsbG9jYXRlZE1lbW9yeQogICAgICAgICAgICAgICAgKiB1bmxvY2sgY2FuIGJlIG1vcmUgZWFzeQogICAgICAgICAgICAgICAgKi8KCiAgICAgICAgICAgIFRSQUNFKCJsb2NraW5nIGEgcmVuZGVyIHRhcmdldFxuIik7CgogICAgICAgICAgICBpZiAoVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID09IE5VTEwpCiAgICAgICAgICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCkgLDAgLFRoaXMtPnJlc291cmNlLnNpemUpOwoKICAgICAgICAgICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfQUNUSVZFTE9DSzsgLypXaGVuIHRoaXMgZmxhZyBpcyBzZXQgdG8gdHJ1ZSwgbG9hZGluZyB0aGUgc3VyZmFjZSBhZ2FpbiB3b24ndCBmcmVlIFRIaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSovCiAgICAgICAgICAgIHBMb2NrZWRSZWN0LT5wQml0cyA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeTsKCiAgICAgICAgICAgIGdsRmx1c2goKTsKICAgICAgICAgICAgdmNoZWNrR0xjYWxsKCJnbEZsdXNoIik7CiAgICAgICAgICAgIGdsR2V0SW50ZWdlcnYoR0xfUkVBRF9CVUZGRVIsICZwcmV2X3JlYWQpOwogICAgICAgICAgICB2Y2hlY2tHTGNhbGwoImdsSW50ZWdlcnYiKTsKICAgICAgICAgICAgZ2xHZXRJbnRlZ2VydihHTF9QQUNLX1NXQVBfQllURVMsICZwcmV2X3N0b3JlKTsKICAgICAgICAgICAgdmNoZWNrR0xjYWxsKCJnbEludGVnZXJ2Iik7CgogICAgLyogSGVyZSdzIHdoYXQgd2UgaGF2ZSB0byBkbzoKICAgICAgICAgICAgICAgIFNlZSBpZiB0aGUgc3dhcGNoYWluIGhhcyB0aGUgc2FtZSBjb250ZXh0IGFzIHRoZSByZW5kZXJUYXJnZXQgb3IgdGhlIHN1cmZhY2UgaXMgdGhlIHJlbmRlciB0YXJnZXQuCiAgICAgICAgICAgICAgICBPdGhlcndpc2UsIHNlZSBpZiB3ZXJlIHNoYXJpbmcgYSBjb250ZXh0IHdpdGggdGhlIGltcGxpY2l0IHN3YXBjaGFpbiAoYmVjYXVzZSB3ZSdyZSB1c2luZyBhIHNoYXJlZCBjb250ZXh0IG1vZGVsISkKICAgICAgICAgICAgICAgIGFuZCB1c2UgdGhlIGZyb250IGJhY2sgYnVmZmVyIGFzIHJlcXVpcmVkLgogICAgICAgICAgICAgICAgaWYgbm90LCB3ZSBuZWVkIHRvIHN3aXRjaCBjb250ZXh0cyBhbmQgdGhlbiBzd2l0Y2hiYWNrIGF0IHRoZSBlbmQuCiAgICAgICAgICAgICovCiAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9HZXRDb250YWluZXIoaWZhY2UsICZJSURfSVdpbmVEM0RTd2FwQ2hhaW4sICh2b2lkICoqKSZzd2FwY2hhaW4pOwogICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfR2V0Q29udGFpbmVyKG15RGV2aWNlLT5yZW5kZXJUYXJnZXQsICZJSURfSVdpbmVEM0RTd2FwQ2hhaW4sICh2b2lkICoqKSZ0YXJnZXRTd2FwQ2hhaW4pOwoKICAgICAgICAgICAgLyogTk9URTogSW4gYSBzaGFyZWQgY29udGV4dCBlbnZpcm9ubWVudCB0aGUgcmVuZGVyVGFyZ2V0IHdpbGwgdXNlIHRoZSBzYW1lIGNvbnRleHQgYXMgdGhlIGltcGxpY2l0IHN3YXBjaGFpbiAod2UncmUgbm90IGluIGEgc2hhcmVkIGVudmlyb25tZW50IHlldCEgKi8KICAgICAgICAgICAgaWYgKChzd2FwY2hhaW4gPT0gdGFyZ2V0U3dhcENoYWluICYmIHRhcmdldFN3YXBDaGFpbiAhPSBOVUxMKSB8fCBpZmFjZSA9PSBteURldmljZS0+cmVuZGVyVGFyZ2V0KSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHN3YXBjaGFpbiAmJiBpZmFjZSA9PSBzd2FwY2hhaW4tPmZyb250QnVmZmVyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIFRSQUNFKCJsb2NraW5nIGZyb250XG4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgZ2xSZWFkQnVmZmVyKEdMX0ZST05UKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoaWZhY2UgPT0gbXlEZXZpY2UtPnJlbmRlclRhcmdldCB8fCBiYWNrYnVmKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIFRSQUNFKCJsb2NraW5nIGJhY2sgYnVmZmVyXG4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgZ2xSZWFkQnVmZmVyKEdMX0JBQ0spOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaWZhY2UgPT0gbXlEZXZpY2UtPmRlcHRoU3RlbmNpbEJ1ZmZlcikgewogICAgICAgICAgICAgICAgICAgICAgICBGSVhNRSgiU3RlbmNpbCBCdWZmZXIgbG9jayB1bnN1cHBvcnRlZCBmb3Igbm93XG4iKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgRklYTUUoIiglcCkgU2hvdWxkbid0IGhhdmUgZ290IGhlcmUhXG4iLCBUaGlzKTsKICAgICAgICAgICAgICAgICAgICAgIGdsUmVhZEJ1ZmZlcihHTF9CQUNLKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSBpZiAoc3dhcGNoYWluICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgIElXaW5lRDNEU3dhcENoYWluSW1wbCAqaW1wbFN3YXBDaGFpbjsKICAgICAgICAgICAgICAgIElXaW5lRDNERGV2aWNlX0dldFN3YXBDaGFpbigoSVdpbmVEM0REZXZpY2UgKilteURldmljZSwgMCwgKElXaW5lRDNEU3dhcENoYWluICoqKSZpbXBsU3dhcENoYWluKTsKICAgICAgICAgICAgICAgIGlmIChzd2FwY2hhaW4tPmdsQ3R4ID09IGltcGxTd2FwQ2hhaW4tPnJlbmRlcl9jdHggJiYgc3dhcGNoYWluLT5kcmF3YWJsZSA9PSBpbXBsU3dhcENoYWluLT53aW4pIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogVGhpcyB3aWxsIGZhaWwgZm9yIHRoZSBpbXBsaWNpdCBzd2FwY2hhaW4sIHdoaWNoIGlzIHdoeSB0aGVyZSBuZWVkcyB0byBiZSBhIGNvbnRleHQgbWFuYWdlciAqLwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoYmFja2J1ZikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2xSZWFkQnVmZmVyKEdMX0JBQ0spOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGlmYWNlID09IHN3YXBjaGFpbi0+ZnJvbnRCdWZmZXIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdsUmVhZEJ1ZmZlcihHTF9GUk9OVCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaWZhY2UgPT0gbXlEZXZpY2UtPmRlcHRoU3RlbmNpbEJ1ZmZlcikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYTUUoIlN0ZW5jaWwgQnVmZmVyIGxvY2sgdW5zdXBwb3J0ZWQgZm9yIG5vd1xuIik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSVhNRSgiU2hvdWxkIGhhdmUgZ290IGhlcmUhXG4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdsUmVhZEJ1ZmZlcihHTF9CQUNLKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAvKiBXZSBuZWVkIHRvIHN3aXRjaCBjb250ZXh0cyB0byBiZSBhYmxlIHRvIHJlYWQgdGhlIGJ1ZmZlciEhISAqLwogICAgICAgICAgICAgICAgICAgIEZJWE1FKCJUaGUgYnVmZmVyIHJlcXVlc3RlZCBpc24ndCBpbiB0aGUgY3VycmVudCBvcGVuR0wgY29udGV4dFxuIik7CiAgICAgICAgICAgICAgICAgICAgbm90SW5Db250ZXh0ID0gVFJVRTsKICAgICAgICAgICAgICAgICAgICAvKiBUT0RPOiBjaGVjayB0aGUgY29udGV4dHMsIHRvIHNlZSBpZiB3ZXJlIHNoYXJlZCB3aXRoIHRoZSBjdXJyZW50IGNvbnRleHQgKi8KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2UoKElXaW5lRDNEU3dhcENoYWluICopaW1wbFN3YXBDaGFpbik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHN3YXBjaGFpbiAhPSBOVUxMKSAgICAgICBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKChJV2luZUQzRFN3YXBDaGFpbiAqKXN3YXBjaGFpbik7CiAgICAgICAgICAgIGlmICh0YXJnZXRTd2FwQ2hhaW4gIT0gTlVMTCkgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZSgoSVdpbmVEM0RTd2FwQ2hhaW4gKil0YXJnZXRTd2FwQ2hhaW4pOwoKICAgICAgICAgICAgLyoqIHRoZSBkZXB0aCBzdGVuY2lsIGluIG9wZW5HTCBoYXMgYSBmb3JtYXQgb2YgR0xfRkxPQVQKICAgICAgICAgICAgKiB3aGljaCBzaG91bGQgYmUgZ29vZCBmb3IgV0lORUQzREZNVF9EMTZfTE9DS0FCTEUKICAgICAgICAgICAgKiBhbmQgV0lORUQzREZNVF9EMTYKICAgICAgICAgICAgKiBpdCBpcyB1bmNsZWFyIHdoYXQgZm9ybWF0IHRoZSBzdGVuY2lsIGJ1ZmZlciBpcyBpbiBleGNlcHQuCiAgICAgICAgICAgICogJ0VhY2ggaW5kZXggaXMgY29udmVydGVkIHRvIGZpeGVkIHBvaW50Li4uCiAgICAgICAgICAgICogSWYgR0xfTUFQX1NURU5DSUwgaXMgR0xfVFJVRSwgaW5kaWNlcyBhcmUgcmVwbGFjZWQgYnkgdGhlaXIKICAgICAgICAgICAgKiBtYXBwaW5ncyBpbiB0aGUgdGFibGUgR0xfUElYRUxfTUFQX1NfVE9fUy4KICAgICAgICAgICAgKiBnbFJlYWRQaXhlbHMoVGhpcy0+bG9ja2VkUmVjdC5sZWZ0LAogICAgICAgICAgICAqICAgICAgICAgICAgIFRoaXMtPmxvY2tlZFJlY3QuYm90dG9tIC0gaiAtIDEsCiAgICAgICAgICAgICogICAgICAgICAgICAgVGhpcy0+bG9ja2VkUmVjdC5yaWdodCAtIFRoaXMtPmxvY2tlZFJlY3QubGVmdCwKICAgICAgICAgICAgKiAgICAgICAgICAgICAxLAogICAgICAgICAgICAqICAgICAgICAgICAgIEdMX0RFUFRIX0NPTVBPTkVOVCwKICAgICAgICAgICAgKiAgICAgICAgICAgICB0eXBlLAogICAgICAgICAgICAqICAgICAgICAgICAgIChjaGFyICopcExvY2tlZFJlY3QtPnBCaXRzICsgKHBMb2NrZWRSZWN0LT5QaXRjaCAqIChqLVRoaXMtPmxvY2tlZFJlY3QudG9wKSkpOwogICAgICAgICAgICAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCiAgICAgICAgICAgIGlmICghbm90SW5Db250ZXh0KSB7IC8qIE9ubHkgcmVhZCB0aGUgYnVmZmVyIGlmIGl0J3MgaW4gdGhlIGN1cnJlbnQgY29udGV4dCAqLwogICAgICAgICAgICAgICAgc3dpdGNoKHdpbmVkM2Rfc2V0dGluZ3MucmVuZGVydGFyZ2V0bG9ja19tb2RlKSB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBSVExfQVVUTzoKICAgICAgICAgICAgICAgICAgICBjYXNlIFJUTF9SRUFERFJBVzoKICAgICAgICAgICAgICAgICAgICBjYXNlIFJUTF9SRUFEVEVYOgogICAgICAgICAgICAgICAgICAgICAgICByZWFkX2Zyb21fZnJhbWVidWZmZXIoVGhpcywgJlRoaXMtPmxvY2tlZFJlY3QsIHBMb2NrZWRSZWN0LT5wQml0cywgcExvY2tlZFJlY3QtPlBpdGNoKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgIGNhc2UgUlRMX1RFWERSQVc6CiAgICAgICAgICAgICAgICAgICAgY2FzZSBSVExfVEVYVEVYOgogICAgICAgICAgICAgICAgICAgICAgICByZWFkX2Zyb21fZnJhbWVidWZmZXIoVGhpcywgJlRoaXMtPmxvY2tlZFJlY3QsIHBMb2NrZWRSZWN0LT5wQml0cywgcExvY2tlZFJlY3QtPlBpdGNoKTsKICAgICAgICAgICAgICAgICAgICAgICAgRklYTUUoIlJlYWRpbmcgZnJvbSByZW5kZXIgdGFyZ2V0IHdpdGggYSB0ZXh0dXJlIGlzbid0IGltcGxlbWVudGVkIHlldCwgZmFsbGluZyBiYWNrIHRvIGZyYW1lYnVmZmVyIHJlYWRpbmdcbiIpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICAgICAgY2FzZSBSVExfRElTQUJMRToKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRpYyBCT09MIHdhcm5lZCA9IEZBTFNFOwogICAgICAgICAgICAgICAgICAgICAgICBpZighd2FybmVkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBFUlIoIkFwcGxpY2F0aW9uIHRyaWVzIHRvIGxvY2sgdGhlIHJlbmRlciB0YXJnZXQsIGJ1dCByZW5kZXIgdGFyZ2V0IGxvY2tpbmcgaXMgZGlzYWJsZWRcbiIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgd2FybmVkID0gVFJVRTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBUUkFDRSgiUmVzZXR0aW5nIGJ1ZmZlclxuIik7CgogICAgICAgICAgICBnbFJlYWRCdWZmZXIocHJldl9yZWFkKTsKICAgICAgICAgICAgdmNoZWNrR0xjYWxsKCJnbFJlYWRCdWZmZXIiKTsKCiAgICAgICAgICAgIExFQVZFX0dMKCk7CiAgICAgICAgfQogICAgfSBlbHNlIGlmIChXSU5FRDNEVVNBR0VfREVQVEhTVEVOQ0lMICYgVGhpcy0+cmVzb3VyY2UudXNhZ2UpIHsgLyogc3RlbmNpbCBzdXJmYWNlcyAqLwoKICAgICAgICBpZiAoIW1lc3NhZ2VzICYgMSkgewogICAgICAgICAgICBGSVhNRSgiVE9ETyBzdGVuY2lsIGRlcHRoIHN1cmZhY2UgbG9ja2luZyBzdXJmJXAgdXNhZ2UoJXMpXG4iLCBUaGlzLCBkZWJ1Z19kM2R1c2FnZShUaGlzLT5yZXNvdXJjZS51c2FnZSkpOwogICAgICAgICAgICAvKgoKICAgICAgICAgICAgZ2xSZWFkUGl4ZWxzKFRoaXMtPmxvY2tlZFJlY3QubGVmdCwKICAgICAgICAgICAgVGhpcy0+bG9ja2VkUmVjdC5ib3R0b20gLSBqIC0gMSwKICAgICAgICAgICAgVGhpcy0+bG9ja2VkUmVjdC5yaWdodCAtIFRoaXMtPmxvY2tlZFJlY3QubGVmdCwKICAgICAgICAgICAgMSwKICAgICAgICAgICAgR0xfU1RFTkNJTF9JTkRFWCBvciBHTF9ERVBUSF9DT01QT05FTlQKCiAgICAgICAgICAgICkKICAgICAgICAgICAgKi8KICAgICAgICAgICAgbWVzc2FnZXMgfD0gMTsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIEZJWE1FKCJ1bnN1cHBvcnRlZCBsb2NraW5nIHRvIHN1cmZhY2Ugc3VyZkAlcCB1c2FnZSglcylcbiIsIFRoaXMsIGRlYnVnX2QzZHVzYWdlKFRoaXMtPnJlc291cmNlLnVzYWdlKSk7CiAgICB9CgogICAgaWYgKEZsYWdzICYgKFdJTkVEM0RMT0NLX05PX0RJUlRZX1VQREFURSB8IFdJTkVEM0RMT0NLX1JFQURPTkxZKSkgewogICAgICAgIC8qIERvbid0IGRpcnRpZnkgKi8KICAgIH0gZWxzZSB7CiAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZSAqcEJhc2VUZXh0dXJlOwogICAgICAgIC8qKgogICAgICAgICAqIERpcnRpZnkgb24gbG9jawogICAgICAgICAqIGFzIHNlZW4gaW4gbXNkbiBkb2NzCiAgICAgICAgICovCiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0FkZERpcnR5UmVjdChpZmFjZSwgJlRoaXMtPmxvY2tlZFJlY3QpOwoKICAgICAgICAvKiogRGlydGlmeSBDb250YWluZXIgaWYgbmVlZGVkICovCiAgICAgICAgaWYgKFdJTkVEM0RfT0sgPT0gSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lcihpZmFjZSwgJklJRF9JV2luZUQzREJhc2VUZXh0dXJlLCAodm9pZCAqKikmcEJhc2VUZXh0dXJlKSAmJiBwQmFzZVRleHR1cmUgIT0gTlVMTCkgewogICAgICAgICAgICBUUkFDRSgiTWFraW5nIGNvbnRhaW5lciBkaXJ0eVxuIik7CiAgICAgICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVfU2V0RGlydHkocEJhc2VUZXh0dXJlLCBUUlVFKTsKICAgICAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9SZWxlYXNlKHBCYXNlVGV4dHVyZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgVFJBQ0UoIlN1cmZhY2UgaXMgc3RhbmRhbG9uZSwgbm8gbmVlZCB0byBkaXJ0eSB0aGUgY29udGFpbmVyXG4iKTsKICAgICAgICB9CiAgICB9CgogICAgVFJBQ0UoInJldHVybmluZyBtZW1vcnlAJXAsIHBpdGNoKCVkKSBkaXJ0eWZpZWQoJWQpXG4iLCBwTG9ja2VkUmVjdC0+cEJpdHMsIHBMb2NrZWRSZWN0LT5QaXRjaCwgVGhpcy0+RmxhZ3MgJiBTRkxBR19ESVJUWSA/IDAgOiAxKTsKCiAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19MT0NLRUQ7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIHZvaWQgZmx1c2hfdG9fZnJhbWVidWZmZXJfZHJhd3BpeGVscyhJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzKSB7CiAgICBHTGludCAgcHJldl9zdG9yZTsKICAgIEdMaW50ICBwcmV2X3Jhc3RlcnBvc1s0XTsKICAgIEdMaW50IHNraXBCeXRlcyA9IDA7CiAgICBCT09MIHN0b3JlY2hhbmdlZCA9IEZBTFNFOwogICAgR0xpbnQgZm10LCB0eXBlOwogICAgdm9pZCAqbWVtOwoKICAgIGdsRGlzYWJsZShHTF9URVhUVVJFXzJEKTsKICAgIHZjaGVja0dMY2FsbCgiZ2xEaXNhYmxlKEdMX1RFWFRVUkVfMkQpIik7CiAgICBnbERpc2FibGUoR0xfVEVYVFVSRV8xRCk7CiAgICB2Y2hlY2tHTGNhbGwoImdsRGlzYWJsZShHTF9URVhUVVJFXzFEKSIpOwoKICAgIGdsRmx1c2goKTsKICAgIHZjaGVja0dMY2FsbCgiZ2xGbHVzaCIpOwogICAgZ2xHZXRJbnRlZ2VydihHTF9QQUNLX1NXQVBfQllURVMsICZwcmV2X3N0b3JlKTsKICAgIHZjaGVja0dMY2FsbCgiZ2xJbnRlZ2VydiIpOwogICAgZ2xHZXRJbnRlZ2VydihHTF9DVVJSRU5UX1JBU1RFUl9QT1NJVElPTiwgJnByZXZfcmFzdGVycG9zWzBdKTsKICAgIHZjaGVja0dMY2FsbCgiZ2xJbnRlZ2VydiIpOwogICAgZ2xQaXhlbFpvb20oMS4wLCAtMS4wKTsKICAgIHZjaGVja0dMY2FsbCgiZ2xQaXhlbFpvb20iKTsKCiAgICAvKiBJZiBub3QgZnVsbHNjcmVlbiwgd2UgbmVlZCB0byBza2lwIGEgbnVtYmVyIG9mIGJ5dGVzIHRvIGZpbmQgdGhlIG5leHQgcm93IG9mIGRhdGEgKi8KICAgIGdsR2V0SW50ZWdlcnYoR0xfVU5QQUNLX1JPV19MRU5HVEgsICZza2lwQnl0ZXMpOwogICAgZ2xQaXhlbFN0b3JlaShHTF9VTlBBQ0tfUk9XX0xFTkdUSCwgVGhpcy0+Y3VycmVudERlc2MuV2lkdGgpOwoKICAgIGdsUmFzdGVyUG9zM2koVGhpcy0+bG9ja2VkUmVjdC5sZWZ0LCBUaGlzLT5sb2NrZWRSZWN0LnRvcCwgMSk7CiAgICB2Y2hlY2tHTGNhbGwoImdsUmFzdGVyUG9zMmYiKTsKCiAgICAvKiBTb21lIGRyaXZlcnMocmFkZW9uIGRyaSwgb3RoZXJzPykgZG9uJ3QgbGlrZSBleGNlcHRpb25zIGR1cmluZwogICAgICogZ2xEcmF3UGl4ZWxzLiBJZiB0aGUgc3VyZmFjZSBpcyBhIERJQiBzZWN0aW9uLCBpdCBtaWdodCBiZSBpbiBHRElNb2RlCiAgICAgKiBhZnRlciBSZWxlYXNlREMuIFJlYWRpbmcgaXQgd2lsbCBjYXVzZSBhbiBleGNlcHRpb24sIHdoaWNoIHgxMWRydiB3aWxsCiAgICAgKiBjYXRjaCB0byBwdXQgdGhlIGRpYiBzZWN0aW9uIGluIEluU3luYyBtb2RlLCB3aGljaCBsZWFkcyB0byBhIGNyYXNoCiAgICAgKiBhbmQgYSBibG9ja2VkIHggc2VydmVyIG9uIG15IHJhZGVvbiBjYXJkLgogICAgICoKICAgICAqIFRoZSBmb2xsb3dpbmcgbGluZXMgcmVhZCB0aGUgZGliIHNlY3Rpb24gc28gaXQgaXMgcHV0IGluIGluU3luYyBtb2RlCiAgICAgKiBiZWZvcmUgZ2xEcmF3UGl4ZWxzIGlzIGNhbGxlZCBhbmQgdGhlIGNyYXNoIGlzIHByZXZlbnRlZC4gVGhlcmUgd29uJ3QKICAgICAqIGJlIGFueSBpbnRlcmZlcmluZyBnZGkgYWNjZXNzZXMsIGJlY2F1c2UgVW5sb2NrUmVjdCBpcyBjYWxsZWQgZnJvbQogICAgICogUmVsZWFzZURDLCBhbmQgdGhlIGFwcCB3b24ndCB1c2UgdGhlIGRjIGFueSBtb3JlIGFmdGVyd2FyZHMuCiAgICAgKi8KICAgIGlmKFRoaXMtPkZsYWdzICYgU0ZMQUdfRElCU0VDVElPTikgewogICAgICAgIHZvbGF0aWxlIEJZVEUgcmVhZDsKICAgICAgICByZWFkID0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5WzBdOwogICAgfQoKICAgIHN3aXRjaCAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0KSB7CiAgICAgICAgLyogTm8gc3BlY2lhbCBjYXJlIG5lZWRlZCAqLwogICAgICAgIGNhc2UgV0lORUQzREZNVF9BNFI0RzRCNDoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfUjVHNkI1OgogICAgICAgIGNhc2UgV0lORUQzREZNVF9BMVI1RzVCNToKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfUjhHOEI4OgogICAgICAgICAgICB0eXBlID0gVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbFR5cGU7CiAgICAgICAgICAgIGZtdCA9IFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xGb3JtYXQ7CiAgICAgICAgICAgIG1lbSA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgV0lORUQzREZNVF9YNFI0RzRCNDoKICAgICAgICB7CiAgICAgICAgICAgIGludCBzaXplOwogICAgICAgICAgICB1bnNpZ25lZCBzaG9ydCAqZGF0YTsKICAgICAgICAgICAgZGF0YSA9ICh1bnNpZ25lZCBzaG9ydCAqKVRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeTsKICAgICAgICAgICAgc2l6ZSA9IChUaGlzLT5sb2NrZWRSZWN0LmJvdHRvbSAtIFRoaXMtPmxvY2tlZFJlY3QudG9wKSAqIChUaGlzLT5sb2NrZWRSZWN0LnJpZ2h0IC0gVGhpcy0+bG9ja2VkUmVjdC5sZWZ0KTsKICAgICAgICAgICAgd2hpbGUoc2l6ZSA+IDApIHsKICAgICAgICAgICAgICAgICpkYXRhIHw9IDB4RjAwMDsKICAgICAgICAgICAgICAgIGRhdGErKzsKICAgICAgICAgICAgICAgIHNpemUtLTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0eXBlID0gVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbFR5cGU7CiAgICAgICAgICAgIGZtdCA9IFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xGb3JtYXQ7CiAgICAgICAgICAgIG1lbSA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgV0lORUQzREZNVF9YMVI1RzVCNToKICAgICAgICB7CiAgICAgICAgICAgIGludCBzaXplOwogICAgICAgICAgICB1bnNpZ25lZCBzaG9ydCAqZGF0YTsKICAgICAgICAgICAgZGF0YSA9ICh1bnNpZ25lZCBzaG9ydCAqKVRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeTsKICAgICAgICAgICAgc2l6ZSA9IChUaGlzLT5sb2NrZWRSZWN0LmJvdHRvbSAtIFRoaXMtPmxvY2tlZFJlY3QudG9wKSAqIChUaGlzLT5sb2NrZWRSZWN0LnJpZ2h0IC0gVGhpcy0+bG9ja2VkUmVjdC5sZWZ0KTsKICAgICAgICAgICAgd2hpbGUoc2l6ZSA+IDApIHsKICAgICAgICAgICAgICAgICpkYXRhIHw9IDB4ODAwMDsKICAgICAgICAgICAgICAgIGRhdGErKzsKICAgICAgICAgICAgICAgIHNpemUtLTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0eXBlID0gVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbFR5cGU7CiAgICAgICAgICAgIGZtdCA9IFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xGb3JtYXQ7CiAgICAgICAgICAgIG1lbSA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgV0lORUQzREZNVF9YOFI4RzhCODoKICAgICAgICB7CiAgICAgICAgICAgIC8qIG1ha2Ugc3VyZSB0aGUgWCBieXRlIGlzIHNldCB0byBhbHBoYSBvbiwgc2luY2UgaXQgCiAgICAgICAgICAgICAgIGNvdWxkIGJlIGFueSByYW5kb20gdmFsdWUuIFRoaXMgZml4ZXMgdGhlIGludHJvIG1vdmllIGluIFBpcmF0ZXMhICovCiAgICAgICAgICAgIGludCBzaXplOwogICAgICAgICAgICB1bnNpZ25lZCBpbnQgKmRhdGE7CiAgICAgICAgICAgIGRhdGEgPSAodW5zaWduZWQgaW50ICopVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5OwogICAgICAgICAgICBzaXplID0gKFRoaXMtPmxvY2tlZFJlY3QuYm90dG9tIC0gVGhpcy0+bG9ja2VkUmVjdC50b3ApICogKFRoaXMtPmxvY2tlZFJlY3QucmlnaHQgLSBUaGlzLT5sb2NrZWRSZWN0LmxlZnQpOwogICAgICAgICAgICB3aGlsZShzaXplID4gMCkgewogICAgICAgICAgICAgICAgKmRhdGEgfD0gMHhGRjAwMDAwMDsKICAgICAgICAgICAgICAgIGRhdGErKzsKICAgICAgICAgICAgICAgIHNpemUtLTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKiBGYWxsIHRocm91Z2ggKi8KCiAgICAgICAgY2FzZSBXSU5FRDNERk1UX0E4UjhHOEI4OgogICAgICAgIHsKICAgICAgICAgICAgZ2xQaXhlbFN0b3JlaShHTF9QQUNLX1NXQVBfQllURVMsIFRSVUUpOwogICAgICAgICAgICB2Y2hlY2tHTGNhbGwoImdsUGl4ZWxTdG9yZWkiKTsKICAgICAgICAgICAgc3RvcmVjaGFuZ2VkID0gVFJVRTsKICAgICAgICAgICAgdHlwZSA9IFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xUeXBlOwogICAgICAgICAgICBmbXQgPSBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0OwogICAgICAgICAgICBtZW0gPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnk7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfQTJSMTBHMTBCMTA6CiAgICAgICAgewogICAgICAgICAgICBnbFBpeGVsU3RvcmVpKEdMX1BBQ0tfU1dBUF9CWVRFUywgVFJVRSk7CiAgICAgICAgICAgIHZjaGVja0dMY2FsbCgiZ2xQaXhlbFN0b3JlaSIpOwogICAgICAgICAgICBzdG9yZWNoYW5nZWQgPSBUUlVFOwogICAgICAgICAgICB0eXBlID0gVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbFR5cGU7CiAgICAgICAgICAgIGZtdCA9IFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xGb3JtYXQ7CiAgICAgICAgICAgIG1lbSA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgV0lORUQzREZNVF9QODoKICAgICAgICB7CiAgICAgICAgICAgIFVJTlQgcGl0Y2ggPSBJV2luZUQzRFN1cmZhY2VfR2V0UGl0Y2goKElXaW5lRDNEU3VyZmFjZSAqKSBUaGlzKTsgICAgLyogdGFyZ2V0IGlzIGFyZ2IsIDQgYnl0ZSAqLwogICAgICAgICAgICBpbnQgaGVpZ2h0ID0gVGhpcy0+Z2xSZWN0LmJvdHRvbSAtIFRoaXMtPmdsUmVjdC50b3A7CiAgICAgICAgICAgIHR5cGUgPSBHTF9VTlNJR05FRF9CWVRFOwogICAgICAgICAgICBmbXQgPSBHTF9SR0JBOwoKICAgICAgICAgICAgbWVtID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnJlc291cmNlLnNpemUgKiBzaXplb2YoRFdPUkQpKTsKICAgICAgICAgICAgaWYoIW1lbSkgewogICAgICAgICAgICAgICAgRVJSKCJPdXQgb2YgbWVtb3J5XG4iKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICBkM2RmbXRfY29udmVydF9zdXJmYWNlKFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGl0Y2gqaGVpZ2h0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTlZFUlRfUEFMRVRURUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcyk7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBGSVhNRSgiVW5zdXBwb3J0ZWQgRm9ybWF0ICV1IGluIGxvY2tpbmcgZnVuY1xuIiwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0KTsKCiAgICAgICAgICAgIC8qIEdpdmUgaXQgYSB0cnkgKi8KICAgICAgICAgICAgdHlwZSA9IFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xUeXBlOwogICAgICAgICAgICBmbXQgPSBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0OwogICAgICAgICAgICBtZW0gPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnk7CiAgICB9CgogICAgZ2xEcmF3UGl4ZWxzKFRoaXMtPmxvY2tlZFJlY3QucmlnaHQgLSBUaGlzLT5sb2NrZWRSZWN0LmxlZnQsCiAgICAgICAgICAgICAgICAgKFRoaXMtPmxvY2tlZFJlY3QuYm90dG9tIC0gVGhpcy0+bG9ja2VkUmVjdC50b3ApLTEsCiAgICAgICAgICAgICAgICAgZm10LCB0eXBlLAogICAgICAgICAgICAgICAgIG1lbSk7CiAgICBjaGVja0dMY2FsbCgiZ2xEcmF3UGl4ZWxzIik7CiAgICBnbFBpeGVsWm9vbSgxLjAsMS4wKTsKICAgIHZjaGVja0dMY2FsbCgiZ2xQaXhlbFpvb20iKTsKCiAgICBnbFJhc3RlclBvczNpdigmcHJldl9yYXN0ZXJwb3NbMF0pOwogICAgdmNoZWNrR0xjYWxsKCJnbFJhc3RlclBvczNpdiIpOwoKICAgIC8qIFJlc2V0IHRvIHByZXZpb3VzIHBhY2sgcm93IGxlbmd0aCAqLwogICAgZ2xQaXhlbFN0b3JlaShHTF9VTlBBQ0tfUk9XX0xFTkdUSCwgc2tpcEJ5dGVzKTsKICAgIHZjaGVja0dMY2FsbCgiZ2xQaXhlbFN0b3JlaSBHTF9VTlBBQ0tfUk9XX0xFTkdUSCIpOwogICAgaWYoc3RvcmVjaGFuZ2VkKSB7CiAgICAgICAgZ2xQaXhlbFN0b3JlaShHTF9QQUNLX1NXQVBfQllURVMsIHByZXZfc3RvcmUpOwogICAgICAgIHZjaGVja0dMY2FsbCgiZ2xQaXhlbFN0b3JlaSBHTF9QQUNLX1NXQVBfQllURVMiKTsKICAgIH0KCiAgICBpZihtZW0gIT0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KSBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBtZW0pOwogICAgcmV0dXJuOwp9CgpzdGF0aWMgdm9pZCBmbHVzaF90b19mcmFtZWJ1ZmZlcl90ZXh0dXJlKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgZmxvYXQgZ2xUZXhDb29yZFs0XTsKCiAgICBnbFRleENvb3JkWzBdID0gMC4wOyAvKiBsZWZ0ICovCiAgICBnbFRleENvb3JkWzFdID0gKGZsb2F0KSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCAvIChmbG9hdCkgVGhpcy0+cG93MldpZHRoOyAvKiByaWdodCAqLwogICAgZ2xUZXhDb29yZFsyXSA9IDAuMDsgLyogdG9wICovCiAgICBnbFRleENvb3JkWzNdID0gKGZsb2F0KSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQgLyAoZmxvYXQpIFRoaXMtPnBvdzJIZWlnaHQ7IC8qIGJvdHRvbSAqLwoKICAgIElXaW5lRDNEU3VyZmFjZV9QcmVMb2FkKGlmYWNlKTsKCiAgICBFTlRFUl9HTCgpOwoKICAgIC8qIERpc2FibGUgc29tZSBmYW5jeSBncmFwaGljcyBlZmZlY3RzICovCiAgICBnbERpc2FibGUoR0xfTElHSFRJTkcpOwogICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9MSUdIVElORyIpOwogICAgZ2xEaXNhYmxlKEdMX0RFUFRIX1RFU1QpOwogICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9ERVBUSF9URVNUIik7CiAgICBnbERpc2FibGUoR0xfRk9HKTsKICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUgR0xfRk9HIik7CiAgICBnbERpc2FibGUoR0xfQ1VMTF9GQUNFKTsKICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUgR0xfQ1VMTF9GQUNFIik7CiAgICBnbERpc2FibGUoR0xfQkxFTkQpOwogICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9CTEVORCIpOwogICAgZ2xEaXNhYmxlKEdMX1NURU5DSUxfVEVTVCk7CiAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlIEdMX1NURU5DSUxfVEVTVCIpOwoKICAgIGdsRW5hYmxlKEdMX1RFWFRVUkVfMkQpOwogICAgZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCBUaGlzLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lKTsKICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZSBnbEJpbmRUZXh0dXJlIik7CgogICAgLyogTm8gZmlsdGVyaW5nIGZvciBibHRzICovCiAgICBnbFRleFBhcmFtZXRlcmkoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9NQUdfRklMVEVSLCBHTF9ORUFSRVNUKTsKICAgIGNoZWNrR0xjYWxsKCJnbFRleFBhcmFtZXRlcmkiKTsKICAgIGdsVGV4UGFyYW1ldGVyaShHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX01JTl9GSUxURVIsIEdMX05FQVJFU1QpOwogICAgY2hlY2tHTGNhbGwoImdsVGV4UGFyYW1ldGVyaSIpOwoKICAgIC8qIFN0YXJ0IGRyYXdpbmcgYSBxdWFkICovCiAgICBnbEJlZ2luKEdMX1FVQURTKTsKCiAgICBnbENvbG9yM2QoMS4wZiwgMS4wZiwgMS4wZik7CiAgICBnbFRleENvb3JkMmYoZ2xUZXhDb29yZFswXSwgZ2xUZXhDb29yZFsyXSk7CiAgICBnbFZlcnRleDNmKDAsIDAsIDAuMCk7CgogICAgZ2xUZXhDb29yZDJmKGdsVGV4Q29vcmRbMF0sIGdsVGV4Q29vcmRbM10pOwogICAgZ2xWZXJ0ZXgzZigwLCBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQsIDAuMCk7CgogICAgZ2xUZXhDb29yZDJmKGdsVGV4Q29vcmRbMV0sIGdsVGV4Q29vcmRbM10pOwogICAgZ2xWZXJ0ZXgzZChUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCwgVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0LCAwLjApOwoKICAgIGdsVGV4Q29vcmQyZihnbFRleENvb3JkWzFdLCBnbFRleENvb3JkWzJdKTsKICAgIGdsVmVydGV4M2YoVGhpcy0+Y3VycmVudERlc2MuV2lkdGgsIDAsIDAuMCk7CgogICAgZ2xFbmQoKTsKICAgIGNoZWNrR0xjYWxsKCJnbEVuZCIpOwoKICAgIC8qIFVuYmluZCB0aGUgdGV4dHVyZSAqLwogICAgZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCAwKTsKICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZSBnbEJpbmRUZXh0dXJlIik7CgogICAgTEVBVkVfR0woKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfVW5sb2NrUmVjdChJV2luZUQzRFN1cmZhY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAgKm15RGV2aWNlID0gVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZTsKICAgIGNvbnN0IGNoYXIgKmJ1ZmZlcm5hbWUgPSAiIjsKICAgIElXaW5lRDNEU3dhcENoYWluSW1wbCAqc3dhcGNoYWluID0gTlVMTDsKICAgIEJPT0wgYmFja2J1ZiA9IEZBTFNFOwoKICAgIGlmICghKFRoaXMtPkZsYWdzICYgU0ZMQUdfTE9DS0VEKSkgewogICAgICAgIFdBUk4oInRyeWluZyB0byBVbmxvY2sgYW4gdW5sb2NrZWQgc3VyZkAlcFxuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgaWYgKFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQgJiBUaGlzLT5yZXNvdXJjZS51c2FnZSkgewogICAgICAgIElXaW5lRDNEU3VyZmFjZV9HZXRDb250YWluZXIoaWZhY2UsICZJSURfSVdpbmVEM0RTd2FwQ2hhaW4sICh2b2lkICoqKSZzd2FwY2hhaW4pOwoKICAgICAgICBpZihzd2FwY2hhaW4pIHsKICAgICAgICAgICAgaW50IGk7CiAgICAgICAgICAgIGZvcihpID0gMDsgaSA8IHN3YXBjaGFpbi0+cHJlc2VudFBhcm1zLkJhY2tCdWZmZXJDb3VudDsgaSsrKSB7CiAgICAgICAgICAgICAgICBpZihpZmFjZSA9PSBzd2FwY2hhaW4tPmJhY2tCdWZmZXJbaV0pIHsKICAgICAgICAgICAgICAgICAgICBiYWNrYnVmID0gVFJVRTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKGJhY2tidWYpIHsKICAgICAgICAgICAgICAgIGJ1ZmZlcm5hbWUgPSAiYmFja0J1ZmZlciI7CiAgICAgICAgfSBlbHNlIGlmICgoc3dhcGNoYWluICE9IE5VTEwpICYmIGlmYWNlID09ICBzd2FwY2hhaW4tPmZyb250QnVmZmVyKSB7CiAgICAgICAgICAgICAgICBidWZmZXJuYW1lID0gImZyb250QnVmZmVyIjsKICAgICAgICB9IGVsc2UgaWYgKGlmYWNlID09IG15RGV2aWNlLT5kZXB0aFN0ZW5jaWxCdWZmZXIpIHsKICAgICAgICAgICAgICAgIGJ1ZmZlcm5hbWUgPSAiZGVwdGhTdGVuY2lsQnVmZmVyIjsKICAgICAgICB9IGVsc2UgaWYgKGlmYWNlID09IG15RGV2aWNlLT5yZW5kZXJUYXJnZXQpIHsKICAgICAgICAgICAgICAgIGJ1ZmZlcm5hbWUgPSAicmVuZGVyVGFyZ2V0IjsKICAgICAgICB9CiAgICB9CgogICAgaWYgKHN3YXBjaGFpbiAhPSBOVUxMKSB7CiAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZSgoSVdpbmVEM0RTd2FwQ2hhaW4gKilzd2FwY2hhaW4pOwogICAgfQoKICAgIFRSQUNFKCIoJXAgJXMpIDogZGlydHlmaWVkKCVkKVxuIiwgVGhpcywgYnVmZmVybmFtZSwgVGhpcy0+RmxhZ3MgJiBTRkxBR19ESVJUWSA/IDEgOiAwKTsKCiAgICBpZiAoIShUaGlzLT5GbGFncyAmIFNGTEFHX0RJUlRZKSkgewogICAgICAgIFRSQUNFKCIoJXApIDogTm90IERpcnRpZmllZCBzbyBub3RoaW5nIHRvIGRvLCByZXR1cm4gbm93XG4iLCBUaGlzKTsKICAgICAgICBnb3RvIHVubG9ja19lbmQ7CiAgICB9CgogICAgaWYgKDAgPT0gVGhpcy0+cmVzb3VyY2UudXNhZ2UpIHsgLyogY2xhc3NpYyBzdXJmYWNlICovCiAgICAgICAgLyoqCiAgICAgICAgICogbm90aGluZyB0byBkbwogICAgICAgICAqIHdhaXRpbmcgdG8gcmVsb2FkIHRoZSBzdXJmYWNlIHZpYSBJRGlyZWN0M0REZXZpY2U4OjpVcGRhdGVUZXh0dXJlCiAgICAgICAgICovCiAgICB9IGVsc2UgaWYgKFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQgJiBUaGlzLT5yZXNvdXJjZS51c2FnZSkgeyAvKiByZW5kZXIgc3VyZmFjZXMgKi8KCiAgICAgICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioKICAgICAgICAqIFRPRE86IFJlbmRlciB0YXJnZXRzIGFyZSAnc3BlY2lhbCcgYW5kCiAgICAgICAgKiA/c29tZT8gbG9ja2luZyBuZWVkcyB0byBiZSBwYXNzZWQgb250byB0aGUgY29udGV4dCBtYW5hZ2VyCiAgICAgICAgKiBzbyB0aGF0IGl0IGJlY29tZXMgcG9zc2libGUgdG8gdXNlIGF1eGlsaWFyeSBidWZmZXJzLCBwYnVmZmVycwogICAgICAgICogcmVuZGVyLXRvLXRleHR1cmUsIHNoYXJlZCwgY2FjaGVkIGNvbnRleHRzIGV0Yy4uLgogICAgICAgICogKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KICAgICAgICBJV2luZUQzRFN3YXBDaGFpbkltcGwgKmltcGxTd2FwQ2hhaW47CiAgICAgICAgSVdpbmVEM0REZXZpY2VfR2V0U3dhcENoYWluKChJV2luZUQzRERldmljZSAqKW15RGV2aWNlLCAwLCAoSVdpbmVEM0RTd2FwQ2hhaW4gKiopJmltcGxTd2FwQ2hhaW4pOwoKICAgICAgICBpZiAoYmFja2J1ZiB8fCBpZmFjZSA9PSAgaW1wbFN3YXBDaGFpbi0+ZnJvbnRCdWZmZXIgfHwgaWZhY2UgPT0gbXlEZXZpY2UtPnJlbmRlclRhcmdldCkgewogICAgICAgICAgICBpbnQgdGV4OwoKICAgICAgICAgICAgRU5URVJfR0woKTsKCiAgICAgICAgICAgIC8qIGdsRHJhd1BpeGVscyB0cmFuc2Zvcm1zIHRoZSByYXN0ZXIgcG9zaXRpb24gYXMgdGhvdWdoIGl0IHdhcyBhIHZlcnRleCAtCiAgICAgICAgICAgICAgIHdlIHdhbnQgdG8gZHJhdyBhdCBzY3JlZW4gcG9zaXRpb24gMCwwIC0gU2V0IHVwIG9ydGhvIChyaHcpIG1vZGUgYXMKICAgICAgICAgICAgICAgcGVyIGRyYXdwcmltIChhbmQgbGVhdmUgc2V0IC0gaXQgd2lsbCBzb3J0IGl0c2VsZiBvdXQgZHVlIHRvIGxhc3Rfd2FzX3JodyAqLwogICAgICAgICAgICBkM2RkZXZpY2Vfc2V0X29ydGhvKFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2UpOwoKICAgICAgICAgICAgaWYgKGlmYWNlID09ICBpbXBsU3dhcENoYWluLT5mcm9udEJ1ZmZlcikgewogICAgICAgICAgICAgICAgZ2xEcmF3QnVmZmVyKEdMX0ZST05UKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERyYXdCdWZmZXIgR0xfRlJPTlQiKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChiYWNrYnVmIHx8IGlmYWNlID09IG15RGV2aWNlLT5yZW5kZXJUYXJnZXQpIHsKICAgICAgICAgICAgICAgIGdsRHJhd0J1ZmZlcihHTF9CQUNLKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERyYXdCdWZmZXIgR0xfQkFDSyIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKiBEaXNhYmxlIGhpZ2hlciB0ZXh0dXJlcyBiZWZvcmUgY2FsbGluZyBnbERyYXdQaXhlbHMgKi8KICAgICAgICAgICAgZm9yKHRleCA9IDE7IHRleCA8IEdMX0xJTUlUUyhzYW1wbGVycyk7IHRleCsrKSB7CiAgICAgICAgICAgICAgICBpZiAoR0xfU1VQUE9SVChBUkJfTVVMVElURVhUVVJFKSkgewogICAgICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xBY3RpdmVUZXh0dXJlQVJCKEdMX1RFWFRVUkUwX0FSQiArIHRleCkpOwogICAgICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEFjdGl2ZVRleHR1cmVBUkIiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGdsRGlzYWJsZShHTF9URVhUVVJFXzJEKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUgR0xfVEVYVFVSRV8yRCIpOwogICAgICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX1RFWFRVUkVfMUQpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9URVhUVVJFXzFEIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyogQWN0aXZhdGUgdGV4dHVyZSAwLCBidXQgZG9uJ3QgZGlzYWJsZSBpdCBuZWNlc3NhcmlsbHkgKi8KICAgICAgICAgICAgaWYgKEdMX1NVUFBPUlQoQVJCX01VTFRJVEVYVFVSRSkpIHsKICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xBY3RpdmVUZXh0dXJlQVJCKEdMX1RFWFRVUkUwX0FSQikpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsQWN0aXZlVGV4dHVyZUFSQiIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKiBBbmQgYmFjayBidWZmZXJzIGFyZSBub3QgYmxlbmRlZC4gRGlzYWJsZSB0aGUgZGVwdGggdGVzdCwgCiAgICAgICAgICAgICAgIHRoYXQgaGVscHMgcGVyZm9ybWFuY2UgKi8KICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX0JMRU5EKTsKICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX0RFUFRIX1RFU1QpOwogICAgICAgICAgICBnbERpc2FibGUoR0xfRk9HKTsKCiAgICAgICAgICAgIHN3aXRjaCh3aW5lZDNkX3NldHRpbmdzLnJlbmRlcnRhcmdldGxvY2tfbW9kZSkgewogICAgICAgICAgICAgICAgY2FzZSBSVExfQVVUTzoKICAgICAgICAgICAgICAgIGNhc2UgUlRMX1JFQUREUkFXOgogICAgICAgICAgICAgICAgY2FzZSBSVExfVEVYRFJBVzoKICAgICAgICAgICAgICAgICAgICBmbHVzaF90b19mcmFtZWJ1ZmZlcl9kcmF3cGl4ZWxzKFRoaXMpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgUlRMX1JFQURURVg6CiAgICAgICAgICAgICAgICBjYXNlIFJUTF9URVhURVg6CiAgICAgICAgICAgICAgICAgICAgZmx1c2hfdG9fZnJhbWVidWZmZXJfdGV4dHVyZShpZmFjZSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSBSVExfRElTQUJMRToKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzdGF0aWMgQk9PTCB3YXJuZWQgPSBGQUxTRTsKICAgICAgICAgICAgICAgICAgICBpZighd2FybmVkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIEVSUigiVGhlIGFwcGxpY2F0aW9uIHRyaWVzIHRvIHdyaXRlIHRvIHRoZSByZW5kZXIgdGFyZ2V0LCBidXQgcmVuZGVyIHRhcmdldCBsb2NraW5nIGlzIGRpc2FibGVkXG4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgd2FybmVkID0gVFJVRTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYoaW1wbFN3YXBDaGFpbi0+YmFja0J1ZmZlciAmJiBpbXBsU3dhcENoYWluLT5iYWNrQnVmZmVyWzBdKSB7CiAgICAgICAgICAgICAgICBnbERyYXdCdWZmZXIoR0xfQkFDSyk7CiAgICAgICAgICAgICAgICB2Y2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlciIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKG15RGV2aWNlLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtEM0RSU19aRU5BQkxFXSA9PSBEM0RaQl9UUlVFIHx8CiAgICAgICAgICAgICAgIG15RGV2aWNlLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtEM0RSU19aRU5BQkxFXSA9PSBEM0RaQl9VU0VXKSBnbEVuYWJsZShHTF9ERVBUSF9URVNUKTsKICAgICAgICAgICAgaWYgKG15RGV2aWNlLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtEM0RSU19BTFBIQUJMRU5ERU5BQkxFXSkgZ2xFbmFibGUoR0xfQkxFTkQpOwogICAgICAgICAgICBpZiAobXlEZXZpY2UtPnN0YXRlQmxvY2stPnJlbmRlclN0YXRlW0QzRFJTX0ZPR0VOQUJMRV0pIGdsRW5hYmxlKEdMX0ZPRyk7CgogICAgICAgICAgICBMRUFWRV9HTCgpOwoKICAgICAgICAgICAgLyoqIHJlc3RvcmUgY2xlYW4gZGlydHkgc3RhdGUgKi8KICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0NsZWFuRGlydHlSZWN0KGlmYWNlKTsKCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgRklYTUUoInVuc3VwcG9ydGVkIHVubG9ja2luZyB0byBSZW5kZXJpbmcgc3VyZmFjZSBzdXJmQCVwIHVzYWdlKCVzKVxuIiwgVGhpcywgZGVidWdfZDNkdXNhZ2UoVGhpcy0+cmVzb3VyY2UudXNhZ2UpKTsKICAgICAgICB9CiAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZSgoSVdpbmVEM0RTd2FwQ2hhaW4gKilpbXBsU3dhcENoYWluKTsKCiAgICB9IGVsc2UgaWYgKFdJTkVEM0RVU0FHRV9ERVBUSFNURU5DSUwgJiBUaGlzLT5yZXNvdXJjZS51c2FnZSkgeyAvKiBzdGVuY2lsIHN1cmZhY2VzICovCgogICAgICAgIGlmIChpZmFjZSA9PSBteURldmljZS0+ZGVwdGhTdGVuY2lsQnVmZmVyKSB7CiAgICAgICAgICAgIEZJWE1FKCJUT0RPIHN0ZW5jaWwgZGVwdGggc3VyZmFjZSB1bmxvY2tpbmcgc3VyZkAlcCB1c2FnZSglcylcbiIsIFRoaXMsIGRlYnVnX2QzZHVzYWdlKFRoaXMtPnJlc291cmNlLnVzYWdlKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgRklYTUUoInVuc3VwcG9ydGVkIHVubG9ja2luZyB0byBTdGVuY2lsRGVwdGggc3VyZmFjZSBzdXJmQCVwIHVzYWdlKCVzKVxuIiwgVGhpcywgZGVidWdfZDNkdXNhZ2UoVGhpcy0+cmVzb3VyY2UudXNhZ2UpKTsKICAgICAgICB9CgogICAgfSBlbHNlIHsKICAgICAgICBGSVhNRSgidW5zdXBwb3J0ZWQgdW5sb2NraW5nIHRvIHN1cmZhY2Ugc3VyZkAlcCB1c2FnZSglcylcbiIsIFRoaXMsIGRlYnVnX2QzZHVzYWdlKFRoaXMtPnJlc291cmNlLnVzYWdlKSk7CiAgICB9CgogICAgdW5sb2NrX2VuZDoKICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19MT0NLRUQ7CiAgICBtZW1zZXQoJlRoaXMtPmxvY2tlZFJlY3QsIDAsIHNpemVvZihSRUNUKSk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXREQyhJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBIREMgKnBIREMpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgV0lORUQzRExPQ0tFRF9SRUNUIGxvY2s7CiAgICBVSU5UIHVzYWdlOwogICAgQklUTUFQSU5GTyogYl9pbmZvOwogICAgSERDIGRkYzsKICAgIERXT1JEICptYXNrczsKICAgIEhSRVNVTFQgaHI7CiAgICBSR0JRVUFEIGNvbFsyNTZdOwogICAgY29uc3QgUGl4ZWxGb3JtYXREZXNjICpmb3JtYXRFbnRyeSA9IGdldEZvcm1hdERlc2NFbnRyeShUaGlzLT5yZXNvdXJjZS5mb3JtYXQpOwoKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLFRoaXMscEhEQyk7CgogICAgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19VU0VSUFRSKSB7CiAgICAgICAgRVJSKCJOb3Qgc3VwcG9ydGVkIG9uIHN1cmZhY2VzIHdpdGggYW4gYXBwbGljYXRpb24tcHJvdmlkZWQgc3VyZmFjZXNcbiIpOwogICAgICAgIHJldHVybiBEREVSUl9OT0RDOwogICAgfQoKICAgIC8qIEdpdmUgbW9yZSBkZXRhaWxlZCBpbmZvIGZvciBkZHJhdyAqLwogICAgaWYgKFRoaXMtPkZsYWdzICYgU0ZMQUdfRENJTlVTRSkKICAgICAgICByZXR1cm4gRERFUlJfRENBTFJFQURZQ1JFQVRFRDsKCiAgICAvKiBDYW4ndCBHZXREQyBpZiB0aGUgc3VyZmFjZSBpcyBsb2NrZWQgKi8KICAgIGlmIChUaGlzLT5GbGFncyAmIFNGTEFHX0xPQ0tFRCkKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKCiAgICBtZW1zZXQoJmxvY2ssIDAsIHNpemVvZihsb2NrKSk7IC8qIFRvIGJlIHN1cmUgKi8KCiAgICAvKiBDcmVhdGUgYSBESUIgc2VjdGlvbiBpZiB0aGVyZSBpc24ndCBhIGhkYyB5ZXQgKi8KICAgIGlmKCFUaGlzLT5oREMpIHsKICAgICAgICBpbnQgZXh0cmFsaW5lID0gMDsKICAgICAgICBTWVNURU1fSU5GTyBzeXNJbmZvOwoKICAgICAgICBpZihUaGlzLT5GbGFncyAmIFNGTEFHX0FDVElWRUxPQ0spIHsKICAgICAgICAgICAgRVJSKCJDcmVhdGluZyBhIERJQiBzZWN0aW9uIHdoaWxlIGEgbG9jayBpcyBhY3RpdmUuIFVuY2VydGFpbiBjb25zZXF1ZW5jZXNcbiIpOwogICAgICAgIH0KCiAgICAgICAgc3dpdGNoIChUaGlzLT5ieXRlc1BlclBpeGVsKSB7CiAgICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgY2FzZSA0OgogICAgICAgICAgICAgICAgLyogQWxsb2NhdGUgZXh0cmEgc3BhY2UgdG8gc3RvcmUgdGhlIFJHQiBiaXQgbWFza3MuICovCiAgICAgICAgICAgICAgICBiX2luZm8gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKEJJVE1BUElORk9IRUFERVIpICsgMyAqIHNpemVvZihEV09SRCkpOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgICAgICBiX2luZm8gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKEJJVE1BUElORk9IRUFERVIpKTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIC8qIEFsbG9jYXRlIGV4dHJhIHNwYWNlIGZvciBhIHBhbGV0dGUuICovCiAgICAgICAgICAgICAgICBiX2luZm8gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihCSVRNQVBJTkZPSEVBREVSKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBzaXplb2YoUkdCUVVBRCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogKDEgPDwgKFRoaXMtPmJ5dGVzUGVyUGl4ZWwgKiA4KSkpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWJfaW5mbykKICAgICAgICAgICAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CgogICAgICAgIC8qIFNvbWUgYXBwcyBhY2Nlc3MgdGhlIHN1cmZhY2UgaW4gdmlhIERXT1JEcywgYW5kIGRvIG5vdCB0YWtlIHRoZSBuZWNlc3NhcnkgY2FyZSBhdCB0aGUgZW5kIG9mIHRoZQogICAgICAgICAqIHN1cmZhY2UuIFNvIHdlIG5lZWQgYXQgbGVhc3QgZXh0cmEgNCBieXRlcyBhdCB0aGUgZW5kIG9mIHRoZSBzdXJmYWNlLiBDaGVjayBhZ2FpbnN0IHRoZSBwYWdlIHNpemUsCiAgICAgICAgICogaWYgdGhlIGxhc3QgcGFnZSB1c2VkIGZvciB0aGUgc3VyZmFjZSBoYXMgYXQgbGVhc3QgNCBzcGFyZSBieXRlcyB3ZSdyZSBzYWZlLCBvdGhlcndpc2UKICAgICAgICAgKiBhZGQgYW4gZXh0cmEgbGluZSB0byB0aGUgZGliIHNlY3Rpb24KICAgICAgICAgKi8KICAgICAgICBHZXRTeXN0ZW1JbmZvKCZzeXNJbmZvKTsKICAgICAgICBpZiggKChUaGlzLT5yZXNvdXJjZS5zaXplICsgMykgJSBzeXNJbmZvLmR3UGFnZVNpemUpIDwgNCkgewogICAgICAgICAgICBleHRyYWxpbmUgPSAxOwogICAgICAgICAgICBUUkFDRSgiQWRkaW5nIGFuIGV4dHJhIGxpbmUgdG8gdGhlIGRpYiBzZWN0aW9uXG4iKTsKICAgICAgICB9CgogICAgICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpU2l6ZSA9IHNpemVvZihCSVRNQVBJTkZPSEVBREVSKTsKICAgICAgICBpZiggKE5QMl9SRVBBQ0sgPT0gd2luZWQzZF9zZXR0aW5ncy5ub25wb3dlcjJfbW9kZSB8fCBUaGlzLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQpKSB7CiAgICAgICAgICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpV2lkdGggPSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICAgICAgYl9pbmZvLT5ibWlIZWFkZXIuYmlIZWlnaHQgPSAtVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0IC1leHRyYWxpbmU7CiAgICAgICAgICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpU2l6ZUltYWdlID0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGggKiBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQgKiBUaGlzLT5ieXRlc1BlclBpeGVsOwogICAgICAgICAgICAvKiBVc2UgdGhlIGZ1bGwgcG93MiBpbWFnZSBzaXplKGFzc2lnbmVkIGJlbG93KSBiZWNhdXNlIExvY2tSZWN0CiAgICAgICAgICAgICAqIHdpbGwgbmVlZCBpdCBmb3IgYSBmdWxsIGdsR2V0VGV4SW1hZ2UgY2FsbAogICAgICAgICAgICAgKi8KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBiX2luZm8tPmJtaUhlYWRlci5iaVdpZHRoID0gVGhpcy0+cG93MldpZHRoOwogICAgICAgICAgICBiX2luZm8tPmJtaUhlYWRlci5iaUhlaWdodCA9IC1UaGlzLT5wb3cySGVpZ2h0IC1leHRyYWxpbmU7CiAgICAgICAgICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpU2l6ZUltYWdlID0gVGhpcy0+cmVzb3VyY2Uuc2l6ZTsKICAgICAgICB9CiAgICAgICAgYl9pbmZvLT5ibWlIZWFkZXIuYmlQbGFuZXMgPSAxOwogICAgICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpQml0Q291bnQgPSBUaGlzLT5ieXRlc1BlclBpeGVsICogODsKCiAgICAgICAgYl9pbmZvLT5ibWlIZWFkZXIuYmlYUGVsc1Blck1ldGVyID0gMDsKICAgICAgICBiX2luZm8tPmJtaUhlYWRlci5iaVlQZWxzUGVyTWV0ZXIgPSAwOwogICAgICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpQ2xyVXNlZCA9IDA7CiAgICAgICAgYl9pbmZvLT5ibWlIZWFkZXIuYmlDbHJJbXBvcnRhbnQgPSAwOwoKICAgICAgICAvKiBHZXQgdGhlIGJpdCBtYXNrcyAqLwogICAgICAgIG1hc2tzID0gKERXT1JEICopICYoYl9pbmZvLT5ibWlDb2xvcnMpOwogICAgICAgIHN3aXRjaCAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0KSB7CiAgICAgICAgICAgIGNhc2UgV0lORUQzREZNVF9SOEc4Qjg6CiAgICAgICAgICAgICAgICB1c2FnZSA9IERJQl9SR0JfQ09MT1JTOwogICAgICAgICAgICAgICAgYl9pbmZvLT5ibWlIZWFkZXIuYmlDb21wcmVzc2lvbiA9IEJJX1JHQjsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBXSU5FRDNERk1UX1gxUjVHNUI1OgogICAgICAgICAgICBjYXNlIFdJTkVEM0RGTVRfQTFSNUc1QjU6CiAgICAgICAgICAgIGNhc2UgV0lORUQzREZNVF9BNFI0RzRCNDoKICAgICAgICAgICAgY2FzZSBXSU5FRDNERk1UX1g0UjRHNEI0OgogICAgICAgICAgICBjYXNlIFdJTkVEM0RGTVRfUjNHM0IyOgogICAgICAgICAgICBjYXNlIFdJTkVEM0RGTVRfQThSM0czQjI6CiAgICAgICAgICAgIGNhc2UgV0lORUQzREZNVF9BMkIxMEcxMFIxMDoKICAgICAgICAgICAgY2FzZSBXSU5FRDNERk1UX0E4QjhHOFI4OgogICAgICAgICAgICBjYXNlIFdJTkVEM0RGTVRfWDhCOEc4Ujg6CiAgICAgICAgICAgIGNhc2UgV0lORUQzREZNVF9BMlIxMEcxMEIxMDoKICAgICAgICAgICAgY2FzZSBXSU5FRDNERk1UX1I1RzZCNToKICAgICAgICAgICAgY2FzZSBXSU5FRDNERk1UX0ExNkIxNkcxNlIxNjoKICAgICAgICAgICAgICAgIHVzYWdlID0gMDsKICAgICAgICAgICAgICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpQ29tcHJlc3Npb24gPSBCSV9CSVRGSUVMRFM7CiAgICAgICAgICAgICAgICBtYXNrc1swXSA9IGZvcm1hdEVudHJ5LT5yZWRNYXNrOwogICAgICAgICAgICAgICAgbWFza3NbMV0gPSBmb3JtYXRFbnRyeS0+Z3JlZW5NYXNrOwogICAgICAgICAgICAgICAgbWFza3NbMl0gPSBmb3JtYXRFbnRyeS0+Ymx1ZU1hc2s7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAvKiBEb24ndCBrbm93IHBhbGV0dGUgKi8KICAgICAgICAgICAgICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpQ29tcHJlc3Npb24gPSBCSV9SR0I7CiAgICAgICAgICAgICAgICB1c2FnZSA9IDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGRkYyA9IENyZWF0ZURDQSgiRElTUExBWSIsIE5VTEwsIE5VTEwsIE5VTEwpOwogICAgICAgIGlmIChkZGMgPT0gMCkgewogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBiX2luZm8pOwogICAgICAgICAgICByZXR1cm4gSFJFU1VMVF9GUk9NX1dJTjMyKEdldExhc3RFcnJvcigpKTsKICAgICAgICB9CgogICAgICAgIFRSQUNFKCJDcmVhdGluZyBhIERJQiBzZWN0aW9uIHdpdGggc2l6ZSAlbGR4JWxkeCVkLCBzaXplPSVsZFxuIiwgYl9pbmZvLT5ibWlIZWFkZXIuYmlXaWR0aCwgYl9pbmZvLT5ibWlIZWFkZXIuYmlIZWlnaHQsIGJfaW5mby0+Ym1pSGVhZGVyLmJpQml0Q291bnQsIGJfaW5mby0+Ym1pSGVhZGVyLmJpU2l6ZUltYWdlKTsKICAgICAgICBUaGlzLT5kaWIuRElCc2VjdGlvbiA9IENyZWF0ZURJQlNlY3Rpb24oZGRjLCBiX2luZm8sIHVzYWdlLCAmVGhpcy0+ZGliLmJpdG1hcF9kYXRhLCAwIC8qIEhhbmRsZSAqLywgMCAvKiBPZmZzZXQgKi8pOwogICAgICAgIERlbGV0ZURDKGRkYyk7CgogICAgICAgIGlmICghVGhpcy0+ZGliLkRJQnNlY3Rpb24pIHsKICAgICAgICAgICAgRVJSKCJDcmVhdGVESUJTZWN0aW9uIGZhaWxlZCFcbiIpOwogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBiX2luZm8pOwogICAgICAgICAgICByZXR1cm4gSFJFU1VMVF9GUk9NX1dJTjMyKEdldExhc3RFcnJvcigpKTsKICAgICAgICB9CgogICAgICAgIFRSQUNFKCJESUJTZWN0aW9uIGF0IDogJXBcbiIsIFRoaXMtPmRpYi5iaXRtYXBfZGF0YSk7CgogICAgICAgIC8qIGNvcHkgdGhlIGV4aXN0aW5nIHN1cmZhY2UgdG8gdGhlIGRpYiBzZWN0aW9uICovCiAgICAgICAgaWYoVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KSB7CiAgICAgICAgICAgIG1lbWNweShUaGlzLT5kaWIuYml0bWFwX2RhdGEsIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSwgYl9pbmZvLT5ibWlIZWFkZXIuYmlTaXplSW1hZ2UpOwogICAgICAgICAgICAvKiBXZSB3b24ndCBuZWVkIHRoYXQgYW55IG1vcmUgKi8KICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvKiBUaGlzIGlzIHRvIG1ha2UgTG9ja1JlY3QgcmVhZCB0aGUgZ2wgVGV4dHVyZSBhbHRob3VnaCBtZW1vcnkgaXMgYWxsb2NhdGVkICovCiAgICAgICAgICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX0dMRElSVFk7CiAgICAgICAgfQoKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBiX2luZm8pOwoKICAgICAgICAvKiBVc2UgdGhlIGRpYiBzZWN0aW9uIGZyb20gbm93IG9uICovCiAgICAgICAgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gVGhpcy0+ZGliLmJpdG1hcF9kYXRhOwoKICAgICAgICAvKiBOb3cgYWxsb2NhdGUgYSBIREMgKi8KICAgICAgICBUaGlzLT5oREMgPSBDcmVhdGVDb21wYXRpYmxlREMoMCk7CiAgICAgICAgVGhpcy0+ZGliLmhvbGRiaXRtYXAgPSBTZWxlY3RPYmplY3QoVGhpcy0+aERDLCBUaGlzLT5kaWIuRElCc2VjdGlvbik7CiAgICAgICAgVFJBQ0UoInVzaW5nIHdpbmVkM2QgcGFsZXR0ZSAlcFxuIiwgVGhpcy0+cGFsZXR0ZSk7CiAgICAgICAgU2VsZWN0UGFsZXR0ZShUaGlzLT5oREMsCiAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5wYWxldHRlID8gVGhpcy0+cGFsZXR0ZS0+aHBhbCA6IDAsCiAgICAgICAgICAgICAgICAgICAgICBGQUxTRSk7CgogICAgICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX0RJQlNFQ1RJT047CiAgICB9CgogICAgLyogTG9jayB0aGUgc3VyZmFjZSAqLwogICAgaHIgPSBJV2luZUQzRFN1cmZhY2VfTG9ja1JlY3QoaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbG9jaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwKTsKICAgIGlmKEZBSUxFRChocikpIHsKICAgICAgICBFUlIoIklXaW5lRDNEU3VyZmFjZV9Mb2NrUmVjdCBmYWlsZWQgd2l0aCBociA9ICUwOGx4XG4iLCBocik7CiAgICAgICAgLyoga2VlcCB0aGUgZGliIHNlY3Rpb24gKi8KICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgaWYoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfUDggfHwKICAgICAgICBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9BOFA4KSB7CiAgICAgICAgdW5zaWduZWQgaW50IG47CiAgICAgICAgaWYoVGhpcy0+cGFsZXR0ZSkgewogICAgICAgICAgICBQQUxFVFRFRU5UUlkgZW50WzI1Nl07CgogICAgICAgICAgICBHZXRQYWxldHRlRW50cmllcyhUaGlzLT5wYWxldHRlLT5ocGFsLCAwLCAyNTYsIGVudCk7CiAgICAgICAgICAgIGZvciAobj0wOyBuPDI1NjsgbisrKSB7CiAgICAgICAgICAgICAgICBjb2xbbl0ucmdiUmVkICAgPSBlbnRbbl0ucGVSZWQ7CiAgICAgICAgICAgICAgICBjb2xbbl0ucmdiR3JlZW4gPSBlbnRbbl0ucGVHcmVlbjsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JCbHVlICA9IGVudFtuXS5wZUJsdWU7CiAgICAgICAgICAgICAgICBjb2xbbl0ucmdiUmVzZXJ2ZWQgPSAwOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsICpkZXZpY2UgPSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOwoKICAgICAgICAgICAgZm9yIChuPTA7IG48MjU2OyBuKyspIHsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JSZWQgICA9IGRldmljZS0+cGFsZXR0ZXNbZGV2aWNlLT5jdXJyZW50UGFsZXR0ZV1bbl0ucGVSZWQ7CiAgICAgICAgICAgICAgICBjb2xbbl0ucmdiR3JlZW4gPSBkZXZpY2UtPnBhbGV0dGVzW2RldmljZS0+Y3VycmVudFBhbGV0dGVdW25dLnBlR3JlZW47CiAgICAgICAgICAgICAgICBjb2xbbl0ucmdiQmx1ZSAgPSBkZXZpY2UtPnBhbGV0dGVzW2RldmljZS0+Y3VycmVudFBhbGV0dGVdW25dLnBlQmx1ZTsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JSZXNlcnZlZCA9IDA7CiAgICAgICAgICAgIH0KCiAgICAgICAgfQogICAgICAgIFNldERJQkNvbG9yVGFibGUoVGhpcy0+aERDLCAwLCAyNTYsIGNvbCk7CiAgICB9CgogICAgKnBIREMgPSBUaGlzLT5oREM7CiAgICBUUkFDRSgicmV0dXJuaW5nICVwXG4iLCpwSERDKTsKICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX0RDSU5VU0U7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfUmVsZWFzZURDKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIEhEQyBoREMpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwoKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLFRoaXMsaERDKTsKCiAgICBpZiAoIShUaGlzLT5GbGFncyAmIFNGTEFHX0RDSU5VU0UpKQogICAgICAgIHJldHVybiBEM0RFUlJfSU5WQUxJRENBTEw7CgogICAgLyogd2UgbG9ja2VkIGZpcnN0LCBzbyB1bmxvY2sgbm93ICovCiAgICBJV2luZUQzRFN1cmZhY2VfVW5sb2NrUmVjdChpZmFjZSk7CgogICAgVGhpcy0+RmxhZ3MgJj0gflNGTEFHX0RDSU5VU0U7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogICBJV2luZUQzRFN1cmZhY2UgSW50ZXJuYWwgKE5vIG1hcHBpbmcgdG8gZGlyZWN0eCBhcGkpIHBhcnRzIGZvbGxvdwogICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi8KCkhSRVNVTFQgZDNkZm10X2dldF9jb252KElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMsIEJPT0wgbmVlZF9hbHBoYV9jaywgQk9PTCB1c2VfdGV4dHVyaW5nLCBHTGVudW0gKmZvcm1hdCwgR0xlbnVtICppbnRlcm5hbCwgR0xlbnVtICp0eXBlLCBDT05WRVJUX1RZUEVTICpjb252ZXJ0LCBpbnQgKnRhcmdldF9icHApIHsKICAgIEJPT0wgY29sb3JrZXlfYWN0aXZlID0gbmVlZF9hbHBoYV9jayAmJiAoVGhpcy0+Q0tleUZsYWdzICYgRERTRF9DS1NSQ0JMVCk7CiAgICBjb25zdCBQaXhlbEZvcm1hdERlc2MgKmZvcm1hdEVudHJ5ID0gZ2V0Rm9ybWF0RGVzY0VudHJ5KFRoaXMtPnJlc291cmNlLmZvcm1hdCk7CgogICAgLyogRGVmYXVsdCB2YWx1ZXM6IEZyb20gdGhlIHN1cmZhY2UgKi8KICAgICpmb3JtYXQgPSBmb3JtYXRFbnRyeS0+Z2xGb3JtYXQ7CiAgICAqaW50ZXJuYWwgPSBmb3JtYXRFbnRyeS0+Z2xJbnRlcm5hbDsKICAgICp0eXBlID0gZm9ybWF0RW50cnktPmdsVHlwZTsKICAgICpjb252ZXJ0ID0gTk9fQ09OVkVSU0lPTjsKICAgICp0YXJnZXRfYnBwID0gVGhpcy0+Ynl0ZXNQZXJQaXhlbDsKCiAgICAvKiBPaywgbm93IGxvb2sgaWYgd2UgaGF2ZSB0byBkbyBhbnkgY29udmVyc2lvbiAqLwogICAgc3dpdGNoKFRoaXMtPnJlc291cmNlLmZvcm1hdCkgewogICAgICAgIGNhc2UgV0lORUQzREZNVF9QODoKICAgICAgICAgICAgLyogKioqKioqKioqKioqKioqKgogICAgICAgICAgICAgICAgUGFsZXR0ZWQgVGV4dHVyZQogICAgICAgICAgICAgICAgKioqKioqKioqKioqKioqKiAqLwogICAgICAgICAgICAvKiBVc2UgY29udmVyc2lvbiB3aGVuIHRoZSBwYWxldHRlZCB0ZXh0dXJlIGV4dGVuc2lvbiBpcyBub3QgYXZhaWxhYmxlLCBvciB3aGVuIGl0IGlzIGF2YWlsYWJsZSBtYWtlIHN1cmUgaXQgaXMgdXNlZAogICAgICAgICAgICAgKiBmb3IgdGV4dHVyaW5nIGFzIGl0IHdvbid0IHdvcmsgZm9yIGNhbGxzIGxpa2UgZ2xEcmF3LS9nbFJlYWRQaXhlbHMgYW5kIGZ1cnRoZXIgYWxzbyB1c2UgY29udmVyc2lvbiBpbiBjYXNlIG9mIGNvbG9yIGtleWluZy4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmKCFHTF9TVVBQT1JUKEVYVF9QQUxFVFRFRF9URVhUVVJFKSB8fCBjb2xvcmtleV9hY3RpdmUgfHwgKCF1c2VfdGV4dHVyaW5nICYmIEdMX1NVUFBPUlQoRVhUX1BBTEVUVEVEX1RFWFRVUkUpKSApIHsKICAgICAgICAgICAgICAgICpmb3JtYXQgPSBHTF9SR0JBOwogICAgICAgICAgICAgICAgKmludGVybmFsID0gR0xfUkdCQTsKICAgICAgICAgICAgICAgICp0eXBlID0gR0xfVU5TSUdORURfQllURTsKICAgICAgICAgICAgICAgICp0YXJnZXRfYnBwID0gNDsKICAgICAgICAgICAgICAgIGlmKGNvbG9ya2V5X2FjdGl2ZSkgewogICAgICAgICAgICAgICAgICAgICpjb252ZXJ0ID0gQ09OVkVSVF9QQUxFVFRFRF9DSzsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgKmNvbnZlcnQgPSBDT05WRVJUX1BBTEVUVEVEOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1IzRzNCMjoKICAgICAgICAgICAgLyogKioqKioqKioqKioqKioqKioqKioqKgogICAgICAgICAgICAgICAgR0xfVU5TSUdORURfQllURV8zXzNfMgogICAgICAgICAgICAgICAgKioqKioqKioqKioqKioqKioqKioqKiAqLwogICAgICAgICAgICBpZiAoY29sb3JrZXlfYWN0aXZlKSB7CiAgICAgICAgICAgICAgICAvKiBUaGlzIHRleHR1cmUgZm9ybWF0IHdpbGwgbmV2ZXIgYmUgdXNlZC4uIFNvIGRvIG5vdCBjYXJlIGFib3V0IGNvbG9yIGtleWluZwogICAgICAgICAgICAgICAgICAgIHVwIHVudGlsIHRoZSBwb2ludCBpbiB0aW1lIGl0IHdpbGwgYmUgbmVlZGVkIDotKSAqLwogICAgICAgICAgICAgICAgRklYTUUoIiBDb2xvcktleWluZyBub3Qgc3VwcG9ydGVkIGluIHRoZSBSR0IgMzMyIGZvcm1hdCAhXG4iKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1I1RzZCNToKICAgICAgICAgICAgaWYgKGNvbG9ya2V5X2FjdGl2ZSkgewogICAgICAgICAgICAgICAgKmNvbnZlcnQgPSBDT05WRVJUX0NLXzU2NTsKICAgICAgICAgICAgICAgICpmb3JtYXQgPSBHTF9SR0JBOwogICAgICAgICAgICAgICAgKmludGVybmFsID0gR0xfUkdCQTsKICAgICAgICAgICAgICAgICp0eXBlID0gR0xfVU5TSUdORURfU0hPUlRfNV81XzVfMTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1I4RzhCODoKICAgICAgICAgICAgaWYgKGNvbG9ya2V5X2FjdGl2ZSkgewogICAgICAgICAgICAgICAgKmNvbnZlcnQgPSBDT05WRVJUX0NLX1JHQjI0OwogICAgICAgICAgICAgICAgKmZvcm1hdCA9IEdMX1JHQkE7CiAgICAgICAgICAgICAgICAqaW50ZXJuYWwgPSBHTF9SR0JBOwogICAgICAgICAgICAgICAgKnR5cGUgPSBHTF9VTlNJR05FRF9JTlRfOF84XzhfODsKICAgICAgICAgICAgICAgICp0YXJnZXRfYnBwID0gNDsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1g4UjhHOEI4OgogICAgICAgICAgICBpZiAoY29sb3JrZXlfYWN0aXZlKSB7CiAgICAgICAgICAgICAgICAqY29udmVydCA9IENPTlZFUlRfUkdCMzJfODg4OwogICAgICAgICAgICAgICAgKmZvcm1hdCA9IEdMX1JHQkE7CiAgICAgICAgICAgICAgICAqaW50ZXJuYWwgPSBHTF9SR0JBOwogICAgICAgICAgICAgICAgKnR5cGUgPSBHTF9VTlNJR05FRF9JTlRfOF84XzhfODsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKI2lmIDAKICAgICAgICAvKiBOb3Qgc3VyZSBpZiB3ZSBzaG91bGQgZG8gY29sb3Iga2V5aW5nIG9uIEFscGhhLUVuYWJsZWQgc3VyZmFjZXMgKi8KICAgICAgICBjYXNlIFdJTkVEM0RGTVRfQTRSNEc0QjQ6CiAgICAgICAgICAgIGlmIChjb2xvcmtleV9hY3RpdmUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICpjb252ZXJ0ID0gQ09OVkVSVF9DS180NDQ0X0FSR0I7CiAgICAgICAgICAgICAgICAqZm9ybWF0ID0gR0xfUkdCQTsKICAgICAgICAgICAgICAgICppbnRlcm5hbCA9IEdMX1JHQkE7CiAgICAgICAgICAgICAgICAqdHlwZSA9IEdMX1VOU0lHTkVEX1NIT1JUXzRfNF80XzQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgV0lORUQzREZNVF9BMVI1RzVCNToKICAgICAgICAgICAgaWYgKGNvbG9ya2V5X2FjdGl2ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgKmNvbnZlcnQgPSBDT05WRVJUX0NLXzE1NTU7CiAgICAgICAgICAgIH0KCiAgICAgICAgY2FzZSBXSU5FRDNERk1UX0E4UjhHOEI4OgogICAgICAgICAgICBpZiAoY29sb3JrZXlfYWN0aXZlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAqY29udmVydCA9IENPTlZFUlRfQ0tfODg4OF9BUkdCOwogICAgICAgICAgICAgICAgKmZvcm1hdCA9IEdMX1JHQkE7CiAgICAgICAgICAgICAgICAqaW50ZXJuYWwgPSBHTF9SR0JBOwogICAgICAgICAgICAgICAgKnR5cGUgPSBHTF9VTlNJR05FRF9JTlRfOF84XzhfODsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKI2VuZGlmCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgYnJlYWs7CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgZDNkZm10X2NvbnZlcnRfc3VyZmFjZShCWVRFICpzcmMsIEJZVEUgKmRzdCwgdW5zaWduZWQgbG9uZyBsZW4sIENPTlZFUlRfVFlQRVMgY29udmVydCwgSVdpbmVEM0RTdXJmYWNlSW1wbCAqc3VyZikgewogICAgVFJBQ0UoIiglcCktPiglcCksKCVsZCwlZCwlcClcbiIsIHNyYywgZHN0LCBsZW4sIGNvbnZlcnQsIHN1cmYpOwoKICAgIHN3aXRjaCAoY29udmVydCkgewogICAgICAgIGNhc2UgTk9fQ09OVkVSU0lPTjoKICAgICAgICB7CiAgICAgICAgICAgIG1lbWNweShkc3QsIHNyYywgbGVuICogc3VyZi0+Ynl0ZXNQZXJQaXhlbCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBjYXNlIENPTlZFUlRfUEFMRVRURUQ6CiAgICAgICAgY2FzZSBDT05WRVJUX1BBTEVUVEVEX0NLOgogICAgICAgIHsKICAgICAgICAgICAgSVdpbmVEM0RQYWxldHRlSW1wbCogcGFsID0gc3VyZi0+cGFsZXR0ZTsKICAgICAgICAgICAgQllURSB0YWJsZVsyNTZdWzRdOwogICAgICAgICAgICB1bnNpZ25lZCBpbnQgaTsKICAgICAgICAgICAgdW5zaWduZWQgaW50IHg7CgogICAgICAgICAgICBpZiggcGFsID09IE5VTEwpIHsKICAgICAgICAgICAgICAgIC8qIFRPRE86IElmIHdlIGFyZSBhIHN1YmxldmVsLCB0cnkgdG8gZ2V0IHRoZSBwYWxldHRlIGZyb20gbGV2ZWwgMCAqLwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAocGFsID09IE5VTEwpIHsKICAgICAgICAgICAgICAgIC8qIFN0aWxsIG5vIHBhbGV0dGU/IFVzZSB0aGUgZGV2aWNlJ3MgcGFsZXR0ZSAqLwogICAgICAgICAgICAgICAgLyogR2V0IHRoZSBzdXJmYWNlJ3MgcGFsZXR0ZSAqLwogICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IDI1NjsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsICpkZXZpY2UgPSBzdXJmLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOwoKICAgICAgICAgICAgICAgICAgICB0YWJsZVtpXVswXSA9IGRldmljZS0+cGFsZXR0ZXNbZGV2aWNlLT5jdXJyZW50UGFsZXR0ZV1baV0ucGVSZWQ7CiAgICAgICAgICAgICAgICAgICAgdGFibGVbaV1bMV0gPSBkZXZpY2UtPnBhbGV0dGVzW2RldmljZS0+Y3VycmVudFBhbGV0dGVdW2ldLnBlR3JlZW47CiAgICAgICAgICAgICAgICAgICAgdGFibGVbaV1bMl0gPSBkZXZpY2UtPnBhbGV0dGVzW2RldmljZS0+Y3VycmVudFBhbGV0dGVdW2ldLnBlQmx1ZTsKICAgICAgICAgICAgICAgICAgICBpZiAoKGNvbnZlcnQgPT0gQ09OVkVSVF9QQUxFVFRFRF9DSykgJiYKICAgICAgICAgICAgICAgICAgICAgICAgKGkgPj0gc3VyZi0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VMb3dWYWx1ZSkgJiYKICAgICAgICAgICAgICAgICAgICAgICAgKGkgPD0gc3VyZi0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VIaWdoVmFsdWUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIFdlIHNob3VsZCBtYXliZSBoZXJlIHB1dCBhIG1vcmUgJ25ldXRyYWwnIGNvbG9yIHRoYW4gdGhlIHN0YW5kYXJkIGJyaWdodCBwdXJwbGUKICAgICAgICAgICAgICAgICAgICAgICAgICBvbmUgb2Z0ZW4gdXNlZCBieSBhcHBsaWNhdGlvbiB0byBwcmV2ZW50IHRoZSBuaWNlIHB1cnBsZSBib3JkZXJzIHdoZW4gYmktbGluZWFyCiAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyaW5nIGlzIG9uICovCiAgICAgICAgICAgICAgICAgICAgICAgIHRhYmxlW2ldWzNdID0gMHgwMDsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICB0YWJsZVtpXVszXSA9IDB4RkY7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgVFJBQ0UoIlVzaW5nIHN1cmZhY2UgcGFsZXR0ZSAlcFxuIiwgcGFsKTsKICAgICAgICAgICAgICAgIC8qIEdldCB0aGUgc3VyZmFjZSdzIHBhbGV0dGUgKi8KICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCAyNTY7IGkrKykgewogICAgICAgICAgICAgICAgICAgIHRhYmxlW2ldWzBdID0gcGFsLT5wYWxlbnRzW2ldLnBlUmVkOwogICAgICAgICAgICAgICAgICAgIHRhYmxlW2ldWzFdID0gcGFsLT5wYWxlbnRzW2ldLnBlR3JlZW47CiAgICAgICAgICAgICAgICAgICAgdGFibGVbaV1bMl0gPSBwYWwtPnBhbGVudHNbaV0ucGVCbHVlOwogICAgICAgICAgICAgICAgICAgIGlmICgoY29udmVydCA9PSBDT05WRVJUX1BBTEVUVEVEX0NLKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAoaSA+PSBzdXJmLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUxvd1ZhbHVlKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAoaSA8PSBzdXJmLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUhpZ2hWYWx1ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogV2Ugc2hvdWxkIG1heWJlIGhlcmUgcHV0IGEgbW9yZSAnbmV1dHJhbCcgY29sb3IgdGhhbiB0aGUgc3RhbmRhcmQgYnJpZ2h0IHB1cnBsZQogICAgICAgICAgICAgICAgICAgICAgICAgIG9uZSBvZnRlbiB1c2VkIGJ5IGFwcGxpY2F0aW9uIHRvIHByZXZlbnQgdGhlIG5pY2UgcHVycGxlIGJvcmRlcnMgd2hlbiBiaS1saW5lYXIKICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXJpbmcgaXMgb24gKi8KICAgICAgICAgICAgICAgICAgICAgICAgdGFibGVbaV1bM10gPSAweDAwOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRhYmxlW2ldWzNdID0gMHhGRjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAoeCA9IDA7IHggPCBsZW47IHgrKykgewogICAgICAgICAgICAgICAgQllURSBjb2xvciA9ICpzcmMrKzsKICAgICAgICAgICAgICAgICpkc3QrKyA9IHRhYmxlW2NvbG9yXVswXTsKICAgICAgICAgICAgICAgICpkc3QrKyA9IHRhYmxlW2NvbG9yXVsxXTsKICAgICAgICAgICAgICAgICpkc3QrKyA9IHRhYmxlW2NvbG9yXVsyXTsKICAgICAgICAgICAgICAgICpkc3QrKyA9IHRhYmxlW2NvbG9yXVszXTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBDT05WRVJUX0NLXzU2NToKICAgICAgICB7CiAgICAgICAgICAgIC8qIENvbnZlcnRpbmcgdGhlIDU2NSBmb3JtYXQgaW4gNTU1MSBwYWNrZWQgdG8gZW11bGF0ZSBjb2xvci1rZXlpbmcuCgogICAgICAgICAgICAgIE5vdGUgOiBpbiBhbGwgdGhlc2UgY29udmVyc2lvbiwgaXQgd291bGQgYmUgYmVzdCB0byBhdmVyYWdlIHRoZSBhdmVyYWdpbmcKICAgICAgICAgICAgICAgICAgICAgIHBpeGVscyB0byBnZXQgdGhlIGNvbG9yIG9mIHRoZSBwaXhlbCB0aGF0IHdpbGwgYmUgY29sb3Ita2V5ZWQgdG8KICAgICAgICAgICAgICAgICAgICAgIHByZXZlbnQgJ2NvbG9yIGJsZWVkaW5nJy4gVGhpcyB3aWxsIGJlIGRvbmUgbGF0ZXIgb24gaWYgZXZlciBpdCBpcwogICAgICAgICAgICAgICAgICAgICAgdG9vIHZpc2libGUuCgogICAgICAgICAgICAgIE5vdGUyOiB3aGVuIHVzaW5nIGNvbG9yLWtleWluZyArIGFscGhhLCBhcmUgdGhlIGFscGhhIGJpdHMgcGFydCBvZiB0aGUKICAgICAgICAgICAgICAgICAgICAgIGNvbG9yLXNwYWNlIG9yIG5vdCA/CiAgICAgICAgICAgICovCiAgICAgICAgICAgIHVuc2lnbmVkIGludCB4OwogICAgICAgICAgICBXT1JEICpTb3VyY2UgPSAoV09SRCAqKSBzcmM7CiAgICAgICAgICAgIFdPUkQgKkRlc3QgPSAoV09SRCAqKSBkc3Q7CgogICAgICAgICAgICBUUkFDRSgiQ29sb3Iga2V5ZWQgNTY1XG4iKTsKCiAgICAgICAgICAgIGZvciAoeCA9IDA7IHggPCBsZW47IHgrKyApIHsKICAgICAgICAgICAgICAgIFdPUkQgY29sb3IgPSAqU291cmNlKys7CiAgICAgICAgICAgICAgICAqRGVzdCA9ICgoY29sb3IgJiAweEZGQzApIHwgKChjb2xvciAmIDB4MUYpIDw8IDEpKTsKICAgICAgICAgICAgICAgIGlmICgoY29sb3IgPCBzdXJmLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUxvd1ZhbHVlKSB8fAogICAgICAgICAgICAgICAgICAgIChjb2xvciA+IHN1cmYtPlNyY0JsdENLZXkuZHdDb2xvclNwYWNlSGlnaFZhbHVlKSkgewogICAgICAgICAgICAgICAgICAgICpEZXN0IHw9IDB4MDAwMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIERlc3QrKzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBDT05WRVJUX0NLXzE1NTU6CiAgICAgICAgewogICAgICAgICAgICB1bnNpZ25lZCBpbnQgeDsKICAgICAgICAgICAgV09SRCAqU291cmNlID0gKFdPUkQgKikgc3JjOwogICAgICAgICAgICBXT1JEICpEZXN0ID0gKFdPUkQgKikgZHN0OwoKICAgICAgICAgICAgZm9yICh4ID0gMDsgeCA8IGxlbiAqIHNpemVvZihXT1JEKTsgeCs9c2l6ZW9mKFdPUkQpKSB7CiAgICAgICAgICAgICAgICBXT1JEIGNvbG9yID0gKlNvdXJjZSsrOwogICAgICAgICAgICAgICAgKkRlc3QgPSAoY29sb3IgJiAweDdGRkYpOwogICAgICAgICAgICAgICAgaWYgKChjb2xvciA8IHN1cmYtPlNyY0JsdENLZXkuZHdDb2xvclNwYWNlTG93VmFsdWUpIHx8CiAgICAgICAgICAgICAgICAgICAgKGNvbG9yID4gc3VyZi0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VIaWdoVmFsdWUpKQogICAgICAgICAgICAgICAgICAgICpEZXN0IHw9IChjb2xvciAmIDB4ODAwMCk7CiAgICAgICAgICAgICAgICBEZXN0Kys7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgQ09OVkVSVF9DS180NDQ0X0FSR0I6CiAgICAgICAgewogICAgICAgICAgICAvKiBNb3ZlIHRoZSBmb3VyIEFscGhhIGJpdHMuLi4gKi8KICAgICAgICAgICAgdW5zaWduZWQgaW50IHg7CiAgICAgICAgICAgIFdPUkQgKlNvdXJjZSA9IChXT1JEICopIHNyYzsKICAgICAgICAgICAgV09SRCAqRGVzdCA9IChXT1JEICopIGRzdDsKCiAgICAgICAgICAgIGZvciAoeCA9IDA7IHggPCBsZW47IHgrKykgewogICAgICAgICAgICAgICAgV09SRCBjb2xvciA9ICpTb3VyY2UrKzsKICAgICAgICAgICAgICAgICpkc3QgPSAoY29sb3IgJiAweDBGRkYpIDw8IDQ7CiAgICAgICAgICAgICAgICBpZiAoKGNvbG9yIDwgc3VyZi0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VMb3dWYWx1ZSkgfHwKICAgICAgICAgICAgICAgICAgICAoY29sb3IgPiBzdXJmLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUhpZ2hWYWx1ZSkpCiAgICAgICAgICAgICAgICAgICAgKkRlc3QgfD0gKGNvbG9yICYgMHhGMDAwKSA+PiAxMjsKICAgICAgICAgICAgICAgIERlc3QrKzsKICAgICAgICAgICAgfQogICAgICAgIH0gYnJlYWs7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIEVSUigiVW5zdXBwb3J0ZWQgY29udmVyc2F0aW9uIHR5cGUgJWRcbiIsIGNvbnZlcnQpOwogICAgfQoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgaW4gY2FzZSBvZiA4Yml0IHBhbGV0dGVkIHRleHR1cmVzIHRvIHVwbG9hZCB0aGUgcGFsZXR0ZS4KICAgRm9yIG5vdyBpdCBvbmx5IHN1cHBvcnRzIEdMX0VYVF9wYWxldHRlZF90ZXh0dXJlIGV4dGVuc2lvbiBidXQgc3VwcG9ydCBmb3Igb3RoZXIKICAgZXh0ZW5zaW9ucyBsaWtlIEFSQl9mcmFnbWVudF9wcm9ncmFtIGFuZCBBVElfZnJhZ21lbnRfc2hhZGVycyB3aWxsIGJlIGFkZGVkIGFzd2VsbC4KKi8Kdm9pZCBkM2RmbXRfcDhfdXBsb2FkX3BhbGV0dGUoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgQ09OVkVSVF9UWVBFUyBjb252ZXJ0KSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEUGFsZXR0ZUltcGwqIHBhbCA9IFRoaXMtPnBhbGV0dGU7CiAgICBCWVRFIHRhYmxlWzI1Nl1bNF07CiAgICBpbnQgaTsKCiAgICBpZiAocGFsID09IE5VTEwpIHsKICAgICAgICAvKiBTdGlsbCBubyBwYWxldHRlPyBVc2UgdGhlIGRldmljZSdzIHBhbGV0dGUgKi8KICAgICAgICAvKiBHZXQgdGhlIHN1cmZhY2UncyBwYWxldHRlICovCiAgICAgICAgZm9yIChpID0gMDsgaSA8IDI1NjsgaSsrKSB7CiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlSW1wbCAqZGV2aWNlID0gVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZTsKCiAgICAgICAgICAgIHRhYmxlW2ldWzBdID0gZGV2aWNlLT5wYWxldHRlc1tkZXZpY2UtPmN1cnJlbnRQYWxldHRlXVtpXS5wZVJlZDsKICAgICAgICAgICAgdGFibGVbaV1bMV0gPSBkZXZpY2UtPnBhbGV0dGVzW2RldmljZS0+Y3VycmVudFBhbGV0dGVdW2ldLnBlR3JlZW47CiAgICAgICAgICAgIHRhYmxlW2ldWzJdID0gZGV2aWNlLT5wYWxldHRlc1tkZXZpY2UtPmN1cnJlbnRQYWxldHRlXVtpXS5wZUJsdWU7CiAgICAgICAgICAgIGlmICgoY29udmVydCA9PSBDT05WRVJUX1BBTEVUVEVEX0NLKSAmJgogICAgICAgICAgICAgICAgKGkgPj0gVGhpcy0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VMb3dWYWx1ZSkgJiYKICAgICAgICAgICAgICAgIChpIDw9IFRoaXMtPlNyY0JsdENLZXkuZHdDb2xvclNwYWNlSGlnaFZhbHVlKSkgewogICAgICAgICAgICAgICAgLyogV2Ugc2hvdWxkIG1heWJlIGhlcmUgcHV0IGEgbW9yZSAnbmV1dHJhbCcgY29sb3IgdGhhbiB0aGUgc3RhbmRhcmQgYnJpZ2h0IHB1cnBsZQogICAgICAgICAgICAgICAgICAgb25lIG9mdGVuIHVzZWQgYnkgYXBwbGljYXRpb24gdG8gcHJldmVudCB0aGUgbmljZSBwdXJwbGUgYm9yZGVycyB3aGVuIGJpLWxpbmVhcgogICAgICAgICAgICAgICAgICAgZmlsdGVyaW5nIGlzIG9uICovCiAgICAgICAgICAgICAgICB0YWJsZVtpXVszXSA9IDB4MDA7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0YWJsZVtpXVszXSA9IDB4RkY7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIFRSQUNFKCJVc2luZyBzdXJmYWNlIHBhbGV0dGUgJXBcbiIsIHBhbCk7CiAgICAgICAgLyogR2V0IHRoZSBzdXJmYWNlJ3MgcGFsZXR0ZSAqLwogICAgICAgIGZvciAoaSA9IDA7IGkgPCAyNTY7IGkrKykgewogICAgICAgICAgICB0YWJsZVtpXVswXSA9IHBhbC0+cGFsZW50c1tpXS5wZVJlZDsKICAgICAgICAgICAgdGFibGVbaV1bMV0gPSBwYWwtPnBhbGVudHNbaV0ucGVHcmVlbjsKICAgICAgICAgICAgdGFibGVbaV1bMl0gPSBwYWwtPnBhbGVudHNbaV0ucGVCbHVlOwogICAgICAgICAgICBpZiAoKGNvbnZlcnQgPT0gQ09OVkVSVF9QQUxFVFRFRF9DSykgJiYKICAgICAgICAgICAgICAgIChpID49IFRoaXMtPlNyY0JsdENLZXkuZHdDb2xvclNwYWNlTG93VmFsdWUpICYmCiAgICAgICAgICAgICAgICAoaSA8PSBUaGlzLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUhpZ2hWYWx1ZSkpIHsKICAgICAgICAgICAgICAgIC8qIFdlIHNob3VsZCBtYXliZSBoZXJlIHB1dCBhIG1vcmUgJ25ldXRyYWwnIGNvbG9yIHRoYW4gdGhlIHN0YW5kYXJkIGJyaWdodCBwdXJwbGUKICAgICAgICAgICAgICAgICAgIG9uZSBvZnRlbiB1c2VkIGJ5IGFwcGxpY2F0aW9uIHRvIHByZXZlbnQgdGhlIG5pY2UgcHVycGxlIGJvcmRlcnMgd2hlbiBiaS1saW5lYXIKICAgICAgICAgICAgICAgICAgIGZpbHRlcmluZyBpcyBvbiAqLwogICAgICAgICAgICAgICAgdGFibGVbaV1bM10gPSAweDAwOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdGFibGVbaV1bM10gPSAweEZGOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgR0xfRVhUQ0FMTChnbENvbG9yVGFibGVFWFQoR0xfVEVYVFVSRV8yRCxHTF9SR0JBLDI1NixHTF9SR0JBLEdMX1VOU0lHTkVEX0JZVEUsIHRhYmxlKSk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0xvYWRUZXh0dXJlKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgR0xlbnVtIGZvcm1hdCwgaW50ZXJuYWwsIHR5cGU7CiAgICBDT05WRVJUX1RZUEVTIGNvbnZlcnQ7CiAgICBpbnQgYnBwOwogICAgaW50IHBpdGNoOwogICAgQllURSAqbWVtOwoKICAgIGlmIChUaGlzLT5GbGFncyAmIFNGTEFHX0lOVEVYVFVSRSkgewogICAgICAgIFRSQUNFKCJTdXJmYWNlIGFscmVhZHkgaW4gdGV4dHVyZVxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CiAgICBpZiAoVGhpcy0+RmxhZ3MgJiBTRkxBR19ESVJUWSkgewogICAgICAgIFRSQUNFKCJSZWxvYWRpbmcgYmVjYXVzZSBzdXJmYWNlIGlzIGRpcnR5XG4iKTsKICAgIH0gZWxzZSBpZigvKiBSZWxvYWQ6IGdsIHRleHR1cmUgaGFzIGNrLCBub3cgbm8gY2tleSBpcyBzZXQgT1IgKi8KICAgICAgICAgICAgICAoKFRoaXMtPkZsYWdzICYgU0ZMQUdfR0xDS0VZKSAmJiAoIShUaGlzLT5DS2V5RmxhZ3MgJiBERFNEX0NLU1JDQkxUKSkpIHx8CiAgICAgICAgICAgICAgLyogUmVsb2FkOiB2aWNlIHZlcnNhICBPUiAqLwogICAgICAgICAgICAgICgoIShUaGlzLT5GbGFncyAmIFNGTEFHX0dMQ0tFWSkpICYmIChUaGlzLT5DS2V5RmxhZ3MgJiBERFNEX0NLU1JDQkxUKSkgfHwKICAgICAgICAgICAgICAvKiBBbHNvIHJlbG9hZDogQ29sb3Iga2V5IGlzIGFjdGl2ZSBBTkQgdGhlIGNvbG9yIGtleSBoYXMgY2hhbmdlZCAqLwogICAgICAgICAgICAgICgoVGhpcy0+Q0tleUZsYWdzICYgRERTRF9DS1NSQ0JMVCkgJiYgKAogICAgICAgICAgICAgICAgKFRoaXMtPmdsQ0tleS5kd0NvbG9yU3BhY2VMb3dWYWx1ZSAhPSBUaGlzLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUxvd1ZhbHVlKSB8fAogICAgICAgICAgICAgICAgKFRoaXMtPmdsQ0tleS5kd0NvbG9yU3BhY2VIaWdoVmFsdWUgIT0gVGhpcy0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VIaWdoVmFsdWUpKSkpIHsKICAgICAgICBUUkFDRSgiUmVsb2FkaW5nIGJlY2F1c2Ugb2YgY29sb3Iga2V5aW5nXG4iKTsKICAgIH0gZWxzZSB7CiAgICAgICAgVFJBQ0UoInN1cmZhY2UgaXNuJ3QgZGlydHlcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19ESVJUWTsKCiAgICAvKiBSZXNvdXJjZXMgYXJlIHBsYWNlZCBpbiBzeXN0ZW0gUkFNIGFuZCBkbyBub3QgbmVlZCB0byBiZSByZWNyZWF0ZWQgd2hlbiBhIGRldmljZSBpcyBsb3N0LgogICAgKiAgVGhlc2UgcmVzb3VyY2VzIGFyZSBub3QgYm91bmQgYnkgZGV2aWNlIHNpemUgb3IgZm9ybWF0IHJlc3RyaWN0aW9ucy4gQmVjYXVzZSBvZiB0aGlzLAogICAgKiAgdGhlc2UgcmVzb3VyY2VzIGNhbm5vdCBiZSBhY2Nlc3NlZCBieSB0aGUgRGlyZWN0M0QgZGV2aWNlIG5vciBzZXQgYXMgdGV4dHVyZXMgb3IgcmVuZGVyIHRhcmdldHMuCiAgICAqICBIb3dldmVyLCB0aGVzZSByZXNvdXJjZXMgY2FuIGFsd2F5cyBiZSBjcmVhdGVkLCBsb2NrZWQsIGFuZCBjb3BpZWQuCiAgICAqLwogICAgaWYgKFRoaXMtPnJlc291cmNlLnBvb2wgPT0gV0lORUQzRFBPT0xfU0NSQVRDSCAmJiAhKFRoaXMtPkZsYWdzICYgU0ZMQUdfRk9SQ0VMT0FEKSApCiAgICB7CiAgICAgICAgRklYTUUoIiglcCkgT3BlcmF0aW9uIG5vdCBzdXBwb3J0ZWQgZm9yIHNjcmF0Y2ggdGV4dHVyZXNcbiIsVGhpcyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgaWYgKFRoaXMtPkZsYWdzICYgU0ZMQUdfSU5QQlVGRkVSKSB7CiAgICAgICAgaWYgKFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwgIT0gMCkKICAgICAgICAgICAgRklYTUUoIlN1cmZhY2UgaW4gdGV4dHVyZSBpcyBvbmx5IHN1cHBvcnRlZCBmb3IgbGV2ZWwgMFxuIik7CiAgICAgICAgZWxzZSBpZiAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfUDggfHwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfQThQOCB8fAogICAgICAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDEgfHwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMiB8fAogICAgICAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDMgfHwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNCB8fAogICAgICAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDUpCiAgICAgICAgICAgIEZJWE1FKCJGb3JtYXQgJWQgbm90IHN1cHBvcnRlZFxuIiwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0KTsKICAgICAgICBlbHNlIHsKICAgICAgICAgICAgR0xpbnQgcHJldlJlYWQ7CgogICAgICAgICAgICBFTlRFUl9HTCgpOwoKICAgICAgICAgICAgZ2xHZXRJbnRlZ2VydihHTF9SRUFEX0JVRkZFUiwgJnByZXZSZWFkKTsKICAgICAgICAgICAgdmNoZWNrR0xjYWxsKCJnbEdldEludGVnZXJ2Iik7CiAgICAgICAgICAgIGdsUmVhZEJ1ZmZlcihHTF9CQUNLKTsKICAgICAgICAgICAgdmNoZWNrR0xjYWxsKCJnbFJlYWRCdWZmZXIiKTsKCiAgICAgICAgICAgIGdsQ29weVRleEltYWdlMkQoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0SW50ZXJuYWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPmN1cnJlbnREZXNjLldpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwKTsKCiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbENvcHlUZXhJbWFnZTJEIik7CiAgICAgICAgICAgIGdsUmVhZEJ1ZmZlcihwcmV2UmVhZCk7CiAgICAgICAgICAgIHZjaGVja0dMY2FsbCgiZ2xSZWFkQnVmZmVyIik7CgogICAgICAgICAgICBMRUFWRV9HTCgpOwoKICAgICAgICAgICAgVFJBQ0UoIlVwZGF0aW5nIHRhcmdldCAlZFxuIiwgVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQpOwogICAgICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19JTlRFWFRVUkU7CiAgICAgICAgfQogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIGlmKFRoaXMtPkNLZXlGbGFncyAmIEREU0RfQ0tTUkNCTFQpIHsKICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19HTENLRVk7CiAgICAgICAgVGhpcy0+Z2xDS2V5ID0gVGhpcy0+U3JjQmx0Q0tleTsKICAgIH0KICAgIGVsc2UgVGhpcy0+RmxhZ3MgJj0gflNGTEFHX0dMQ0tFWTsKCiAgICBkM2RmbXRfZ2V0X2NvbnYoVGhpcywgVFJVRSAvKiBXZSBuZWVkIGNvbG9yIGtleWluZyAqLywgVFJVRSAvKiBXZSB3aWxsIHVzZSB0ZXh0dXJlcyAqLywgJmZvcm1hdCwgJmludGVybmFsLCAmdHlwZSwgJmNvbnZlcnQsICZicHApOwoKICAgIC8qIFRoZSBwaXRjaCBpcyBpbiAnbGVuZ3RoJyBub3QgaW4gYnl0ZXMgKi8KICAgIGlmIChOUDJfUkVQQUNLID09IHdpbmVkM2Rfc2V0dGluZ3Mubm9ucG93ZXIyX21vZGUgfHwgVGhpcy0+cmVzb3VyY2UudXNhZ2UgJiBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUKQogICAgICAgIHBpdGNoID0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICBlbHNlCiAgICAgICAgcGl0Y2ggPSBUaGlzLT5wb3cyV2lkdGg7CgogICAgaWYoKGNvbnZlcnQgIT0gTk9fQ09OVkVSU0lPTikgJiYgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KSB7CiAgICAgICAgaW50IGhlaWdodCA9IFRoaXMtPmdsUmVjdC5ib3R0b20gLSBUaGlzLT5nbFJlY3QudG9wOwoKICAgICAgICBtZW0gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcGl0Y2ggKiBoZWlnaHQgKiBicHApOwogICAgICAgIGlmKCFtZW0pIHsKICAgICAgICAgICAgRVJSKCJPdXQgb2YgbWVtb3J5ICVkLCAlZCFcbiIsIHBpdGNoLCBoZWlnaHQpOwogICAgICAgICAgICByZXR1cm4gV0lORUQzREVSUl9PVVRPRlZJREVPTUVNT1JZOwogICAgICAgIH0KICAgICAgICBkM2RmbXRfY29udmVydF9zdXJmYWNlKFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSwgbWVtLCBwaXRjaCAqIGhlaWdodCwgY29udmVydCwgVGhpcyk7CgogICAgICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX0NPTlZFUlRFRDsKICAgIH0gZWxzZSBpZiAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfUDggJiYgR0xfU1VQUE9SVChFWFRfUEFMRVRURURfVEVYVFVSRSkpIHsKICAgICAgICBkM2RmbXRfcDhfdXBsb2FkX3BhbGV0dGUoaWZhY2UsIGNvbnZlcnQpOwogICAgICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19DT05WRVJURUQ7CiAgICAgICAgbWVtID0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5OwogICAgfSBlbHNlIHsKICAgICAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfQ09OVkVSVEVEOwogICAgICAgIG1lbSA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeTsKICAgIH0KCiAgICAvKiBNYWtlIHN1cmUgdGhlIGNvcnJlY3QgcGl0Y2ggaXMgdXNlZCAqLwogICAgZ2xQaXhlbFN0b3JlaShHTF9VTlBBQ0tfUk9XX0xFTkdUSCwgcGl0Y2gpOwoKICAgIGlmIChOUDJfUkVQQUNLID09IHdpbmVkM2Rfc2V0dGluZ3Mubm9ucG93ZXIyX21vZGUgJiYgKFRoaXMtPkZsYWdzICYgU0ZMQUdfTk9OUE9XMikgJiYgIShUaGlzLT5GbGFncyAmIFNGTEFHX09WRVJTSVpFKSkgewogICAgICAgIFRSQUNFKCJub24gcG93ZXIgb2YgdHdvIHN1cHBvcnRcbiIpOwogICAgICAgIHN1cmZhY2VfYWxsb2NhdGVfc3VyZmFjZShUaGlzLCBpbnRlcm5hbCwgVGhpcy0+cG93MldpZHRoLCBUaGlzLT5wb3cySGVpZ2h0LCBmb3JtYXQsIHR5cGUpOwogICAgICAgIGlmIChtZW0pIHsKICAgICAgICAgICAgc3VyZmFjZV91cGxvYWRfZGF0YShUaGlzLCBUaGlzLT5wb3cyV2lkdGgsIFRoaXMtPnBvdzJIZWlnaHQsIGZvcm1hdCwgdHlwZSwgbWVtKTsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIHN1cmZhY2VfYWxsb2NhdGVfc3VyZmFjZShUaGlzLCBpbnRlcm5hbCwgVGhpcy0+Z2xSZWN0LnJpZ2h0IC0gVGhpcy0+Z2xSZWN0LmxlZnQsIFRoaXMtPmdsUmVjdC5ib3R0b20gLSBUaGlzLT5nbFJlY3QudG9wLCBmb3JtYXQsIHR5cGUpOwogICAgICAgIGlmIChtZW0pIHsKICAgICAgICAgICAgc3VyZmFjZV91cGxvYWRfZGF0YShUaGlzLCBUaGlzLT5nbFJlY3QucmlnaHQgLSBUaGlzLT5nbFJlY3QubGVmdCwgVGhpcy0+Z2xSZWN0LmJvdHRvbSAtIFRoaXMtPmdsUmVjdC50b3AsIGZvcm1hdCwgdHlwZSwgbWVtKTsKICAgICAgICB9CiAgICB9CgogICAgLyogUmVzdG9yZSB0aGUgZGVmYXVsdCBwaXRjaCAqLwogICAgZ2xQaXhlbFN0b3JlaShHTF9VTlBBQ0tfUk9XX0xFTkdUSCwgMCk7CgogICAgaWYgKG1lbSAhPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpCiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbWVtKTsKCiNpZiAwCiAgICB7CiAgICAgICAgc3RhdGljIHVuc2lnbmVkIGludCBnZW4gPSAwOwogICAgICAgIGNoYXIgYnVmZmVyWzQwOTZdOwogICAgICAgICsrZ2VuOwogICAgICAgIGlmICgoZ2VuICUgMTApID09IDApIHsKICAgICAgICAgICAgc25wcmludGYoYnVmZmVyLCBzaXplb2YoYnVmZmVyKSwgIi90bXAvc3VyZmFjZSVwX3R5cGUldV9sZXZlbCV1XyV1LnBwbSIsIFRoaXMsIFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLCBnZW4pOwogICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1NhdmVTbmFwc2hvdChpZmFjZSwgYnVmZmVyKTsKICAgICAgICB9CiAgICAgICAgLyoKICAgICAgICAgKiBkZWJ1Z2dpbmcgY3Jhc2ggY29kZQogICAgICAgICBpZiAoZ2VuID09IDI1MCkgewogICAgICAgICB2b2lkKiogdGVzdCA9IE5VTEw7CiAgICAgICAgICp0ZXN0ID0gMDsKICAgICAgICAgfQogICAgICAgICAqLwogICAgfQojZW5kaWYKCiAgICBpZiAoIShUaGlzLT5GbGFncyAmIFNGTEFHX0RPTk9URlJFRSkpIHsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpOwogICAgICAgIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IE5VTEw7CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8c3RkaW8uaD4KSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9TYXZlU25hcHNob3QoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgY29uc3QgY2hhciogZmlsZW5hbWUpIHsKICAgIEZJTEUqIGYgPSBOVUxMOwogICAgVUlOVCBpLCB5OwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBjaGFyICphbGxvY2F0ZWRNZW1vcnk7CiAgICBjaGFyICp0ZXh0dXJlUm93OwogICAgSVdpbmVEM0RTd2FwQ2hhaW4gKnN3YXBDaGFpbiA9IE5VTEw7CiAgICBpbnQgd2lkdGgsIGhlaWdodDsKICAgIEdMdWludCB0bXBUZXh0dXJlID0gMDsKICAgIERXT1JEIGNvbG9yOwogICAgLypGSVhNRToKICAgIFRleHR1cmVzIG15IG5vdCBiZSBzdG9yZWQgaW4gLT5hbGxvY2F0ZWRnTWVtb3J5IGFuZCBhIEdsVGV4dHVyZQogICAgc28gd2Ugc2hvdWxkIGxvY2sgdGhlIHN1cmZhY2UgYmVmb3JlIHNhdmluZyBhIHNuYXBzaG90LCBvciBhdCBsZWFzdCBjaGVjayB0aGF0CiAgICAqLwogICAgLyogVE9ETzogQ29tcHJlc3NlZCB0ZXh0dXJlIGltYWdlcyBjYW4gYmUgb2J0YWluZWQgZnJvbSB0aGUgR0wgaW4gdW5jb21wcmVzc2VkIGZvcm0KICAgIGJ5IGNhbGxpbmcgR2V0VGV4SW1hZ2UgYW5kIGluIGNvbXByZXNzZWQgZm9ybSBieSBjYWxsaW5nCiAgICBHZXRDb21wcmVzc2VkVGV4SW1hZ2VBUkIuICBRdWVyaWVkIGNvbXByZXNzZWQgaW1hZ2VzIGNhbiBiZSBzYXZlZCBhbmQKICAgIGxhdGVyIHJldXNlZCBieSBjYWxsaW5nIENvbXByZXNzZWRUZXhJbWFnZVsxMjNdREFSQi4gIFByZS1jb21wcmVzc2VkCiAgICB0ZXh0dXJlIGltYWdlcyBkbyBub3QgbmVlZCB0byBiZSBwcm9jZXNzZWQgYnkgdGhlIEdMIGFuZCBzaG91bGQKICAgIHNpZ25pZmljYW50bHkgaW1wcm92ZSB0ZXh0dXJlIGxvYWRpbmcgcGVyZm9ybWFuY2UgcmVsYXRpdmUgdG8gdW5jb21wcmVzc2VkCiAgICBpbWFnZXMuICovCgovKiBTZXR1cCB0aGUgd2lkdGggYW5kIGhlaWdodCB0byBiZSB0aGUgaW50ZXJuYWwgdGV4dHVyZSB3aWR0aCBhbmQgaGVpZ2h0LiAqLwogICAgd2lkdGggID0gVGhpcy0+cG93MldpZHRoOwogICAgaGVpZ2h0ID0gVGhpcy0+cG93MkhlaWdodDsKLyogY2hlY2sgdG8gc2VlIGlmIHdlcmUgYSAndmlydHVhbCcgdGV4dHVyZSBlLmcuIHdlcmUgbm90IGEgcGJ1ZmZlciBvZiB0ZXh0dXJlIHdlcmUgYSBiYWNrIGJ1ZmZlciovCiAgICBJV2luZUQzRFN1cmZhY2VfR2V0Q29udGFpbmVyKGlmYWNlLCAmSUlEX0lXaW5lRDNEU3dhcENoYWluLCAodm9pZCAqKikmc3dhcENoYWluKTsKCiAgICBpZiAoc3dhcENoYWluIHx8IChUaGlzLT5GbGFncyAmIFNGTEFHX0lOUEJVRkZFUikpIHsgLyogaWYgd2VyZSBub3QgYSByZWFsIHRleHR1cmUgdGhlbiByZWFkIHRoZSBiYWNrIGJ1ZmZlciBpbnRvIGEgcmVhbCB0ZXh0dXJlKi8KLyogd2UgZG9uJ3Qgd2FudCB0byBpbnRlcmZlcmUgd2l0aCB0aGUgYmFjayBidWZmZXIgc28gcmVhZCB0aGUgZGF0YSBpbnRvIGEgdGVtcG9yYXJ5IHRleHR1cmUgYW5kIHRoZW4gc2F2ZSB0aGUgZGF0YSBvdXQgb2YgdGhlIHRlbXBvcmFyeSB0ZXh0dXJlICovCiAgICAgICAgR0xpbnQgcHJldlJlYWQ7CiAgICAgICAgRU5URVJfR0woKTsKICAgICAgICBGSVhNRSgiKCVwKSBUaGlzIHN1cmZhY2UgbmVlZHMgdG8gYmUgbG9ja2VkIGJlZm9yZSBhIHNuYXBzaG90IGNhbiBiZSB0YWtlblxuIiwgVGhpcyk7CiAgICAgICAgZ2xFbmFibGUoR0xfVEVYVFVSRV8yRCk7CgogICAgICAgIGdsR2VuVGV4dHVyZXMoMSwgJnRtcFRleHR1cmUpOwogICAgICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgdG1wVGV4dHVyZSk7CgogICAgICAgIGdsVGV4SW1hZ2UyRChHTF9URVhUVVJFXzJELAogICAgICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgICAgICBHTF9SR0JBLAogICAgICAgICAgICAgICAgICAgICAgICB3aWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0LAogICAgICAgICAgICAgICAgICAgICAgICAwLypib3JkZXIqLywKICAgICAgICAgICAgICAgICAgICAgICAgR0xfUkdCQSwKICAgICAgICAgICAgICAgICAgICAgICAgR0xfVU5TSUdORURfSU5UXzhfOF84XzhfUkVWLAogICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKCiAgICAgICAgZ2xHZXRJbnRlZ2VydihHTF9SRUFEX0JVRkZFUiwgJnByZXZSZWFkKTsKICAgICAgICB2Y2hlY2tHTGNhbGwoImdsR2V0SW50ZWdlcnYiKTsKICAgICAgICBnbFJlYWRCdWZmZXIoR0xfQkFDSyk7CiAgICAgICAgdmNoZWNrR0xjYWxsKCJnbFJlYWRCdWZmZXIiKTsKICAgICAgICBnbENvcHlUZXhJbWFnZTJEKEdMX1RFWFRVUkVfMkQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgR0xfUkdCQSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAwKTsKCiAgICAgICAgY2hlY2tHTGNhbGwoImdsQ29weVRleEltYWdlMkQiKTsKICAgICAgICBnbFJlYWRCdWZmZXIocHJldlJlYWQpOwogICAgICAgIExFQVZFX0dMKCk7CgogICAgfSBlbHNlIHsgLyogYmluZCB0aGUgcmVhbCB0ZXh0dXJlICovCiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1ByZUxvYWQoaWZhY2UpOwogICAgfQogICAgYWxsb2NhdGVkTWVtb3J5ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHdpZHRoICAqIGhlaWdodCAqIDQpOwogICAgRU5URVJfR0woKTsKICAgIEZJWE1FKCJTYXZpbmcgdGV4dHVyZSBsZXZlbCAlZCB3aWR0aCAlZCBoZWlnaHQgJWRcbiIsIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsIHdpZHRoLCBoZWlnaHQpOwogICAgZ2xHZXRUZXhJbWFnZShHTF9URVhUVVJFXzJELAogICAgICAgICAgICAgICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCwKICAgICAgICAgICAgICAgIEdMX1JHQkEsCiAgICAgICAgICAgICAgICBHTF9VTlNJR05FRF9JTlRfOF84XzhfOF9SRVYsCiAgICAgICAgICAgICAgICBhbGxvY2F0ZWRNZW1vcnkpOwogICAgY2hlY2tHTGNhbGwoImdsVGV4SW1hZ2UyRCIpOwogICAgaWYgKHRtcFRleHR1cmUpIHsKICAgICAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIDApOwogICAgICAgIGdsRGVsZXRlVGV4dHVyZXMoMSwgJnRtcFRleHR1cmUpOwogICAgfQogICAgTEVBVkVfR0woKTsKCiAgICBmID0gZm9wZW4oZmlsZW5hbWUsICJ3KyIpOwogICAgaWYgKE5VTEwgPT0gZikgewogICAgICAgIEVSUigib3BlbmluZyBvZiAlcyBmYWlsZWQgd2l0aDogJXNcbiIsIGZpbGVuYW1lLCBzdHJlcnJvcihlcnJubykpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQovKiBTYXZlIHRoZSBkYXQgb3V0IHRvIGEgVEdBIGZpbGUgYmVjYXVzZSAxOiBpdCdzIGFuIGVhc3kgcmF3IGZvcm1hdCwgMjogaXQgc3VwcG9ydHMgYW4gYWxwaGEgY2hhbmVsKi8KICAgIFRSQUNFKCIoJXApIG9wZW5lZCAlcyB3aXRoIGZvcm1hdCAlc1xuIiwgVGhpcywgZmlsZW5hbWUsIGRlYnVnX2QzZGZvcm1hdChUaGlzLT5yZXNvdXJjZS5mb3JtYXQpKTsKLyogVEdBIGhlYWRlciAqLwogICAgZnB1dGMoMCxmKTsKICAgIGZwdXRjKDAsZik7CiAgICBmcHV0YygyLGYpOwogICAgZnB1dGMoMCxmKTsKICAgIGZwdXRjKDAsZik7CiAgICBmcHV0YygwLGYpOwogICAgZnB1dGMoMCxmKTsKICAgIGZwdXRjKDAsZik7CiAgICBmcHV0YygwLGYpOwogICAgZnB1dGMoMCxmKTsKICAgIGZwdXRjKDAsZik7CiAgICBmcHV0YygwLGYpOwovKiBzaG9ydCB3aWR0aCovCiAgICBmd3JpdGUoJndpZHRoLDIsMSxmKTsKLyogc2hvcnQgaGVpZ2h0ICovCiAgICBmd3JpdGUoJmhlaWdodCwyLDEsZik7Ci8qIGZvcm1hdCByZ2JhICovCiAgICBmcHV0YygweDIwLGYpOwogICAgZnB1dGMoMHgyOCxmKTsKLyogcmF3IGRhdGEgKi8KICAgIC8qIGlmICB0aGUgZGF0YSBpcyB1cHNpZGUgZG93biBpZiB3ZSd2ZSBmZXRjaGVkIGl0IGZyb20gYSBiYWNrIGJ1ZmZlciwgc28gaXQgbmVlZHMgZmxpcHBpbmcgYWdhaW4gdG8gbWFrZSBpdCB0aGUgY29ycmVjdCB3YXkgdXAqLwogICAgaWYoc3dhcENoYWluKQogICAgICAgIHRleHR1cmVSb3cgPSBhbGxvY2F0ZWRNZW1vcnkgKyAod2lkdGggKiAoaGVpZ2h0IC0gMSkgKjQpOwogICAgZWxzZQogICAgICAgIHRleHR1cmVSb3cgPSBhbGxvY2F0ZWRNZW1vcnk7CiAgICBmb3IgKHkgPSAwIDsgeSA8IGhlaWdodDsgeSsrKSB7CiAgICAgICAgZm9yIChpID0gMDsgaSA8IHdpZHRoOyAgaSsrKSB7CiAgICAgICAgICAgIGNvbG9yID0gKigoRFdPUkQqKXRleHR1cmVSb3cpOwogICAgICAgICAgICBmcHV0YygoY29sb3IgPj4gMTYpICYgMHhGRiwgZik7IC8qIEIgKi8KICAgICAgICAgICAgZnB1dGMoKGNvbG9yID4+ICA4KSAmIDB4RkYsIGYpOyAvKiBHICovCiAgICAgICAgICAgIGZwdXRjKChjb2xvciA+PiAgMCkgJiAweEZGLCBmKTsgLyogUiAqLwogICAgICAgICAgICBmcHV0YygoY29sb3IgPj4gMjQpICYgMHhGRiwgZik7IC8qIEEgKi8KICAgICAgICAgICAgdGV4dHVyZVJvdyArPSA0OwogICAgICAgIH0KICAgICAgICAvKiB0YWtlIHR3byByb3dzIG9mIHRoZSBwb2ludGVyIHRvIHRoZSB0ZXh0dXJlIG1lbW9yeSAqLwogICAgICAgIGlmKHN3YXBDaGFpbikKICAgICAgICAgICAgKHRleHR1cmVSb3ctPSB3aWR0aCA8PCAzKTsKCiAgICB9CiAgICBUUkFDRSgiQ2xvc2luZyBmaWxlXG4iKTsKICAgIGZjbG9zZShmKTsKCiAgICBpZihzd2FwQ2hhaW4pIHsKICAgICAgICBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKHN3YXBDaGFpbik7CiAgICB9CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBhbGxvY2F0ZWRNZW1vcnkpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfQ2xlYW5EaXJ0eVJlY3QoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfRElSVFk7CiAgICBUaGlzLT5kaXJ0eVJlY3QubGVmdCAgID0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICBUaGlzLT5kaXJ0eVJlY3QudG9wICAgID0gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0OwogICAgVGhpcy0+ZGlydHlSZWN0LnJpZ2h0ICA9IDA7CiAgICBUaGlzLT5kaXJ0eVJlY3QuYm90dG9tID0gMDsKICAgIFRSQUNFKCIoJXApIDogRGlydHk/JWQsIFJlY3Q6KCVsZCwlbGQsJWxkLCVsZClcbiIsIFRoaXMsIFRoaXMtPkZsYWdzICYgU0ZMQUdfRElSVFkgPyAxIDogMCwgVGhpcy0+ZGlydHlSZWN0LmxlZnQsCiAgICAgICAgICBUaGlzLT5kaXJ0eVJlY3QudG9wLCBUaGlzLT5kaXJ0eVJlY3QucmlnaHQsIFRoaXMtPmRpcnR5UmVjdC5ib3R0b20pOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qKgogKiAgIFNsaWdodGx5IGluZWZmaWNpZW50IHdheSB0byBoYW5kbGUgbXVsdGlwbGUgZGlydHkgcmVjdHMgYnV0IGl0IHdvcmtzIDopCiAqLwpleHRlcm4gSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9BZGREaXJ0eVJlY3QoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgQ09OU1QgUkVDVCogcERpcnR5UmVjdCkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzREJhc2VUZXh0dXJlICpiYXNlVGV4dHVyZSA9IE5VTEw7CiAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19ESVJUWTsKICAgIGlmIChOVUxMICE9IHBEaXJ0eVJlY3QpIHsKICAgICAgICBUaGlzLT5kaXJ0eVJlY3QubGVmdCAgID0gbWluKFRoaXMtPmRpcnR5UmVjdC5sZWZ0LCAgIHBEaXJ0eVJlY3QtPmxlZnQpOwogICAgICAgIFRoaXMtPmRpcnR5UmVjdC50b3AgICAgPSBtaW4oVGhpcy0+ZGlydHlSZWN0LnRvcCwgICAgcERpcnR5UmVjdC0+dG9wKTsKICAgICAgICBUaGlzLT5kaXJ0eVJlY3QucmlnaHQgID0gbWF4KFRoaXMtPmRpcnR5UmVjdC5yaWdodCwgIHBEaXJ0eVJlY3QtPnJpZ2h0KTsKICAgICAgICBUaGlzLT5kaXJ0eVJlY3QuYm90dG9tID0gbWF4KFRoaXMtPmRpcnR5UmVjdC5ib3R0b20sIHBEaXJ0eVJlY3QtPmJvdHRvbSk7CiAgICB9IGVsc2UgewogICAgICAgIFRoaXMtPmRpcnR5UmVjdC5sZWZ0ICAgPSAwOwogICAgICAgIFRoaXMtPmRpcnR5UmVjdC50b3AgICAgPSAwOwogICAgICAgIFRoaXMtPmRpcnR5UmVjdC5yaWdodCAgPSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICBUaGlzLT5kaXJ0eVJlY3QuYm90dG9tID0gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0OwogICAgfQogICAgVFJBQ0UoIiglcCkgOiBEaXJ0eT8lbGQsIFJlY3Q6KCVsZCwlbGQsJWxkLCVsZClcbiIsIFRoaXMsIFRoaXMtPkZsYWdzICYgU0ZMQUdfRElSVFksIFRoaXMtPmRpcnR5UmVjdC5sZWZ0LAogICAgICAgICAgVGhpcy0+ZGlydHlSZWN0LnRvcCwgVGhpcy0+ZGlydHlSZWN0LnJpZ2h0LCBUaGlzLT5kaXJ0eVJlY3QuYm90dG9tKTsKICAgIC8qIGlmIHRoZSBjb250YWluZXIgaXMgYSBiYXNldGV4dHVyZSB0aGVuIG1hcmsgaXQgZGlydHkuICovCiAgICBpZiAoSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lcihpZmFjZSwgJklJRF9JV2luZUQzREJhc2VUZXh0dXJlLCAodm9pZCAqKikmYmFzZVRleHR1cmUpID09IFdJTkVEM0RfT0spIHsKICAgICAgICBUUkFDRSgiUGFzc2luZyB0byBjb25hdGluZXJcbiIpOwogICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVfU2V0RGlydHkoYmFzZVRleHR1cmUsIFRSVUUpOwogICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVfUmVsZWFzZShiYXNlVGV4dHVyZSk7CiAgICB9CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRDb250YWluZXIoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgSVdpbmVEM0RCYXNlICpjb250YWluZXIpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwoKICAgIFRSQUNFKCJUaGlzICVwLCBjb250YWluZXIgJXBcbiIsIFRoaXMsIGNvbnRhaW5lcik7CgogICAgLyogV2UgY2FuJ3Qga2VlcCBhIHJlZmVyZW5jZSB0byB0aGUgY29udGFpbmVyLCBzaW5jZSB0aGUgY29udGFpbmVyIGFscmVhZHkga2VlcHMgYSByZWZlcmVuY2UgdG8gdXMuICovCgogICAgVFJBQ0UoIlNldHRpbmcgY29udGFpbmVyIHRvICVwIGZyb20gJXBcbiIsIGNvbnRhaW5lciwgVGhpcy0+Y29udGFpbmVyKTsKICAgIFRoaXMtPmNvbnRhaW5lciA9IGNvbnRhaW5lcjsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRGb3JtYXQoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgV0lORUQzREZPUk1BVCBmb3JtYXQpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgY29uc3QgUGl4ZWxGb3JtYXREZXNjICpmb3JtYXRFbnRyeSA9IGdldEZvcm1hdERlc2NFbnRyeShmb3JtYXQpOwoKICAgIGlmIChUaGlzLT5yZXNvdXJjZS5mb3JtYXQgIT0gV0lORUQzREZNVF9VTktOT1dOKSB7CiAgICAgICAgRklYTUUoIiglcCkgOiBUaGUgZm9yYW10IG9mIHRoZSBzdXJmYWNlIG11c3QgYmUgV0lORUQzREZPUk1BVF9VTktOT1dOXG4iLCBUaGlzKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBUUkFDRSgiKCVwKSA6IFNldHRpbmcgdGV4dHVyZSBmb3JhbXQgdG8gKCVkLCVzKVxuIiwgVGhpcywgZm9ybWF0LCBkZWJ1Z19kM2Rmb3JtYXQoZm9ybWF0KSk7CiAgICBpZiAoZm9ybWF0ID09IFdJTkVEM0RGTVRfVU5LTk9XTikgewogICAgICAgIFRoaXMtPnJlc291cmNlLnNpemUgPSAwOwogICAgfSBlbHNlIGlmIChmb3JtYXQgPT0gV0lORUQzREZNVF9EWFQxKSB7CiAgICAgICAgLyogRFhUMSBpcyBoYWxmIGJ5dGUgcGVyIHBpeGVsICovCiAgICAgICAgVGhpcy0+cmVzb3VyY2Uuc2l6ZSA9ICgobWF4KFRoaXMtPnBvdzJXaWR0aCwgNCkgKiBmb3JtYXRFbnRyeS0+YnBwKSAqIG1heChUaGlzLT5wb3cySGVpZ2h0LCA0KSkgPj4gMTsKCiAgICB9IGVsc2UgaWYgKGZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDIgfHwgZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMyB8fAogICAgICAgICAgICAgICBmb3JtYXQgPT0gV0lORUQzREZNVF9EWFQ0IHx8IGZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDUpIHsKICAgICAgICBUaGlzLT5yZXNvdXJjZS5zaXplID0gKChtYXgoVGhpcy0+cG93MldpZHRoLCA0KSAqIGZvcm1hdEVudHJ5LT5icHApICogbWF4KFRoaXMtPnBvdzJIZWlnaHQsIDQpKTsKICAgIH0gZWxzZSB7CiAgICAgICAgVGhpcy0+cmVzb3VyY2Uuc2l6ZSA9ICgoVGhpcy0+cG93MldpZHRoICogZm9ybWF0RW50cnktPmJwcCkgKyAzKSAmIH4zOwogICAgICAgIFRoaXMtPnJlc291cmNlLnNpemUgKj0gVGhpcy0+cG93MkhlaWdodDsKICAgIH0KCgogICAgLyogU2V0dXAgc29tZSBnbGZvcm1hdCBkZWZhdWx0cyAqLwogICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdCAgICAgICAgID0gZm9ybWF0RW50cnktPmdsRm9ybWF0OwogICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdEludGVybmFsID0gZm9ybWF0RW50cnktPmdsSW50ZXJuYWw7CiAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmdsVHlwZSAgICAgICAgICAgPSBmb3JtYXRFbnRyeS0+Z2xUeXBlOwoKICAgIGlmIChmb3JtYXQgIT0gV0lORUQzREZNVF9VTktOT1dOKSB7CiAgICAgICAgVGhpcy0+Ynl0ZXNQZXJQaXhlbCA9IGZvcm1hdEVudHJ5LT5icHA7CiAgICAgICAgVGhpcy0+cG93MlNpemUgICAgICA9IChUaGlzLT5wb3cyV2lkdGggKiBUaGlzLT5ieXRlc1BlclBpeGVsKSAqIFRoaXMtPnBvdzJIZWlnaHQ7CiAgICB9IGVsc2UgewogICAgICAgIFRoaXMtPmJ5dGVzUGVyUGl4ZWwgPSAwOwogICAgICAgIFRoaXMtPnBvdzJTaXplICAgICAgPSAwOwogICAgfQoKICAgIFRoaXMtPkZsYWdzIHw9IChXSU5FRDNERk1UX0QxNl9MT0NLQUJMRSA9PSBmb3JtYXQpID8gU0ZMQUdfTE9DS0FCTEUgOiAwOwoKICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCA9IGZvcm1hdDsKCiAgICBUUkFDRSgiKCVwKSA6IFNpemUgJWQsIHBvdzJTaXplICVkLCBieXRlc1BlclBpeGVsICVkLCBnbEZvcm1hdCAlZCwgZ2xGb3RtYXRJbnRlcm5hbCAlZCwgZ2xUeXBlICVkXG4iLCBUaGlzLCBUaGlzLT5yZXNvdXJjZS5zaXplLCBUaGlzLT5wb3cyU2l6ZSwgVGhpcy0+Ynl0ZXNQZXJQaXhlbCwgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdCwgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdEludGVybmFsLCBUaGlzLT5nbERlc2NyaXB0aW9uLmdsVHlwZSk7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0TWVtKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIHZvaWQgKk1lbSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwoKICAgIC8qIFJlbmRlciB0YXJnZXRzIGRlcGVuZCBvbiB0aGVpciBoZGMsIGFuZCB3ZSBjYW4ndCBjcmVhdGUgYSBoZGMgb24gYSB1c2VyIHBvaW50ZXIgKi8KICAgIGlmKFRoaXMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkgewogICAgICAgIEVSUigiTm90IHN1cHBvcnRlZCBvbiByZW5kZXIgdGFyZ2V0c1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgaWYoVGhpcy0+RmxhZ3MgJiAoU0ZMQUdfTE9DS0VEIHwgU0ZMQUdfRENJTlVTRSkpIHsKICAgICAgICBXQVJOKCJTdXJmYWNlIGlzIGxvY2tlZCBvciB0aGUgSERDIGlzIGluIHVzZVxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgaWYoTWVtICYmIE1lbSAhPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpIHsKCiAgICAgICAgLyogRG8gSSBoYXZlIHRvIGNvcHkgdGhlIG9sZCBzdXJmYWNlIGNvbnRlbnQ/ICovCiAgICAgICAgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19ESUJTRUNUSU9OKSB7CiAgICAgICAgICAgICAgICAvKiBSZWxlYXNlIHRoZSBEQy4gTm8gbmVlZCB0byBob2xkIHRoZSBjcml0aWNhbCBzZWN0aW9uIGZvciB0aGUgdXBkYXRlCiAgICAgICAgICAgICAgICAgKiBUaHJlYWQgYmVjYXVzZSB0aGlzIHRocmVhZCBydW5zIG9ubHkgb24gZnJvbnQgYnVmZmVycywgYnV0IHRoaXMgbWV0aG9kCiAgICAgICAgICAgICAgICAgKiBmYWlscyBmb3IgcmVuZGVyIHRhcmdldHMgaW4gdGhlIGNoZWNrIGFib3ZlLgogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBTZWxlY3RPYmplY3QoVGhpcy0+aERDLCBUaGlzLT5kaWIuaG9sZGJpdG1hcCk7CiAgICAgICAgICAgICAgICBEZWxldGVEQyhUaGlzLT5oREMpOwogICAgICAgICAgICAgICAgLyogUmVsZWFzZSB0aGUgRElCIHNlY3Rpb24gKi8KICAgICAgICAgICAgICAgIERlbGV0ZU9iamVjdChUaGlzLT5kaWIuRElCc2VjdGlvbik7CiAgICAgICAgICAgICAgICBUaGlzLT5kaWIuYml0bWFwX2RhdGEgPSBOVUxMOwogICAgICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gTlVMTDsKICAgICAgICAgICAgICAgIFRoaXMtPmhEQyA9IE5VTEw7CiAgICAgICAgICAgICAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfRElCU0VDVElPTjsKICAgICAgICB9IGVsc2UgaWYoIShUaGlzLT5GbGFncyAmIFNGTEFHX1VTRVJQVFIpKSB7CiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSk7CiAgICAgICAgfQogICAgICAgIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IE1lbTsKICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19VU0VSUFRSOwogICAgfSBlbHNlIGlmKFRoaXMtPkZsYWdzICYgU0ZMQUdfVVNFUlBUUikgewogICAgICAgIC8qIExvY2tyZWN0IGFuZCBHZXREQyB3aWxsIHJlLWNyZWF0ZSB0aGUgZGliIHNlY3Rpb24gYW5kIGFsbG9jYXRlZCBtZW1vcnkgKi8KICAgICAgICBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgPSBOVUxMOwogICAgICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19VU0VSUFRSOwogICAgfQogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qIFRPRE86IHJlcGxhY2UgdGhpcyBmdW5jdGlvbiB3aXRoIGNvbnRleHQgbWFuYWdlbWVudCByb3V0aW5lcyAqLwpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1NldFBCdWZmZXJTdGF0ZShJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBCT09MIGluUEJ1ZmZlciwgQk9PTCAgaW5UZXh0dXJlKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKCiAgICBpZihpblBCdWZmZXIpIHsKICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19JTlBCVUZGRVI7CiAgICB9IGVsc2UgewogICAgICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19JTlBCVUZGRVI7CiAgICB9CgogICAgaWYoaW5UZXh0dXJlKSB7CiAgICAgICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfSU5URVhUVVJFOwogICAgfSBlbHNlIHsKICAgICAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfSU5URVhUVVJFOwogICAgfQoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9GbGlwKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIElXaW5lRDNEU3VyZmFjZSAqb3ZlcnJpZGUsIERXT1JEIEZsYWdzKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNERGV2aWNlICpEM0QgPSAoSVdpbmVEM0REZXZpY2UgKikgVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZTsKICAgIFRSQUNFKCIoJXApLT4oJXAsJWx4KVxuIiwgVGhpcywgb3ZlcnJpZGUsIEZsYWdzKTsKCiAgICAvKiBGbGlwcGluZyBpcyBvbmx5IHN1cHBvcnRlZCBvbiBSZW5kZXJUYXJnZXRzICovCiAgICBpZiggIShUaGlzLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQpICkgcmV0dXJuIERERVJSX05PVEZMSVBQQUJMRTsKCiAgICBpZihvdmVycmlkZSkgewogICAgICAgIC8qIEREcmF3IHNldHMgdGhpcyBmb3IgdGhlIFgxMSBzdXJmYWNlcywgc28gZG9uJ3QgY29uZnVzZSB0aGUgdXNlciAKICAgICAgICAgKiBGSVhNRSgiKCVwKSBUYXJnZXQgb3ZlcnJpZGUgaXMgbm90IHN1cHBvcnRlZCBieSBub3dcbiIsIFRoaXMpOwogICAgICAgICAqIEFkZGl0aW9uYWxseSwgaXQgaXNuJ3QgcmVhbGx5IHBvc3NpYmxlIHRvIHN1cHBvcnQgdHJpcGxlLWJ1ZmZlcmluZwogICAgICAgICAqIHByb3Blcmx5IG9uIG9wZW5nbCBhdCBhbGwKICAgICAgICAgKi8KICAgIH0KCiAgICAvKiBGbGlwcGluZyBhIE9wZW5HTCBzdXJmYWNlIC0+IFVzZSBXaW5lRDNERGV2aWNlOjpQcmVzZW50ICovCiAgICByZXR1cm4gSVdpbmVEM0REZXZpY2VfUHJlc2VudChEM0QsIE5VTEwsIE5VTEwsIDAsIE5VTEwpOwp9CgovKiBOb3QgY2FsbGVkIGZyb20gdGhlIFZUYWJsZSAqLwpzdGF0aWMgSFJFU1VMVCBJV2luZUQzRFN1cmZhY2VJbXBsX0JsdE92ZXJyaWRlKElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMsIFJFQ1QgKkRlc3RSZWN0LCBJV2luZUQzRFN1cmZhY2UgKlNyY1N1cmZhY2UsIFJFQ1QgKlNyY1JlY3QsIERXT1JEIEZsYWdzLCBEREJMVEZYICpEREJsdEZ4KSB7CiAgICBEM0RSRUNUIHJlY3Q7CiAgICBJV2luZUQzRERldmljZUltcGwgKm15RGV2aWNlID0gVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZTsKICAgIElXaW5lRDNEU3dhcENoYWluSW1wbCAqc3dhcGNoYWluID0gTlVMTDsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlNyYyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIFNyY1N1cmZhY2U7CiAgICBCT09MIFNyY09LID0gVFJVRTsKCiAgICBUUkFDRSgiKCVwKS0+KCVwLCVwLCVwLCUwOGx4LCVwKVxuIiwgVGhpcywgRGVzdFJlY3QsIFNyY1N1cmZhY2UsIFNyY1JlY3QsIEZsYWdzLCBEREJsdEZ4KTsKCiAgICAvKiBHZXQgdGhlIHN3YXBjaGFpbi4gT25lIG9mIHRoZSBzdXJmYWNlcyBoYXMgdG8gYmUgYSBwcmltYXJ5IHN1cmZhY2UgKi8KICAgIElXaW5lRDNEU3VyZmFjZV9HZXRDb250YWluZXIoIChJV2luZUQzRFN1cmZhY2UgKikgVGhpcywgJklJRF9JV2luZUQzRFN3YXBDaGFpbiwgKHZvaWQgKiopJnN3YXBjaGFpbik7CiAgICBpZihzd2FwY2hhaW4pIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2UoKElXaW5lRDNEU3dhcENoYWluICopIHN3YXBjaGFpbik7CiAgICBlbHNlIGlmKFNyYykgewogICAgICAgIElXaW5lRDNEU3VyZmFjZV9HZXRDb250YWluZXIoIChJV2luZUQzRFN1cmZhY2UgKikgU3JjLCAmSUlEX0lXaW5lRDNEU3dhcENoYWluLCAodm9pZCAqKikmc3dhcGNoYWluKTsKICAgICAgICBpZihzd2FwY2hhaW4pIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2UoKElXaW5lRDNEU3dhcENoYWluICopIHN3YXBjaGFpbik7CiAgICAgICAgZWxzZSByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0gZWxzZSB7CiAgICAgICAgc3dhcGNoYWluID0gTlVMTDsKICAgIH0KCiAgICBpZiAoRGVzdFJlY3QpIHsKICAgICAgICByZWN0LngxID0gRGVzdFJlY3QtPmxlZnQ7CiAgICAgICAgcmVjdC55MSA9IERlc3RSZWN0LT50b3A7CiAgICAgICAgcmVjdC54MiA9IERlc3RSZWN0LT5yaWdodDsKICAgICAgICByZWN0LnkyID0gRGVzdFJlY3QtPmJvdHRvbTsKICAgIH0gZWxzZSB7CiAgICAgICAgcmVjdC54MSA9IDA7CiAgICAgICAgcmVjdC55MSA9IDA7CiAgICAgICAgcmVjdC54MiA9IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoOwogICAgICAgIHJlY3QueTIgPSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICB9CgogICAgLyogSGFsZi1saWZlIGRvZXMgYSBCbHQgZnJvbSB0aGUgYmFjayBidWZmZXIgdG8gdGhlIGZyb250IGJ1ZmZlciwKICAgICAqIEZ1bGwgc3VyZmFjZSBzaXplLCBubyBmbGFncy4uLiBVc2UgcHJlc2VudCBpbnN0ZWFkCiAgICAgKi8KICAgIGlmKFNyYykKICAgIHsKICAgICAgICAvKiBGaXJzdCwgY2hlY2sgaWYgd2UgY2FuIGRvIGEgRmxpcCAqLwoKICAgICAgICAvKiBDaGVjayByZWN0cyAtIElXaW5lRDNERGV2aWNlX1ByZXNlbnQgZG9lc24ndCBoYW5kbGUgdGhlbSAqLwogICAgICAgIGlmKCBTcmNSZWN0ICkgewogICAgICAgICAgICBpZiggKFNyY1JlY3QtPmxlZnQgPT0gMCkgJiYgKFNyY1JlY3QtPnRvcCA9PSAwKSAmJgogICAgICAgICAgICAgICAgKFNyY1JlY3QtPnJpZ2h0ID09IFNyYy0+Y3VycmVudERlc2MuV2lkdGgpICYmIChTcmNSZWN0LT5ib3R0b20gPT0gU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQpICkgewogICAgICAgICAgICAgICAgU3JjT0sgPSBUUlVFOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgU3JjT0sgPSBUUlVFOwogICAgICAgIH0KCiAgICAgICAgLyogQ2hlY2sgdGhlIERlc3RpbmF0aW9uIHJlY3QgYW5kIHRoZSBzdXJmYWNlIHNpemVzICovCiAgICAgICAgaWYoU3JjT0sgJiYKICAgICAgICAgICAocmVjdC54MSA9PSAwKSAmJiAocmVjdC55MSA9PSAwKSAmJgogICAgICAgICAgIChyZWN0LngyID09ICBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCkgJiYgKHJlY3QueTIgPT0gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0KSAmJgogICAgICAgICAgIChUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCA9PSBTcmMtPmN1cnJlbnREZXNjLldpZHRoKSAmJgogICAgICAgICAgIChUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQgPT0gU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQpKSB7CiAgICAgICAgICAgIC8qIFRoZXNlIGZsYWdzIGFyZSB1bmltcG9ydGFudCBmb3IgdGhlIGZsYWcgY2hlY2ssIHJlbW92ZSB0aGVtICovCgogICAgICAgICAgICBpZigoRmxhZ3MgJiB+KEREQkxUX0RPTk9UV0FJVCB8IEREQkxUX1dBSVQpKSA9PSAwKSB7CiAgICAgICAgICAgICAgICBpZiggc3dhcGNoYWluLT5iYWNrQnVmZmVyICYmICgoSVdpbmVEM0RTdXJmYWNlICopIFRoaXMgPT0gc3dhcGNoYWluLT5mcm9udEJ1ZmZlcikgJiYgKChJV2luZUQzRFN1cmZhY2UgKikgU3JjID09IHN3YXBjaGFpbi0+YmFja0J1ZmZlclswXSkgKSB7CgogICAgICAgICAgICAgICAgICAgIEQzRFNXQVBFRkZFQ1Qgb3JpZ19zd2FwID0gc3dhcGNoYWluLT5wcmVzZW50UGFybXMuU3dhcEVmZmVjdDsKCiAgICAgICAgICAgICAgICAgICAgLyogVGhlIGlkZWEgYmVoaW5kIHRoaXMgaXMgdGhhdCBhIGdsUmVhZFBpeGVscyBhbmQgYSBnbERyYXdQaXhlbHMgY2FsbAogICAgICAgICAgICAgICAgICAgICAqIHRha2UgdmVyeSBsb25nLCB3aGlsZSBhIGZsaXAgaXMgZmFzdC4KICAgICAgICAgICAgICAgICAgICAgKiBUaGlzIGFwcGxpZXMgdG8gSGFsZi1MaWZlLCB3aGljaCBkb2VzIHN1Y2ggQmx0cyBldmVyeSB0aW1lIGl0IGZpbmlzaGVkCiAgICAgICAgICAgICAgICAgICAgICogYSBmcmFtZSwgYW5kIHRvIFByaW5jZSBvZiBQZXJzaWEgM0QsIHdoaWNoIHVzZXMgdGhpcyB0byBkcmF3IGF0IGxlYXN0IHRoZSBtYWluCiAgICAgICAgICAgICAgICAgICAgICogbWVudS4gVGhpcyBpcyBhbHNvIHVzZWQgYnkgYWxsIGFwcHMgd2hlbiB0aGV5IGRvIHdpbmRvd2VkIHJlbmRlcmluZwogICAgICAgICAgICAgICAgICAgICAqCiAgICAgICAgICAgICAgICAgICAgICogVGhlIHByb2JsZW0gaXMgdGhhdCBmbGlwcGluZyBpcyBub3QgcmVhbGx5IHRoZSBzYW1lIGFzIGNvcHlpbmcuIEFmdGVyIGEKICAgICAgICAgICAgICAgICAgICAgKiBCbHQgdGhlIGZyb250IGJ1ZmZlciBpcyBhIGNvcHkgb2YgdGhlIGJhY2sgYnVmZmVyLCBhbmQgdGhlIGJhY2sgYnVmZmVyIGlzCiAgICAgICAgICAgICAgICAgICAgICogdW50b3VjaGVkLiBUaGVyZWZvcmUgaXQncyBuZWNlc3NhcnkgdG8gb3ZlcnJpZGUgdGhlIHN3YXAgZWZmZWN0CiAgICAgICAgICAgICAgICAgICAgICogYW5kIHRvIHNldCBpdCBiYWNrIGFmdGVyIHRoZSBmbGlwLgogICAgICAgICAgICAgICAgICAgICAqLwoKICAgICAgICAgICAgICAgICAgICBzd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5Td2FwRWZmZWN0ID0gV0lORUQzRFNXQVBFRkZFQ1RfQ09QWTsKCiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIkZ1bGwgc2NyZWVuIGJhY2sgYnVmZmVyIC0+IGZyb250IGJ1ZmZlciBibHQsIHBlcmZvcm1pbmcgYSBmbGlwIGluc3RlYWRcbiIpOwogICAgICAgICAgICAgICAgICAgIElXaW5lRDNERGV2aWNlX1ByZXNlbnQoKElXaW5lRDNERGV2aWNlICopIFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgTlVMTCwgMCwgTlVMTCk7CgogICAgICAgICAgICAgICAgICAgIHN3YXBjaGFpbi0+cHJlc2VudFBhcm1zLlN3YXBFZmZlY3QgPSBvcmlnX3N3YXA7CgogICAgICAgICAgICAgICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKiBCbHQgZnJvbSB0ZXh0dXJlIHRvIHJlbmRlcnRhcmdldD8gKi8KICAgICAgICBpZiggKCAoIChJV2luZUQzRFN1cmZhY2UgKikgVGhpcyA9PSBzd2FwY2hhaW4tPmZyb250QnVmZmVyKSB8fAogICAgICAgICAgICAgICggc3dhcGNoYWluLT5iYWNrQnVmZmVyICYmIChJV2luZUQzRFN1cmZhY2UgKikgVGhpcyA9PSBzd2FwY2hhaW4tPmJhY2tCdWZmZXJbMF0pICkKICAgICAgICAgICAgICAmJgogICAgICAgICAgICAgICggKCAoSVdpbmVEM0RTdXJmYWNlICopIFNyYyAhPSBzd2FwY2hhaW4tPmZyb250QnVmZmVyKSAmJgogICAgICAgICAgICAgICAgKCBzd2FwY2hhaW4tPmJhY2tCdWZmZXIgJiYgKElXaW5lRDNEU3VyZmFjZSAqKSBTcmMgIT0gc3dhcGNoYWluLT5iYWNrQnVmZmVyWzBdKSApICkgewogICAgICAgICAgICBmbG9hdCBnbFRleENvb3JkWzRdOwogICAgICAgICAgICBEV09SRCBvbGRDS2V5OwogICAgICAgICAgICBERENPTE9SS0VZIG9sZEJsdENLZXkgPSB7MCwwfTsKICAgICAgICAgICAgR0xpbnQgb2xkTGlnaHQsIG9sZEZvZywgb2xkRGVwdGgsIG9sZEJsZW5kLCBvbGRDdWxsLCBvbGRBbHBoYTsKICAgICAgICAgICAgR0xpbnQgYWxwaGFmdW5jOwogICAgICAgICAgICBHTGNsYW1wZiBhbHBoYXJlZjsKICAgICAgICAgICAgR0xpbnQgb2xkU3RlbmNpbDsKICAgICAgICAgICAgUkVDVCBTb3VyY2VSZWN0YW5nbGU7CiAgICAgICAgICAgIEdMaW50IG9sZERyYXc7CgogICAgICAgICAgICBUUkFDRSgiQmx0IGZyb20gc3VyZmFjZSAlcCB0byByZW5kZXJ0YXJnZXQgJXBcbiIsIFNyYywgVGhpcyk7CgogICAgICAgICAgICBpZihTcmNSZWN0KSB7CiAgICAgICAgICAgICAgICBTb3VyY2VSZWN0YW5nbGUubGVmdCA9IFNyY1JlY3QtPmxlZnQ7CiAgICAgICAgICAgICAgICBTb3VyY2VSZWN0YW5nbGUucmlnaHQgPSBTcmNSZWN0LT5yaWdodDsKICAgICAgICAgICAgICAgIFNvdXJjZVJlY3RhbmdsZS50b3AgPSBTcmNSZWN0LT50b3A7CiAgICAgICAgICAgICAgICBTb3VyY2VSZWN0YW5nbGUuYm90dG9tID0gU3JjUmVjdC0+Ym90dG9tOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgU291cmNlUmVjdGFuZ2xlLmxlZnQgPSAwOwogICAgICAgICAgICAgICAgU291cmNlUmVjdGFuZ2xlLnJpZ2h0ID0gU3JjLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICAgICAgICAgIFNvdXJjZVJlY3RhbmdsZS50b3AgPSAwOwogICAgICAgICAgICAgICAgU291cmNlUmVjdGFuZ2xlLmJvdHRvbSA9IFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0OwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZighQ2FsY3VsYXRlVGV4UmVjdChTcmMsICZTb3VyY2VSZWN0YW5nbGUsIGdsVGV4Q29vcmQpKSB7CiAgICAgICAgICAgICAgICAvKiBGYWxsIGJhY2sgdG8gc29mdHdhcmUgKi8KICAgICAgICAgICAgICAgIFdBUk4oIiglcCkgU291cmNlIHRleHR1cmUgYXJlYSAoJWxkLCVsZCktKCVsZCwlbGQpIGlzIHRvbyBiaWdcbiIsIFNyYywKICAgICAgICAgICAgICAgICAgICAgU291cmNlUmVjdGFuZ2xlLmxlZnQsIFNvdXJjZVJlY3RhbmdsZS50b3AsCiAgICAgICAgICAgICAgICAgICAgIFNvdXJjZVJlY3RhbmdsZS5yaWdodCwgU291cmNlUmVjdGFuZ2xlLmJvdHRvbSk7CiAgICAgICAgICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyogQ29sb3Iga2V5aW5nOiBDaGVjayBpZiB3ZSBoYXZlIHRvIGRvIGEgY29sb3Iga2V5ZWQgYmx0LAogICAgICAgICAgICAgKiBhbmQgaWYgbm90IGNoZWNrIGlmIGEgY29sb3Iga2V5IGlzIGFjdGl2YXRlZC4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIG9sZENLZXkgPSBTcmMtPkNLZXlGbGFnczsKICAgICAgICAgICAgaWYoIShGbGFncyAmIEREQkxUX0tFWVNSQykgJiYgCiAgICAgICAgICAgICAgIFNyYy0+Q0tleUZsYWdzICYgRERTRF9DS1NSQ0JMVCkgewogICAgICAgICAgICAgICAgLyogT2ssIHRoZSBzdXJmYWNlIGhhcyBhIGNvbG9yIGtleSwgYnV0IHdlIHNoYWxsIG5vdCB1c2UgaXQgLQogICAgICAgICAgICAgICAgICogRGVhY3RpdmF0ZSBpdCBmb3Igbm93LCBMb2FkVGV4dHVyZSB3aWxsIGNhdGNoIHRoaXMKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgU3JjLT5DS2V5RmxhZ3MgJj0gfkREU0RfQ0tTUkNCTFQ7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIENvbG9yIGtleWluZyAqLwogICAgICAgICAgICBpZihGbGFncyAmIEREQkxUX0tFWURFU1QpIHsKICAgICAgICAgICAgICAgIG9sZEJsdENLZXkgPSBUaGlzLT5TcmNCbHRDS2V5OwogICAgICAgICAgICAgICAgLyogVGVtcG9yYXJ5IHJlcGxhY2UgdGhlIHNvdXJjZSBjb2xvciBrZXkgd2l0aCB0aGUgZGVzdGluYXRpb24gb25lLiBXZSBkbyB0aGlzIGJlY2F1c2UgdGhlIGNvbG9yIGNvbnZlcnNpb24gY29kZSB3aGljaAogICAgICAgICAgICAgICAgICogaXMgaW4gdGhlIGVuZCBjYWxsZWQgZnJvbSBMb2FkVGV4dHVyZSB3b3JrcyB3aXRoIHRoZSBzb3VyY2UgY29sb3IuIEF0IHRoZSBlbmQgb2YgdGhpcyBmdW5jdGlvbiB3ZSByZXN0b3JlIHRoZSBjb2xvciBrZXkuCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIFRoaXMtPlNyY0JsdENLZXkgPSBUaGlzLT5EZXN0Qmx0Q0tleTsKICAgICAgICAgICAgfSBlbHNlIGlmIChGbGFncyAmIEREQkxUX0tFWVNSQykKICAgICAgICAgICAgICAgIG9sZEJsdENLZXkgPSBUaGlzLT5TcmNCbHRDS2V5OwoKICAgICAgICAgICAgLyogTm93IGxvYWQgdGhlIHN1cmZhY2UgKi8KICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1ByZUxvYWQoKElXaW5lRDNEU3VyZmFjZSAqKSBTcmMpOwoKICAgICAgICAgICAgRU5URVJfR0woKTsKCiAgICAgICAgICAgIC8qIFNhdmUgYWxsIHRoZSBvbGQgc3R1ZmYgdW50aWwgd2UgaGF2ZSBhIHByb3BlciBvcGVuZ2wgc3RhdGUgbWFuYWdlciAqLwogICAgICAgICAgICBvbGRMaWdodCA9IGdsSXNFbmFibGVkKEdMX0xJR0hUSU5HKTsKICAgICAgICAgICAgb2xkRm9nID0gZ2xJc0VuYWJsZWQoR0xfRk9HKTsKICAgICAgICAgICAgb2xkRGVwdGggPSBnbElzRW5hYmxlZChHTF9ERVBUSF9URVNUKTsKICAgICAgICAgICAgb2xkQmxlbmQgPSBnbElzRW5hYmxlZChHTF9CTEVORCk7CiAgICAgICAgICAgIG9sZEN1bGwgPSBnbElzRW5hYmxlZChHTF9DVUxMX0ZBQ0UpOwogICAgICAgICAgICBvbGRBbHBoYSA9IGdsSXNFbmFibGVkKEdMX0FMUEhBX1RFU1QpOwogICAgICAgICAgICBvbGRTdGVuY2lsID0gZ2xJc0VuYWJsZWQoR0xfU1RFTkNJTF9URVNUKTsKCiAgICAgICAgICAgIGdsR2V0SW50ZWdlcnYoR0xfQUxQSEFfVEVTVF9GVU5DLCAmYWxwaGFmdW5jKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsR2V0RmxvYXR2IEdMX0FMUEhBX1RFU1RfRlVOQyIpOwogICAgICAgICAgICBnbEdldEZsb2F0dihHTF9BTFBIQV9URVNUX1JFRiwgJmFscGhhcmVmKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsR2V0RmxvYXR2IEdMX0FMUEhBX1RFU1RfUkVGIik7CgogICAgICAgICAgICBnbEdldEludGVnZXJ2KEdMX0RSQVdfQlVGRkVSLCAmb2xkRHJhdyk7CiAgICAgICAgICAgIGlmKFRoaXMgPT0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgc3dhcGNoYWluLT5mcm9udEJ1ZmZlcikgewogICAgICAgICAgICAgICAgVFJBQ0UoIkRyYXdpbmcgdG8gZnJvbnQgYnVmZmVyXG4iKTsKICAgICAgICAgICAgICAgIGdsRHJhd0J1ZmZlcihHTF9GUk9OVCk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEcmF3QnVmZmVyIEdMX0ZST05UIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIFVuYmluZCB0aGUgb2xkIHRleHR1cmUgKi8KICAgICAgICAgICAgZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCAwKTsKCiAgICAgICAgICAgIGlmIChHTF9TVVBQT1JUKEFSQl9NVUxUSVRFWFRVUkUpKSB7CiAgICAgICAgICAgIC8qIFdlIHVzZSB0ZXh0dXJlIHVuaXQgMCBmb3IgYmx0cyAqLwogICAgICAgICAgICAgICAgR0xfRVhUQ0FMTChnbEFjdGl2ZVRleHR1cmVBUkIoR0xfVEVYVFVSRTBfQVJCKSk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xBY3RpdmVUZXh0dXJlQVJCIik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBXQVJOKCJNdWx0aS10ZXh0dXJpbmcgaXMgdW5zdXBwb3J0ZWQgaW4gdGhlIGxvY2FsIE9wZW5HTCBpbXBsZW1lbnRhdGlvblxuIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIERpc2FibGUgc29tZSBmYW5jeSBncmFwaGljcyBlZmZlY3RzICovCiAgICAgICAgICAgIGdsRGlzYWJsZShHTF9MSUdIVElORyk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUgR0xfTElHSFRJTkciKTsKICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX0RFUFRIX1RFU1QpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlIEdMX0RFUFRIX1RFU1QiKTsKICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX0ZPRyk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUgR0xfRk9HIik7CiAgICAgICAgICAgIGdsRGlzYWJsZShHTF9CTEVORCk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUgR0xfQkxFTkQiKTsKICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX0NVTExfRkFDRSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUgR0xfQ1VMTF9GQUNFIik7CiAgICAgICAgICAgIGdsRGlzYWJsZShHTF9TVEVOQ0lMX1RFU1QpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlIEdMX1NURU5DSUxfVEVTVCIpOwoKICAgICAgICAgICAgLyogT2ssIHdlIG5lZWQgMmQgdGV4dHVyZXMsIGJ1dCBub3QgMUQgb3IgM0QgKi8KICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX1RFWFRVUkVfMUQpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlIEdMX1RFWFRVUkVfMUQiKTsKICAgICAgICAgICAgZ2xFbmFibGUoR0xfVEVYVFVSRV8yRCk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZSBHTF9URVhUVVJFXzJEIik7CiAgICAgICAgICAgIGdsRGlzYWJsZShHTF9URVhUVVJFXzNEKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9URVhUVVJFXzNEIik7CgogICAgICAgICAgICAvKiBCaW5kIHRoZSB0ZXh0dXJlICovCiAgICAgICAgICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgU3JjLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsQmluZFRleHR1cmUiKTsKCiAgICAgICAgICAgIGdsRW5hYmxlKEdMX1NDSVNTT1JfVEVTVCk7CgogICAgICAgICAgICBnbFRleEVudmkoR0xfVEVYVFVSRV9FTlYsIEdMX1RFWFRVUkVfRU5WX01PREUsIEdMX1JFUExBQ0UpOwoKICAgICAgICAgICAgLyogTm8gZmlsdGVyaW5nIGZvciBibHRzICovCiAgICAgICAgICAgIGdsVGV4UGFyYW1ldGVyaShHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX01BR19GSUxURVIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgR0xfTkVBUkVTVCk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFRleFBhcmFtZXRlcmkiKTsKICAgICAgICAgICAgZ2xUZXhQYXJhbWV0ZXJpKEdMX1RFWFRVUkVfMkQsIEdMX1RFWFRVUkVfTUlOX0ZJTFRFUiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBHTF9ORUFSRVNUKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsVGV4UGFyYW1ldGVyaSIpOwogICAgICAgICAgICBnbFRleFBhcmFtZXRlcmkoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9XUkFQX1MsIEdMX0NMQU1QKTsKICAgICAgICAgICAgZ2xUZXhQYXJhbWV0ZXJpKEdMX1RFWFRVUkVfMkQsIEdMX1RFWFRVUkVfV1JBUF9ULCBHTF9DTEFNUCk7CiAgICAgICAgICAgIGdsVGV4RW52aShHTF9URVhUVVJFX0VOViwgR0xfVEVYVFVSRV9FTlZfTU9ERSwgR0xfUkVQTEFDRSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFRleEVudmkiKTsKCiAgICAgICAgICAgIC8qIFRoaXMgaXMgZm9yIGNvbG9yIGtleWluZyAqLwogICAgICAgICAgICBpZihGbGFncyAmIEREQkxUX0tFWVNSQykgewogICAgICAgICAgICAgICAgZ2xFbmFibGUoR0xfQUxQSEFfVEVTVCk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUgR0xfQUxQSEFfVEVTVCIpOwogICAgICAgICAgICAgICAgZ2xBbHBoYUZ1bmMoR0xfTk9URVFVQUwsIDAuMCk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xBbHBoYUZ1bmNcbiIpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX0FMUEhBX1RFU1QpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9BTFBIQV9URVNUIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIERyYXcgYSB0ZXh0dXJlZCBxdWFkCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBkM2RkZXZpY2Vfc2V0X29ydGhvKFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2UpOwoKICAgICAgICAgICAgZ2xCZWdpbihHTF9RVUFEUyk7CgogICAgICAgICAgICBnbENvbG9yM2QoMS4wZiwgMS4wZiwgMS4wZik7CiAgICAgICAgICAgIGdsVGV4Q29vcmQyZihnbFRleENvb3JkWzBdLCBnbFRleENvb3JkWzJdKTsKICAgICAgICAgICAgZ2xWZXJ0ZXgzZihyZWN0LngxLAogICAgICAgICAgICAgICAgICAgICAgIHJlY3QueTEsCiAgICAgICAgICAgICAgICAgICAgICAgMC4wKTsKCiAgICAgICAgICAgIGdsVGV4Q29vcmQyZihnbFRleENvb3JkWzBdLCBnbFRleENvb3JkWzNdKTsKICAgICAgICAgICAgZ2xWZXJ0ZXgzZihyZWN0LngxLCByZWN0LnkyLCAwLjApOwoKICAgICAgICAgICAgZ2xUZXhDb29yZDJmKGdsVGV4Q29vcmRbMV0sIGdsVGV4Q29vcmRbM10pOwogICAgICAgICAgICBnbFZlcnRleDNmKHJlY3QueDIsCiAgICAgICAgICAgICAgICAgICAgICAgcmVjdC55MiwKICAgICAgICAgICAgICAgICAgICAgICAwLjApOwoKICAgICAgICAgICAgZ2xUZXhDb29yZDJmKGdsVGV4Q29vcmRbMV0sIGdsVGV4Q29vcmRbMl0pOwogICAgICAgICAgICBnbFZlcnRleDNmKHJlY3QueDIsCiAgICAgICAgICAgICAgICAgICAgICAgcmVjdC55MSwKICAgICAgICAgICAgICAgICAgICAgICAwLjApOwogICAgICAgICAgICBnbEVuZCgpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmQiKTsKCiAgICAgICAgICAgIC8qIFVuYmluZCB0aGUgdGV4dHVyZSAqLwogICAgICAgICAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIDApOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUgZ2xCaW5kVGV4dHVyZSIpOwoKICAgICAgICAgICAgLyogUmVzdG9yZSB0aGUgb2xkIHNldHRpbmdzICovCiAgICAgICAgICAgIGlmKG9sZExpZ2h0KSB7CiAgICAgICAgICAgICAgICBnbEVuYWJsZShHTF9MSUdIVElORyk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUgR0xfTElHSFRJTkciKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZihvbGRGb2cpIHsKICAgICAgICAgICAgICAgIGdsRW5hYmxlKEdMX0ZPRyk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUgR0xfRk9HIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYob2xkRGVwdGgpIHsKICAgICAgICAgICAgICAgIGdsRW5hYmxlKEdMX0RFUFRIX1RFU1QpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlIEdMX0RFUFRIX1RFU1QiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZihvbGRCbGVuZCkgewogICAgICAgICAgICAgICAgZ2xFbmFibGUoR0xfQkxFTkQpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlIEdMX0JMRU5EIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYob2xkQ3VsbCkgewogICAgICAgICAgICAgICAgZ2xFbmFibGUoR0xfQ1VMTF9GQUNFKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZSBHTF9DVUxMX0ZBQ0UiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZihvbGRTdGVuY2lsKSB7CiAgICAgICAgICAgICAgICBnbEVuYWJsZShHTF9TVEVOQ0lMX1RFU1QpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlIEdMX1NURU5DSUxfVEVTVCIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKCFvbGRBbHBoYSkgewogICAgICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX0FMUEhBX1RFU1QpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9BTFBIQV9URVNUIik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBnbEVuYWJsZShHTF9BTFBIQV9URVNUKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZSBHTF9BTFBIQV9URVNUIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGdsQWxwaGFGdW5jKGFscGhhZnVuYywgYWxwaGFyZWYpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xBbHBoYUZ1bmNcbiIpOwoKICAgICAgICAgICAgaWYoVGhpcyA9PSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBzd2FwY2hhaW4tPmZyb250QnVmZmVyICYmIG9sZERyYXcgPT0gR0xfQkFDSykgewogICAgICAgICAgICAgICAgZ2xEcmF3QnVmZmVyKG9sZERyYXcpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKiBSZXN0b3JlIHRoZSBjb2xvciBrZXkgZmxhZ3MgKi8KICAgICAgICAgICAgaWYob2xkQ0tleSAhPSBTcmMtPkNLZXlGbGFncykgewogICAgICAgICAgICAgICAgU3JjLT5DS2V5RmxhZ3MgPSBvbGRDS2V5OwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKiBSZXN0b3JlIHRoZSBvbGQgY29sb3Iga2V5ICovCiAgICAgICAgICAgIGlmIChGbGFncyAmIChEREJMVF9LRVlTUkMgfCBEREJMVF9LRVlERVNUKSkKICAgICAgICAgICAgICAgIFRoaXMtPlNyY0JsdENLZXkgPSBvbGRCbHRDS2V5OwoKICAgICAgICAgICAgTEVBVkVfR0woKTsKCiAgICAgICAgICAgIC8qIFRPRE86IElmIHRoZSBzdXJmYWNlIGlzIGxvY2tlZCBvZnRlbiwgcGVyZm9ybSB0aGUgQmx0IGluIHNvZnR3YXJlIG9uIHRoZSBtZW1vcnkgaW5zdGVhZCAqLwogICAgICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19HTERJUlRZOwoKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICAgICAgfQoKCiAgICAgICAgLyogQmx0IGZyb20gcmVuZGVydGFyZ2V0IHRvIHRleHR1cmU/ICovCiAgICAgICAgaWYoIChTcmNTdXJmYWNlID09IHN3YXBjaGFpbi0+ZnJvbnRCdWZmZXIpIHx8CiAgICAgICAgICAgIChzd2FwY2hhaW4tPmJhY2tCdWZmZXIgJiYgU3JjU3VyZmFjZSA9PSBzd2FwY2hhaW4tPmJhY2tCdWZmZXJbMF0pICkgewogICAgICAgICAgICBpZiggKCAoSVdpbmVEM0RTdXJmYWNlICopIFRoaXMgIT0gc3dhcGNoYWluLT5mcm9udEJ1ZmZlcikgJiYKICAgICAgICAgICAgICAgICggc3dhcGNoYWluLT5iYWNrQnVmZmVyICYmIChJV2luZUQzRFN1cmZhY2UgKikgVGhpcyAhPSBzd2FwY2hhaW4tPmJhY2tCdWZmZXJbMF0pICkgewogICAgICAgICAgICAgICAgVUlOVCByb3c7CiAgICAgICAgICAgICAgICBEM0RSRUNUIHNyZWN0OwogICAgICAgICAgICAgICAgZmxvYXQgeHJlbCwgeXJlbDsKCiAgICAgICAgICAgICAgICBUUkFDRSgiQmx0IGZyb20gcmVuZGVydGFyZ2V0IHRvIHRleHR1cmVcbiIpOwoKICAgICAgICAgICAgICAgIC8qIENhbGwgcHJlbG9hZCBmb3IgdGhlIHN1cmZhY2UgdG8gbWFrZSBzdXJlIGl0IGlzbid0IGRpcnR5ICovCiAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfUHJlTG9hZCgoSVdpbmVEM0RTdXJmYWNlICopIFRoaXMpOwoKICAgICAgICAgICAgICAgIGlmKFNyY1JlY3QpIHsKICAgICAgICAgICAgICAgICAgICBzcmVjdC54MSA9IFNyY1JlY3QtPmxlZnQ7CiAgICAgICAgICAgICAgICAgICAgc3JlY3QueTEgPSBTcmNSZWN0LT50b3A7CiAgICAgICAgICAgICAgICAgICAgc3JlY3QueDIgPSBTcmNSZWN0LT5yaWdodDsKICAgICAgICAgICAgICAgICAgICBzcmVjdC55MiA9IFNyY1JlY3QtPmJvdHRvbTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgc3JlY3QueDEgPSAwOwogICAgICAgICAgICAgICAgICAgIHNyZWN0LnkxID0gMDsKICAgICAgICAgICAgICAgICAgICBzcmVjdC54MiA9IFNyYy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAgICAgICAgICAgICAgICAgc3JlY3QueTIgPSBTcmMtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBFTlRFUl9HTCgpOwoKICAgICAgICAgICAgICAgIC8qIEJpbmQgdGhlIHRhcmdldCB0ZXh0dXJlICovCiAgICAgICAgICAgICAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIFRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsQmluZFRleHR1cmUiKTsKICAgICAgICAgICAgICAgIGlmKHN3YXBjaGFpbi0+YmFja0J1ZmZlciAmJiBTcmNTdXJmYWNlID09IHN3YXBjaGFpbi0+YmFja0J1ZmZlclswXSkgewogICAgICAgICAgICAgICAgICAgIGdsUmVhZEJ1ZmZlcihHTF9CQUNLKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgZ2xSZWFkQnVmZmVyKEdMX0ZST05UKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFJlYWRCdWZmZXIiKTsKCiAgICAgICAgICAgICAgICB4cmVsID0gKGZsb2F0KSAoc3JlY3QueDIgLSBzcmVjdC54MSkgLyAoZmxvYXQpIChyZWN0LngyIC0gcmVjdC54MSk7CiAgICAgICAgICAgICAgICB5cmVsID0gKGZsb2F0KSAoc3JlY3QueTIgLSBzcmVjdC55MSkgLyAoZmxvYXQpIChyZWN0LnkyIC0gcmVjdC55MSk7CgogICAgICAgICAgICAgICAgLyogSSBoYXZlIHRvIHByb2Nlc3MgdGhpcyByb3cgYnkgcm93IHRvIHN3YXAgdGhlIGltYWdlLAogICAgICAgICAgICAgICAgICogb3RoZXJ3aXNlIGl0IHdvdWxkIGJlIHVwc2lkZSBkb3duLCBzbyBzdHJlY2hpbmcgaW4geSBkaXJlY3Rpb24KICAgICAgICAgICAgICAgICAqIGRvZXNuJ3QgY29zdCBleHRyYSB0aW1lCiAgICAgICAgICAgICAgICAgKgogICAgICAgICAgICAgICAgICogSG93ZXZlciwgc3RyZWNoaW5nIGluIHggZGlyZWN0aW9uIGNhbiBiZSBhdm9pZGVkIGlmIG5vdCBuZWNlc3NhcnkKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgZm9yKHJvdyA9IHJlY3QueTE7IHJvdyA8IHJlY3QueTI7IHJvdysrKSB7CiAgICAgICAgICAgICAgICAgICAgaWYoICh4cmVsIC0gMS4wIDwgLWVwcykgfHwgKHhyZWwgLSAxLjAgPiBlcHMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIFdlbGwsIHRoYXQgc3R1ZmYgd29ya3MsIGJ1dCBpdCdzIHZlcnkgc2xvdy4KICAgICAgICAgICAgICAgICAgICAgICAgICogZmluZCBhIGJldHRlciB3YXkgaW5zdGVhZAogICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgVUlOVCBjb2w7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvcihjb2wgPSByZWN0LngxOyBjb2wgPCByZWN0LngyOyBjb2wrKykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2xDb3B5VGV4U3ViSW1hZ2UyRChHTF9URVhUVVJFXzJELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAvKiBsZXZlbCAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWN0LngxICsgY29sLCBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQgLSByb3cgLSAxLCAvKiB4b2Zmc2V0LCB5b2Zmc2V0ICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNyZWN0LngxICsgY29sICogeHJlbCwgU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQgLSBzcmVjdC55MiArIHJvdyAqIHlyZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEsIDEpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgZ2xDb3B5VGV4U3ViSW1hZ2UyRChHTF9URVhUVVJFXzJELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIC8qIGxldmVsICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVjdC54MSwgVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0IC0gcm93IC0gMSwgLyogeG9mZnNldCwgeW9mZnNldCAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNyZWN0LngxLCBTcmMtPmN1cnJlbnREZXNjLkhlaWdodCAtIHNyZWN0LnkyICsgcm93ICogeXJlbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWN0LngyLCAxKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgdmNoZWNrR0xjYWxsKCJnbENvcHlUZXhTdWJJbWFnZTJEIik7CiAgICAgICAgICAgICAgICBMRUFWRV9HTCgpOwoKICAgICAgICAgICAgICAgIGlmKCEoVGhpcy0+RmxhZ3MgJiBTRkxBR19ET05PVEZSRUUpKSB7CiAgICAgICAgICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKICAgICAgICAgICAgICAgICAgICBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgPSBOVUxMOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19HTERJUlRZOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGlmIChGbGFncyAmIEREQkxUX0NPTE9SRklMTCkgewogICAgICAgIC8qIFRoaXMgaXMgZWFzeSB0byBoYW5kbGUgZm9yIHRoZSBEM0QgRGV2aWNlLi4uICovCiAgICAgICAgRFdPUkQgY29sb3I7CiAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICppbXBsU3dhcENoYWluOwoKICAgICAgICBUUkFDRSgiQ29sb3JmaWxsXG4iKTsKCiAgICAgICAgLyogVGhlIGNvbG9yIGFzIGdpdmVuIGluIHRoZSBCbHQgZnVuY3Rpb24gaXMgaW4gdGhlIGZvcm1hdCBvZiB0aGUgZnJhbWUtYnVmZmVyLi4uCiAgICAgICAgICogJ2NsZWFyJyBleHBlY3QgaXQgaW4gQVJHQiBmb3JtYXQgPT4gd2UgbmVlZCB0byBkbyBzb21lIGNvbnZlcnNpb24gOi0pCiAgICAgICAgICovCiAgICAgICAgaWYgKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX1A4KSB7CiAgICAgICAgICAgIGlmIChUaGlzLT5wYWxldHRlKSB7CiAgICAgICAgICAgICAgICBjb2xvciA9ICgoMHhGRjAwMDAwMCkgfAogICAgICAgICAgICAgICAgICAgICAgICAgIChUaGlzLT5wYWxldHRlLT5wYWxlbnRzW0REQmx0RngtPnU1LmR3RmlsbENvbG9yXS5wZVJlZCA8PCAxNikgfAogICAgICAgICAgICAgICAgICAgICAgICAgIChUaGlzLT5wYWxldHRlLT5wYWxlbnRzW0REQmx0RngtPnU1LmR3RmlsbENvbG9yXS5wZUdyZWVuIDw8IDgpIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAoVGhpcy0+cGFsZXR0ZS0+cGFsZW50c1tEREJsdEZ4LT51NS5kd0ZpbGxDb2xvcl0ucGVCbHVlKSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBjb2xvciA9IDB4RkYwMDAwMDA7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfUjVHNkI1KSB7CiAgICAgICAgICAgIGlmIChEREJsdEZ4LT51NS5kd0ZpbGxDb2xvciA9PSAweEZGRkYpIHsKICAgICAgICAgICAgICAgIGNvbG9yID0gMHhGRkZGRkZGRjsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGNvbG9yID0gKCgweEZGMDAwMDAwKSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgKChEREJsdEZ4LT51NS5kd0ZpbGxDb2xvciAmIDB4RjgwMCkgPDwgOCkgfAogICAgICAgICAgICAgICAgICAgICAgICAgICgoRERCbHRGeC0+dTUuZHdGaWxsQ29sb3IgJiAweDA3RTApIDw8IDUpIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAoKEREQmx0RngtPnU1LmR3RmlsbENvbG9yICYgMHgwMDFGKSA8PCAzKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX1I4RzhCOCkgfHwKICAgICAgICAgICAgICAgICAgKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX1g4UjhHOEI4KSApIHsKICAgICAgICAgICAgY29sb3IgPSAweEZGMDAwMDAwIHwgRERCbHRGeC0+dTUuZHdGaWxsQ29sb3I7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0E4UjhHOEI4KSB7CiAgICAgICAgICAgIGNvbG9yID0gRERCbHRGeC0+dTUuZHdGaWxsQ29sb3I7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICBFUlIoIldyb25nIHN1cmZhY2UgdHlwZSBmb3IgQkxUIG92ZXJyaWRlKEZvcm1hdCBkb2Vzbid0IG1hdGNoKSAhXG4iKTsKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICAgICAgfQoKICAgICAgICBUUkFDRSgiQ2FsbGluZyBHZXRTd2FwQ2hhaW4gd2l0aCBteWRldmljZSA9ICVwXG4iLCBteURldmljZSk7CiAgICAgICAgSVdpbmVEM0REZXZpY2VfR2V0U3dhcENoYWluKChJV2luZUQzRERldmljZSAqKW15RGV2aWNlLCAwLCAoSVdpbmVEM0RTd2FwQ2hhaW4gKiopJmltcGxTd2FwQ2hhaW4pOwogICAgICAgIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2UoIChJV2luZUQzRFN3YXBDaGFpbiAqKSBpbXBsU3dhcENoYWluICk7CiAgICAgICAgaWYoaW1wbFN3YXBDaGFpbi0+YmFja0J1ZmZlciAmJiBUaGlzID09IChJV2luZUQzRFN1cmZhY2VJbXBsKikgaW1wbFN3YXBDaGFpbi0+YmFja0J1ZmZlclswXSkgewogICAgICAgICAgICBnbERyYXdCdWZmZXIoR0xfQkFDSyk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERyYXdCdWZmZXIoR0xfQkFDSykiKTsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoVGhpcyA9PSAoSVdpbmVEM0RTdXJmYWNlSW1wbCopIGltcGxTd2FwQ2hhaW4tPmZyb250QnVmZmVyKSB7CiAgICAgICAgICAgIGdsRHJhd0J1ZmZlcihHTF9GUk9OVCk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERyYXdCdWZmZXIoR0xfRlJPTlQpIik7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICBFUlIoIldyb25nIHN1cmZhY2UgdHlwZSBmb3IgQkxUIG92ZXJyaWRlKG5vdCBvbiBzd2FwY2hhaW4pICFcbiIpOwogICAgICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgICAgICB9CgogICAgICAgIFRSQUNFKCIoJXApIGV4ZWN1dGluZyBSZW5kZXIgVGFyZ2V0IG92ZXJyaWRlLCBjb2xvciA9ICVseFxuIiwgVGhpcywgY29sb3IpOwoKICAgICAgICBJV2luZUQzRERldmljZV9DbGVhciggKElXaW5lRDNERGV2aWNlICopIG15RGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxIC8qIE51bWJlciBvZiByZWN0YW5nbGVzICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcmVjdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEQ0xFQVJfVEFSR0VULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMC4wIC8qIFogKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAgLyogU3RlbmNpbCAqLyk7CgogICAgICAgIC8qIFJlc3RvcmUgdGhlIG9yaWdpbmFsIGRyYXcgYnVmZmVyICovCiAgICAgICAgaWYoaW1wbFN3YXBDaGFpbi0+YmFja0J1ZmZlciAmJiBpbXBsU3dhcENoYWluLT5iYWNrQnVmZmVyWzBdKSB7CiAgICAgICAgICAgIGdsRHJhd0J1ZmZlcihHTF9CQUNLKTsKICAgICAgICAgICAgdmNoZWNrR0xjYWxsKCJnbERyYXdCdWZmZXIiKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIC8qIERlZmF1bHQ6IEZhbGwgYmFjayB0byB0aGUgZ2VuZXJpYyBibHQgKi8KICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9CbHQoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgUkVDVCAqRGVzdFJlY3QsIElXaW5lRDNEU3VyZmFjZSAqU3JjU3VyZmFjZSwgUkVDVCAqU3JjUmVjdCwgRFdPUkQgRmxhZ3MsIEREQkxURlggKkREQmx0RngpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqU3JjID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgU3JjU3VyZmFjZTsKICAgIFRSQUNFKCIoJXApLT4oJXAsJXAsJXAsJWx4LCVwKVxuIiwgVGhpcywgRGVzdFJlY3QsIFNyY1N1cmZhY2UsIFNyY1JlY3QsIEZsYWdzLCBEREJsdEZ4KTsKICAgIFRSQUNFKCIoJXApOiBVc2FnZSBpcyAlc1xuIiwgVGhpcywgZGVidWdfZDNkdXNhZ2UoVGhpcy0+cmVzb3VyY2UudXNhZ2UpKTsKCiAgICAvKiBTcGVjaWFsIGNhc2VzIGZvciBSZW5kZXJUYXJnZXRzICovCiAgICBpZiggKFRoaXMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkgfHwKICAgICAgICAoIFNyYyAmJiAoU3JjLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQpICkpIHsKICAgICAgICBpZihJV2luZUQzRFN1cmZhY2VJbXBsX0JsdE92ZXJyaWRlKFRoaXMsIERlc3RSZWN0LCBTcmNTdXJmYWNlLCBTcmNSZWN0LCBGbGFncywgRERCbHRGeCkgPT0gV0lORUQzRF9PSykgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgLyogRm9yIHRoZSByZXN0IGNhbGwgdGhlIFgxMSBzdXJmYWNlIGltcGxlbWVudGF0aW9uLgogICAgICogRm9yIFJlbmRlclRhcmdldHMgdGhpcyBzaG91bGQgYmUgaW1wbGVtZW50ZWQgT3BlbkdMIGFjY2VsZXJhdGVkIGluIEJsdE92ZXJyaWRlLAogICAgICogb3RoZXIgQmx0cyBhcmUgcmF0aGVyIHJhcmUKICAgICAqLwogICAgcmV0dXJuIElXaW5lR0RJU3VyZmFjZUltcGxfQmx0KGlmYWNlLCBEZXN0UmVjdCwgU3JjU3VyZmFjZSwgU3JjUmVjdCwgRmxhZ3MsIEREQmx0RngpOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0dldEJsdFN0YXR1cyhJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBEV09SRCBGbGFncykgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKS0+KCVseClcbiIsIFRoaXMsIEZsYWdzKTsKCiAgICBzd2l0Y2ggKEZsYWdzKQogICAgewogICAgY2FzZSBEREdCU19DQU5CTFQ6CiAgICBjYXNlIERER0JTX0lTQkxURE9ORToKICAgICAgICByZXR1cm4gRERfT0s7CgogICAgZGVmYXVsdDoKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgIH0KfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRGbGlwU3RhdHVzKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIERXT1JEIEZsYWdzKSB7CiAgICAvKiBYWFg6IERERVJSX0lOVkFMSURTVVJGQUNFVFlQRSAqLwoKICAgIFRSQUNFKCIoJXApLT4oJTA4bHgpXG4iLGlmYWNlLEZsYWdzKTsKICAgIHN3aXRjaCAoRmxhZ3MpIHsKICAgIGNhc2UgRERHRlNfQ0FORkxJUDoKICAgIGNhc2UgRERHRlNfSVNGTElQRE9ORToKICAgICAgICByZXR1cm4gRERfT0s7CgogICAgZGVmYXVsdDoKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgIH0KfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9Jc0xvc3QoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwoKICAgIHJldHVybiBUaGlzLT5GbGFncyAmIFNGTEFHX0xPU1QgPyBEREVSUl9TVVJGQUNFTE9TVCA6IFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfUmVzdG9yZShJV2luZUQzRFN1cmZhY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CgogICAgLyogU28gZmFyIHdlIGRvbid0IGxvc2UgYW55dGhpbmcgOikgKi8KICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19MT1NUOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfQmx0RmFzdChJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBEV09SRCBkc3R4LCBEV09SRCBkc3R5LCBJV2luZUQzRFN1cmZhY2UgKlNvdXJjZSwgUkVDVCAqcnNyYywgRFdPUkQgdHJhbnMpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBpZmFjZTsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKnNyY0ltcGwgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBTb3VyY2U7CiAgICBUUkFDRSgiKCVwKS0+KCVsZCwgJWxkLCAlcCwgJXAsICUwOGx4XG4iLCBpZmFjZSwgZHN0eCwgZHN0eSwgU291cmNlLCByc3JjLCB0cmFucyk7CgogICAgLyogU3BlY2lhbCBjYXNlcyBmb3IgUmVuZGVyVGFyZ2V0cyAqLwogICAgaWYoIChUaGlzLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQpIHx8CiAgICAgICAgKCBzcmNJbXBsICYmIChzcmNJbXBsLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQpICkpIHsKCiAgICAgICAgUkVDVCBTcmNSZWN0LCBEc3RSZWN0OwogICAgICAgIERXT1JEIEZsYWdzPTA7CgogICAgICAgIGlmKHJzcmMpIHsKICAgICAgICAgICAgU3JjUmVjdC5sZWZ0ID0gcnNyYy0+bGVmdDsKICAgICAgICAgICAgU3JjUmVjdC50b3A9IHJzcmMtPnRvcDsKICAgICAgICAgICAgU3JjUmVjdC5ib3R0b20gPSByc3JjLT5ib3R0b207CiAgICAgICAgICAgIFNyY1JlY3QucmlnaHQgPSByc3JjLT5yaWdodDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBTcmNSZWN0LmxlZnQgPSAwOwogICAgICAgICAgICBTcmNSZWN0LnRvcCA9IDA7CiAgICAgICAgICAgIFNyY1JlY3QucmlnaHQgPSBzcmNJbXBsLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICAgICAgU3JjUmVjdC5ib3R0b20gPSBzcmNJbXBsLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICAgICAgfQoKICAgICAgICBEc3RSZWN0LmxlZnQgPSBkc3R4OwogICAgICAgIERzdFJlY3QudG9wPWRzdHk7CiAgICAgICAgRHN0UmVjdC5yaWdodCA9IGRzdHggKyBTcmNSZWN0LnJpZ2h0IC0gU3JjUmVjdC5sZWZ0OwogICAgICAgIERzdFJlY3QuYm90dG9tID0gZHN0eSArIFNyY1JlY3QuYm90dG9tIC0gU3JjUmVjdC50b3A7CgogICAgICAgIC8qIENvbnZlcnQgQmx0RmFzdCBmbGFncyBpbnRvIEJ0bCBvbmVzIGJlY2F1c2UgaXQgaXMgY2FsbGVkIGZyb20gU3VyZmFjZUltcGxfQmx0IGFzIHdlbGwgKi8KICAgICAgICBpZih0cmFucyAmIEREQkxURkFTVF9TUkNDT0xPUktFWSkKICAgICAgICAgICAgRmxhZ3MgfD0gRERCTFRfS0VZU1JDOwogICAgICAgIGlmKHRyYW5zICYgRERCTFRGQVNUX0RFU1RDT0xPUktFWSkKICAgICAgICAgICAgRmxhZ3MgfD0gRERCTFRfS0VZREVTVDsKICAgICAgICBpZih0cmFucyAmIEREQkxURkFTVF9XQUlUKQogICAgICAgICAgICBGbGFncyB8PSBEREJMVF9XQUlUOwogICAgICAgIGlmKHRyYW5zICYgRERCTFRGQVNUX0RPTk9UV0FJVCkKICAgICAgICAgICAgRmxhZ3MgfD0gRERCTFRfRE9OT1RXQUlUOwoKICAgICAgICBpZihJV2luZUQzRFN1cmZhY2VJbXBsX0JsdE92ZXJyaWRlKFRoaXMsICZEc3RSZWN0LCBTb3VyY2UsICZTcmNSZWN0LCBGbGFncywgTlVMTCkgPT0gV0lORUQzRF9PSykgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgoKICAgIHJldHVybiBJV2luZUdESVN1cmZhY2VJbXBsX0JsdEZhc3QoaWZhY2UsIGRzdHgsIGRzdHksIFNvdXJjZSwgcnNyYywgdHJhbnMpOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0dldFBhbGV0dGUoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgSVdpbmVEM0RQYWxldHRlICoqUGFsKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIiwgVGhpcywgUGFsKTsKCiAgICAqUGFsID0gKElXaW5lRDNEUGFsZXR0ZSAqKSBUaGlzLT5wYWxldHRlOwogICAgcmV0dXJuIEREX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1JlYWxpemVQYWxldHRlKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBpZmFjZTsKICAgIFJHQlFVQUQgY29sWzI1Nl07CiAgICBJV2luZUQzRFBhbGV0dGVJbXBsICpwYWwgPSBUaGlzLT5wYWxldHRlOwogICAgdW5zaWduZWQgaW50IG47CiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CgogICAgaWYoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfUDggfHwKICAgICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0E4UDgpCiAgICB7CiAgICAgICAgVFJBQ0UoIkRpcnRpZnlpbmcgc3VyZmFjZVxuIik7CiAgICAgICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfRElSVFk7CiAgICB9CgogICAgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19ESUJTRUNUSU9OKSB7CiAgICAgICAgVFJBQ0UoIiglcCk6IFVwZGF0aW5nIHRoZSBoZGMncyBwYWxldHRlXG4iLCBUaGlzKTsKICAgICAgICBmb3IgKG49MDsgbjwyNTY7IG4rKykgewogICAgICAgICAgICBpZihwYWwpIHsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JSZWQgICA9IHBhbC0+cGFsZW50c1tuXS5wZVJlZDsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JHcmVlbiA9IHBhbC0+cGFsZW50c1tuXS5wZUdyZWVuOwogICAgICAgICAgICAgICAgY29sW25dLnJnYkJsdWUgID0gcGFsLT5wYWxlbnRzW25dLnBlQmx1ZTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIElXaW5lRDNERGV2aWNlSW1wbCAqZGV2aWNlID0gVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZTsKICAgICAgICAgICAgICAgIC8qIFVzZSB0aGUgZGVmYXVsdCBkZXZpY2UgcGFsZXR0ZSAqLwogICAgICAgICAgICAgICAgY29sW25dLnJnYlJlZCAgID0gZGV2aWNlLT5wYWxldHRlc1tkZXZpY2UtPmN1cnJlbnRQYWxldHRlXVtuXS5wZVJlZDsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JHcmVlbiA9IGRldmljZS0+cGFsZXR0ZXNbZGV2aWNlLT5jdXJyZW50UGFsZXR0ZV1bbl0ucGVHcmVlbjsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JCbHVlICA9IGRldmljZS0+cGFsZXR0ZXNbZGV2aWNlLT5jdXJyZW50UGFsZXR0ZV1bbl0ucGVCbHVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNvbFtuXS5yZ2JSZXNlcnZlZCA9IDA7CiAgICAgICAgfQogICAgICAgIFNldERJQkNvbG9yVGFibGUoVGhpcy0+aERDLCAwLCAyNTYsIGNvbCk7CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0UGFsZXR0ZShJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBJV2luZUQzRFBhbGV0dGUgKlBhbCkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwogICAgSVdpbmVEM0RQYWxldHRlSW1wbCAqUGFsSW1wbCA9IChJV2luZUQzRFBhbGV0dGVJbXBsICopIFBhbDsKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLCBUaGlzLCBQYWwpOwoKICAgIGlmKFRoaXMtPnBhbGV0dGUgIT0gTlVMTCkgCiAgICAgICAgaWYoVGhpcy0+cmVzb3VyY2UudXNhZ2UgJiBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUKQogICAgICAgICAgICBUaGlzLT5wYWxldHRlLT5GbGFncyAmPSB+RERQQ0FQU19QUklNQVJZU1VSRkFDRTsKCiAgICBpZihQYWxJbXBsICE9IE5VTEwpIHsKICAgICAgICBpZihUaGlzLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQpIHsKICAgICAgICAgICAgLyogU2V0IHRoZSBkZXZpY2UncyBtYWluIHBhbGV0dGUgaWYgdGhlIHBhbGV0dGUKICAgICAgICAgICAgICogd2Fzbid0IGEgcHJpbWFyeSBwYWxldHRlIGJlZm9yZQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYoIShQYWxJbXBsLT5GbGFncyAmIEREUENBUFNfUFJJTUFSWVNVUkZBQ0UpKSB7CiAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZUltcGwgKmRldmljZSA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CiAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgaTsKCiAgICAgICAgICAgICAgICBmb3IoaT0wOyBpIDwgMjU2OyBpKyspIHsKICAgICAgICAgICAgICAgICAgICBkZXZpY2UtPnBhbGV0dGVzW2RldmljZS0+Y3VycmVudFBhbGV0dGVdW2ldID0gUGFsSW1wbC0+cGFsZW50c1tpXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgKFBhbEltcGwpLT5GbGFncyB8PSBERFBDQVBTX1BSSU1BUllTVVJGQUNFOwogICAgICAgIH0KICAgIH0KICAgIFRoaXMtPnBhbGV0dGUgPSBQYWxJbXBsOwoKICAgIHJldHVybiBJV2luZUQzRFN1cmZhY2VfUmVhbGl6ZVBhbGV0dGUoaWZhY2UpOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1NldENvbG9yS2V5KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIERXT1JEIEZsYWdzLCBERENPTE9SS0VZICpDS2V5KSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CiAgICBUUkFDRSgiKCVwKS0+KCUwOGx4LCVwKVxuIiwgVGhpcywgRmxhZ3MsIENLZXkpOwoKICAgIGlmICgoRmxhZ3MgJiBERENLRVlfQ09MT1JTUEFDRSkgIT0gMCkgewogICAgICAgIEZJWE1FKCIgY29sb3JrZXkgdmFsdWUgbm90IHN1cHBvcnRlZCAoJTA4bHgpICFcbiIsIEZsYWdzKTsKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgIH0KCiAgICAvKiBEaXJ0aWZ5IHRoZSBzdXJmYWNlLCBidXQgb25seSBpZiBhIGtleSB3YXMgY2hhbmdlZCAqLwogICAgaWYoQ0tleSkgewogICAgICAgIHN3aXRjaCAoRmxhZ3MgJiB+RERDS0VZX0NPTE9SU1BBQ0UpIHsKICAgICAgICAgICAgY2FzZSBERENLRVlfREVTVEJMVDoKICAgICAgICAgICAgICAgIFRoaXMtPkRlc3RCbHRDS2V5ID0gKkNLZXk7CiAgICAgICAgICAgICAgICBUaGlzLT5DS2V5RmxhZ3MgfD0gRERTRF9DS0RFU1RCTFQ7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgRERDS0VZX0RFU1RPVkVSTEFZOgogICAgICAgICAgICAgICAgVGhpcy0+RGVzdE92ZXJsYXlDS2V5ID0gKkNLZXk7CiAgICAgICAgICAgICAgICBUaGlzLT5DS2V5RmxhZ3MgfD0gRERTRF9DS0RFU1RPVkVSTEFZOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIEREQ0tFWV9TUkNPVkVSTEFZOgogICAgICAgICAgICAgICAgVGhpcy0+U3JjT3ZlcmxheUNLZXkgPSAqQ0tleTsKICAgICAgICAgICAgICAgIFRoaXMtPkNLZXlGbGFncyB8PSBERFNEX0NLU1JDT1ZFUkxBWTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBERENLRVlfU1JDQkxUOgogICAgICAgICAgICAgICAgVGhpcy0+U3JjQmx0Q0tleSA9ICpDS2V5OwogICAgICAgICAgICAgICAgVGhpcy0+Q0tleUZsYWdzIHw9IEREU0RfQ0tTUkNCTFQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CiAgICBlbHNlIHsKICAgICAgICBzd2l0Y2ggKEZsYWdzICYgfkREQ0tFWV9DT0xPUlNQQUNFKSB7CiAgICAgICAgICAgIGNhc2UgRERDS0VZX0RFU1RCTFQ6CiAgICAgICAgICAgICAgICBUaGlzLT5DS2V5RmxhZ3MgJj0gfkREU0RfQ0tERVNUQkxUOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIEREQ0tFWV9ERVNUT1ZFUkxBWToKICAgICAgICAgICAgICAgIFRoaXMtPkNLZXlGbGFncyAmPSB+RERTRF9DS0RFU1RPVkVSTEFZOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIEREQ0tFWV9TUkNPVkVSTEFZOgogICAgICAgICAgICAgICAgVGhpcy0+Q0tleUZsYWdzICY9IH5ERFNEX0NLU1JDT1ZFUkxBWTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBERENLRVlfU1JDQkxUOgogICAgICAgICAgICAgICAgVGhpcy0+Q0tleUZsYWdzICY9IH5ERFNEX0NLU1JDQkxUOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9Qcml2YXRlU2V0dXAoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgLyoqIENoZWNrIGFnYWluc3QgdGhlIG1heGltdW0gdGV4dHVyZSBzaXplcyBzdXBwb3J0ZWQgYnkgdGhlIHZpZGVvIGNhcmQgKiovCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CgogICAgVFJBQ0UoIiVwXG4iLCBUaGlzKTsKICAgIGlmICgoVGhpcy0+cG93MldpZHRoID4gR0xfTElNSVRTKHRleHR1cmVfc2l6ZSkgfHwgVGhpcy0+cG93MkhlaWdodCA+IEdMX0xJTUlUUyh0ZXh0dXJlX3NpemUpKSAmJiAhKFRoaXMtPnJlc291cmNlLnVzYWdlICYgKFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQgfCBXSU5FRDNEVVNBR0VfREVQVEhTVEVOQ0lMKSkpIHsKICAgICAgICAvKiBvbmUgb2YgdGhyZWUgb3B0aW9ucwogICAgICAgIDE6IERvIHRoZSBzYW1lIGFzIHdlIGRvIHdpdGggbm9ucG93IDIgYW5kIHNjYWxlIHRoZSB0ZXh0dXJlLCAoYW55IHRleHR1cmUgb3BzIHdvdWxkIHJlcXVpcmUgdGhlIHRleHR1cmUgdG8gYmUgc2NhbGVkIHdoaWNoIGlzIHBvdGVudGlhbGx5IHNsb3cpCiAgICAgICAgMjogU2V0IHRoZSB0ZXh0dXJlIHRvIHRoZSBtYXhpdW0gc2l6ZSAoYmFkIGlkZWEpCiAgICAgICAgMzogICAgV0FSTiBhbmQgcmV0dXJuIFdJTkVEM0RFUlJfTk9UQVZBSUxBQkxFOwogICAgICAgIDQ6IENyZWF0ZSB0aGUgc3VyZmFjZSwgYnV0IGFsbG93IGl0IHRvIGJlIHVzZWQgb25seSBmb3IgRGlyZWN0RHJhdyBCbHRzLiBTb21lIGFwcHMoZS5nLiBTd2F0IDMpIGNyZWF0ZSB0ZXh0dXJlcyB3aXRoIGEgSGVpZ2h0IG9mIDE2IGFuZCBhIFdpZHRoID4gMzAwMCBhbmQgYmx0IDE2eDE2IGxldHRlciBhcmVhcyBmcm9tIHRoZW0gdG8gdGhlIHJlbmRlciB0YXJnZXQuCiAgICAgICAgKi8KICAgICAgICBXQVJOKCIoJXApIENyZWF0aW5nIGFuIG92ZXJzaXplZCBzdXJmYWNlXG4iLCBUaGlzKTsKICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19PVkVSU0laRTsKCiAgICAgICAgLyogVGhpcyB3aWxsIGJlIGluaXRpYWxpemVkIG9uIHRoZSBmaXJzdCBibHQgKi8KICAgICAgICBUaGlzLT5nbFJlY3QubGVmdCA9IDA7CiAgICAgICAgVGhpcy0+Z2xSZWN0LnRvcCA9IDA7CiAgICAgICAgVGhpcy0+Z2xSZWN0LnJpZ2h0ID0gMDsKICAgICAgICBUaGlzLT5nbFJlY3QuYm90dG9tID0gMDsKICAgIH0gZWxzZSB7CiAgICAgICAgLyogTm8gb3ZlcnNpemUsIGdsIHJlY3QgaXMgdGhlIGZ1bGwgdGV4dHVyZSBzaXplICovCiAgICAgICAgVGhpcy0+RmxhZ3MgJj0gflNGTEFHX09WRVJTSVpFOwogICAgICAgIFRoaXMtPmdsUmVjdC5sZWZ0ID0gMDsKICAgICAgICBUaGlzLT5nbFJlY3QudG9wID0gMDsKICAgICAgICBUaGlzLT5nbFJlY3QucmlnaHQgPSBUaGlzLT5wb3cyV2lkdGg7CiAgICAgICAgVGhpcy0+Z2xSZWN0LmJvdHRvbSA9IFRoaXMtPnBvdzJIZWlnaHQ7CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkRXT1JEIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0dldFBpdGNoKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBpZmFjZTsKICAgIERXT1JEIHJldDsKICAgIFRSQUNFKCIoJXApXG4iLCBUaGlzKTsKCiAgICAvKiBEWFRuIGZvcm1hdHMgZG9uJ3QgaGF2ZSBleGFjdCBwaXRjaGVzIGFzIHRoZXkgYXJlIHRvIHRoZSBuZXcgcm93IG9mIGJsb2NrcywKICAgICAgICAgd2hlcmUgZWFjaCBibG9jayBpcyA0eDQgcGl4ZWxzLCA4IGJ5dGVzIChkeHQxKSBhbmQgMTYgYnl0ZXMgKGR4dDIvMy80LzUpCiAgICAgICAgICBpZSBwaXRjaCA9ICh3aWR0aC80KSAqIGJ5dGVzIHBlciBibG9jayAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwogICAgaWYgKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDEpIC8qIERYVDEgaXMgOCBieXRlcyBwZXIgYmxvY2sgKi8KICAgICAgICByZXQgPSAoVGhpcy0+Y3VycmVudERlc2MuV2lkdGggPj4gMikgPDwgMzsKICAgIGVsc2UgaWYgKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDIgfHwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMyB8fAogICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNCB8fCBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQ1KSAvKiBEWFQyLzMvNC81IGlzIDE2IGJ5dGVzIHBlciBibG9jayAqLwogICAgICAgIHJldCA9IChUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCA+PiAyKSA8PCA0OwogICAgZWxzZSB7CiAgICAgICAgaWYgKE5QMl9SRVBBQ0sgPT0gd2luZWQzZF9zZXR0aW5ncy5ub25wb3dlcjJfbW9kZSB8fCBUaGlzLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQpIHsKICAgICAgICAgICAgLyogRnJvbnQgYW5kIGJhY2sgYnVmZmVycyBhcmUgYWx3YXlzIGxvY2tlcy91bmxvY2tlZCBvbiBjdXJyZW50RGVzYy5XaWR0aCAqLwogICAgICAgICAgICByZXQgPSBUaGlzLT5ieXRlc1BlclBpeGVsICogVGhpcy0+Y3VycmVudERlc2MuV2lkdGg7ICAvKiBCeXRlcyAvIHJvdyAqLwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldCA9IFRoaXMtPmJ5dGVzUGVyUGl4ZWwgKiBUaGlzLT5wb3cyV2lkdGg7CiAgICAgICAgfQogICAgICAgIC8qIFN1cmZhY2VzIGFyZSAzMiBiaXQgYWxpZ25lZCAqLwogICAgICAgIHJldCA9IChyZXQgKyAzKSAmIH4zOwogICAgfQogICAgVFJBQ0UoIiglcCkgUmV0dXJuaW5nICVsZFxuIiwgVGhpcywgcmV0KTsKICAgIHJldHVybiByZXQ7Cn0KCmNvbnN0IElXaW5lRDNEU3VyZmFjZVZ0YmwgSVdpbmVEM0RTdXJmYWNlX1Z0YmwgPQp7CiAgICAvKiBJVW5rbm93biAqLwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9RdWVyeUludGVyZmFjZSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfQWRkUmVmLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9SZWxlYXNlLAogICAgLyogSVdpbmVEM0RSZXNvdXJjZSAqLwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRQYXJlbnQsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldERldmljZSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0UHJpdmF0ZURhdGEsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldFByaXZhdGVEYXRhLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9GcmVlUHJpdmF0ZURhdGEsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1NldFByaW9yaXR5LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRQcmlvcml0eSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfUHJlTG9hZCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0VHlwZSwKICAgIC8qIElXaW5lRDNEU3VyZmFjZSAqLwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRDb250YWluZXJQYXJlbnQsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldENvbnRhaW5lciwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0RGVzYywKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfTG9ja1JlY3QsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1VubG9ja1JlY3QsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldERDLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9SZWxlYXNlREMsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0ZsaXAsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0JsdCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0Qmx0U3RhdHVzLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRGbGlwU3RhdHVzLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9Jc0xvc3QsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1Jlc3RvcmUsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0JsdEZhc3QsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldFBhbGV0dGUsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1NldFBhbGV0dGUsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1JlYWxpemVQYWxldHRlLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRDb2xvcktleSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0UGl0Y2gsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1NldE1lbSwKICAgIC8qIEludGVybmFsIHVzZTogKi8KICAgIElXaW5lRDNEU3VyZmFjZUltcGxfQ2xlYW5EaXJ0eVJlY3QsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0FkZERpcnR5UmVjdCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfTG9hZFRleHR1cmUsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1NhdmVTbmFwc2hvdCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0Q29udGFpbmVyLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRQQnVmZmVyU3RhdGUsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1NldEdsVGV4dHVyZURlc2MsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldEdsRGVzYywKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0RGF0YSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0Rm9ybWF0LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9Qcml2YXRlU2V0dXAKfTsK