LyoKICogSVdpbmVEM0RTdXJmYWNlIEltcGxlbWVudGF0aW9uCiAqCiAqIENvcHlyaWdodCAxOTk4IExpb25lbCBVbG1lcgogKiBDb3B5cmlnaHQgMjAwMC0yMDAxIFRyYW5zR2FtaW5nIFRlY2hub2xvZ2llcyBJbmMuCiAqIENvcHlyaWdodCAyMDAyLTIwMDUgSmFzb24gRWRtZWFkZXMKICogQ29weXJpZ2h0IDIwMDItMjAwMyBSYXBoYWVsIEp1bnF1ZWlyYQogKiBDb3B5cmlnaHQgMjAwNCBDaHJpc3RpYW4gQ29zdGEKICogQ29weXJpZ2h0IDIwMDUgT2xpdmVyIFN0aWViZXIKICogQ29weXJpZ2h0IDIwMDYgU3RlZmFuIET2c2luZ2VyIGZvciBDb2RlV2VhdmVycwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCiNpbmNsdWRlICJ3aW5lL3BvcnQuaCIKI2luY2x1ZGUgIndpbmVkM2RfcHJpdmF0ZS5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoZDNkX3N1cmZhY2UpOwojZGVmaW5lIEdMSU5GT19MT0NBVElPTiAoKElXaW5lRDNESW1wbCAqKSgoKElXaW5lRDNERGV2aWNlSW1wbCAqKVRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2UpLT53aW5lRDNEKSktPmdsX2luZm8KCnR5cGVkZWYgZW51bSB7CiAgICBOT19DT05WRVJTSU9OLAogICAgQ09OVkVSVF9QQUxFVFRFRCwKICAgIENPTlZFUlRfUEFMRVRURURfQ0ssCiAgICBDT05WRVJUX0NLXzU2NSwKICAgIENPTlZFUlRfQ0tfNTU1MSwKICAgIENPTlZFUlRfQ0tfNDQ0NCwKICAgIENPTlZFUlRfQ0tfNDQ0NF9BUkdCLAogICAgQ09OVkVSVF9DS18xNTU1LAogICAgQ09OVkVSVF81NTUsCiAgICBDT05WRVJUX0NLX1JHQjI0LAogICAgQ09OVkVSVF9DS184ODg4LAogICAgQ09OVkVSVF9DS184ODg4X0FSR0IsCiAgICBDT05WRVJUX1JHQjMyXzg4OAp9IENPTlZFUlRfVFlQRVM7CgpIUkVTVUxUIGQzZGZtdF9jb252ZXJ0X3N1cmZhY2UoQllURSAqc3JjLCBCWVRFICpkc3QsIFVJTlQgcGl0Y2gsIFVJTlQgaGVpZ2h0LCBVSU5UIG91dHBpdGNoLCBDT05WRVJUX1RZUEVTIGNvbnZlcnQsIElXaW5lRDNEU3VyZmFjZUltcGwgKnN1cmYpOwoKc3RhdGljIHZvaWQgc3VyZmFjZV9kb3dubG9hZF9kYXRhKElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMpIHsKICAgIGlmIChUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQxIHx8CiAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDIgfHwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMyB8fAogICAgICAgICAgICBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQ0IHx8IFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDUpIHsKICAgICAgICBpZiAoIUdMX1NVUFBPUlQoRVhUX1RFWFRVUkVfQ09NUFJFU1NJT05fUzNUQykpIHsgLyogV2UgY2FuIGFzc3VtZSB0aGlzIGFzIHRoZSB0ZXh0dXJlIHdvdWxkIG5vdCBoYXZlIGJlZW4gY3JlYXRlZCBvdGhlcndpc2UgKi8KICAgICAgICAgICAgRklYTUUoIiglcCkgOiBBdHRlbXB0aW5nIHRvIGxvY2sgYSBjb21wcmVzc2VkIHRleHR1cmUgd2hlbiB0ZXh0dXJlIGNvbXByZXNzaW9uIGlzbid0IHN1cHBvcnRlZCBieSBvcGVuZ2xcbiIsIFRoaXMpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIFRSQUNFKCIoJXApIDogQ2FsbGluZyBnbEdldENvbXByZXNzZWRUZXhJbWFnZUFSQiBsZXZlbCAlZCwgZm9ybWF0ICUjeCwgdHlwZSAlI3gsIGRhdGEgJXBcbiIsIFRoaXMsIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsCiAgICAgICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0LCBUaGlzLT5nbERlc2NyaXB0aW9uLmdsVHlwZSwgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKCiAgICAgICAgICAgIEVOVEVSX0dMKCk7CgogICAgICAgICAgICBHTF9FWFRDQUxMKGdsR2V0Q29tcHJlc3NlZFRleEltYWdlQVJCKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLCBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsR2V0Q29tcHJlc3NlZFRleEltYWdlQVJCKCkiKTsKCiAgICAgICAgICAgIExFQVZFX0dMKCk7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICBUUkFDRSgiKCVwKSA6IENhbGxpbmcgZ2xHZXRUZXhJbWFnZSBsZXZlbCAlZCwgZm9ybWF0ICUjeCwgdHlwZSAlI3gsIGRhdGEgJXBcbiIsIFRoaXMsIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsCiAgICAgICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0LCBUaGlzLT5nbERlc2NyaXB0aW9uLmdsVHlwZSwgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKCiAgICAgICAgRU5URVJfR0woKTsKCiAgICAgICAgZ2xHZXRUZXhJbWFnZShUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCwgVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCwgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdCwKICAgICAgICAgICAgICAgIFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xUeXBlLCBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEdldFRleEltYWdlKCkiKTsKCiAgICAgICAgTEVBVkVfR0woKTsKCiAgICAgICAgaWYgKHdpbmVkM2Rfc2V0dGluZ3Mubm9ucG93ZXIyX21vZGUgPT0gTlAyX1JFUEFDSykgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBTb21lIGdhbWVzIChlLmcuIHdhcmhhbW1lciA0MGspIGRvbid0IHdvcmsgcHJvcGVybHkgd2l0aCB0aGUgb2RkIHBpdGNoZXMsIHByZXZlbnRpbmcKICAgICAgICAgICAgICogdGhlIHN1cmZhY2UgcGl0Y2ggZnJvbSBiZWluZyB1c2VkIHRvIGJveCBub24tcG93ZXIyIHRleHR1cmVzLiBJbnN0ZWFkIHdlIGhhdmUgdG8gdXNlIGEgaGFjayB0bwogICAgICAgICAgICAgKiByZXBhY2sgdGhlIHRleHR1cmUgc28gdGhhdCB0aGUgYnBwICogd2lkdGggcGl0Y2ggY2FuIGJlIHVzZWQgaW5zdGVhZCBvZiBicHAgKiBwb3cyd2lkdGguCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIFdlJ3JlIGRvaW5nIHRoaXMuLi4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogaW5zdGVhZCBvZiBib3hpbmcgdGhlIHRleHR1cmUgOgogICAgICAgICAgICAgKiB8PC10ZXh0dXJlIHdpZHRoIC0+fCAgLS0+cG93MndpZHRofCAgIC9cCiAgICAgICAgICAgICAqIHwxMTExMTExMTExMTExMTExMTF8ICAgICAgICAgICAgICB8ICAgfAogICAgICAgICAgICAgKiB8MjIyIFRleHR1cmUgMjIyMjIyfCBib3hlZCBlbXB0eSAgfCB0ZXh0dXJlIGhlaWdodAogICAgICAgICAgICAgKiB8MzMzMyBEYXRhIDMzMzMzMzMzfCAgICAgICAgICAgICAgfCAgIHwKICAgICAgICAgICAgICogfDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NHwgICAgICAgICAgICAgIHwgICBcLwogICAgICAgICAgICAgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAgIHwKICAgICAgICAgICAgICogfCAgICAgYm94ZWQgIGVtcHR5IHwgYm94ZWQgZW1wdHkgIHwgcG93MmhlaWdodAogICAgICAgICAgICAgKiB8ICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgfCAgIFwvCiAgICAgICAgICAgICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIHdlJ3JlIHJlcGFja2luZyB0aGUgZGF0YSB0byB0aGUgZXhwZWN0ZWQgdGV4dHVyZSB3aWR0aAogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiB8PC10ZXh0dXJlIHdpZHRoIC0+fCAgLS0+cG93MndpZHRofCAgIC9cCiAgICAgICAgICAgICAqIHwxMTExMTExMTExMTExMTExMTEyMjIyMjIyMjIyMjIyMjJ8ICAgfAogICAgICAgICAgICAgKiB8MjIyMzMzMzMzMzMzMzMzMzMzMzMzNDQ0NDQ0NDQ0NDQ0fCB0ZXh0dXJlIGhlaWdodAogICAgICAgICAgICAgKiB8NDQ0NDQ0ICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgIHwKICAgICAgICAgICAgICogfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICBcLwogICAgICAgICAgICAgKiB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgIHwKICAgICAgICAgICAgICogfCAgICAgICAgICAgIGVtcHR5ICAgICAgICAgICAgICAgIHwgcG93MmhlaWdodAogICAgICAgICAgICAgKiB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgIFwvCiAgICAgICAgICAgICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqID09IGlzIHRoZSBzYW1lIGFzCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIHw8LXRleHR1cmUgd2lkdGggLT58ICAgIC9cCiAgICAgICAgICAgICAqIHwxMTExMTExMTExMTExMTExMTF8CiAgICAgICAgICAgICAqIHwyMjIyMjIyMjIyMjIyMjIyMjJ8dGV4dHVyZSBoZWlnaHQKICAgICAgICAgICAgICogfDMzMzMzMzMzMzMzMzMzMzMzM3wKICAgICAgICAgICAgICogfDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NHwgICAgXC8KICAgICAgICAgICAgICogLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogdGhpcyBhbHNvIG1lYW5zIHRoYXQgYW55IHJlZmVyZW5jZXMgdG8gYWxsb2NhdGVkTWVtb3J5IHNob3VsZCB3b3JrIHdpdGggdGhlIGRhdGEgYXMgaWYgd2VyZSBhCiAgICAgICAgICAgICAqIHN0YW5kYXJkIHRleHR1cmUgd2l0aCBhIG5vbi1wb3dlcjIgd2lkdGggaW5zdGVhZCBvZiB0ZXh0dXJlIGJveGVkIHVwIHRvIGJlIGEgcG93ZXIyIHRleHR1cmUuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIGludGVybmFsbHkgdGhlIHRleHR1cmUgaXMgc3RpbGwgc3RvcmVkIGluIGEgYm94ZWQgZm9ybWF0IHNvIGFueSByZWZlcmVuY2VzIHRvIHRleHR1cmVOYW1lIHdpbGwKICAgICAgICAgICAgICogZ2V0IGEgYm94ZWQgdGV4dHVyZSB3aXRoIHdpZHRoIHBvdzJ3aWR0aCBhbmQgbm90IGEgdGV4dHVyZSBvZiB3aWR0aCBjdXJyZW50RGVzYy5XaWR0aC4KICAgICAgICAgICAgICovCgogICAgICAgICAgICBpZiAoVGhpcy0+RmxhZ3MgJiBTRkxBR19OT05QT1cyKSB7CiAgICAgICAgICAgICAgICBMUEJZVEUgc3JjX2RhdGEsIGRzdF9kYXRhOwogICAgICAgICAgICAgICAgaW50IHNyY19waXRjaCA9IFRoaXMtPmJ5dGVzUGVyUGl4ZWwgKiBUaGlzLT5wb3cyV2lkdGg7CiAgICAgICAgICAgICAgICBpbnQgZHN0X3BpdGNoID0gVGhpcy0+Ynl0ZXNQZXJQaXhlbCAqIFRoaXMtPmN1cnJlbnREZXNjLldpZHRoOwogICAgICAgICAgICAgICAgaW50IHk7CgogICAgICAgICAgICAgICAgc3JjX2RhdGEgPSBkc3RfZGF0YSA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeTsKICAgICAgICAgICAgICAgIEZJWE1FKCIoJXApIDogUmVwYWNraW5nIHRoZSBzdXJmYWNlIGRhdGEgZnJvbSBwaXRjaCAlZCB0byBwaXRjaCAlZFxuIiwgVGhpcywgc3JjX3BpdGNoLCBkc3RfcGl0Y2gpOwogICAgICAgICAgICAgICAgZm9yICh5ID0gMSA7IHkgPCBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQ7IHkrKykgewogICAgICAgICAgICAgICAgICAgIC8qIHNraXAgdGhlIGZpcnN0IHJvdyAqLwogICAgICAgICAgICAgICAgICAgIHNyY19kYXRhICs9IHNyY19waXRjaDsKICAgICAgICAgICAgICAgICAgICBkc3RfZGF0YSArPSBkc3RfcGl0Y2g7CiAgICAgICAgICAgICAgICAgICAgbWVtY3B5KGRzdF9kYXRhLCBzcmNfZGF0YSwgZHN0X3BpdGNoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfQoKc3RhdGljIHZvaWQgc3VyZmFjZV91cGxvYWRfZGF0YShJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzLCBHTHNpemVpIHdpZHRoLCBHTHNpemVpIGhlaWdodCwgR0xlbnVtIGZvcm1hdCwgR0xlbnVtIHR5cGUsIGNvbnN0IEdMdm9pZCAqZGF0YSkgewogICAgaWYgKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDEgfHwKICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMiB8fCBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQzIHx8CiAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDQgfHwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNSkgewogICAgICAgIGlmICghR0xfU1VQUE9SVChFWFRfVEVYVFVSRV9DT01QUkVTU0lPTl9TM1RDKSkgewogICAgICAgICAgICBGSVhNRSgiVXNpbmcgRFhUMS8zLzUgd2l0aG91dCBhZHZlcnRpemVkIHN1cHBvcnRcbiIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIFRSQUNFKCIoJXApIDogQ2FsbGluZyBnbENvbXByZXNzZWRUZXhTdWJJbWFnZTJEIHcgJWQsIGggJWQsIGRhdGEgJXBcbiIsIFRoaXMsIHdpZHRoLCBoZWlnaHQsIGRhdGEpOwogICAgICAgICAgICBFTlRFUl9HTCgpOwogICAgICAgICAgICBHTF9FWFRDQUxMKGdsQ29tcHJlc3NlZFRleFN1YkltYWdlMkRBUkIoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsIDAsIDAsIHdpZHRoLCBoZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdEludGVybmFsLCBUaGlzLT5yZXNvdXJjZS5zaXplLCBkYXRhKSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbENvbXByZXNzZWRUZXhTdWJJbWFnZTJEIik7CiAgICAgICAgICAgIExFQVZFX0dMKCk7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICBUUkFDRSgiKCVwKSA6IENhbGxpbmcgZ2xUZXhTdWJJbWFnZTJEIHcgJWQsICBoICVkLCBkYXRhLCAlcFxuIiwgVGhpcywgd2lkdGgsIGhlaWdodCwgZGF0YSk7CiAgICAgICAgRU5URVJfR0woKTsKICAgICAgICBnbFRleFN1YkltYWdlMkQoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsIDAsIDAsIHdpZHRoLCBoZWlnaHQsIGZvcm1hdCwgdHlwZSwgZGF0YSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsVGV4U3ViSW1hZ2UyRCIpOwogICAgICAgIExFQVZFX0dMKCk7CiAgICB9Cn0KCnN0YXRpYyB2b2lkIHN1cmZhY2VfYWxsb2NhdGVfc3VyZmFjZShJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzLCBHTGVudW0gaW50ZXJuYWwsIEdMc2l6ZWkgd2lkdGgsIEdMc2l6ZWkgaGVpZ2h0LCBHTGVudW0gZm9ybWF0LCBHTGVudW0gdHlwZSkgewogICAgVFJBQ0UoIiglcCkgOiBDcmVhdGluZyBzdXJmYWNlICh0YXJnZXQgJSN4KSAgbGV2ZWwgJWQsIGQzZCBmb3JtYXQgJXMsIGludGVybmFsIGZvcm1hdCAlI3gsIHdpZHRoICVkLCBoZWlnaHQgJWQsIGdsIGZvcm1hdCAlI3gsIGdsIHR5cGU9JSN4XG4iLCBUaGlzLAogICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCwgVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCwgZGVidWdfZDNkZm9ybWF0KFRoaXMtPnJlc291cmNlLmZvcm1hdCksIGludGVybmFsLCB3aWR0aCwgaGVpZ2h0LCBmb3JtYXQsIHR5cGUpOwoKICAgIEVOVEVSX0dMKCk7CgogICAgZ2xUZXhJbWFnZTJEKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLCBpbnRlcm5hbCwgd2lkdGgsIGhlaWdodCwgMCwgZm9ybWF0LCB0eXBlLCBOVUxMKTsKICAgIGNoZWNrR0xjYWxsKCJnbFRleEltYWdlMkQiKTsKCiAgICBMRUFWRV9HTCgpOwp9CgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgIElXaW5lRDNEU3VyZmFjZSBJVW5rbm93biBwYXJ0cyBmb2xsb3cKICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqLwpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1F1ZXJ5SW50ZXJmYWNlKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIFJFRklJRCByaWlkLCBMUFZPSUQgKnBwb2JqKQp7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIC8qIFdhcm4gLGJ1dCBiZSBuaWNlIGFib3V0IHRoaW5ncyAqLwogICAgVFJBQ0UoIiglcCktPiglcywlcClcbiIsIFRoaXMsZGVidWdzdHJfZ3VpZChyaWlkKSxwcG9iaik7CiAgICBpZiAocmlpZCA9PSBOVUxMKSB7CiAgICAgICAgRVJSKCJQcm9iYWJseSBGSVhNRTogQ2FsbGluZyBxdWVyeSBpbnRlcmZhY2Ugd2l0aCBOVUxMIHJpaWRcbiIpOwogICAgfQogICAgaWYgKElzRXF1YWxHVUlEKHJpaWQsICZJSURfSVVua25vd24pCiAgICAgICAgfHwgSXNFcXVhbEdVSUQocmlpZCwgJklJRF9JV2luZUQzREJhc2UpCiAgICAgICAgfHwgSXNFcXVhbEdVSUQocmlpZCwgJklJRF9JV2luZUQzRFJlc291cmNlKQogICAgICAgIHx8IElzRXF1YWxHVUlEKHJpaWQsICZJSURfSVdpbmVEM0RTdXJmYWNlKSkgewogICAgICAgIElVbmtub3duX0FkZFJlZigoSVVua25vd24qKWlmYWNlKTsKICAgICAgICAqcHBvYmogPSBUaGlzOwogICAgICAgIHJldHVybiBTX09LOwogICAgfQogICAgKnBwb2JqID0gTlVMTDsKICAgIHJldHVybiBFX05PSU5URVJGQUNFOwp9CgpVTE9ORyBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9BZGRSZWYoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVzb3VyY2UucmVmKTsKICAgIFRSQUNFKCIoJXApIDogQWRkUmVmIGluY3JlYXNpbmcgZnJvbSAlZFxuIiwgVGhpcyxyZWYgLSAxKTsKICAgIHJldHVybiByZWY7Cn0KClVMT05HIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1JlbGVhc2UoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+cmVzb3VyY2UucmVmKTsKICAgIFRSQUNFKCIoJXApIDogUmVsZWFzaW5nIGZyb20gJWRcbiIsIFRoaXMsIHJlZiArIDEpOwogICAgaWYgKHJlZiA9PSAwKSB7CiAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsICpkZXZpY2UgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CiAgICAgICAgVFJBQ0UoIiglcCkgOiBjbGVhbmluZyB1cFxuIiwgVGhpcyk7CiAgICAgICAgaWYgKFRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUgIT0gMCkgeyAvKiByZWxlYXNlIHRoZSBvcGVuR0wgdGV4dHVyZS4uICovCiAgICAgICAgICAgIEVOVEVSX0dMKCk7CiAgICAgICAgICAgIFRSQUNFKCJEZWxldGluZyB0ZXh0dXJlICVkXG4iLCBUaGlzLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lKTsKICAgICAgICAgICAgZ2xEZWxldGVUZXh0dXJlcygxLCAmVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSk7CiAgICAgICAgICAgIExFQVZFX0dMKCk7CiAgICAgICAgfQoKICAgICAgICBpZihUaGlzLT5GbGFncyAmIFNGTEFHX0RJQlNFQ1RJT04pIHsKICAgICAgICAgICAgLyogUmVsZWFzZSB0aGUgREMgKi8KICAgICAgICAgICAgU2VsZWN0T2JqZWN0KFRoaXMtPmhEQywgVGhpcy0+ZGliLmhvbGRiaXRtYXApOwogICAgICAgICAgICBEZWxldGVEQyhUaGlzLT5oREMpOwogICAgICAgICAgICAvKiBSZWxlYXNlIHRoZSBESUIgc2VjdGlvbiAqLwogICAgICAgICAgICBEZWxldGVPYmplY3QoVGhpcy0+ZGliLkRJQnNlY3Rpb24pOwogICAgICAgICAgICBUaGlzLT5kaWIuYml0bWFwX2RhdGEgPSBOVUxMOwogICAgICAgICAgICBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgPSBOVUxMOwogICAgICAgIH0KICAgICAgICBpZihUaGlzLT5GbGFncyAmIFNGTEFHX1VTRVJQVFIpIElXaW5lRDNEU3VyZmFjZV9TZXRNZW0oaWZhY2UsIE5VTEwpOwoKICAgICAgICBJV2luZUQzRFJlc291cmNlSW1wbF9DbGVhblVwKChJV2luZUQzRFJlc291cmNlICopaWZhY2UpOwogICAgICAgIGlmKGlmYWNlID09IGRldmljZS0+ZGRyYXdfcHJpbWFyeSkKICAgICAgICAgICAgZGV2aWNlLT5kZHJhd19wcmltYXJ5ID0gTlVMTDsKCiAgICAgICAgVFJBQ0UoIiglcCkgUmVsZWFzZWRcbiIsIFRoaXMpOwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMpOwoKICAgIH0KICAgIHJldHVybiByZWY7Cn0KCi8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICAgSVdpbmVEM0RTdXJmYWNlIElXaW5lRDNEUmVzb3VyY2UgcGFydHMgZm9sbG93CiAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi8KSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXREZXZpY2UoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgSVdpbmVEM0REZXZpY2UqKiBwcERldmljZSkgewogICAgcmV0dXJuIElXaW5lRDNEUmVzb3VyY2VJbXBsX0dldERldmljZSgoSVdpbmVEM0RSZXNvdXJjZSAqKWlmYWNlLCBwcERldmljZSk7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0UHJpdmF0ZURhdGEoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgUkVGR1VJRCByZWZndWlkLCBDT05TVCB2b2lkKiBwRGF0YSwgRFdPUkQgU2l6ZU9mRGF0YSwgRFdPUkQgRmxhZ3MpIHsKICAgIHJldHVybiBJV2luZUQzRFJlc291cmNlSW1wbF9TZXRQcml2YXRlRGF0YSgoSVdpbmVEM0RSZXNvdXJjZSAqKWlmYWNlLCByZWZndWlkLCBwRGF0YSwgU2l6ZU9mRGF0YSwgRmxhZ3MpOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0dldFByaXZhdGVEYXRhKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIFJFRkdVSUQgcmVmZ3VpZCwgdm9pZCogcERhdGEsIERXT1JEKiBwU2l6ZU9mRGF0YSkgewogICAgcmV0dXJuIElXaW5lRDNEUmVzb3VyY2VJbXBsX0dldFByaXZhdGVEYXRhKChJV2luZUQzRFJlc291cmNlICopaWZhY2UsIHJlZmd1aWQsIHBEYXRhLCBwU2l6ZU9mRGF0YSk7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfRnJlZVByaXZhdGVEYXRhKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIFJFRkdVSUQgcmVmZ3VpZCkgewogICAgcmV0dXJuIElXaW5lRDNEUmVzb3VyY2VJbXBsX0ZyZWVQcml2YXRlRGF0YSgoSVdpbmVEM0RSZXNvdXJjZSAqKWlmYWNlLCByZWZndWlkKTsKfQoKRFdPUkQgICBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRQcmlvcml0eShJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBEV09SRCBQcmlvcml0eU5ldykgewogICAgcmV0dXJuIElXaW5lRDNEUmVzb3VyY2VJbXBsX1NldFByaW9yaXR5KChJV2luZUQzRFJlc291cmNlICopaWZhY2UsIFByaW9yaXR5TmV3KTsKfQoKRFdPUkQgICBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRQcmlvcml0eShJV2luZUQzRFN1cmZhY2UgKmlmYWNlKSB7CiAgICByZXR1cm4gSVdpbmVEM0RSZXNvdXJjZUltcGxfR2V0UHJpb3JpdHkoKElXaW5lRDNEUmVzb3VyY2UgKilpZmFjZSk7Cn0KCnZvaWQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfUHJlTG9hZChJV2luZUQzRFN1cmZhY2UgKmlmYWNlKSB7CiAgICAvKiBUT0RPOiByZS13cml0ZSB0aGUgd2F5IHRleHR1cmVzIGFuZCBtYW5hZ2VkLAogICAgKiAgdXNlIGEgJ29wZW5nbCBjb250ZXh0IG1hbmFnZXInIHRvIG1hbmFnZSBSZW5kZXJUYXJnZXQgc3VyZmFjZXMKICAgICoqICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICAvKiBUT0RPOiBjaGVjayBmb3IgbG9ja3MgKi8KICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RCYXNlVGV4dHVyZSAqYmFzZVRleHR1cmUgPSBOVUxMOwogICAgVFJBQ0UoIiglcClDaGVja2luZyB0byBzZWUgaWYgdGhlIGNvbnRhaW5lciBpcyBhIGJhc2UgdGV4dHVyZVxuIiwgVGhpcyk7CiAgICBpZiAoSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lcihpZmFjZSwgJklJRF9JV2luZUQzREJhc2VUZXh0dXJlLCAodm9pZCAqKikmYmFzZVRleHR1cmUpID09IFdJTkVEM0RfT0spIHsKICAgICAgICBUUkFDRSgiUGFzc2luZyB0byBjb25hdGluZXJcbiIpOwogICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVfUHJlTG9hZChiYXNlVGV4dHVyZSk7CiAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9SZWxlYXNlKGJhc2VUZXh0dXJlKTsKICAgIH0gZWxzZSB7CiAgICBUUkFDRSgiKCVwKSA6IEFib3V0IHRvIGxvYWQgc3VyZmFjZVxuIiwgVGhpcyk7CiAgICBFTlRFUl9HTCgpOwojaWYgMCAvKiBUT0RPOiBjb250ZXh0IG1hbmFnZXIgc3VwcG9ydCAqLwogICAgIElXaW5lRDNEQ29udGV4dE1hbmFnZXJfUHVzaFN0YXRlKFRoaXMtPmNvbnRleHRNYW5hZ2VyLCBHTF9URVhUVVJFXzJELCBFTkFCTEVELCBOT1cgLyogbWFrZSBzdXJlIHRoZSBzdGF0ZSBpcyBhcHBsaWVkIG5vdyAqLyk7CiNlbmRpZgogICAgZ2xFbmFibGUoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQpOy8qIG1ha2Ugc3VyZSB0ZXh0dXJlIHN1cHBvcnQgaXMgZW5hYmxlZCBpbiB0aGlzIGNvbnRleHQgKi8KICAgIGlmICghVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCkgewogICAgICAgIGlmICghVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSkgewogICAgICAgICAgICBnbEdlblRleHR1cmVzKDEsICZUaGlzLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsR2VuVGV4dHVyZXMiKTsKICAgICAgICAgICAgVFJBQ0UoIlN1cmZhY2UgJXAgZ2l2ZW4gbmFtZSAlZFxuIiwgVGhpcywgVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSk7CiAgICAgICAgfQogICAgICAgIGdsQmluZFRleHR1cmUoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsIFRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRUZXh0dXJlIik7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0xvYWRUZXh0dXJlKGlmYWNlKTsKICAgICAgICAvKiBUaGlzIGlzIHdoZXJlIHdlIHNob3VsZCBiZSByZWR1Y2luZyB0aGUgYW1vdW50IG9mIEdMTWVtb3J5VXNlZCAqLwogICAgfSBlbHNlIGlmIChUaGlzLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lKSB7IC8qIE5PVEU6IHRoZSBsZXZlbCAwIHN1cmZhY2Ugb2YgYSBtcG1hcHBlZCB0ZXh0dXJlIG11c3QgYmUgbG9hZGVkIGZpcnN0ISAqLwogICAgICAgIC8qIGFzc3VtZSB0aGlzIGlzIGEgY29kaW5nIGVycm9yIG5vdCBhIHJlYWwgZXJyb3IgZm9yIG5vdyAqLwogICAgICAgIEZJWE1FKCJNaXBtYXAgc3VyZmFjZSBoYXMgYSBnbFRleHR1cmUgYm91bmQgdG8gaXQhXG4iKTsKICAgIH0KICAgIGlmIChUaGlzLT5yZXNvdXJjZS5wb29sID09IFdJTkVEM0RQT09MX0RFRkFVTFQpIHsKICAgICAgIC8qIFRlbGwgb3BlbmdsIHRvIHRyeSBhbmQga2VlcCB0aGlzIHRleHR1cmUgaW4gdmlkZW8gcmFtICh3ZWxsIG1vc3RseSkgKi8KICAgICAgIEdMY2xhbXBmIHRtcDsKICAgICAgIHRtcCA9IDAuOWY7CiAgICAgICAgZ2xQcmlvcml0aXplVGV4dHVyZXMoMSwgJlRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUsICZ0bXApOwogICAgfQogICAgLyogVE9ETzogZGlzYWJsZSB0ZXh0dXJlIHN1cHBvcnQsIGlmIGl0IHdhc3RuJ3QgZW5hYmxlZCB3aGVuIHdlIGVudGVyZWQuICovCiNpZiAwIC8qIFRPRE86IGNvbnRleHQgbWFuYWdlciBzdXBwb3J0ICovCiAgICAgSVdpbmVEM0RDb250ZXh0TWFuYWdlcl9Qb3BTdGF0ZShUaGlzLT5jb250ZXh0TWFuYWdlciwgR0xfVEVYVFVSRV8yRCwgRElTQUJMRUQsREVMQVlFRAogICAgICAgICAgICAgIC8qIHdlIGRvbid0IGNhcmUgd2hlbiB0aGUgc3RhdGUgaXMgZGlzYWJsZWQoaWYgYXRhbGwpICovKTsKI2VuZGlmCiAgICBMRUFWRV9HTCgpOwogICAgfQogICAgcmV0dXJuOwp9CgpXSU5FRDNEUkVTT1VSQ0VUWVBFIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0dldFR5cGUoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgVFJBQ0UoIiglcCkgOiBjYWxsaW5nIHJlc291cmNlaW1wbF9HZXRUeXBlXG4iLCBpZmFjZSk7CiAgICByZXR1cm4gSVdpbmVEM0RSZXNvdXJjZUltcGxfR2V0VHlwZSgoSVdpbmVEM0RSZXNvdXJjZSAqKWlmYWNlKTsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRQYXJlbnQoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgSVVua25vd24gKipwUGFyZW50KSB7CiAgICBUUkFDRSgiKCVwKSA6IGNhbGxpbmcgcmVzb3VyY2VpbXBsX0dldFBhcmVudFxuIiwgaWZhY2UpOwogICAgcmV0dXJuIElXaW5lRDNEUmVzb3VyY2VJbXBsX0dldFBhcmVudCgoSVdpbmVEM0RSZXNvdXJjZSAqKWlmYWNlLCBwUGFyZW50KTsKfQoKLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgIElXaW5lRDNEU3VyZmFjZSBJV2luZUQzRFN1cmZhY2UgcGFydHMgZm9sbG93CiAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqLwoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRDb250YWluZXJQYXJlbnQoSVdpbmVEM0RTdXJmYWNlKiBpZmFjZSwgSVVua25vd24gKipwcENvbnRhaW5lclBhcmVudCkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CgogICAgVFJBQ0UoIiglcCkgOiBwcENvbnRhaW5lclBhcmVudCAlcClcbiIsIFRoaXMsIHBwQ29udGFpbmVyUGFyZW50KTsKCiAgICBpZiAoIXBwQ29udGFpbmVyUGFyZW50KSB7CiAgICAgICAgRVJSKCIoJXApIDogQ2FsbGVkIHdpdGhvdXQgYSB2YWxpZCBwcENvbnRhaW5lclBhcmVudC5cbiIsIFRoaXMpOwogICAgfQoKICAgIGlmIChUaGlzLT5jb250YWluZXIpIHsKICAgICAgICBJV2luZUQzREJhc2VfR2V0UGFyZW50KFRoaXMtPmNvbnRhaW5lciwgcHBDb250YWluZXJQYXJlbnQpOwogICAgICAgIGlmICghcHBDb250YWluZXJQYXJlbnQpIHsKICAgICAgICAgICAgLyogV2luZUQzRCBvYmplY3RzIHNob3VsZCBhbHdheXMgaGF2ZSBhIHBhcmVudCAqLwogICAgICAgICAgICBFUlIoIiglcCkgOiBHZXRQYXJlbnQgcmV0dXJuZWQgTlVMTFxuIiwgVGhpcyk7CiAgICAgICAgfQogICAgICAgIElVbmtub3duX1JlbGVhc2UoKnBwQ29udGFpbmVyUGFyZW50KTsgLyogR2V0UGFyZW50IGFkZHMgYSByZWZlcmVuY2U7IHdlIHdhbnQganVzdCB0aGUgcG9pbnRlciAqLwogICAgfSBlbHNlIHsKICAgICAgICAqcHBDb250YWluZXJQYXJlbnQgPSBOVUxMOwogICAgfQoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0dldENvbnRhaW5lcihJV2luZUQzRFN1cmZhY2UqIGlmYWNlLCBSRUZJSUQgcmlpZCwgdm9pZCoqIHBwQ29udGFpbmVyKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEQmFzZSAqY29udGFpbmVyID0gMDsKCiAgICBUUkFDRSgiKFRoaXMgJXAsIHJpaWQgJXMsIHBwQ29udGFpbmVyICVwKVxuIiwgVGhpcywgZGVidWdzdHJfZ3VpZChyaWlkKSwgcHBDb250YWluZXIpOwoKICAgIGlmICghcHBDb250YWluZXIpIHsKICAgICAgICBFUlIoIkNhbGxlZCB3aXRob3V0IGEgdmFsaWQgcHBDb250YWluZXIuXG4iKTsKICAgIH0KCiAgICAvKiogRnJvbSBNU0ROOgogICAgICogSWYgdGhlIHN1cmZhY2UgaXMgY3JlYXRlZCB1c2luZyBDcmVhdGVJbWFnZVN1cmZhY2UvQ3JlYXRlT2Zmc2NyZWVuUGxhaW5TdXJmYWNlLCBDcmVhdGVSZW5kZXJUYXJnZXQsCiAgICAgKiBvciBDcmVhdGVEZXB0aFN0ZW5jaWxTdXJmYWNlLCB0aGUgc3VyZmFjZSBpcyBjb25zaWRlcmVkIHN0YW5kIGFsb25lLiBJbiB0aGlzIGNhc2UsCiAgICAgKiBHZXRDb250YWluZXIgd2lsbCByZXR1cm4gdGhlIERpcmVjdDNEIGRldmljZSB1c2VkIHRvIGNyZWF0ZSB0aGUgc3VyZmFjZS4KICAgICAqLwogICAgaWYgKFRoaXMtPmNvbnRhaW5lcikgewogICAgICAgIGNvbnRhaW5lciA9IFRoaXMtPmNvbnRhaW5lcjsKICAgIH0gZWxzZSB7CiAgICAgICAgY29udGFpbmVyID0gKElXaW5lRDNEQmFzZSAqKVRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CiAgICB9CgogICAgVFJBQ0UoIlJlbGF5aW5nIHRvIFF1ZXJ5SW50ZXJmYWNlXG4iKTsKICAgIHJldHVybiBJVW5rbm93bl9RdWVyeUludGVyZmFjZShjb250YWluZXIsIHJpaWQsIHBwQ29udGFpbmVyKTsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXREZXNjKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIFdJTkVEM0RTVVJGQUNFX0RFU0MgKnBEZXNjKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKCiAgICBUUkFDRSgiKCVwKSA6IGNvcHlpbmcgaW50byAlcFxuIiwgVGhpcywgcERlc2MpOwogICAgaWYocERlc2MtPkZvcm1hdCAhPSBOVUxMKSAgICAgICAgICAgICAqKHBEZXNjLT5Gb3JtYXQpID0gVGhpcy0+cmVzb3VyY2UuZm9ybWF0OwogICAgaWYocERlc2MtPlR5cGUgIT0gTlVMTCkgICAgICAgICAgICAgICAqKHBEZXNjLT5UeXBlKSAgID0gVGhpcy0+cmVzb3VyY2UucmVzb3VyY2VUeXBlOwogICAgaWYocERlc2MtPlVzYWdlICE9IE5VTEwpICAgICAgICAgICAgICAqKHBEZXNjLT5Vc2FnZSkgICAgICAgICAgICAgID0gVGhpcy0+cmVzb3VyY2UudXNhZ2U7CiAgICBpZihwRGVzYy0+UG9vbCAhPSBOVUxMKSAgICAgICAgICAgICAgICoocERlc2MtPlBvb2wpICAgICAgICAgICAgICAgPSBUaGlzLT5yZXNvdXJjZS5wb29sOwogICAgaWYocERlc2MtPlNpemUgIT0gTlVMTCkgICAgICAgICAgICAgICAqKHBEZXNjLT5TaXplKSAgICAgICAgICAgICAgID0gVGhpcy0+cmVzb3VyY2Uuc2l6ZTsgICAvKiBkeDggb25seSAqLwogICAgaWYocERlc2MtPk11bHRpU2FtcGxlVHlwZSAhPSBOVUxMKSAgICAqKHBEZXNjLT5NdWx0aVNhbXBsZVR5cGUpICAgID0gVGhpcy0+Y3VycmVudERlc2MuTXVsdGlTYW1wbGVUeXBlOwogICAgaWYocERlc2MtPk11bHRpU2FtcGxlUXVhbGl0eSAhPSBOVUxMKSAqKHBEZXNjLT5NdWx0aVNhbXBsZVF1YWxpdHkpID0gVGhpcy0+Y3VycmVudERlc2MuTXVsdGlTYW1wbGVRdWFsaXR5OwogICAgaWYocERlc2MtPldpZHRoICE9IE5VTEwpICAgICAgICAgICAgICAqKHBEZXNjLT5XaWR0aCkgICAgICAgICAgICAgID0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICBpZihwRGVzYy0+SGVpZ2h0ICE9IE5VTEwpICAgICAgICAgICAgICoocERlc2MtPkhlaWdodCkgICAgICAgICAgICAgPSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKdm9pZCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRHbFRleHR1cmVEZXNjKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIFVJTlQgdGV4dHVyZU5hbWUsIGludCB0YXJnZXQpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCkgOiBzZXR0aW5nIHRleHR1cmVOYW1lICV1LCB0YXJnZXQgJWlcbiIsIFRoaXMsIHRleHR1cmVOYW1lLCB0YXJnZXQpOwogICAgaWYgKFRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUgPT0gMCAmJiB0ZXh0dXJlTmFtZSAhPSAwKSB7CiAgICAgICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfRElSVFk7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0FkZERpcnR5UmVjdChpZmFjZSwgTlVMTCk7CiAgICB9CiAgICBUaGlzLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lID0gdGV4dHVyZU5hbWU7CiAgICBUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCAgICAgID0gdGFyZ2V0Owp9Cgp2b2lkIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0dldEdsRGVzYyhJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBnbERlc2NyaXB0b3IgKipnbERlc2NyaXB0aW9uKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIFRSQUNFKCIoJXApIDogcmV0dXJuaW5nICVwXG4iLCBUaGlzLCAmVGhpcy0+Z2xEZXNjcmlwdGlvbik7CiAgICAqZ2xEZXNjcmlwdGlvbiA9ICZUaGlzLT5nbERlc2NyaXB0aW9uOwp9CgovKiBUT0RPOiB0aGluayBhYm91dCBtb3ZpbmcgdGhpcyBkb3duIHRvIHJlc291cmNlPyAqLwpjb25zdCB2b2lkICpXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXREYXRhKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgLyogVGhpcyBzaG91bGQgb25seSBiZSBjYWxsZWQgZm9yIHN5c21lbSB0ZXh0dXJlcywgaXQgbWF5IGJlIGEgZ29vZCBpZGVhIHRvIGV4dGVuZCB0aGlzIHRvIGFsbCBwb29scyBhdCBzb21lIHBvaW50IGluIHRoZSBmdXR0dXJlICAqLwogICAgaWYgKFRoaXMtPnJlc291cmNlLnBvb2wgIT0gV0lORUQzRFBPT0xfU1lTVEVNTUVNKSB7CiAgICAgICAgRklYTUUoIiAoJXApQXR0ZW1wdGluZyB0byBnZXQgc3lzdGVtIG1lbW9yeSBmb3IgYSBub24tc3lzdGVtIG1lbW9yeSB0ZXh0dXJlXG4iLCBpZmFjZSk7CiAgICB9CiAgICByZXR1cm4gKENPTlNUIHZvaWQqKShUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpOwp9CgpzdGF0aWMgdm9pZCByZWFkX2Zyb21fZnJhbWVidWZmZXIoSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcywgQ09OU1QgUkVDVCAqcmVjdCwgdm9pZCAqZGVzdCwgVUlOVCBwaXRjaCkgewogICAgbG9uZyBqOwogICAgdm9pZCAqbWVtOwogICAgR0xpbnQgZm10OwogICAgR0xpbnQgdHlwZTsKCiAgICBzd2l0Y2goVGhpcy0+cmVzb3VyY2UuZm9ybWF0KQogICAgewogICAgICAgIGNhc2UgV0lORUQzREZNVF9QODoKICAgICAgICB7CiAgICAgICAgICAgIC8qIEdMIGNhbid0IHJldHVybiBwYWxldHRpemVkIGRhdGEsIHNvIHJlYWQgQVJHQiBwaXhlbHMgaW50byBhCiAgICAgICAgICAgICAqIHNlcGFyYXRlIGJsb2NrIG9mIG1lbW9yeSBhbmQgY29udmVydCB0aGVtIGludG8gcGFsZXR0aXplZCBmb3JtYXQKICAgICAgICAgICAgICogaW4gc29mdHdhcmUuIFNsb3csIGJ1dCBpZiB0aGUgYXBwIG1lYW5zIHRvIHVzZSBwYWxldHRpemVkIHJlbmRlcgogICAgICAgICAgICAgKiB0YXJnZXRzIGFuZCBsb2NrcyBpdC4uLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBVc2UgR0xfUkdCLCBHTF9VTlNJR05FRF9CWVRFIHRvIHJlYWQgdGhlIHN1cmZhY2UgZm9yIHBlcmZvcm1hbmNlIHJlYXNvbnMKICAgICAgICAgICAgICogRG9uJ3QgdXNlIEdMX0JHUiBhcyBpbiB0aGUgV0lORUQzREZNVF9SOEc4QjggY2FzZSwgaW5zdGVhZCB3YXRjaCBvdXQKICAgICAgICAgICAgICogZm9yIHRoZSBjb2xvciBjaGFubmVscyB3aGVuIHBhbGV0dGl6aW5nIHRoZSBjb2xvcnMuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBmbXQgPSBHTF9SR0I7CiAgICAgICAgICAgIHR5cGUgPSBHTF9VTlNJR05FRF9CWVRFOwogICAgICAgICAgICBwaXRjaCAqPSAzOwogICAgICAgICAgICBtZW0gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgKHJlY3QtPmJvdHRvbSAtIHJlY3QtPnRvcCkgKiBwaXRjaCk7CiAgICAgICAgICAgIGlmKCFtZW0pIHsKICAgICAgICAgICAgICAgIEVSUigiT3V0IG9mIG1lbW9yeVxuIik7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIG1lbSA9IGRlc3Q7CiAgICAgICAgICAgIGZtdCA9IFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xGb3JtYXQ7CiAgICAgICAgICAgIHR5cGUgPSBUaGlzLT5nbERlc2NyaXB0aW9uLmdsVHlwZTsKICAgIH0KCiAgICBpZiAocmVjdC0+bGVmdCA9PSAwICYmCiAgICAgICAgcmVjdC0+cmlnaHQgPT0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGggKSB7CiAgICAgICAgQllURSAqcm93LCAqdG9wLCAqYm90dG9tOwogICAgICAgIGludCBpOwoKICAgICAgICBnbFJlYWRQaXhlbHMoMCwgcmVjdC0+dG9wLAogICAgICAgICAgICAgICAgICAgICBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCwKICAgICAgICAgICAgICAgICAgICAgcmVjdC0+Ym90dG9tIC0gcmVjdC0+dG9wLAogICAgICAgICAgICAgICAgICAgICBmbXQsCiAgICAgICAgICAgICAgICAgICAgIHR5cGUsCiAgICAgICAgICAgICAgICAgICAgIG1lbSk7CgogICAgICAgLyogZ2xSZWFkUGl4ZWxzIHJldHVybnMgdGhlIGltYWdlIHVwc2lkZSBkb3duLCBhbmQgdGhlcmUgaXMgbm8gd2F5IHRvIHByZXZlbnQgdGhpcy4KICAgICAgICAgIEZsaXAgdGhlIGxpbmVzIGluIHNvZnR3YXJlICovCiAgICAgICAgcm93ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHBpdGNoKTsKICAgICAgICBpZighcm93KSB7CiAgICAgICAgICAgIEVSUigiT3V0IG9mIG1lbW9yeVxuIik7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgdG9wID0gbWVtOwogICAgICAgIGJvdHRvbSA9ICgoQllURSAqKSBtZW0pICsgcGl0Y2ggKiAoIHJlY3QtPmJvdHRvbSAtIHJlY3QtPnRvcCAtIDEpOwogICAgICAgIGZvcihpID0gMDsgaSA8IChyZWN0LT5ib3R0b20gLSByZWN0LT50b3ApIC8gMjsgaSsrKSB7CiAgICAgICAgICAgIG1lbWNweShyb3csIHRvcCwgcGl0Y2gpOwogICAgICAgICAgICBtZW1jcHkodG9wLCBib3R0b20sIHBpdGNoKTsKICAgICAgICAgICAgbWVtY3B5KGJvdHRvbSwgcm93LCBwaXRjaCk7CiAgICAgICAgICAgIHRvcCArPSBwaXRjaDsKICAgICAgICAgICAgYm90dG9tIC09IHBpdGNoOwogICAgICAgIH0KICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCByb3cpOwoKICAgICAgICBpZihUaGlzLT5sb2NrZWRSZWN0LnRvcCA9PSAwICYmIFRoaXMtPmxvY2tlZFJlY3QuYm90dG9tID09ICBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQpIHsKICAgICAgICAgICAgVGhpcy0+RmxhZ3MgJj0gflNGTEFHX0dMRElSVFk7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICBmb3IgKGogPSBUaGlzLT5sb2NrZWRSZWN0LnRvcDsgaiA8IFRoaXMtPmxvY2tlZFJlY3QuYm90dG9tIC0gVGhpcy0+bG9ja2VkUmVjdC50b3A7ICsraikgewogICAgICAgICAgICBnbFJlYWRQaXhlbHMocmVjdC0+bGVmdCwKICAgICAgICAgICAgICAgICAgICAgICAgIHJlY3QtPmJvdHRvbSAtIGogLSAxLAogICAgICAgICAgICAgICAgICAgICAgICAgcmVjdC0+cmlnaHQgLSByZWN0LT5sZWZ0LAogICAgICAgICAgICAgICAgICAgICAgICAgMSwKICAgICAgICAgICAgICAgICAgICAgICAgIGZtdCwKICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAoY2hhciAqKW1lbSArIChwaXRjaCAqIChqLXJlY3QtPnRvcCkpKTsKICAgICAgICB9CiAgICB9CgogICAgdmNoZWNrR0xjYWxsKCJnbFJlYWRQaXhlbHMiKTsKCiAgICBpZihUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9QOCkgewogICAgICAgIFBBTEVUVEVFTlRSWSAqcGFsOwogICAgICAgIERXT1JEIHdpZHRoID0gcGl0Y2ggLyAzOwogICAgICAgIGludCB4LCB5LCBjOwogICAgICAgIGlmKFRoaXMtPnBhbGV0dGUpIHsKICAgICAgICAgICAgcGFsID0gVGhpcy0+cGFsZXR0ZS0+cGFsZW50czsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBwYWwgPSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlLT5wYWxldHRlc1tUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlLT5jdXJyZW50UGFsZXR0ZV07CiAgICAgICAgfQoKICAgICAgICBmb3IoeSA9IHJlY3QtPnRvcDsgeSA8IHJlY3QtPmJvdHRvbTsgeSsrKSB7CiAgICAgICAgICAgIGZvcih4ID0gcmVjdC0+bGVmdDsgeCA8IHJlY3QtPnJpZ2h0OyB4KyspIHsKICAgICAgICAgICAgICAgIC8qICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0ICAgICAgICAgICAgICBsaW5lcyAgICAgICAgICAgIHBpeGVscyAgICAgICovCiAgICAgICAgICAgICAgICBCWVRFICpibHVlID0gIChCWVRFICopICgoQllURSAqKSBtZW0pICsgeSAqIHBpdGNoICsgeCAqIChzaXplb2YoQllURSkgKiAzKTsKICAgICAgICAgICAgICAgIEJZVEUgKmdyZWVuID0gYmx1ZSAgKyAxOwogICAgICAgICAgICAgICAgQllURSAqcmVkID0gICBncmVlbiArIDE7CgogICAgICAgICAgICAgICAgZm9yKGMgPSAwOyBjIDwgMjU2OyBjKyspIHsKICAgICAgICAgICAgICAgICAgICBpZigqcmVkICAgPT0gcGFsW2NdLnBlUmVkICAgJiYKICAgICAgICAgICAgICAgICAgICAgICAqZ3JlZW4gPT0gcGFsW2NdLnBlR3JlZW4gJiYKICAgICAgICAgICAgICAgICAgICAgICAqYmx1ZSAgPT0gcGFsW2NdLnBlQmx1ZSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICooKEJZVEUgKikgZGVzdCArIHkgKiB3aWR0aCArIHgpID0gYzsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG1lbSk7CiAgICB9Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0xvY2tSZWN0KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIFdJTkVEM0RMT0NLRURfUkVDVCogcExvY2tlZFJlY3QsIENPTlNUIFJFQ1QqIHBSZWN0LCBEV09SRCBGbGFncykgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRERldmljZUltcGwgICpteURldmljZSA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CiAgICBJV2luZUQzRFN3YXBDaGFpbkltcGwgKnN3YXBjaGFpbiA9IE5VTEw7CiAgICBzdGF0aWMgVUlOVCBtZXNzYWdlcyA9IDA7IC8qIGhvbGRzIGZsYWdzIHRvIGRpc2FibGUgZml4bWUgbWVzc2FnZXMgKi8KICAgIEJPT0wgYmFja2J1ZiA9IEZBTFNFOwoKICAgIC8qIGZpeG1lOiBzaG91bGQgd2UgcmVhbGx5IGxvY2sgYXMgc3VjaD8gKi8KICAgIGlmKChUaGlzLT5GbGFncyAmIChTRkxBR19JTlRFWFRVUkUgfCBTRkxBR19JTlBCVUZGRVIpKSA9PQogICAgICAgICAgICAgICAgICAgICAgKFNGTEFHX0lOVEVYVFVSRSB8IFNGTEFHX0lOUEJVRkZFUikgKSB7CiAgICAgICAgRklYTUUoIldhcm5pbmc6IFN1cmZhY2UgaXMgaW4gdGV4dHVyZSBtZW1vcnkgb3IgcGJ1ZmZlclxuIik7CiAgICAgICAgVGhpcy0+RmxhZ3MgJj0gfihTRkxBR19JTlRFWFRVUkUgfCBTRkxBR19JTlBCVUZGRVIpOwogICAgfQoKICAgIGlmICghKFRoaXMtPkZsYWdzICYgU0ZMQUdfTE9DS0FCTEUpKSB7CiAgICAgICAgLyogTm90ZTogVXBkYXRlVGV4dHVyZXMgY2FsbHMgQ29weVJlY3RzIHdoaWNoIGNhbGxzIHRoaXMgcm91dGluZSB0byBwb3B1bGF0ZSB0aGUKICAgICAgICAgICAgICB0ZXh0dXJlIHJlZ2lvbnMsIGFuZCBzaW5jZSB0aGUgZGVzdGluYXRpb24gaXMgYW4gdW5sb2NrYWJsZSByZWdpb24gd2UgbmVlZAogICAgICAgICAgICAgIHRvIHRvbGVyYXRlIHRoaXMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgVFJBQ0UoIldhcm5pbmc6IHRyeWluZyB0byBsb2NrIHVubG9ja2FibGUgc3VyZkAlcFxuIiwgVGhpcyk7CiAgICAgICAgLypyZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsgKi8KICAgIH0KCiAgICBpZiAoVGhpcy0+cmVzb3VyY2UudXNhZ2UgJiBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUKSB7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lcihpZmFjZSwgJklJRF9JV2luZUQzRFN3YXBDaGFpbiwgKHZvaWQgKiopJnN3YXBjaGFpbik7CgogICAgICAgIGlmIChzd2FwY2hhaW4gIT0gTlVMTCB8fCAgaWZhY2UgPT0gbXlEZXZpY2UtPnJlbmRlclRhcmdldCB8fCBpZmFjZSA9PSBteURldmljZS0+ZGVwdGhTdGVuY2lsQnVmZmVyKSB7CiAgICAgICAgICAgIGlmKHN3YXBjaGFpbiAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICBpbnQgaTsKICAgICAgICAgICAgICAgIGZvcihpID0gMDsgaSA8IHN3YXBjaGFpbi0+cHJlc2VudFBhcm1zLkJhY2tCdWZmZXJDb3VudDsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgaWYoaWZhY2UgPT0gc3dhcGNoYWluLT5iYWNrQnVmZmVyW2ldKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJhY2tidWYgPSBUUlVFOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGJhY2tidWYpIHsKICAgICAgICAgICAgICAgIFRSQUNFKCIoJXAsIGJhY2tCdWZmZXIpIDogcmVjdEAlcCBmbGFncyglMDh4KSwgb3V0cHV0IGxvY2tlZFJlY3RAJXAsIG1lbW9yeUAlcFxuIiwgVGhpcywgcFJlY3QsIEZsYWdzLCBwTG9ja2VkUmVjdCwgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKICAgICAgICAgICAgfSBlbHNlIGlmIChzd2FwY2hhaW4gIT0gTlVMTCAmJiBpZmFjZSA9PSAgc3dhcGNoYWluLT5mcm9udEJ1ZmZlcikgewogICAgICAgICAgICAgICAgVFJBQ0UoIiglcCwgZnJvbnRCdWZmZXIpIDogcmVjdEAlcCBmbGFncyglMDh4KSwgb3V0cHV0IGxvY2tlZFJlY3RAJXAsIG1lbW9yeUAlcFxuIiwgVGhpcywgcFJlY3QsIEZsYWdzLCBwTG9ja2VkUmVjdCwgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKICAgICAgICAgICAgfSBlbHNlIGlmIChpZmFjZSA9PSBteURldmljZS0+cmVuZGVyVGFyZ2V0KSB7CiAgICAgICAgICAgICAgICBUUkFDRSgiKCVwLCByZW5kZXJUYXJnZXQpIDogcmVjdEAlcCBmbGFncyglMDh4KSwgb3V0cHV0IGxvY2tlZFJlY3RAJXAsIG1lbW9yeUAlcFxuIiwgVGhpcywgcFJlY3QsIEZsYWdzLCBwTG9ja2VkUmVjdCwgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKICAgICAgICAgICAgfSBlbHNlIGlmIChpZmFjZSA9PSBteURldmljZS0+ZGVwdGhTdGVuY2lsQnVmZmVyKSB7CiAgICAgICAgICAgICAgICBUUkFDRSgiKCVwLCBzdGVuY2lsQnVmZmVyKSA6IHJlY3RAJXAgZmxhZ3MoJTA4eCksIG91dHB1dCBsb2NrZWRSZWN0QCVwLCBtZW1vcnlAJXBcbiIsIFRoaXMsIHBSZWN0LCBGbGFncywgcExvY2tlZFJlY3QsIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChOVUxMICE9IHN3YXBjaGFpbikgewogICAgICAgICAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZSgoSVdpbmVEM0RTd2FwQ2hhaW4gKilzd2FwY2hhaW4pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHN3YXBjaGFpbiA9IE5VTEw7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICBUUkFDRSgiKCVwKSA6IHJlY3RAJXAgZmxhZ3MoJTA4eCksIG91dHB1dCBsb2NrZWRSZWN0QCVwLCBtZW1vcnlAJXBcbiIsIFRoaXMsIHBSZWN0LCBGbGFncywgcExvY2tlZFJlY3QsIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSk7CiAgICB9CgogICAgcExvY2tlZFJlY3QtPlBpdGNoID0gSVdpbmVEM0RTdXJmYWNlX0dldFBpdGNoKGlmYWNlKTsKCiAgICBpZiAoTlVMTCA9PSBwUmVjdCkgewogICAgICAgIHBMb2NrZWRSZWN0LT5wQml0cyA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeTsKICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LmxlZnQgICA9IDA7CiAgICAgICAgVGhpcy0+bG9ja2VkUmVjdC50b3AgICAgPSAwOwogICAgICAgIFRoaXMtPmxvY2tlZFJlY3QucmlnaHQgID0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAgICAgVGhpcy0+bG9ja2VkUmVjdC5ib3R0b20gPSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICAgICAgVFJBQ0UoIkxvY2tlZCBSZWN0ICglcCkgPSBsICVkLCB0ICVkLCByICVkLCBiICVkXG4iLCAmVGhpcy0+bG9ja2VkUmVjdCwgVGhpcy0+bG9ja2VkUmVjdC5sZWZ0LCBUaGlzLT5sb2NrZWRSZWN0LnRvcCwgVGhpcy0+bG9ja2VkUmVjdC5yaWdodCwgVGhpcy0+bG9ja2VkUmVjdC5ib3R0b20pOwogICAgfSBlbHNlIHsKICAgICAgICBUUkFDRSgiTG9jayBSZWN0ICglcCkgPSBsICVkLCB0ICVkLCByICVkLCBiICVkXG4iLCBwUmVjdCwgcFJlY3QtPmxlZnQsIHBSZWN0LT50b3AsIHBSZWN0LT5yaWdodCwgcFJlY3QtPmJvdHRvbSk7CgogICAgICAgIGlmICgocFJlY3QtPnRvcCA8IDApIHx8CiAgICAgICAgICAgICAocFJlY3QtPmxlZnQgPCAwKSB8fAogICAgICAgICAgICAgKHBSZWN0LT5sZWZ0ID49IHBSZWN0LT5yaWdodCkgfHwKICAgICAgICAgICAgIChwUmVjdC0+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+Z2xSZWN0LmJvdHRvbSAtIFRoaXMtPmdsUmVjdC50b3A7CiAgICAgICAgICAgIHR5cGUgPSBHTF9VTlNJR05FRF9CWVRFOwogICAgICAgICAgICBmbXQgPSBHTF9SR0JBOwoKICAgICAgICAgICAgbWVtID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnJlc291cmNlLnNpemUgKiBzaXplb2YoRFdPUkQpKTsKICAgICAgICAgICAgaWYoIW1lbSkgewogICAgICAgICAgICAgICAgRVJSKCJPdXQgb2YgbWVtb3J5XG4iKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICBkM2RmbXRfY29udmVydF9zdXJmYWNlKFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGl0Y2gsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpdGNoICogNCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT05WRVJUX1BBTEVUVEVELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMpOwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRklYTUUoIlVuc3VwcG9ydGVkIEZvcm1hdCAldSBpbiBsb2NraW5nIGZ1bmNcbiIsIFRoaXMtPnJlc291cmNlLmZvcm1hdCk7CgogICAgICAgICAgICAvKiBHaXZlIGl0IGEgdHJ5ICovCiAgICAgICAgICAgIHR5cGUgPSBUaGlzLT5nbERlc2NyaXB0aW9uLmdsVHlwZTsKICAgICAgICAgICAgZm10ID0gVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdDsKICAgICAgICAgICAgbWVtID0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5OwogICAgfQoKICAgIGdsRHJhd1BpeGVscyhUaGlzLT5sb2NrZWRSZWN0LnJpZ2h0IC0gVGhpcy0+bG9ja2VkUmVjdC5sZWZ0LAogICAgICAgICAgICAgICAgIChUaGlzLT5sb2NrZWRSZWN0LmJvdHRvbSAtIFRoaXMtPmxvY2tlZFJlY3QudG9wKS0xLAogICAgICAgICAgICAgICAgIGZtdCwgdHlwZSwKICAgICAgICAgICAgICAgICBtZW0pOwogICAgY2hlY2tHTGNhbGwoImdsRHJhd1BpeGVscyIpOwogICAgZ2xQaXhlbFpvb20oMS4wLDEuMCk7CiAgICB2Y2hlY2tHTGNhbGwoImdsUGl4ZWxab29tIik7CgogICAgZ2xSYXN0ZXJQb3MzaXYoJnByZXZfcmFzdGVycG9zWzBdKTsKICAgIHZjaGVja0dMY2FsbCgiZ2xSYXN0ZXJQb3MzaXYiKTsKCiAgICAvKiBSZXNldCB0byBwcmV2aW91cyBwYWNrIHJvdyBsZW5ndGggKi8KICAgIGdsUGl4ZWxTdG9yZWkoR0xfVU5QQUNLX1JPV19MRU5HVEgsIHNraXBCeXRlcyk7CiAgICB2Y2hlY2tHTGNhbGwoImdsUGl4ZWxTdG9yZWkgR0xfVU5QQUNLX1JPV19MRU5HVEgiKTsKICAgIGlmKHN0b3JlY2hhbmdlZCkgewogICAgICAgIGdsUGl4ZWxTdG9yZWkoR0xfUEFDS19TV0FQX0JZVEVTLCBwcmV2X3N0b3JlKTsKICAgICAgICB2Y2hlY2tHTGNhbGwoImdsUGl4ZWxTdG9yZWkgR0xfUEFDS19TV0FQX0JZVEVTIik7CiAgICB9CgogICAgaWYobWVtICE9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSkgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbWVtKTsKICAgIHJldHVybjsKfQoKc3RhdGljIHZvaWQgZmx1c2hfdG9fZnJhbWVidWZmZXJfdGV4dHVyZShJV2luZUQzRFN1cmZhY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIGZsb2F0IGdsVGV4Q29vcmRbNF07CgogICAgZ2xUZXhDb29yZFswXSA9IDAuMDsgLyogbGVmdCAqLwogICAgZ2xUZXhDb29yZFsxXSA9IChmbG9hdCkgVGhpcy0+Y3VycmVudERlc2MuV2lkdGggLyAoZmxvYXQpIFRoaXMtPnBvdzJXaWR0aDsgLyogcmlnaHQgKi8KICAgIGdsVGV4Q29vcmRbMl0gPSAwLjA7IC8qIHRvcCAqLwogICAgZ2xUZXhDb29yZFszXSA9IChmbG9hdCkgVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0IC8gKGZsb2F0KSBUaGlzLT5wb3cySGVpZ2h0OyAvKiBib3R0b20gKi8KCiAgICBJV2luZUQzRFN1cmZhY2VfUHJlTG9hZChpZmFjZSk7CgogICAgRU5URVJfR0woKTsKCiAgICAvKiBEaXNhYmxlIHNvbWUgZmFuY3kgZ3JhcGhpY3MgZWZmZWN0cyAqLwogICAgZ2xEaXNhYmxlKEdMX0xJR0hUSU5HKTsKICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUgR0xfTElHSFRJTkciKTsKICAgIGdsRGlzYWJsZShHTF9ERVBUSF9URVNUKTsKICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUgR0xfREVQVEhfVEVTVCIpOwogICAgZ2xEaXNhYmxlKEdMX0ZPRyk7CiAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlIEdMX0ZPRyIpOwogICAgZ2xEaXNhYmxlKEdMX0NVTExfRkFDRSk7CiAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlIEdMX0NVTExfRkFDRSIpOwogICAgZ2xEaXNhYmxlKEdMX0JMRU5EKTsKICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUgR0xfQkxFTkQiKTsKICAgIGdsRGlzYWJsZShHTF9TVEVOQ0lMX1RFU1QpOwogICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9TVEVOQ0lMX1RFU1QiKTsKCiAgICBnbEVuYWJsZShHTF9URVhUVVJFXzJEKTsKICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSk7CiAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUgZ2xCaW5kVGV4dHVyZSIpOwoKICAgIC8qIE5vIGZpbHRlcmluZyBmb3IgYmx0cyAqLwogICAgZ2xUZXhQYXJhbWV0ZXJpKEdMX1RFWFRVUkVfMkQsIEdMX1RFWFRVUkVfTUFHX0ZJTFRFUiwgR0xfTkVBUkVTVCk7CiAgICBjaGVja0dMY2FsbCgiZ2xUZXhQYXJhbWV0ZXJpIik7CiAgICBnbFRleFBhcmFtZXRlcmkoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9NSU5fRklMVEVSLCBHTF9ORUFSRVNUKTsKICAgIGNoZWNrR0xjYWxsKCJnbFRleFBhcmFtZXRlcmkiKTsKCiAgICAvKiBTdGFydCBkcmF3aW5nIGEgcXVhZCAqLwogICAgZ2xCZWdpbihHTF9RVUFEUyk7CgogICAgZ2xDb2xvcjNkKDEuMGYsIDEuMGYsIDEuMGYpOwogICAgZ2xUZXhDb29yZDJmKGdsVGV4Q29vcmRbMF0sIGdsVGV4Q29vcmRbMl0pOwogICAgZ2xWZXJ0ZXgzZigwLCAwLCAwLjApOwoKICAgIGdsVGV4Q29vcmQyZihnbFRleENvb3JkWzBdLCBnbFRleENvb3JkWzNdKTsKICAgIGdsVmVydGV4M2YoMCwgVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0LCAwLjApOwoKICAgIGdsVGV4Q29vcmQyZihnbFRleENvb3JkWzFdLCBnbFRleENvb3JkWzNdKTsKICAgIGdsVmVydGV4M2QoVGhpcy0+Y3VycmVudERlc2MuV2lkdGgsIFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodCwgMC4wKTsKCiAgICBnbFRleENvb3JkMmYoZ2xUZXhDb29yZFsxXSwgZ2xUZXhDb29yZFsyXSk7CiAgICBnbFZlcnRleDNmKFRoaXMtPmN1cnJlbnREZXNjLldpZHRoLCAwLCAwLjApOwoKICAgIGdsRW5kKCk7CiAgICBjaGVja0dMY2FsbCgiZ2xFbmQiKTsKCiAgICAvKiBVbmJpbmQgdGhlIHRleHR1cmUgKi8KICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgMCk7CiAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUgZ2xCaW5kVGV4dHVyZSIpOwoKICAgIExFQVZFX0dMKCk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1VubG9ja1JlY3QoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRERldmljZUltcGwgICpteURldmljZSA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CiAgICBjb25zdCBjaGFyICpidWZmZXJuYW1lID0gIiI7CiAgICBJV2luZUQzRFN3YXBDaGFpbkltcGwgKnN3YXBjaGFpbiA9IE5VTEw7CiAgICBCT09MIGJhY2tidWYgPSBGQUxTRTsKCiAgICBpZiAoIShUaGlzLT5GbGFncyAmIFNGTEFHX0xPQ0tFRCkpIHsKICAgICAgICBXQVJOKCJ0cnlpbmcgdG8gVW5sb2NrIGFuIHVubG9ja2VkIHN1cmZAJXBcbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIGlmIChXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUICYgVGhpcy0+cmVzb3VyY2UudXNhZ2UpIHsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfR2V0Q29udGFpbmVyKGlmYWNlLCAmSUlEX0lXaW5lRDNEU3dhcENoYWluLCAodm9pZCAqKikmc3dhcGNoYWluKTsKCiAgICAgICAgaWYoc3dhcGNoYWluKSB7CiAgICAgICAgICAgIGludCBpOwogICAgICAgICAgICBmb3IoaSA9IDA7IGkgPCBzd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVyQ291bnQ7IGkrKykgewogICAgICAgICAgICAgICAgaWYoaWZhY2UgPT0gc3dhcGNoYWluLT5iYWNrQnVmZmVyW2ldKSB7CiAgICAgICAgICAgICAgICAgICAgYmFja2J1ZiA9IFRSVUU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChiYWNrYnVmKSB7CiAgICAgICAgICAgICAgICBidWZmZXJuYW1lID0gImJhY2tCdWZmZXIiOwogICAgICAgIH0gZWxzZSBpZiAoKHN3YXBjaGFpbiAhPSBOVUxMKSAmJiBpZmFjZSA9PSAgc3dhcGNoYWluLT5mcm9udEJ1ZmZlcikgewogICAgICAgICAgICAgICAgYnVmZmVybmFtZSA9ICJmcm9udEJ1ZmZlciI7CiAgICAgICAgfSBlbHNlIGlmIChpZmFjZSA9PSBteURldmljZS0+ZGVwdGhTdGVuY2lsQnVmZmVyKSB7CiAgICAgICAgICAgICAgICBidWZmZXJuYW1lID0gImRlcHRoU3RlbmNpbEJ1ZmZlciI7CiAgICAgICAgfSBlbHNlIGlmIChpZmFjZSA9PSBteURldmljZS0+cmVuZGVyVGFyZ2V0KSB7CiAgICAgICAgICAgICAgICBidWZmZXJuYW1lID0gInJlbmRlclRhcmdldCI7CiAgICAgICAgfQogICAgfQoKICAgIGlmIChzd2FwY2hhaW4gIT0gTlVMTCkgewogICAgICAgIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2UoKElXaW5lRDNEU3dhcENoYWluICopc3dhcGNoYWluKTsKICAgIH0KCiAgICBUUkFDRSgiKCVwICVzKSA6IGRpcnR5ZmllZCglZClcbiIsIFRoaXMsIGJ1ZmZlcm5hbWUsIFRoaXMtPkZsYWdzICYgU0ZMQUdfRElSVFkgPyAxIDogMCk7CgogICAgaWYgKCEoVGhpcy0+RmxhZ3MgJiBTRkxBR19ESVJUWSkpIHsKICAgICAgICBUUkFDRSgiKCVwKSA6IE5vdCBEaXJ0aWZpZWQgc28gbm90aGluZyB0byBkbywgcmV0dXJuIG5vd1xuIiwgVGhpcyk7CiAgICAgICAgZ290byB1bmxvY2tfZW5kOwogICAgfQoKICAgIGlmICgwID09IFRoaXMtPnJlc291cmNlLnVzYWdlKSB7IC8qIGNsYXNzaWMgc3VyZmFjZSAqLwogICAgICAgIC8qKgogICAgICAgICAqIG5vdGhpbmcgdG8gZG8KICAgICAgICAgKiB3YWl0aW5nIHRvIHJlbG9hZCB0aGUgc3VyZmFjZSB2aWEgSURpcmVjdDNERGV2aWNlODo6VXBkYXRlVGV4dHVyZQogICAgICAgICAqLwogICAgfSBlbHNlIGlmIChXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUICYgVGhpcy0+cmVzb3VyY2UudXNhZ2UpIHsgLyogcmVuZGVyIHN1cmZhY2VzICovCgogICAgICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgICAgICAgKiBUT0RPOiBSZW5kZXIgdGFyZ2V0cyBhcmUgJ3NwZWNpYWwnIGFuZAogICAgICAgICogP3NvbWU/IGxvY2tpbmcgbmVlZHMgdG8gYmUgcGFzc2VkIG9udG8gdGhlIGNvbnRleHQgbWFuYWdlcgogICAgICAgICogc28gdGhhdCBpdCBiZWNvbWVzIHBvc3NpYmxlIHRvIHVzZSBhdXhpbGlhcnkgYnVmZmVycywgcGJ1ZmZlcnMKICAgICAgICAqIHJlbmRlci10by10ZXh0dXJlLCBzaGFyZWQsIGNhY2hlZCBjb250ZXh0cyBldGMuLi4KICAgICAgICAqICoqKioqKioqKioqKioqKioqKioqKioqKioqKiovCiAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICppbXBsU3dhcENoYWluOwogICAgICAgIElXaW5lRDNERGV2aWNlX0dldFN3YXBDaGFpbigoSVdpbmVEM0REZXZpY2UgKilteURldmljZSwgMCwgKElXaW5lRDNEU3dhcENoYWluICoqKSZpbXBsU3dhcENoYWluKTsKCiAgICAgICAgaWYgKGJhY2tidWYgfHwgaWZhY2UgPT0gIGltcGxTd2FwQ2hhaW4tPmZyb250QnVmZmVyIHx8IGlmYWNlID09IG15RGV2aWNlLT5yZW5kZXJUYXJnZXQpIHsKICAgICAgICAgICAgaW50IHRleDsKCiAgICAgICAgICAgIEVOVEVSX0dMKCk7CgogICAgICAgICAgICAvKiBnbERyYXdQaXhlbHMgdHJhbnNmb3JtcyB0aGUgcmFzdGVyIHBvc2l0aW9uIGFzIHRob3VnaCBpdCB3YXMgYSB2ZXJ0ZXggLQogICAgICAgICAgICAgICB3ZSB3YW50IHRvIGRyYXcgYXQgc2NyZWVuIHBvc2l0aW9uIDAsMCAtIFNldCB1cCBvcnRobyAocmh3KSBtb2RlIGFzCiAgICAgICAgICAgICAgIHBlciBkcmF3cHJpbSAoYW5kIGxlYXZlIHNldCAtIGl0IHdpbGwgc29ydCBpdHNlbGYgb3V0IGR1ZSB0byBsYXN0X3dhc19yaHcgKi8KICAgICAgICAgICAgZDNkZGV2aWNlX3NldF9vcnRobyhUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlKTsKCiAgICAgICAgICAgIGlmIChpZmFjZSA9PSAgaW1wbFN3YXBDaGFpbi0+ZnJvbnRCdWZmZXIpIHsKICAgICAgICAgICAgICAgIGdsRHJhd0J1ZmZlcihHTF9GUk9OVCk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEcmF3QnVmZmVyIEdMX0ZST05UIik7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoYmFja2J1ZiB8fCBpZmFjZSA9PSBteURldmljZS0+cmVuZGVyVGFyZ2V0KSB7CiAgICAgICAgICAgICAgICBnbERyYXdCdWZmZXIoR0xfQkFDSyk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEcmF3QnVmZmVyIEdMX0JBQ0siKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyogRGlzYWJsZSBoaWdoZXIgdGV4dHVyZXMgYmVmb3JlIGNhbGxpbmcgZ2xEcmF3UGl4ZWxzICovCiAgICAgICAgICAgIGZvcih0ZXggPSAxOyB0ZXggPCBHTF9MSU1JVFMoc2FtcGxlcnMpOyB0ZXgrKykgewogICAgICAgICAgICAgICAgaWYgKEdMX1NVUFBPUlQoQVJCX01VTFRJVEVYVFVSRSkpIHsKICAgICAgICAgICAgICAgICAgICBHTF9FWFRDQUxMKGdsQWN0aXZlVGV4dHVyZUFSQihHTF9URVhUVVJFMF9BUkIgKyB0ZXgpKTsKICAgICAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xBY3RpdmVUZXh0dXJlQVJCIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBnbERpc2FibGUoR0xfVEVYVFVSRV8yRCk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlIEdMX1RFWFRVUkVfMkQiKTsKICAgICAgICAgICAgICAgIGdsRGlzYWJsZShHTF9URVhUVVJFXzFEKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUgR0xfVEVYVFVSRV8xRCIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qIEFjdGl2YXRlIHRleHR1cmUgMCwgYnV0IGRvbid0IGRpc2FibGUgaXQgbmVjZXNzYXJpbGx5ICovCiAgICAgICAgICAgIGlmIChHTF9TVVBQT1JUKEFSQl9NVUxUSVRFWFRVUkUpKSB7CiAgICAgICAgICAgICAgICBHTF9FWFRDQUxMKGdsQWN0aXZlVGV4dHVyZUFSQihHTF9URVhUVVJFMF9BUkIpKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEFjdGl2ZVRleHR1cmVBUkIiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyogQW5kIGJhY2sgYnVmZmVycyBhcmUgbm90IGJsZW5kZWQuIERpc2FibGUgdGhlIGRlcHRoIHRlc3QsIAogICAgICAgICAgICAgICB0aGF0IGhlbHBzIHBlcmZvcm1hbmNlICovCiAgICAgICAgICAgIGdsRGlzYWJsZShHTF9CTEVORCk7CiAgICAgICAgICAgIGdsRGlzYWJsZShHTF9ERVBUSF9URVNUKTsKICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX0ZPRyk7CgogICAgICAgICAgICBzd2l0Y2god2luZWQzZF9zZXR0aW5ncy5yZW5kZXJ0YXJnZXRsb2NrX21vZGUpIHsKICAgICAgICAgICAgICAgIGNhc2UgUlRMX0FVVE86CiAgICAgICAgICAgICAgICBjYXNlIFJUTF9SRUFERFJBVzoKICAgICAgICAgICAgICAgIGNhc2UgUlRMX1RFWERSQVc6CiAgICAgICAgICAgICAgICAgICAgZmx1c2hfdG9fZnJhbWVidWZmZXJfZHJhd3BpeGVscyhUaGlzKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlIFJUTF9SRUFEVEVYOgogICAgICAgICAgICAgICAgY2FzZSBSVExfVEVYVEVYOgogICAgICAgICAgICAgICAgICAgIGZsdXNoX3RvX2ZyYW1lYnVmZmVyX3RleHR1cmUoaWZhY2UpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgUlRMX0RJU0FCTEU6CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3RhdGljIEJPT0wgd2FybmVkID0gRkFMU0U7CiAgICAgICAgICAgICAgICAgICAgaWYoIXdhcm5lZCkgewogICAgICAgICAgICAgICAgICAgICAgICBFUlIoIlRoZSBhcHBsaWNhdGlvbiB0cmllcyB0byB3cml0ZSB0byB0aGUgcmVuZGVyIHRhcmdldCwgYnV0IHJlbmRlciB0YXJnZXQgbG9ja2luZyBpcyBkaXNhYmxlZFxuIik7CiAgICAgICAgICAgICAgICAgICAgICAgIHdhcm5lZCA9IFRSVUU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmKGltcGxTd2FwQ2hhaW4tPmJhY2tCdWZmZXIgJiYgaW1wbFN3YXBDaGFpbi0+YmFja0J1ZmZlclswXSkgewogICAgICAgICAgICAgICAgZ2xEcmF3QnVmZmVyKEdMX0JBQ0spOwogICAgICAgICAgICAgICAgdmNoZWNrR0xjYWxsKCJnbERyYXdCdWZmZXIiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZihteURldmljZS0+c3RhdGVCbG9jay0+cmVuZGVyU3RhdGVbRDNEUlNfWkVOQUJMRV0gPT0gRDNEWkJfVFJVRSB8fAogICAgICAgICAgICAgICBteURldmljZS0+c3RhdGVCbG9jay0+cmVuZGVyU3RhdGVbRDNEUlNfWkVOQUJMRV0gPT0gRDNEWkJfVVNFVykgZ2xFbmFibGUoR0xfREVQVEhfVEVTVCk7CiAgICAgICAgICAgIGlmIChteURldmljZS0+c3RhdGVCbG9jay0+cmVuZGVyU3RhdGVbRDNEUlNfQUxQSEFCTEVOREVOQUJMRV0pIGdsRW5hYmxlKEdMX0JMRU5EKTsKICAgICAgICAgICAgaWYgKG15RGV2aWNlLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtEM0RSU19GT0dFTkFCTEVdKSBnbEVuYWJsZShHTF9GT0cpOwoKICAgICAgICAgICAgTEVBVkVfR0woKTsKCiAgICAgICAgICAgIC8qKiByZXN0b3JlIGNsZWFuIGRpcnR5IHN0YXRlICovCiAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9DbGVhbkRpcnR5UmVjdChpZmFjZSk7CgogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIEZJWE1FKCJ1bnN1cHBvcnRlZCB1bmxvY2tpbmcgdG8gUmVuZGVyaW5nIHN1cmZhY2Ugc3VyZkAlcCB1c2FnZSglcylcbiIsIFRoaXMsIGRlYnVnX2QzZHVzYWdlKFRoaXMtPnJlc291cmNlLnVzYWdlKSk7CiAgICAgICAgfQogICAgICAgIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2UoKElXaW5lRDNEU3dhcENoYWluICopaW1wbFN3YXBDaGFpbik7CgogICAgfSBlbHNlIGlmIChXSU5FRDNEVVNBR0VfREVQVEhTVEVOQ0lMICYgVGhpcy0+cmVzb3VyY2UudXNhZ2UpIHsgLyogc3RlbmNpbCBzdXJmYWNlcyAqLwoKICAgICAgICBpZiAoaWZhY2UgPT0gbXlEZXZpY2UtPmRlcHRoU3RlbmNpbEJ1ZmZlcikgewogICAgICAgICAgICBGSVhNRSgiVE9ETyBzdGVuY2lsIGRlcHRoIHN1cmZhY2UgdW5sb2NraW5nIHN1cmZAJXAgdXNhZ2UoJXMpXG4iLCBUaGlzLCBkZWJ1Z19kM2R1c2FnZShUaGlzLT5yZXNvdXJjZS51c2FnZSkpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIEZJWE1FKCJ1bnN1cHBvcnRlZCB1bmxvY2tpbmcgdG8gU3RlbmNpbERlcHRoIHN1cmZhY2Ugc3VyZkAlcCB1c2FnZSglcylcbiIsIFRoaXMsIGRlYnVnX2QzZHVzYWdlKFRoaXMtPnJlc291cmNlLnVzYWdlKSk7CiAgICAgICAgfQoKICAgIH0gZWxzZSB7CiAgICAgICAgRklYTUUoInVuc3VwcG9ydGVkIHVubG9ja2luZyB0byBzdXJmYWNlIHN1cmZAJXAgdXNhZ2UoJXMpXG4iLCBUaGlzLCBkZWJ1Z19kM2R1c2FnZShUaGlzLT5yZXNvdXJjZS51c2FnZSkpOwogICAgfQoKICAgIHVubG9ja19lbmQ6CiAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfTE9DS0VEOwogICAgbWVtc2V0KCZUaGlzLT5sb2NrZWRSZWN0LCAwLCBzaXplb2YoUkVDVCkpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0REMoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgSERDICpwSERDKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIFdJTkVEM0RMT0NLRURfUkVDVCBsb2NrOwogICAgVUlOVCB1c2FnZTsKICAgIEJJVE1BUElORk8qIGJfaW5mbzsKICAgIEhEQyBkZGM7CiAgICBEV09SRCAqbWFza3M7CiAgICBIUkVTVUxUIGhyOwogICAgUkdCUVVBRCBjb2xbMjU2XTsKICAgIGNvbnN0IFBpeGVsRm9ybWF0RGVzYyAqZm9ybWF0RW50cnkgPSBnZXRGb3JtYXREZXNjRW50cnkoVGhpcy0+cmVzb3VyY2UuZm9ybWF0KTsKCiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIixUaGlzLHBIREMpOwoKICAgIGlmKFRoaXMtPkZsYWdzICYgU0ZMQUdfVVNFUlBUUikgewogICAgICAgIEVSUigiTm90IHN1cHBvcnRlZCBvbiBzdXJmYWNlcyB3aXRoIGFuIGFwcGxpY2F0aW9uLXByb3ZpZGVkIHN1cmZhY2VzXG4iKTsKICAgICAgICByZXR1cm4gRERFUlJfTk9EQzsKICAgIH0KCiAgICAvKiBHaXZlIG1vcmUgZGV0YWlsZWQgaW5mbyBmb3IgZGRyYXcgKi8KICAgIGlmIChUaGlzLT5GbGFncyAmIFNGTEFHX0RDSU5VU0UpCiAgICAgICAgcmV0dXJuIERERVJSX0RDQUxSRUFEWUNSRUFURUQ7CgogICAgLyogQ2FuJ3QgR2V0REMgaWYgdGhlIHN1cmZhY2UgaXMgbG9ja2VkICovCiAgICBpZiAoVGhpcy0+RmxhZ3MgJiBTRkxBR19MT0NLRUQpCiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CgogICAgbWVtc2V0KCZsb2NrLCAwLCBzaXplb2YobG9jaykpOyAvKiBUbyBiZSBzdXJlICovCgogICAgLyogQ3JlYXRlIGEgRElCIHNlY3Rpb24gaWYgdGhlcmUgaXNuJ3QgYSBoZGMgeWV0ICovCiAgICBpZighVGhpcy0+aERDKSB7CiAgICAgICAgaW50IGV4dHJhbGluZSA9IDA7CiAgICAgICAgU1lTVEVNX0lORk8gc3lzSW5mbzsKCiAgICAgICAgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19BQ1RJVkVMT0NLKSB7CiAgICAgICAgICAgIEVSUigiQ3JlYXRpbmcgYSBESUIgc2VjdGlvbiB3aGlsZSBhIGxvY2sgaXMgYWN0aXZlLiBVbmNlcnRhaW4gY29uc2VxdWVuY2VzXG4iKTsKICAgICAgICB9CgogICAgICAgIHN3aXRjaCAoVGhpcy0+Ynl0ZXNQZXJQaXhlbCkgewogICAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgIGNhc2UgNDoKICAgICAgICAgICAgICAgIC8qIEFsbG9jYXRlIGV4dHJhIHNwYWNlIHRvIHN0b3JlIHRoZSBSR0IgYml0IG1hc2tzLiAqLwogICAgICAgICAgICAgICAgYl9pbmZvID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihCSVRNQVBJTkZPSEVBREVSKSArIDMgKiBzaXplb2YoRFdPUkQpKTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSAzOgogICAgICAgICAgICAgICAgYl9pbmZvID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihCSVRNQVBJTkZPSEVBREVSKSk7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAvKiBBbGxvY2F0ZSBleHRyYSBzcGFjZSBmb3IgYSBwYWxldHRlLiAqLwogICAgICAgICAgICAgICAgYl9pbmZvID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YoQklUTUFQSU5GT0hFQURFUikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgc2l6ZW9mKFJHQlFVQUQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqICgxIDw8IChUaGlzLT5ieXRlc1BlclBpeGVsICogOCkpKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFiX2luZm8pCiAgICAgICAgICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwoKICAgICAgICAvKiBTb21lIGFwcHMgYWNjZXNzIHRoZSBzdXJmYWNlIGluIHZpYSBEV09SRHMsIGFuZCBkbyBub3QgdGFrZSB0aGUgbmVjZXNzYXJ5IGNhcmUgYXQgdGhlIGVuZCBvZiB0aGUKICAgICAgICAgKiBzdXJmYWNlLiBTbyB3ZSBuZWVkIGF0IGxlYXN0IGV4dHJhIDQgYnl0ZXMgYXQgdGhlIGVuZCBvZiB0aGUgc3VyZmFjZS4gQ2hlY2sgYWdhaW5zdCB0aGUgcGFnZSBzaXplLAogICAgICAgICAqIGlmIHRoZSBsYXN0IHBhZ2UgdXNlZCBmb3IgdGhlIHN1cmZhY2UgaGFzIGF0IGxlYXN0IDQgc3BhcmUgYnl0ZXMgd2UncmUgc2FmZSwgb3RoZXJ3aXNlCiAgICAgICAgICogYWRkIGFuIGV4dHJhIGxpbmUgdG8gdGhlIGRpYiBzZWN0aW9uCiAgICAgICAgICovCiAgICAgICAgR2V0U3lzdGVtSW5mbygmc3lzSW5mbyk7CiAgICAgICAgaWYoICgoVGhpcy0+cmVzb3VyY2Uuc2l6ZSArIDMpICUgc3lzSW5mby5kd1BhZ2VTaXplKSA8IDQpIHsKICAgICAgICAgICAgZXh0cmFsaW5lID0gMTsKICAgICAgICAgICAgVFJBQ0UoIkFkZGluZyBhbiBleHRyYSBsaW5lIHRvIHRoZSBkaWIgc2VjdGlvblxuIik7CiAgICAgICAgfQoKICAgICAgICBiX2luZm8tPmJtaUhlYWRlci5iaVNpemUgPSBzaXplb2YoQklUTUFQSU5GT0hFQURFUik7CiAgICAgICAgaWYoIChOUDJfUkVQQUNLID09IHdpbmVkM2Rfc2V0dGluZ3Mubm9ucG93ZXIyX21vZGUgfHwgVGhpcy0+cmVzb3VyY2UudXNhZ2UgJiBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUKSkgewogICAgICAgICAgICBiX2luZm8tPmJtaUhlYWRlci5iaVdpZHRoID0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAgICAgICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpSGVpZ2h0ID0gLVRoaXMtPmN1cnJlbnREZXNjLkhlaWdodCAtZXh0cmFsaW5lOwogICAgICAgICAgICBiX2luZm8tPmJtaUhlYWRlci5iaVNpemVJbWFnZSA9ICggVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0ICsgZXh0cmFsaW5lKSAqIElXaW5lRDNEU3VyZmFjZV9HZXRQaXRjaChpZmFjZSk7CiAgICAgICAgICAgIC8qIFVzZSB0aGUgZnVsbCBwb3cyIGltYWdlIHNpemUoYXNzaWduZWQgYmVsb3cpIGJlY2F1c2UgTG9ja1JlY3QKICAgICAgICAgICAgICogd2lsbCBuZWVkIGl0IGZvciBhIGZ1bGwgZ2xHZXRUZXhJbWFnZSBjYWxsCiAgICAgICAgICAgICAqLwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpV2lkdGggPSBUaGlzLT5wb3cyV2lkdGg7CiAgICAgICAgICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpSGVpZ2h0ID0gLVRoaXMtPnBvdzJIZWlnaHQgLWV4dHJhbGluZTsKICAgICAgICAgICAgYl9pbmZvLT5ibWlIZWFkZXIuYmlTaXplSW1hZ2UgPSBUaGlzLT5yZXNvdXJjZS5zaXplICsgZXh0cmFsaW5lICAqIElXaW5lRDNEU3VyZmFjZV9HZXRQaXRjaChpZmFjZSk7CiAgICAgICAgfQogICAgICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpUGxhbmVzID0gMTsKICAgICAgICBiX2luZm8tPmJtaUhlYWRlci5iaUJpdENvdW50ID0gVGhpcy0+Ynl0ZXNQZXJQaXhlbCAqIDg7CgogICAgICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpWFBlbHNQZXJNZXRlciA9IDA7CiAgICAgICAgYl9pbmZvLT5ibWlIZWFkZXIuYmlZUGVsc1Blck1ldGVyID0gMDsKICAgICAgICBiX2luZm8tPmJtaUhlYWRlci5iaUNsclVzZWQgPSAwOwogICAgICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpQ2xySW1wb3J0YW50ID0gMDsKCiAgICAgICAgLyogR2V0IHRoZSBiaXQgbWFza3MgKi8KICAgICAgICBtYXNrcyA9IChEV09SRCAqKSAmKGJfaW5mby0+Ym1pQ29sb3JzKTsKICAgICAgICBzd2l0Y2ggKFRoaXMtPnJlc291cmNlLmZvcm1hdCkgewogICAgICAgICAgICBjYXNlIFdJTkVEM0RGTVRfUjhHOEI4OgogICAgICAgICAgICAgICAgdXNhZ2UgPSBESUJfUkdCX0NPTE9SUzsKICAgICAgICAgICAgICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpQ29tcHJlc3Npb24gPSBCSV9SR0I7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgV0lORUQzREZNVF9YMVI1RzVCNToKICAgICAgICAgICAgY2FzZSBXSU5FRDNERk1UX0ExUjVHNUI1OgogICAgICAgICAgICBjYXNlIFdJTkVEM0RGTVRfQTRSNEc0QjQ6CiAgICAgICAgICAgIGNhc2UgV0lORUQzREZNVF9YNFI0RzRCNDoKICAgICAgICAgICAgY2FzZSBXSU5FRDNERk1UX1IzRzNCMjoKICAgICAgICAgICAgY2FzZSBXSU5FRDNERk1UX0E4UjNHM0IyOgogICAgICAgICAgICBjYXNlIFdJTkVEM0RGTVRfQTJCMTBHMTBSMTA6CiAgICAgICAgICAgIGNhc2UgV0lORUQzREZNVF9BOEI4RzhSODoKICAgICAgICAgICAgY2FzZSBXSU5FRDNERk1UX1g4QjhHOFI4OgogICAgICAgICAgICBjYXNlIFdJTkVEM0RGTVRfQTJSMTBHMTBCMTA6CiAgICAgICAgICAgIGNhc2UgV0lORUQzREZNVF9SNUc2QjU6CiAgICAgICAgICAgIGNhc2UgV0lORUQzREZNVF9BMTZCMTZHMTZSMTY6CiAgICAgICAgICAgICAgICB1c2FnZSA9IDA7CiAgICAgICAgICAgICAgICBiX2luZm8tPmJtaUhlYWRlci5iaUNvbXByZXNzaW9uID0gQklfQklURklFTERTOwogICAgICAgICAgICAgICAgbWFza3NbMF0gPSBmb3JtYXRFbnRyeS0+cmVkTWFzazsKICAgICAgICAgICAgICAgIG1hc2tzWzFdID0gZm9ybWF0RW50cnktPmdyZWVuTWFzazsKICAgICAgICAgICAgICAgIG1hc2tzWzJdID0gZm9ybWF0RW50cnktPmJsdWVNYXNrOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgLyogRG9uJ3Qga25vdyBwYWxldHRlICovCiAgICAgICAgICAgICAgICBiX2luZm8tPmJtaUhlYWRlci5iaUNvbXByZXNzaW9uID0gQklfUkdCOwogICAgICAgICAgICAgICAgdXNhZ2UgPSAwOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBkZGMgPSBDcmVhdGVEQ0EoIkRJU1BMQVkiLCBOVUxMLCBOVUxMLCBOVUxMKTsKICAgICAgICBpZiAoZGRjID09IDApIHsKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgYl9pbmZvKTsKICAgICAgICAgICAgcmV0dXJuIEhSRVNVTFRfRlJPTV9XSU4zMihHZXRMYXN0RXJyb3IoKSk7CiAgICAgICAgfQoKICAgICAgICBUUkFDRSgiQ3JlYXRpbmcgYSBESUIgc2VjdGlvbiB3aXRoIHNpemUgJWR4JWR4JWQsIHNpemU9JWRcbiIsIGJfaW5mby0+Ym1pSGVhZGVyLmJpV2lkdGgsIGJfaW5mby0+Ym1pSGVhZGVyLmJpSGVpZ2h0LCBiX2luZm8tPmJtaUhlYWRlci5iaUJpdENvdW50LCBiX2luZm8tPmJtaUhlYWRlci5iaVNpemVJbWFnZSk7CiAgICAgICAgVGhpcy0+ZGliLkRJQnNlY3Rpb24gPSBDcmVhdGVESUJTZWN0aW9uKGRkYywgYl9pbmZvLCB1c2FnZSwgJlRoaXMtPmRpYi5iaXRtYXBfZGF0YSwgMCAvKiBIYW5kbGUgKi8sIDAgLyogT2Zmc2V0ICovKTsKICAgICAgICBEZWxldGVEQyhkZGMpOwoKICAgICAgICBpZiAoIVRoaXMtPmRpYi5ESUJzZWN0aW9uKSB7CiAgICAgICAgICAgIEVSUigiQ3JlYXRlRElCU2VjdGlvbiBmYWlsZWQhXG4iKTsKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgYl9pbmZvKTsKICAgICAgICAgICAgcmV0dXJuIEhSRVNVTFRfRlJPTV9XSU4zMihHZXRMYXN0RXJyb3IoKSk7CiAgICAgICAgfQoKICAgICAgICBUUkFDRSgiRElCU2VjdGlvbiBhdCA6ICVwXG4iLCBUaGlzLT5kaWIuYml0bWFwX2RhdGEpOwoKICAgICAgICAvKiBjb3B5IHRoZSBleGlzdGluZyBzdXJmYWNlIHRvIHRoZSBkaWIgc2VjdGlvbiAqLwogICAgICAgIGlmKFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSkgewogICAgICAgICAgICBtZW1jcHkoVGhpcy0+ZGliLmJpdG1hcF9kYXRhLCBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnksIGJfaW5mby0+Ym1pSGVhZGVyLmJpU2l6ZUltYWdlKTsKICAgICAgICAgICAgLyogV2Ugd29uJ3QgbmVlZCB0aGF0IGFueSBtb3JlICovCiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLyogVGhpcyBpcyB0byBtYWtlIExvY2tSZWN0IHJlYWQgdGhlIGdsIFRleHR1cmUgYWx0aG91Z2ggbWVtb3J5IGlzIGFsbG9jYXRlZCAqLwogICAgICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19HTERJUlRZOwogICAgICAgIH0KCiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgYl9pbmZvKTsKCiAgICAgICAgLyogVXNlIHRoZSBkaWIgc2VjdGlvbiBmcm9tIG5vdyBvbiAqLwogICAgICAgIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IFRoaXMtPmRpYi5iaXRtYXBfZGF0YTsKCiAgICAgICAgLyogTm93IGFsbG9jYXRlIGEgSERDICovCiAgICAgICAgVGhpcy0+aERDID0gQ3JlYXRlQ29tcGF0aWJsZURDKDApOwogICAgICAgIFRoaXMtPmRpYi5ob2xkYml0bWFwID0gU2VsZWN0T2JqZWN0KFRoaXMtPmhEQywgVGhpcy0+ZGliLkRJQnNlY3Rpb24pOwogICAgICAgIFRSQUNFKCJ1c2luZyB3aW5lZDNkIHBhbGV0dGUgJXBcbiIsIFRoaXMtPnBhbGV0dGUpOwogICAgICAgIFNlbGVjdFBhbGV0dGUoVGhpcy0+aERDLAogICAgICAgICAgICAgICAgICAgICAgVGhpcy0+cGFsZXR0ZSA/IFRoaXMtPnBhbGV0dGUtPmhwYWwgOiAwLAogICAgICAgICAgICAgICAgICAgICAgRkFMU0UpOwoKICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19ESUJTRUNUSU9OOwogICAgfQoKICAgIC8qIExvY2sgdGhlIHN1cmZhY2UgKi8KICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX0xvY2tSZWN0KGlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmxvY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCk7CiAgICBpZihGQUlMRUQoaHIpKSB7CiAgICAgICAgRVJSKCJJV2luZUQzRFN1cmZhY2VfTG9ja1JlY3QgZmFpbGVkIHdpdGggaHIgPSAlMDh4XG4iLCBocik7CiAgICAgICAgLyoga2VlcCB0aGUgZGliIHNlY3Rpb24gKi8KICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgaWYoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfUDggfHwKICAgICAgICBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9BOFA4KSB7CiAgICAgICAgdW5zaWduZWQgaW50IG47CiAgICAgICAgaWYoVGhpcy0+cGFsZXR0ZSkgewogICAgICAgICAgICBQQUxFVFRFRU5UUlkgZW50WzI1Nl07CgogICAgICAgICAgICBHZXRQYWxldHRlRW50cmllcyhUaGlzLT5wYWxldHRlLT5ocGFsLCAwLCAyNTYsIGVudCk7CiAgICAgICAgICAgIGZvciAobj0wOyBuPDI1NjsgbisrKSB7CiAgICAgICAgICAgICAgICBjb2xbbl0ucmdiUmVkICAgPSBlbnRbbl0ucGVSZWQ7CiAgICAgICAgICAgICAgICBjb2xbbl0ucmdiR3JlZW4gPSBlbnRbbl0ucGVHcmVlbjsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JCbHVlICA9IGVudFtuXS5wZUJsdWU7CiAgICAgICAgICAgICAgICBjb2xbbl0ucmdiUmVzZXJ2ZWQgPSAwOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsICpkZXZpY2UgPSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOwoKICAgICAgICAgICAgZm9yIChuPTA7IG48MjU2OyBuKyspIHsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JSZWQgICA9IGRldmljZS0+cGFsZXR0ZXNbZGV2aWNlLT5jdXJyZW50UGFsZXR0ZV1bbl0ucGVSZWQ7CiAgICAgICAgICAgICAgICBjb2xbbl0ucmdiR3JlZW4gPSBkZXZpY2UtPnBhbGV0dGVzW2RldmljZS0+Y3VycmVudFBhbGV0dGVdW25dLnBlR3JlZW47CiAgICAgICAgICAgICAgICBjb2xbbl0ucmdiQmx1ZSAgPSBkZXZpY2UtPnBhbGV0dGVzW2RldmljZS0+Y3VycmVudFBhbGV0dGVdW25dLnBlQmx1ZTsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JSZXNlcnZlZCA9IDA7CiAgICAgICAgICAgIH0KCiAgICAgICAgfQogICAgICAgIFNldERJQkNvbG9yVGFibGUoVGhpcy0+aERDLCAwLCAyNTYsIGNvbCk7CiAgICB9CgogICAgKnBIREMgPSBUaGlzLT5oREM7CiAgICBUUkFDRSgicmV0dXJuaW5nICVwXG4iLCpwSERDKTsKICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX0RDSU5VU0U7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfUmVsZWFzZURDKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIEhEQyBoREMpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwoKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLFRoaXMsaERDKTsKCiAgICBpZiAoIShUaGlzLT5GbGFncyAmIFNGTEFHX0RDSU5VU0UpKQogICAgICAgIHJldHVybiBEM0RFUlJfSU5WQUxJRENBTEw7CgogICAgLyogd2UgbG9ja2VkIGZpcnN0LCBzbyB1bmxvY2sgbm93ICovCiAgICBJV2luZUQzRFN1cmZhY2VfVW5sb2NrUmVjdChpZmFjZSk7CgogICAgVGhpcy0+RmxhZ3MgJj0gflNGTEFHX0RDSU5VU0U7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogICBJV2luZUQzRFN1cmZhY2UgSW50ZXJuYWwgKE5vIG1hcHBpbmcgdG8gZGlyZWN0eCBhcGkpIHBhcnRzIGZvbGxvdwogICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi8KCkhSRVNVTFQgZDNkZm10X2dldF9jb252KElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMsIEJPT0wgbmVlZF9hbHBoYV9jaywgQk9PTCB1c2VfdGV4dHVyaW5nLCBHTGVudW0gKmZvcm1hdCwgR0xlbnVtICppbnRlcm5hbCwgR0xlbnVtICp0eXBlLCBDT05WRVJUX1RZUEVTICpjb252ZXJ0LCBpbnQgKnRhcmdldF9icHApIHsKICAgIEJPT0wgY29sb3JrZXlfYWN0aXZlID0gbmVlZF9hbHBoYV9jayAmJiAoVGhpcy0+Q0tleUZsYWdzICYgRERTRF9DS1NSQ0JMVCk7CiAgICBjb25zdCBQaXhlbEZvcm1hdERlc2MgKmZvcm1hdEVudHJ5ID0gZ2V0Rm9ybWF0RGVzY0VudHJ5KFRoaXMtPnJlc291cmNlLmZvcm1hdCk7CgogICAgLyogRGVmYXVsdCB2YWx1ZXM6IEZyb20gdGhlIHN1cmZhY2UgKi8KICAgICpmb3JtYXQgPSBmb3JtYXRFbnRyeS0+Z2xGb3JtYXQ7CiAgICAqaW50ZXJuYWwgPSBmb3JtYXRFbnRyeS0+Z2xJbnRlcm5hbDsKICAgICp0eXBlID0gZm9ybWF0RW50cnktPmdsVHlwZTsKICAgICpjb252ZXJ0ID0gTk9fQ09OVkVSU0lPTjsKICAgICp0YXJnZXRfYnBwID0gVGhpcy0+Ynl0ZXNQZXJQaXhlbDsKCiAgICAvKiBPaywgbm93IGxvb2sgaWYgd2UgaGF2ZSB0byBkbyBhbnkgY29udmVyc2lvbiAqLwogICAgc3dpdGNoKFRoaXMtPnJlc291cmNlLmZvcm1hdCkgewogICAgICAgIGNhc2UgV0lORUQzREZNVF9QODoKICAgICAgICAgICAgLyogKioqKioqKioqKioqKioqKgogICAgICAgICAgICAgICAgUGFsZXR0ZWQgVGV4dHVyZQogICAgICAgICAgICAgICAgKioqKioqKioqKioqKioqKiAqLwogICAgICAgICAgICAvKiBVc2UgY29udmVyc2lvbiB3aGVuIHRoZSBwYWxldHRlZCB0ZXh0dXJlIGV4dGVuc2lvbiBpcyBub3QgYXZhaWxhYmxlLCBvciB3aGVuIGl0IGlzIGF2YWlsYWJsZSBtYWtlIHN1cmUgaXQgaXMgdXNlZAogICAgICAgICAgICAgKiBmb3IgdGV4dHVyaW5nIGFzIGl0IHdvbid0IHdvcmsgZm9yIGNhbGxzIGxpa2UgZ2xEcmF3LS9nbFJlYWRQaXhlbHMgYW5kIGZ1cnRoZXIgYWxzbyB1c2UgY29udmVyc2lvbiBpbiBjYXNlIG9mIGNvbG9yIGtleWluZy4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmKCFHTF9TVVBQT1JUKEVYVF9QQUxFVFRFRF9URVhUVVJFKSB8fCBjb2xvcmtleV9hY3RpdmUgfHwgKCF1c2VfdGV4dHVyaW5nICYmIEdMX1NVUFBPUlQoRVhUX1BBTEVUVEVEX1RFWFRVUkUpKSApIHsKICAgICAgICAgICAgICAgICpmb3JtYXQgPSBHTF9SR0JBOwogICAgICAgICAgICAgICAgKmludGVybmFsID0gR0xfUkdCQTsKICAgICAgICAgICAgICAgICp0eXBlID0gR0xfVU5TSUdORURfQllURTsKICAgICAgICAgICAgICAgICp0YXJnZXRfYnBwID0gNDsKICAgICAgICAgICAgICAgIGlmKGNvbG9ya2V5X2FjdGl2ZSkgewogICAgICAgICAgICAgICAgICAgICpjb252ZXJ0ID0gQ09OVkVSVF9QQUxFVFRFRF9DSzsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgKmNvbnZlcnQgPSBDT05WRVJUX1BBTEVUVEVEOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1IzRzNCMjoKICAgICAgICAgICAgLyogKioqKioqKioqKioqKioqKioqKioqKgogICAgICAgICAgICAgICAgR0xfVU5TSUdORURfQllURV8zXzNfMgogICAgICAgICAgICAgICAgKioqKioqKioqKioqKioqKioqKioqKiAqLwogICAgICAgICAgICBpZiAoY29sb3JrZXlfYWN0aXZlKSB7CiAgICAgICAgICAgICAgICAvKiBUaGlzIHRleHR1cmUgZm9ybWF0IHdpbGwgbmV2ZXIgYmUgdXNlZC4uIFNvIGRvIG5vdCBjYXJlIGFib3V0IGNvbG9yIGtleWluZwogICAgICAgICAgICAgICAgICAgIHVwIHVudGlsIHRoZSBwb2ludCBpbiB0aW1lIGl0IHdpbGwgYmUgbmVlZGVkIDotKSAqLwogICAgICAgICAgICAgICAgRklYTUUoIiBDb2xvcktleWluZyBub3Qgc3VwcG9ydGVkIGluIHRoZSBSR0IgMzMyIGZvcm1hdCAhXG4iKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1I1RzZCNToKICAgICAgICAgICAgaWYgKGNvbG9ya2V5X2FjdGl2ZSkgewogICAgICAgICAgICAgICAgKmNvbnZlcnQgPSBDT05WRVJUX0NLXzU2NTsKICAgICAgICAgICAgICAgICpmb3JtYXQgPSBHTF9SR0JBOwogICAgICAgICAgICAgICAgKmludGVybmFsID0gR0xfUkdCQTsKICAgICAgICAgICAgICAgICp0eXBlID0gR0xfVU5TSUdORURfU0hPUlRfNV81XzVfMTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1I4RzhCODoKICAgICAgICAgICAgaWYgKGNvbG9ya2V5X2FjdGl2ZSkgewogICAgICAgICAgICAgICAgKmNvbnZlcnQgPSBDT05WRVJUX0NLX1JHQjI0OwogICAgICAgICAgICAgICAgKmZvcm1hdCA9IEdMX1JHQkE7CiAgICAgICAgICAgICAgICAqaW50ZXJuYWwgPSBHTF9SR0JBOwogICAgICAgICAgICAgICAgKnR5cGUgPSBHTF9VTlNJR05FRF9JTlRfOF84XzhfODsKICAgICAgICAgICAgICAgICp0YXJnZXRfYnBwID0gNDsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1g4UjhHOEI4OgogICAgICAgICAgICBpZiAoY29sb3JrZXlfYWN0aXZlKSB7CiAgICAgICAgICAgICAgICAqY29udmVydCA9IENPTlZFUlRfUkdCMzJfODg4OwogICAgICAgICAgICAgICAgKmZvcm1hdCA9IEdMX1JHQkE7CiAgICAgICAgICAgICAgICAqaW50ZXJuYWwgPSBHTF9SR0JBOwogICAgICAgICAgICAgICAgKnR5cGUgPSBHTF9VTlNJR05FRF9JTlRfOF84XzhfODsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgYnJlYWs7CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgZDNkZm10X2NvbnZlcnRfc3VyZmFjZShCWVRFICpzcmMsIEJZVEUgKmRzdCwgVUlOVCBwaXRjaCwgVUlOVCBoZWlnaHQsIFVJTlQgb3V0cGl0Y2gsIENPTlZFUlRfVFlQRVMgY29udmVydCwgSVdpbmVEM0RTdXJmYWNlSW1wbCAqc3VyZikgewogICAgQllURSAqZGVzdDsKICAgIFRSQUNFKCIoJXApLT4oJXApLCglZCwlZCwlZCwlZCwlcClcbiIsIHNyYywgZHN0LCBwaXRjaCwgaGVpZ2h0LCBvdXRwaXRjaCwgY29udmVydCwgc3VyZik7CgogICAgc3dpdGNoIChjb252ZXJ0KSB7CiAgICAgICAgY2FzZSBOT19DT05WRVJTSU9OOgogICAgICAgIHsKICAgICAgICAgICAgbWVtY3B5KGRzdCwgc3JjLCBwaXRjaCAqIGhlaWdodCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBjYXNlIENPTlZFUlRfUEFMRVRURUQ6CiAgICAgICAgY2FzZSBDT05WRVJUX1BBTEVUVEVEX0NLOgogICAgICAgIHsKICAgICAgICAgICAgSVdpbmVEM0RQYWxldHRlSW1wbCogcGFsID0gc3VyZi0+cGFsZXR0ZTsKICAgICAgICAgICAgQllURSB0YWJsZVsyNTZdWzRdOwogICAgICAgICAgICB1bnNpZ25lZCBpbnQgaTsKICAgICAgICAgICAgdW5zaWduZWQgaW50IHgsIHk7CgogICAgICAgICAgICBpZiggcGFsID09IE5VTEwpIHsKICAgICAgICAgICAgICAgIC8qIFRPRE86IElmIHdlIGFyZSBhIHN1YmxldmVsLCB0cnkgdG8gZ2V0IHRoZSBwYWxldHRlIGZyb20gbGV2ZWwgMCAqLwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAocGFsID09IE5VTEwpIHsKICAgICAgICAgICAgICAgIC8qIFN0aWxsIG5vIHBhbGV0dGU/IFVzZSB0aGUgZGV2aWNlJ3MgcGFsZXR0ZSAqLwogICAgICAgICAgICAgICAgLyogR2V0IHRoZSBzdXJmYWNlJ3MgcGFsZXR0ZSAqLwogICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IDI1NjsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsICpkZXZpY2UgPSBzdXJmLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOwoKICAgICAgICAgICAgICAgICAgICB0YWJsZVtpXVswXSA9IGRldmljZS0+cGFsZXR0ZXNbZGV2aWNlLT5jdXJyZW50UGFsZXR0ZV1baV0ucGVSZWQ7CiAgICAgICAgICAgICAgICAgICAgdGFibGVbaV1bMV0gPSBkZXZpY2UtPnBhbGV0dGVzW2RldmljZS0+Y3VycmVudFBhbGV0dGVdW2ldLnBlR3JlZW47CiAgICAgICAgICAgICAgICAgICAgdGFibGVbaV1bMl0gPSBkZXZpY2UtPnBhbGV0dGVzW2RldmljZS0+Y3VycmVudFBhbGV0dGVdW2ldLnBlQmx1ZTsKICAgICAgICAgICAgICAgICAgICBpZiAoKGNvbnZlcnQgPT0gQ09OVkVSVF9QQUxFVFRFRF9DSykgJiYKICAgICAgICAgICAgICAgICAgICAgICAgKGkgPj0gc3VyZi0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VMb3dWYWx1ZSkgJiYKICAgICAgICAgICAgICAgICAgICAgICAgKGkgPD0gc3VyZi0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VIaWdoVmFsdWUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIFdlIHNob3VsZCBtYXliZSBoZXJlIHB1dCBhIG1vcmUgJ25ldXRyYWwnIGNvbG9yIHRoYW4gdGhlIHN0YW5kYXJkIGJyaWdodCBwdXJwbGUKICAgICAgICAgICAgICAgICAgICAgICAgICBvbmUgb2Z0ZW4gdXNlZCBieSBhcHBsaWNhdGlvbiB0byBwcmV2ZW50IHRoZSBuaWNlIHB1cnBsZSBib3JkZXJzIHdoZW4gYmktbGluZWFyCiAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyaW5nIGlzIG9uICovCiAgICAgICAgICAgICAgICAgICAgICAgIHRhYmxlW2ldWzNdID0gMHgwMDsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICB0YWJsZVtpXVszXSA9IDB4RkY7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgVFJBQ0UoIlVzaW5nIHN1cmZhY2UgcGFsZXR0ZSAlcFxuIiwgcGFsKTsKICAgICAgICAgICAgICAgIC8qIEdldCB0aGUgc3VyZmFjZSdzIHBhbGV0dGUgKi8KICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCAyNTY7IGkrKykgewogICAgICAgICAgICAgICAgICAgIHRhYmxlW2ldWzBdID0gcGFsLT5wYWxlbnRzW2ldLnBlUmVkOwogICAgICAgICAgICAgICAgICAgIHRhYmxlW2ldWzFdID0gcGFsLT5wYWxlbnRzW2ldLnBlR3JlZW47CiAgICAgICAgICAgICAgICAgICAgdGFibGVbaV1bMl0gPSBwYWwtPnBhbGVudHNbaV0ucGVCbHVlOwogICAgICAgICAgICAgICAgICAgIGlmICgoY29udmVydCA9PSBDT05WRVJUX1BBTEVUVEVEX0NLKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAoaSA+PSBzdXJmLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUxvd1ZhbHVlKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAoaSA8PSBzdXJmLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUhpZ2hWYWx1ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogV2Ugc2hvdWxkIG1heWJlIGhlcmUgcHV0IGEgbW9yZSAnbmV1dHJhbCcgY29sb3IgdGhhbiB0aGUgc3RhbmRhcmQgYnJpZ2h0IHB1cnBsZQogICAgICAgICAgICAgICAgICAgICAgICAgIG9uZSBvZnRlbiB1c2VkIGJ5IGFwcGxpY2F0aW9uIHRvIHByZXZlbnQgdGhlIG5pY2UgcHVycGxlIGJvcmRlcnMgd2hlbiBiaS1saW5lYXIKICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXJpbmcgaXMgb24gKi8KICAgICAgICAgICAgICAgICAgICAgICAgdGFibGVbaV1bM10gPSAweDAwOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRhYmxlW2ldWzNdID0gMHhGRjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAoeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZGVzdCA9IGRzdCArIG91dHBpdGNoICogeTsKICAgICAgICAgICAgICAgIC8qIFRoaXMgaXMgYW4gMSBicHAgZm9ybWF0LCB1c2luZyB0aGUgcGl0Y2ggaGVyZSBpcyBmaW5lICovCiAgICAgICAgICAgICAgICBmb3IgKHggPSAwOyB4IDwgcGl0Y2g7IHgrKykgewogICAgICAgICAgICAgICAgICAgIEJZVEUgY29sb3IgPSAqc3JjKys7CiAgICAgICAgICAgICAgICAgICAgKmRlc3QrKyA9IHRhYmxlW2NvbG9yXVswXTsKICAgICAgICAgICAgICAgICAgICAqZGVzdCsrID0gdGFibGVbY29sb3JdWzFdOwogICAgICAgICAgICAgICAgICAgICpkZXN0KysgPSB0YWJsZVtjb2xvcl1bMl07CiAgICAgICAgICAgICAgICAgICAgKmRlc3QrKyA9IHRhYmxlW2NvbG9yXVszXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBDT05WRVJUX0NLXzU2NToKICAgICAgICB7CiAgICAgICAgICAgIC8qIENvbnZlcnRpbmcgdGhlIDU2NSBmb3JtYXQgaW4gNTU1MSBwYWNrZWQgdG8gZW11bGF0ZSBjb2xvci1rZXlpbmcuCgogICAgICAgICAgICAgIE5vdGUgOiBpbiBhbGwgdGhlc2UgY29udmVyc2lvbiwgaXQgd291bGQgYmUgYmVzdCB0byBhdmVyYWdlIHRoZSBhdmVyYWdpbmcKICAgICAgICAgICAgICAgICAgICAgIHBpeGVscyB0byBnZXQgdGhlIGNvbG9yIG9mIHRoZSBwaXhlbCB0aGF0IHdpbGwgYmUgY29sb3Ita2V5ZWQgdG8KICAgICAgICAgICAgICAgICAgICAgIHByZXZlbnQgJ2NvbG9yIGJsZWVkaW5nJy4gVGhpcyB3aWxsIGJlIGRvbmUgbGF0ZXIgb24gaWYgZXZlciBpdCBpcwogICAgICAgICAgICAgICAgICAgICAgdG9vIHZpc2libGUuCgogICAgICAgICAgICAgIE5vdGUyOiBOdmlkaWEgZG9jdW1lbnRzIHNheSB0aGF0IHRoZWlyIGRyaXZlciBkb2VzIG5vdCBzdXBwb3J0IGFscGhhICsgY29sb3Iga2V5aW5nCiAgICAgICAgICAgICAgICAgICAgIG9uIHRoZSBzYW1lIHN1cmZhY2UgYW5kIGRpc2FibGVzIGNvbG9yIGtleWluZyBpbiBzdWNoIGEgY2FzZQogICAgICAgICAgICAqLwogICAgICAgICAgICB1bnNpZ25lZCBpbnQgeCwgeTsKICAgICAgICAgICAgV09SRCAqU291cmNlOwogICAgICAgICAgICBXT1JEICpEZXN0OwoKICAgICAgICAgICAgVFJBQ0UoIkNvbG9yIGtleWVkIDU2NVxuIik7CgogICAgICAgICAgICBmb3IgKHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKICAgICAgICAgICAgICAgIFNvdXJjZSA9IChXT1JEICopIChzcmMgKyB5ICogcGl0Y2gpOwogICAgICAgICAgICAgICAgRGVzdCA9IChXT1JEICopIChkc3QgKyB5ICogb3V0cGl0Y2gpOwogICAgICAgICAgICAgICAgZm9yICh4ID0gMDsgeCA8IHBpdGNoIC8gMjsgeCsrICkgewogICAgICAgICAgICAgICAgICAgIFdPUkQgY29sb3IgPSAqU291cmNlKys7CiAgICAgICAgICAgICAgICAgICAgKkRlc3QgPSAoKGNvbG9yICYgMHhGRkMwKSB8ICgoY29sb3IgJiAweDFGKSA8PCAxKSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKChjb2xvciA8IHN1cmYtPlNyY0JsdENLZXkuZHdDb2xvclNwYWNlTG93VmFsdWUpIHx8CiAgICAgICAgICAgICAgICAgICAgICAgIChjb2xvciA+IHN1cmYtPlNyY0JsdENLZXkuZHdDb2xvclNwYWNlSGlnaFZhbHVlKSkgewogICAgICAgICAgICAgICAgICAgICAgICAqRGVzdCB8PSAweDAwMDE7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIERlc3QrKzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRVJSKCJVbnN1cHBvcnRlZCBjb252ZXJzYXRpb24gdHlwZSAlZFxuIiwgY29udmVydCk7CiAgICB9CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyogVGhpcyBmdW5jdGlvbiBpcyB1c2VkIGluIGNhc2Ugb2YgOGJpdCBwYWxldHRlZCB0ZXh0dXJlcyB0byB1cGxvYWQgdGhlIHBhbGV0dGUuCiAgIEZvciBub3cgaXQgb25seSBzdXBwb3J0cyBHTF9FWFRfcGFsZXR0ZWRfdGV4dHVyZSBleHRlbnNpb24gYnV0IHN1cHBvcnQgZm9yIG90aGVyCiAgIGV4dGVuc2lvbnMgbGlrZSBBUkJfZnJhZ21lbnRfcHJvZ3JhbSBhbmQgQVRJX2ZyYWdtZW50X3NoYWRlcnMgd2lsbCBiZSBhZGRlZCBhc3dlbGwuCiovCnZvaWQgZDNkZm10X3A4X3VwbG9hZF9wYWxldHRlKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIENPTlZFUlRfVFlQRVMgY29udmVydCkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFBhbGV0dGVJbXBsKiBwYWwgPSBUaGlzLT5wYWxldHRlOwogICAgQllURSB0YWJsZVsyNTZdWzRdOwogICAgaW50IGk7CgogICAgaWYgKHBhbCA9PSBOVUxMKSB7CiAgICAgICAgLyogU3RpbGwgbm8gcGFsZXR0ZT8gVXNlIHRoZSBkZXZpY2UncyBwYWxldHRlICovCiAgICAgICAgLyogR2V0IHRoZSBzdXJmYWNlJ3MgcGFsZXR0ZSAqLwogICAgICAgIGZvciAoaSA9IDA7IGkgPCAyNTY7IGkrKykgewogICAgICAgICAgICBJV2luZUQzRERldmljZUltcGwgKmRldmljZSA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CgogICAgICAgICAgICB0YWJsZVtpXVswXSA9IGRldmljZS0+cGFsZXR0ZXNbZGV2aWNlLT5jdXJyZW50UGFsZXR0ZV1baV0ucGVSZWQ7CiAgICAgICAgICAgIHRhYmxlW2ldWzFdID0gZGV2aWNlLT5wYWxldHRlc1tkZXZpY2UtPmN1cnJlbnRQYWxldHRlXVtpXS5wZUdyZWVuOwogICAgICAgICAgICB0YWJsZVtpXVsyXSA9IGRldmljZS0+cGFsZXR0ZXNbZGV2aWNlLT5jdXJyZW50UGFsZXR0ZV1baV0ucGVCbHVlOwogICAgICAgICAgICBpZiAoKGNvbnZlcnQgPT0gQ09OVkVSVF9QQUxFVFRFRF9DSykgJiYKICAgICAgICAgICAgICAgIChpID49IFRoaXMtPlNyY0JsdENLZXkuZHdDb2xvclNwYWNlTG93VmFsdWUpICYmCiAgICAgICAgICAgICAgICAoaSA8PSBUaGlzLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUhpZ2hWYWx1ZSkpIHsKICAgICAgICAgICAgICAgIC8qIFdlIHNob3VsZCBtYXliZSBoZXJlIHB1dCBhIG1vcmUgJ25ldXRyYWwnIGNvbG9yIHRoYW4gdGhlIHN0YW5kYXJkIGJyaWdodCBwdXJwbGUKICAgICAgICAgICAgICAgICAgIG9uZSBvZnRlbiB1c2VkIGJ5IGFwcGxpY2F0aW9uIHRvIHByZXZlbnQgdGhlIG5pY2UgcHVycGxlIGJvcmRlcnMgd2hlbiBiaS1saW5lYXIKICAgICAgICAgICAgICAgICAgIGZpbHRlcmluZyBpcyBvbiAqLwogICAgICAgICAgICAgICAgdGFibGVbaV1bM10gPSAweDAwOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdGFibGVbaV1bM10gPSAweEZGOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICBUUkFDRSgiVXNpbmcgc3VyZmFjZSBwYWxldHRlICVwXG4iLCBwYWwpOwogICAgICAgIC8qIEdldCB0aGUgc3VyZmFjZSdzIHBhbGV0dGUgKi8KICAgICAgICBmb3IgKGkgPSAwOyBpIDwgMjU2OyBpKyspIHsKICAgICAgICAgICAgdGFibGVbaV1bMF0gPSBwYWwtPnBhbGVudHNbaV0ucGVSZWQ7CiAgICAgICAgICAgIHRhYmxlW2ldWzFdID0gcGFsLT5wYWxlbnRzW2ldLnBlR3JlZW47CiAgICAgICAgICAgIHRhYmxlW2ldWzJdID0gcGFsLT5wYWxlbnRzW2ldLnBlQmx1ZTsKICAgICAgICAgICAgaWYgKChjb252ZXJ0ID09IENPTlZFUlRfUEFMRVRURURfQ0spICYmCiAgICAgICAgICAgICAgICAoaSA+PSBUaGlzLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUxvd1ZhbHVlKSAmJgogICAgICAgICAgICAgICAgKGkgPD0gVGhpcy0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VIaWdoVmFsdWUpKSB7CiAgICAgICAgICAgICAgICAvKiBXZSBzaG91bGQgbWF5YmUgaGVyZSBwdXQgYSBtb3JlICduZXV0cmFsJyBjb2xvciB0aGFuIHRoZSBzdGFuZGFyZCBicmlnaHQgcHVycGxlCiAgICAgICAgICAgICAgICAgICBvbmUgb2Z0ZW4gdXNlZCBieSBhcHBsaWNhdGlvbiB0byBwcmV2ZW50IHRoZSBuaWNlIHB1cnBsZSBib3JkZXJzIHdoZW4gYmktbGluZWFyCiAgICAgICAgICAgICAgICAgICBmaWx0ZXJpbmcgaXMgb24gKi8KICAgICAgICAgICAgICAgIHRhYmxlW2ldWzNdID0gMHgwMDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHRhYmxlW2ldWzNdID0gMHhGRjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIEdMX0VYVENBTEwoZ2xDb2xvclRhYmxlRVhUKEdMX1RFWFRVUkVfMkQsR0xfUkdCQSwyNTYsR0xfUkdCQSxHTF9VTlNJR05FRF9CWVRFLCB0YWJsZSkpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9Mb2FkVGV4dHVyZShJV2luZUQzRFN1cmZhY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIEdMZW51bSBmb3JtYXQsIGludGVybmFsLCB0eXBlOwogICAgQ09OVkVSVF9UWVBFUyBjb252ZXJ0OwogICAgaW50IGJwcDsKICAgIGludCB3aWR0aCwgcGl0Y2gsIG91dHBpdGNoOwogICAgQllURSAqbWVtOwoKICAgIGlmIChUaGlzLT5GbGFncyAmIFNGTEFHX0lOVEVYVFVSRSkgewogICAgICAgIFRSQUNFKCJTdXJmYWNlIGFscmVhZHkgaW4gdGV4dHVyZVxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CiAgICBpZiAoVGhpcy0+RmxhZ3MgJiBTRkxBR19ESVJUWSkgewogICAgICAgIFRSQUNFKCJSZWxvYWRpbmcgYmVjYXVzZSBzdXJmYWNlIGlzIGRpcnR5XG4iKTsKICAgIH0gZWxzZSBpZigvKiBSZWxvYWQ6IGdsIHRleHR1cmUgaGFzIGNrLCBub3cgbm8gY2tleSBpcyBzZXQgT1IgKi8KICAgICAgICAgICAgICAoKFRoaXMtPkZsYWdzICYgU0ZMQUdfR0xDS0VZKSAmJiAoIShUaGlzLT5DS2V5RmxhZ3MgJiBERFNEX0NLU1JDQkxUKSkpIHx8CiAgICAgICAgICAgICAgLyogUmVsb2FkOiB2aWNlIHZlcnNhICBPUiAqLwogICAgICAgICAgICAgICgoIShUaGlzLT5GbGFncyAmIFNGTEFHX0dMQ0tFWSkpICYmIChUaGlzLT5DS2V5RmxhZ3MgJiBERFNEX0NLU1JDQkxUKSkgfHwKICAgICAgICAgICAgICAvKiBBbHNvIHJlbG9hZDogQ29sb3Iga2V5IGlzIGFjdGl2ZSBBTkQgdGhlIGNvbG9yIGtleSBoYXMgY2hhbmdlZCAqLwogICAgICAgICAgICAgICgoVGhpcy0+Q0tleUZsYWdzICYgRERTRF9DS1NSQ0JMVCkgJiYgKAogICAgICAgICAgICAgICAgKFRoaXMtPmdsQ0tleS5kd0NvbG9yU3BhY2VMb3dWYWx1ZSAhPSBUaGlzLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUxvd1ZhbHVlKSB8fAogICAgICAgICAgICAgICAgKFRoaXMtPmdsQ0tleS5kd0NvbG9yU3BhY2VIaWdoVmFsdWUgIT0gVGhpcy0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VIaWdoVmFsdWUpKSkpIHsKICAgICAgICBUUkFDRSgiUmVsb2FkaW5nIGJlY2F1c2Ugb2YgY29sb3Iga2V5aW5nXG4iKTsKICAgIH0gZWxzZSB7CiAgICAgICAgVFJBQ0UoInN1cmZhY2UgaXNuJ3QgZGlydHlcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19ESVJUWTsKCiAgICAvKiBSZXNvdXJjZXMgYXJlIHBsYWNlZCBpbiBzeXN0ZW0gUkFNIGFuZCBkbyBub3QgbmVlZCB0byBiZSByZWNyZWF0ZWQgd2hlbiBhIGRldmljZSBpcyBsb3N0LgogICAgKiAgVGhlc2UgcmVzb3VyY2VzIGFyZSBub3QgYm91bmQgYnkgZGV2aWNlIHNpemUgb3IgZm9ybWF0IHJlc3RyaWN0aW9ucy4gQmVjYXVzZSBvZiB0aGlzLAogICAgKiAgdGhlc2UgcmVzb3VyY2VzIGNhbm5vdCBiZSBhY2Nlc3NlZCBieSB0aGUgRGlyZWN0M0QgZGV2aWNlIG5vciBzZXQgYXMgdGV4dHVyZXMgb3IgcmVuZGVyIHRhcmdldHMuCiAgICAqICBIb3dldmVyLCB0aGVzZSByZXNvdXJjZXMgY2FuIGFsd2F5cyBiZSBjcmVhdGVkLCBsb2NrZWQsIGFuZCBjb3BpZWQuCiAgICAqLwogICAgaWYgKFRoaXMtPnJlc291cmNlLnBvb2wgPT0gV0lORUQzRFBPT0xfU0NSQVRDSCAmJiAhKFRoaXMtPkZsYWdzICYgU0ZMQUdfRk9SQ0VMT0FEKSApCiAgICB7CiAgICAgICAgRklYTUUoIiglcCkgT3BlcmF0aW9uIG5vdCBzdXBwb3J0ZWQgZm9yIHNjcmF0Y2ggdGV4dHVyZXNcbiIsVGhpcyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgaWYgKFRoaXMtPkZsYWdzICYgU0ZMQUdfSU5QQlVGRkVSKSB7CiAgICAgICAgaWYgKFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwgIT0gMCkKICAgICAgICAgICAgRklYTUUoIlN1cmZhY2UgaW4gdGV4dHVyZSBpcyBvbmx5IHN1cHBvcnRlZCBmb3IgbGV2ZWwgMFxuIik7CiAgICAgICAgZWxzZSBpZiAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfUDggfHwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfQThQOCB8fAogICAgICAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDEgfHwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMiB8fAogICAgICAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDMgfHwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNCB8fAogICAgICAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDUpCiAgICAgICAgICAgIEZJWE1FKCJGb3JtYXQgJWQgbm90IHN1cHBvcnRlZFxuIiwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0KTsKICAgICAgICBlbHNlIHsKICAgICAgICAgICAgR0xpbnQgcHJldlJlYWQ7CgogICAgICAgICAgICBFTlRFUl9HTCgpOwoKICAgICAgICAgICAgZ2xHZXRJbnRlZ2VydihHTF9SRUFEX0JVRkZFUiwgJnByZXZSZWFkKTsKICAgICAgICAgICAgdmNoZWNrR0xjYWxsKCJnbEdldEludGVnZXJ2Iik7CiAgICAgICAgICAgIGdsUmVhZEJ1ZmZlcihHTF9CQUNLKTsKICAgICAgICAgICAgdmNoZWNrR0xjYWxsKCJnbFJlYWRCdWZmZXIiKTsKCiAgICAgICAgICAgIGdsQ29weVRleEltYWdlMkQoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0SW50ZXJuYWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPmN1cnJlbnREZXNjLldpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwKTsKCiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbENvcHlUZXhJbWFnZTJEIik7CiAgICAgICAgICAgIGdsUmVhZEJ1ZmZlcihwcmV2UmVhZCk7CiAgICAgICAgICAgIHZjaGVja0dMY2FsbCgiZ2xSZWFkQnVmZmVyIik7CgogICAgICAgICAgICBMRUFWRV9HTCgpOwoKICAgICAgICAgICAgVFJBQ0UoIlVwZGF0aW5nIHRhcmdldCAlZFxuIiwgVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQpOwogICAgICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19JTlRFWFRVUkU7CiAgICAgICAgfQogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIGlmKFRoaXMtPkNLZXlGbGFncyAmIEREU0RfQ0tTUkNCTFQpIHsKICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19HTENLRVk7CiAgICAgICAgVGhpcy0+Z2xDS2V5ID0gVGhpcy0+U3JjQmx0Q0tleTsKICAgIH0KICAgIGVsc2UgVGhpcy0+RmxhZ3MgJj0gflNGTEFHX0dMQ0tFWTsKCiAgICBkM2RmbXRfZ2V0X2NvbnYoVGhpcywgVFJVRSAvKiBXZSBuZWVkIGNvbG9yIGtleWluZyAqLywgVFJVRSAvKiBXZSB3aWxsIHVzZSB0ZXh0dXJlcyAqLywgJmZvcm1hdCwgJmludGVybmFsLCAmdHlwZSwgJmNvbnZlcnQsICZicHApOwoKICAgIC8qIFRoZSB3aWR0aCBpcyBpbiAnbGVuZ3RoJyBub3QgaW4gYnl0ZXMgKi8KICAgIGlmIChOUDJfUkVQQUNLID09IHdpbmVkM2Rfc2V0dGluZ3Mubm9ucG93ZXIyX21vZGUgfHwgVGhpcy0+cmVzb3VyY2UudXNhZ2UgJiBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUKQogICAgICAgIHdpZHRoID0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICBlbHNlCiAgICAgICAgd2lkdGggPSBUaGlzLT5wb3cyV2lkdGg7CgogICAgcGl0Y2ggPSBJV2luZUQzRFN1cmZhY2VfR2V0UGl0Y2goaWZhY2UpOwoKICAgIGlmKChjb252ZXJ0ICE9IE5PX0NPTlZFUlNJT04pICYmIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSkgewogICAgICAgIGludCBoZWlnaHQgPSBUaGlzLT5nbFJlY3QuYm90dG9tIC0gVGhpcy0+Z2xSZWN0LnRvcDsKCiAgICAgICAgLyogU3RpY2sgdG8gdGhlIGFsaWdubWVudCBmb3IgdGhlIGNvbnZlcnRlZCBzdXJmYWNlIHRvbywgbWFrZXMgaXQgZWFzaWVyIHRvIGxvYWQgdGhlIHN1cmZhY2UgKi8KICAgICAgICBvdXRwaXRjaCA9IHdpZHRoICogYnBwOwogICAgICAgIG91dHBpdGNoID0gKG91dHBpdGNoICsgMykgJiB+MzsKCiAgICAgICAgbWVtID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIG91dHBpdGNoICogaGVpZ2h0KTsKICAgICAgICBpZighbWVtKSB7CiAgICAgICAgICAgIEVSUigiT3V0IG9mIG1lbW9yeSAlZCwgJWQhXG4iLCBvdXRwaXRjaCwgaGVpZ2h0KTsKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfT1VUT0ZWSURFT01FTU9SWTsKICAgICAgICB9CiAgICAgICAgZDNkZm10X2NvbnZlcnRfc3VyZmFjZShUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnksIG1lbSwgcGl0Y2gsIGhlaWdodCwgb3V0cGl0Y2gsIGNvbnZlcnQsIFRoaXMpOwoKICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19DT05WRVJURUQ7CiAgICB9IGVsc2UgaWYgKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX1A4ICYmIEdMX1NVUFBPUlQoRVhUX1BBTEVUVEVEX1RFWFRVUkUpKSB7CiAgICAgICAgZDNkZm10X3A4X3VwbG9hZF9wYWxldHRlKGlmYWNlLCBjb252ZXJ0KTsKICAgICAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfQ09OVkVSVEVEOwogICAgICAgIG1lbSA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeTsKICAgIH0gZWxzZSB7CiAgICAgICAgVGhpcy0+RmxhZ3MgJj0gflNGTEFHX0NPTlZFUlRFRDsKICAgICAgICBtZW0gPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnk7CiAgICB9CgogICAgLyogTWFrZSBzdXJlIHRoZSBjb3JyZWN0IHBpdGNoIGlzIHVzZWQgKi8KICAgIGdsUGl4ZWxTdG9yZWkoR0xfVU5QQUNLX1JPV19MRU5HVEgsIHdpZHRoKTsKCiAgICBpZiAoTlAyX1JFUEFDSyA9PSB3aW5lZDNkX3NldHRpbmdzLm5vbnBvd2VyMl9tb2RlICYmIChUaGlzLT5GbGFncyAmIFNGTEFHX05PTlBPVzIpICYmICEoVGhpcy0+RmxhZ3MgJiBTRkxBR19PVkVSU0laRSkpIHsKICAgICAgICBUUkFDRSgibm9uIHBvd2VyIG9mIHR3byBzdXBwb3J0XG4iKTsKICAgICAgICBzdXJmYWNlX2FsbG9jYXRlX3N1cmZhY2UoVGhpcywgaW50ZXJuYWwsIFRoaXMtPnBvdzJXaWR0aCwgVGhpcy0+cG93MkhlaWdodCwgZm9ybWF0LCB0eXBlKTsKICAgICAgICBpZiAobWVtKSB7CiAgICAgICAgICAgIHN1cmZhY2VfdXBsb2FkX2RhdGEoVGhpcywgVGhpcy0+cG93MldpZHRoLCBUaGlzLT5wb3cySGVpZ2h0LCBmb3JtYXQsIHR5cGUsIG1lbSk7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICBzdXJmYWNlX2FsbG9jYXRlX3N1cmZhY2UoVGhpcywgaW50ZXJuYWwsIFRoaXMtPmdsUmVjdC5yaWdodCAtIFRoaXMtPmdsUmVjdC5sZWZ0LCBUaGlzLT5nbFJlY3QuYm90dG9tIC0gVGhpcy0+Z2xSZWN0LnRvcCwgZm9ybWF0LCB0eXBlKTsKICAgICAgICBpZiAobWVtKSB7CiAgICAgICAgICAgIHN1cmZhY2VfdXBsb2FkX2RhdGEoVGhpcywgVGhpcy0+Z2xSZWN0LnJpZ2h0IC0gVGhpcy0+Z2xSZWN0LmxlZnQsIFRoaXMtPmdsUmVjdC5ib3R0b20gLSBUaGlzLT5nbFJlY3QudG9wLCBmb3JtYXQsIHR5cGUsIG1lbSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qIFJlc3RvcmUgdGhlIGRlZmF1bHQgcGl0Y2ggKi8KICAgIGdsUGl4ZWxTdG9yZWkoR0xfVU5QQUNLX1JPV19MRU5HVEgsIDApOwoKICAgIGlmIChtZW0gIT0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KQogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG1lbSk7CgojaWYgMAogICAgewogICAgICAgIHN0YXRpYyB1bnNpZ25lZCBpbnQgZ2VuID0gMDsKICAgICAgICBjaGFyIGJ1ZmZlcls0MDk2XTsKICAgICAgICArK2dlbjsKICAgICAgICBpZiAoKGdlbiAlIDEwKSA9PSAwKSB7CiAgICAgICAgICAgIHNucHJpbnRmKGJ1ZmZlciwgc2l6ZW9mKGJ1ZmZlciksICIvdG1wL3N1cmZhY2UlcF90eXBlJXVfbGV2ZWwldV8ldS5wcG0iLCBUaGlzLCBUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCwgVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCwgZ2VuKTsKICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TYXZlU25hcHNob3QoaWZhY2UsIGJ1ZmZlcik7CiAgICAgICAgfQogICAgICAgIC8qCiAgICAgICAgICogZGVidWdnaW5nIGNyYXNoIGNvZGUKICAgICAgICAgaWYgKGdlbiA9PSAyNTApIHsKICAgICAgICAgdm9pZCoqIHRlc3QgPSBOVUxMOwogICAgICAgICAqdGVzdCA9IDA7CiAgICAgICAgIH0KICAgICAgICAgKi8KICAgIH0KI2VuZGlmCgogICAgaWYgKCEoVGhpcy0+RmxhZ3MgJiBTRkxBR19ET05PVEZSRUUpKSB7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKICAgICAgICBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgPSBOVUxMOwogICAgfQoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgojaW5jbHVkZSA8ZXJybm8uaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfU2F2ZVNuYXBzaG90KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIGNvbnN0IGNoYXIqIGZpbGVuYW1lKSB7CiAgICBGSUxFKiBmID0gTlVMTDsKICAgIFVJTlQgaSwgeTsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgY2hhciAqYWxsb2NhdGVkTWVtb3J5OwogICAgY2hhciAqdGV4dHVyZVJvdzsKICAgIElXaW5lRDNEU3dhcENoYWluICpzd2FwQ2hhaW4gPSBOVUxMOwogICAgaW50IHdpZHRoLCBoZWlnaHQ7CiAgICBHTHVpbnQgdG1wVGV4dHVyZSA9IDA7CiAgICBEV09SRCBjb2xvcjsKICAgIC8qRklYTUU6CiAgICBUZXh0dXJlcyBteSBub3QgYmUgc3RvcmVkIGluIC0+YWxsb2NhdGVkZ01lbW9yeSBhbmQgYSBHbFRleHR1cmUKICAgIHNvIHdlIHNob3VsZCBsb2NrIHRoZSBzdXJmYWNlIGJlZm9yZSBzYXZpbmcgYSBzbmFwc2hvdCwgb3IgYXQgbGVhc3QgY2hlY2sgdGhhdAogICAgKi8KICAgIC8qIFRPRE86IENvbXByZXNzZWQgdGV4dHVyZSBpbWFnZXMgY2FuIGJlIG9idGFpbmVkIGZyb20gdGhlIEdMIGluIHVuY29tcHJlc3NlZCBmb3JtCiAgICBieSBjYWxsaW5nIEdldFRleEltYWdlIGFuZCBpbiBjb21wcmVzc2VkIGZvcm0gYnkgY2FsbGluZwogICAgR2V0Q29tcHJlc3NlZFRleEltYWdlQVJCLiAgUXVlcmllZCBjb21wcmVzc2VkIGltYWdlcyBjYW4gYmUgc2F2ZWQgYW5kCiAgICBsYXRlciByZXVzZWQgYnkgY2FsbGluZyBDb21wcmVzc2VkVGV4SW1hZ2VbMTIzXURBUkIuICBQcmUtY29tcHJlc3NlZAogICAgdGV4dHVyZSBpbWFnZXMgZG8gbm90IG5lZWQgdG8gYmUgcHJvY2Vzc2VkIGJ5IHRoZSBHTCBhbmQgc2hvdWxkCiAgICBzaWduaWZpY2FudGx5IGltcHJvdmUgdGV4dHVyZSBsb2FkaW5nIHBlcmZvcm1hbmNlIHJlbGF0aXZlIHRvIHVuY29tcHJlc3NlZAogICAgaW1hZ2VzLiAqLwoKLyogU2V0dXAgdGhlIHdpZHRoIGFuZCBoZWlnaHQgdG8gYmUgdGhlIGludGVybmFsIHRleHR1cmUgd2lkdGggYW5kIGhlaWdodC4gKi8KICAgIHdpZHRoICA9IFRoaXMtPnBvdzJXaWR0aDsKICAgIGhlaWdodCA9IFRoaXMtPnBvdzJIZWlnaHQ7Ci8qIGNoZWNrIHRvIHNlZSBpZiB3ZXJlIGEgJ3ZpcnR1YWwnIHRleHR1cmUgZS5nLiB3ZXJlIG5vdCBhIHBidWZmZXIgb2YgdGV4dHVyZSB3ZXJlIGEgYmFjayBidWZmZXIqLwogICAgSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lcihpZmFjZSwgJklJRF9JV2luZUQzRFN3YXBDaGFpbiwgKHZvaWQgKiopJnN3YXBDaGFpbik7CgogICAgaWYgKHN3YXBDaGFpbiB8fCAoVGhpcy0+RmxhZ3MgJiBTRkxBR19JTlBCVUZGRVIpKSB7IC8qIGlmIHdlcmUgbm90IGEgcmVhbCB0ZXh0dXJlIHRoZW4gcmVhZCB0aGUgYmFjayBidWZmZXIgaW50byBhIHJlYWwgdGV4dHVyZSovCi8qIHdlIGRvbid0IHdhbnQgdG8gaW50ZXJmZXJlIHdpdGggdGhlIGJhY2sgYnVmZmVyIHNvIHJlYWQgdGhlIGRhdGEgaW50byBhIHRlbXBvcmFyeSB0ZXh0dXJlIGFuZCB0aGVuIHNhdmUgdGhlIGRhdGEgb3V0IG9mIHRoZSB0ZW1wb3JhcnkgdGV4dHVyZSAqLwogICAgICAgIEdMaW50IHByZXZSZWFkOwogICAgICAgIEVOVEVSX0dMKCk7CiAgICAgICAgRklYTUUoIiglcCkgVGhpcyBzdXJmYWNlIG5lZWRzIHRvIGJlIGxvY2tlZCBiZWZvcmUgYSBzbmFwc2hvdCBjYW4gYmUgdGFrZW5cbiIsIFRoaXMpOwogICAgICAgIGdsRW5hYmxlKEdMX1RFWFRVUkVfMkQpOwoKICAgICAgICBnbEdlblRleHR1cmVzKDEsICZ0bXBUZXh0dXJlKTsKICAgICAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIHRtcFRleHR1cmUpOwoKICAgICAgICBnbFRleEltYWdlMkQoR0xfVEVYVFVSRV8yRCwKICAgICAgICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgICAgICAgR0xfUkdCQSwKICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgMC8qYm9yZGVyKi8sCiAgICAgICAgICAgICAgICAgICAgICAgIEdMX1JHQkEsCiAgICAgICAgICAgICAgICAgICAgICAgIEdMX1VOU0lHTkVEX0lOVF84XzhfOF84X1JFViwKICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7CgogICAgICAgIGdsR2V0SW50ZWdlcnYoR0xfUkVBRF9CVUZGRVIsICZwcmV2UmVhZCk7CiAgICAgICAgdmNoZWNrR0xjYWxsKCJnbEdldEludGVnZXJ2Iik7CiAgICAgICAgZ2xSZWFkQnVmZmVyKEdMX0JBQ0spOwogICAgICAgIHZjaGVja0dMY2FsbCgiZ2xSZWFkQnVmZmVyIik7CiAgICAgICAgZ2xDb3B5VGV4SW1hZ2UyRChHTF9URVhUVVJFXzJELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdMX1JHQkEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgMCk7CgogICAgICAgIGNoZWNrR0xjYWxsKCJnbENvcHlUZXhJbWFnZTJEIik7CiAgICAgICAgZ2xSZWFkQnVmZmVyKHByZXZSZWFkKTsKICAgICAgICBMRUFWRV9HTCgpOwoKICAgIH0gZWxzZSB7IC8qIGJpbmQgdGhlIHJlYWwgdGV4dHVyZSAqLwogICAgICAgIElXaW5lRDNEU3VyZmFjZV9QcmVMb2FkKGlmYWNlKTsKICAgIH0KICAgIGFsbG9jYXRlZE1lbW9yeSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCB3aWR0aCAgKiBoZWlnaHQgKiA0KTsKICAgIEVOVEVSX0dMKCk7CiAgICBGSVhNRSgiU2F2aW5nIHRleHR1cmUgbGV2ZWwgJWQgd2lkdGggJWQgaGVpZ2h0ICVkXG4iLCBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLCB3aWR0aCwgaGVpZ2h0KTsKICAgIGdsR2V0VGV4SW1hZ2UoR0xfVEVYVFVSRV8yRCwKICAgICAgICAgICAgICAgIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsCiAgICAgICAgICAgICAgICBHTF9SR0JBLAogICAgICAgICAgICAgICAgR0xfVU5TSUdORURfSU5UXzhfOF84XzhfUkVWLAogICAgICAgICAgICAgICAgYWxsb2NhdGVkTWVtb3J5KTsKICAgIGNoZWNrR0xjYWxsKCJnbFRleEltYWdlMkQiKTsKICAgIGlmICh0bXBUZXh0dXJlKSB7CiAgICAgICAgZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCAwKTsKICAgICAgICBnbERlbGV0ZVRleHR1cmVzKDEsICZ0bXBUZXh0dXJlKTsKICAgIH0KICAgIExFQVZFX0dMKCk7CgogICAgZiA9IGZvcGVuKGZpbGVuYW1lLCAidysiKTsKICAgIGlmIChOVUxMID09IGYpIHsKICAgICAgICBFUlIoIm9wZW5pbmcgb2YgJXMgZmFpbGVkIHdpdGg6ICVzXG4iLCBmaWxlbmFtZSwgc3RyZXJyb3IoZXJybm8pKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KLyogU2F2ZSB0aGUgZGF0IG91dCB0byBhIFRHQSBmaWxlIGJlY2F1c2UgMTogaXQncyBhbiBlYXN5IHJhdyBmb3JtYXQsIDI6IGl0IHN1cHBvcnRzIGFuIGFscGhhIGNoYW5lbCovCiAgICBUUkFDRSgiKCVwKSBvcGVuZWQgJXMgd2l0aCBmb3JtYXQgJXNcbiIsIFRoaXMsIGZpbGVuYW1lLCBkZWJ1Z19kM2Rmb3JtYXQoVGhpcy0+cmVzb3VyY2UuZm9ybWF0KSk7Ci8qIFRHQSBoZWFkZXIgKi8KICAgIGZwdXRjKDAsZik7CiAgICBmcHV0YygwLGYpOwogICAgZnB1dGMoMixmKTsKICAgIGZwdXRjKDAsZik7CiAgICBmcHV0YygwLGYpOwogICAgZnB1dGMoMCxmKTsKICAgIGZwdXRjKDAsZik7CiAgICBmcHV0YygwLGYpOwogICAgZnB1dGMoMCxmKTsKICAgIGZwdXRjKDAsZik7CiAgICBmcHV0YygwLGYpOwogICAgZnB1dGMoMCxmKTsKLyogc2hvcnQgd2lkdGgqLwogICAgZndyaXRlKCZ3aWR0aCwyLDEsZik7Ci8qIHNob3J0IGhlaWdodCAqLwogICAgZndyaXRlKCZoZWlnaHQsMiwxLGYpOwovKiBmb3JtYXQgcmdiYSAqLwogICAgZnB1dGMoMHgyMCxmKTsKICAgIGZwdXRjKDB4MjgsZik7Ci8qIHJhdyBkYXRhICovCiAgICAvKiBpZiAgdGhlIGRhdGEgaXMgdXBzaWRlIGRvd24gaWYgd2UndmUgZmV0Y2hlZCBpdCBmcm9tIGEgYmFjayBidWZmZXIsIHNvIGl0IG5lZWRzIGZsaXBwaW5nIGFnYWluIHRvIG1ha2UgaXQgdGhlIGNvcnJlY3Qgd2F5IHVwKi8KICAgIGlmKHN3YXBDaGFpbikKICAgICAgICB0ZXh0dXJlUm93ID0gYWxsb2NhdGVkTWVtb3J5ICsgKHdpZHRoICogKGhlaWdodCAtIDEpICo0KTsKICAgIGVsc2UKICAgICAgICB0ZXh0dXJlUm93ID0gYWxsb2NhdGVkTWVtb3J5OwogICAgZm9yICh5ID0gMCA7IHkgPCBoZWlnaHQ7IHkrKykgewogICAgICAgIGZvciAoaSA9IDA7IGkgPCB3aWR0aDsgIGkrKykgewogICAgICAgICAgICBjb2xvciA9ICooKERXT1JEKil0ZXh0dXJlUm93KTsKICAgICAgICAgICAgZnB1dGMoKGNvbG9yID4+IDE2KSAmIDB4RkYsIGYpOyAvKiBCICovCiAgICAgICAgICAgIGZwdXRjKChjb2xvciA+PiAgOCkgJiAweEZGLCBmKTsgLyogRyAqLwogICAgICAgICAgICBmcHV0YygoY29sb3IgPj4gIDApICYgMHhGRiwgZik7IC8qIFIgKi8KICAgICAgICAgICAgZnB1dGMoKGNvbG9yID4+IDI0KSAmIDB4RkYsIGYpOyAvKiBBICovCiAgICAgICAgICAgIHRleHR1cmVSb3cgKz0gNDsKICAgICAgICB9CiAgICAgICAgLyogdGFrZSB0d28gcm93cyBvZiB0aGUgcG9pbnRlciB0byB0aGUgdGV4dHVyZSBtZW1vcnkgKi8KICAgICAgICBpZihzd2FwQ2hhaW4pCiAgICAgICAgICAgICh0ZXh0dXJlUm93LT0gd2lkdGggPDwgMyk7CgogICAgfQogICAgVFJBQ0UoIkNsb3NpbmcgZmlsZVxuIik7CiAgICBmY2xvc2UoZik7CgogICAgaWYoc3dhcENoYWluKSB7CiAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZShzd2FwQ2hhaW4pOwogICAgfQogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgYWxsb2NhdGVkTWVtb3J5KTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0NsZWFuRGlydHlSZWN0KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgVGhpcy0+RmxhZ3MgJj0gflNGTEFHX0RJUlRZOwogICAgVGhpcy0+ZGlydHlSZWN0LmxlZnQgICA9IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoOwogICAgVGhpcy0+ZGlydHlSZWN0LnRvcCAgICA9IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgIFRoaXMtPmRpcnR5UmVjdC5yaWdodCAgPSAwOwogICAgVGhpcy0+ZGlydHlSZWN0LmJvdHRvbSA9IDA7CiAgICBUUkFDRSgiKCVwKSA6IERpcnR5PyVkLCBSZWN0OiglZCwlZCwlZCwlZClcbiIsIFRoaXMsIFRoaXMtPkZsYWdzICYgU0ZMQUdfRElSVFkgPyAxIDogMCwgVGhpcy0+ZGlydHlSZWN0LmxlZnQsCiAgICAgICAgICBUaGlzLT5kaXJ0eVJlY3QudG9wLCBUaGlzLT5kaXJ0eVJlY3QucmlnaHQsIFRoaXMtPmRpcnR5UmVjdC5ib3R0b20pOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qKgogKiAgIFNsaWdodGx5IGluZWZmaWNpZW50IHdheSB0byBoYW5kbGUgbXVsdGlwbGUgZGlydHkgcmVjdHMgYnV0IGl0IHdvcmtzIDopCiAqLwpleHRlcm4gSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9BZGREaXJ0eVJlY3QoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgQ09OU1QgUkVDVCogcERpcnR5UmVjdCkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzREJhc2VUZXh0dXJlICpiYXNlVGV4dHVyZSA9IE5VTEw7CiAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19ESVJUWTsKICAgIGlmIChOVUxMICE9IHBEaXJ0eVJlY3QpIHsKICAgICAgICBUaGlzLT5kaXJ0eVJlY3QubGVmdCAgID0gbWluKFRoaXMtPmRpcnR5UmVjdC5sZWZ0LCAgIHBEaXJ0eVJlY3QtPmxlZnQpOwogICAgICAgIFRoaXMtPmRpcnR5UmVjdC50b3AgICAgPSBtaW4oVGhpcy0+ZGlydHlSZWN0LnRvcCwgICAgcERpcnR5UmVjdC0+dG9wKTsKICAgICAgICBUaGlzLT5kaXJ0eVJlY3QucmlnaHQgID0gbWF4KFRoaXMtPmRpcnR5UmVjdC5yaWdodCwgIHBEaXJ0eVJlY3QtPnJpZ2h0KTsKICAgICAgICBUaGlzLT5kaXJ0eVJlY3QuYm90dG9tID0gbWF4KFRoaXMtPmRpcnR5UmVjdC5ib3R0b20sIHBEaXJ0eVJlY3QtPmJvdHRvbSk7CiAgICB9IGVsc2UgewogICAgICAgIFRoaXMtPmRpcnR5UmVjdC5sZWZ0ICAgPSAwOwogICAgICAgIFRoaXMtPmRpcnR5UmVjdC50b3AgICAgPSAwOwogICAgICAgIFRoaXMtPmRpcnR5UmVjdC5yaWdodCAgPSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICBUaGlzLT5kaXJ0eVJlY3QuYm90dG9tID0gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0OwogICAgfQogICAgVFJBQ0UoIiglcCkgOiBEaXJ0eT8lZCwgUmVjdDooJWQsJWQsJWQsJWQpXG4iLCBUaGlzLCBUaGlzLT5GbGFncyAmIFNGTEFHX0RJUlRZLCBUaGlzLT5kaXJ0eVJlY3QubGVmdCwKICAgICAgICAgIFRoaXMtPmRpcnR5UmVjdC50b3AsIFRoaXMtPmRpcnR5UmVjdC5yaWdodCwgVGhpcy0+ZGlydHlSZWN0LmJvdHRvbSk7CiAgICAvKiBpZiB0aGUgY29udGFpbmVyIGlzIGEgYmFzZXRleHR1cmUgdGhlbiBtYXJrIGl0IGRpcnR5LiAqLwogICAgaWYgKElXaW5lRDNEU3VyZmFjZV9HZXRDb250YWluZXIoaWZhY2UsICZJSURfSVdpbmVEM0RCYXNlVGV4dHVyZSwgKHZvaWQgKiopJmJhc2VUZXh0dXJlKSA9PSBXSU5FRDNEX09LKSB7CiAgICAgICAgVFJBQ0UoIlBhc3NpbmcgdG8gY29uYXRpbmVyXG4iKTsKICAgICAgICBJV2luZUQzREJhc2VUZXh0dXJlX1NldERpcnR5KGJhc2VUZXh0dXJlLCBUUlVFKTsKICAgICAgICBJV2luZUQzREJhc2VUZXh0dXJlX1JlbGVhc2UoYmFzZVRleHR1cmUpOwogICAgfQogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0Q29udGFpbmVyKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIElXaW5lRDNEQmFzZSAqY29udGFpbmVyKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKCiAgICBUUkFDRSgiVGhpcyAlcCwgY29udGFpbmVyICVwXG4iLCBUaGlzLCBjb250YWluZXIpOwoKICAgIC8qIFdlIGNhbid0IGtlZXAgYSByZWZlcmVuY2UgdG8gdGhlIGNvbnRhaW5lciwgc2luY2UgdGhlIGNvbnRhaW5lciBhbHJlYWR5IGtlZXBzIGEgcmVmZXJlbmNlIHRvIHVzLiAqLwoKICAgIFRSQUNFKCJTZXR0aW5nIGNvbnRhaW5lciB0byAlcCBmcm9tICVwXG4iLCBjb250YWluZXIsIFRoaXMtPmNvbnRhaW5lcik7CiAgICBUaGlzLT5jb250YWluZXIgPSBjb250YWluZXI7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0Rm9ybWF0KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIFdJTkVEM0RGT1JNQVQgZm9ybWF0KSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIGNvbnN0IFBpeGVsRm9ybWF0RGVzYyAqZm9ybWF0RW50cnkgPSBnZXRGb3JtYXREZXNjRW50cnkoZm9ybWF0KTsKCiAgICBpZiAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ICE9IFdJTkVEM0RGTVRfVU5LTk9XTikgewogICAgICAgIEZJWE1FKCIoJXApIDogVGhlIGZvcmFtdCBvZiB0aGUgc3VyZmFjZSBtdXN0IGJlIFdJTkVEM0RGT1JNQVRfVU5LTk9XTlxuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgVFJBQ0UoIiglcCkgOiBTZXR0aW5nIHRleHR1cmUgZm9yYW10IHRvICglZCwlcylcbiIsIFRoaXMsIGZvcm1hdCwgZGVidWdfZDNkZm9ybWF0KGZvcm1hdCkpOwogICAgaWYgKGZvcm1hdCA9PSBXSU5FRDNERk1UX1VOS05PV04pIHsKICAgICAgICBUaGlzLT5yZXNvdXJjZS5zaXplID0gMDsKICAgIH0gZWxzZSBpZiAoZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMSkgewogICAgICAgIC8qIERYVDEgaXMgaGFsZiBieXRlIHBlciBwaXhlbCAqLwogICAgICAgIFRoaXMtPnJlc291cmNlLnNpemUgPSAoKG1heChUaGlzLT5wb3cyV2lkdGgsIDQpICogZm9ybWF0RW50cnktPmJwcCkgKiBtYXgoVGhpcy0+cG93MkhlaWdodCwgNCkpID4+IDE7CgogICAgfSBlbHNlIGlmIChmb3JtYXQgPT0gV0lORUQzREZNVF9EWFQyIHx8IGZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDMgfHwKICAgICAgICAgICAgICAgZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNCB8fCBmb3JtYXQgPT0gV0lORUQzREZNVF9EWFQ1KSB7CiAgICAgICAgVGhpcy0+cmVzb3VyY2Uuc2l6ZSA9ICgobWF4KFRoaXMtPnBvdzJXaWR0aCwgNCkgKiBmb3JtYXRFbnRyeS0+YnBwKSAqIG1heChUaGlzLT5wb3cySGVpZ2h0LCA0KSk7CiAgICB9IGVsc2UgewogICAgICAgIFRoaXMtPnJlc291cmNlLnNpemUgPSAoKFRoaXMtPnBvdzJXaWR0aCAqIGZvcm1hdEVudHJ5LT5icHApICsgMykgJiB+MzsKICAgICAgICBUaGlzLT5yZXNvdXJjZS5zaXplICo9IFRoaXMtPnBvdzJIZWlnaHQ7CiAgICB9CgoKICAgIC8qIFNldHVwIHNvbWUgZ2xmb3JtYXQgZGVmYXVsdHMgKi8KICAgIFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xGb3JtYXQgICAgICAgICA9IGZvcm1hdEVudHJ5LT5nbEZvcm1hdDsKICAgIFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xGb3JtYXRJbnRlcm5hbCA9IGZvcm1hdEVudHJ5LT5nbEludGVybmFsOwogICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbFR5cGUgICAgICAgICAgID0gZm9ybWF0RW50cnktPmdsVHlwZTsKCiAgICBpZiAoZm9ybWF0ICE9IFdJTkVEM0RGTVRfVU5LTk9XTikgewogICAgICAgIFRoaXMtPmJ5dGVzUGVyUGl4ZWwgPSBmb3JtYXRFbnRyeS0+YnBwOwogICAgICAgIFRoaXMtPnBvdzJTaXplICAgICAgPSAoVGhpcy0+cG93MldpZHRoICogVGhpcy0+Ynl0ZXNQZXJQaXhlbCkgKiBUaGlzLT5wb3cySGVpZ2h0OwogICAgfSBlbHNlIHsKICAgICAgICBUaGlzLT5ieXRlc1BlclBpeGVsID0gMDsKICAgICAgICBUaGlzLT5wb3cyU2l6ZSAgICAgID0gMDsKICAgIH0KCiAgICBUaGlzLT5GbGFncyB8PSAoV0lORUQzREZNVF9EMTZfTE9DS0FCTEUgPT0gZm9ybWF0KSA/IFNGTEFHX0xPQ0tBQkxFIDogMDsKCiAgICBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPSBmb3JtYXQ7CgogICAgVFJBQ0UoIiglcCkgOiBTaXplICVkLCBwb3cyU2l6ZSAlZCwgYnl0ZXNQZXJQaXhlbCAlZCwgZ2xGb3JtYXQgJWQsIGdsRm90bWF0SW50ZXJuYWwgJWQsIGdsVHlwZSAlZFxuIiwgVGhpcywgVGhpcy0+cmVzb3VyY2Uuc2l6ZSwgVGhpcy0+cG93MlNpemUsIFRoaXMtPmJ5dGVzUGVyUGl4ZWwsIFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xGb3JtYXQsIFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xGb3JtYXRJbnRlcm5hbCwgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbFR5cGUpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1NldE1lbShJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCB2b2lkICpNZW0pIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBpZmFjZTsKCiAgICAvKiBSZW5kZXIgdGFyZ2V0cyBkZXBlbmQgb24gdGhlaXIgaGRjLCBhbmQgd2UgY2FuJ3QgY3JlYXRlIGEgaGRjIG9uIGEgdXNlciBwb2ludGVyICovCiAgICBpZihUaGlzLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQpIHsKICAgICAgICBFUlIoIk5vdCBzdXBwb3J0ZWQgb24gcmVuZGVyIHRhcmdldHNcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIGlmKFRoaXMtPkZsYWdzICYgKFNGTEFHX0xPQ0tFRCB8IFNGTEFHX0RDSU5VU0UpKSB7CiAgICAgICAgV0FSTigiU3VyZmFjZSBpcyBsb2NrZWQgb3IgdGhlIEhEQyBpcyBpbiB1c2VcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIGlmKE1lbSAmJiBNZW0gIT0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KSB7CgogICAgICAgIC8qIERvIEkgaGF2ZSB0byBjb3B5IHRoZSBvbGQgc3VyZmFjZSBjb250ZW50PyAqLwogICAgICAgIGlmKFRoaXMtPkZsYWdzICYgU0ZMQUdfRElCU0VDVElPTikgewogICAgICAgICAgICAgICAgLyogUmVsZWFzZSB0aGUgREMuIE5vIG5lZWQgdG8gaG9sZCB0aGUgY3JpdGljYWwgc2VjdGlvbiBmb3IgdGhlIHVwZGF0ZQogICAgICAgICAgICAgICAgICogVGhyZWFkIGJlY2F1c2UgdGhpcyB0aHJlYWQgcnVucyBvbmx5IG9uIGZyb250IGJ1ZmZlcnMsIGJ1dCB0aGlzIG1ldGhvZAogICAgICAgICAgICAgICAgICogZmFpbHMgZm9yIHJlbmRlciB0YXJnZXRzIGluIHRoZSBjaGVjayBhYm92ZS4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgU2VsZWN0T2JqZWN0KFRoaXMtPmhEQywgVGhpcy0+ZGliLmhvbGRiaXRtYXApOwogICAgICAgICAgICAgICAgRGVsZXRlREMoVGhpcy0+aERDKTsKICAgICAgICAgICAgICAgIC8qIFJlbGVhc2UgdGhlIERJQiBzZWN0aW9uICovCiAgICAgICAgICAgICAgICBEZWxldGVPYmplY3QoVGhpcy0+ZGliLkRJQnNlY3Rpb24pOwogICAgICAgICAgICAgICAgVGhpcy0+ZGliLmJpdG1hcF9kYXRhID0gTlVMTDsKICAgICAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IE5VTEw7CiAgICAgICAgICAgICAgICBUaGlzLT5oREMgPSBOVUxMOwogICAgICAgICAgICAgICAgVGhpcy0+RmxhZ3MgJj0gflNGTEFHX0RJQlNFQ1RJT047CiAgICAgICAgfSBlbHNlIGlmKCEoVGhpcy0+RmxhZ3MgJiBTRkxBR19VU0VSUFRSKSkgewogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpOwogICAgICAgIH0KICAgICAgICBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgPSBNZW07CiAgICAgICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfVVNFUlBUUjsKICAgIH0gZWxzZSBpZihUaGlzLT5GbGFncyAmIFNGTEFHX1VTRVJQVFIpIHsKICAgICAgICAvKiBMb2NrcmVjdCBhbmQgR2V0REMgd2lsbCByZS1jcmVhdGUgdGhlIGRpYiBzZWN0aW9uIGFuZCBhbGxvY2F0ZWQgbWVtb3J5ICovCiAgICAgICAgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gTlVMTDsKICAgICAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfVVNFUlBUUjsKICAgIH0KICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKiBUT0RPOiByZXBsYWNlIHRoaXMgZnVuY3Rpb24gd2l0aCBjb250ZXh0IG1hbmFnZW1lbnQgcm91dGluZXMgKi8KSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRQQnVmZmVyU3RhdGUoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgQk9PTCBpblBCdWZmZXIsIEJPT0wgIGluVGV4dHVyZSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CgogICAgaWYoaW5QQnVmZmVyKSB7CiAgICAgICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfSU5QQlVGRkVSOwogICAgfSBlbHNlIHsKICAgICAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfSU5QQlVGRkVSOwogICAgfQoKICAgIGlmKGluVGV4dHVyZSkgewogICAgICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX0lOVEVYVFVSRTsKICAgIH0gZWxzZSB7CiAgICAgICAgVGhpcy0+RmxhZ3MgJj0gflNGTEFHX0lOVEVYVFVSRTsKICAgIH0KCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfRmxpcChJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBJV2luZUQzRFN1cmZhY2UgKm92ZXJyaWRlLCBEV09SRCBGbGFncykgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRERldmljZSAqRDNEID0gKElXaW5lRDNERGV2aWNlICopIFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CiAgICBUUkFDRSgiKCVwKS0+KCVwLCV4KVxuIiwgVGhpcywgb3ZlcnJpZGUsIEZsYWdzKTsKCiAgICAvKiBGbGlwcGluZyBpcyBvbmx5IHN1cHBvcnRlZCBvbiBSZW5kZXJUYXJnZXRzICovCiAgICBpZiggIShUaGlzLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQpICkgcmV0dXJuIERERVJSX05PVEZMSVBQQUJMRTsKCiAgICBpZihvdmVycmlkZSkgewogICAgICAgIC8qIEREcmF3IHNldHMgdGhpcyBmb3IgdGhlIFgxMSBzdXJmYWNlcywgc28gZG9uJ3QgY29uZnVzZSB0aGUgdXNlciAKICAgICAgICAgKiBGSVhNRSgiKCVwKSBUYXJnZXQgb3ZlcnJpZGUgaXMgbm90IHN1cHBvcnRlZCBieSBub3dcbiIsIFRoaXMpOwogICAgICAgICAqIEFkZGl0aW9uYWxseSwgaXQgaXNuJ3QgcmVhbGx5IHBvc3NpYmxlIHRvIHN1cHBvcnQgdHJpcGxlLWJ1ZmZlcmluZwogICAgICAgICAqIHByb3Blcmx5IG9uIG9wZW5nbCBhdCBhbGwKICAgICAgICAgKi8KICAgIH0KCiAgICAvKiBGbGlwcGluZyBhIE9wZW5HTCBzdXJmYWNlIC0+IFVzZSBXaW5lRDNERGV2aWNlOjpQcmVzZW50ICovCiAgICByZXR1cm4gSVdpbmVEM0REZXZpY2VfUHJlc2VudChEM0QsIE5VTEwsIE5VTEwsIDAsIE5VTEwpOwp9CgovKiBOb3QgY2FsbGVkIGZyb20gdGhlIFZUYWJsZSAqLwpzdGF0aWMgSFJFU1VMVCBJV2luZUQzRFN1cmZhY2VJbXBsX0JsdE92ZXJyaWRlKElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMsIFJFQ1QgKkRlc3RSZWN0LCBJV2luZUQzRFN1cmZhY2UgKlNyY1N1cmZhY2UsIFJFQ1QgKlNyY1JlY3QsIERXT1JEIEZsYWdzLCBEREJMVEZYICpEREJsdEZ4KSB7CiAgICBEM0RSRUNUIHJlY3Q7CiAgICBJV2luZUQzRERldmljZUltcGwgKm15RGV2aWNlID0gVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZTsKICAgIElXaW5lRDNEU3dhcENoYWluSW1wbCAqc3dhcGNoYWluID0gTlVMTDsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlNyYyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIFNyY1N1cmZhY2U7CiAgICBCT09MIFNyY09LID0gVFJVRTsKCiAgICBUUkFDRSgiKCVwKS0+KCVwLCVwLCVwLCUwOHgsJXApXG4iLCBUaGlzLCBEZXN0UmVjdCwgU3JjU3VyZmFjZSwgU3JjUmVjdCwgRmxhZ3MsIEREQmx0RngpOwoKICAgIC8qIEdldCB0aGUgc3dhcGNoYWluLiBPbmUgb2YgdGhlIHN1cmZhY2VzIGhhcyB0byBiZSBhIHByaW1hcnkgc3VyZmFjZSAqLwogICAgSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lciggKElXaW5lRDNEU3VyZmFjZSAqKSBUaGlzLCAmSUlEX0lXaW5lRDNEU3dhcENoYWluLCAodm9pZCAqKikmc3dhcGNoYWluKTsKICAgIGlmKHN3YXBjaGFpbikgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZSgoSVdpbmVEM0RTd2FwQ2hhaW4gKikgc3dhcGNoYWluKTsKICAgIGVsc2UgaWYoU3JjKSB7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lciggKElXaW5lRDNEU3VyZmFjZSAqKSBTcmMsICZJSURfSVdpbmVEM0RTd2FwQ2hhaW4sICh2b2lkICoqKSZzd2FwY2hhaW4pOwogICAgICAgIGlmKHN3YXBjaGFpbikgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZSgoSVdpbmVEM0RTd2FwQ2hhaW4gKikgc3dhcGNoYWluKTsKICAgICAgICBlbHNlIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfSBlbHNlIHsKICAgICAgICBzd2FwY2hhaW4gPSBOVUxMOwogICAgfQoKICAgIGlmIChEZXN0UmVjdCkgewogICAgICAgIHJlY3QueDEgPSBEZXN0UmVjdC0+bGVmdDsKICAgICAgICByZWN0LnkxID0gRGVzdFJlY3QtPnRvcDsKICAgICAgICByZWN0LngyID0gRGVzdFJlY3QtPnJpZ2h0OwogICAgICAgIHJlY3QueTIgPSBEZXN0UmVjdC0+Ym90dG9tOwogICAgfSBlbHNlIHsKICAgICAgICByZWN0LngxID0gMDsKICAgICAgICByZWN0LnkxID0gMDsKICAgICAgICByZWN0LngyID0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAgICAgcmVjdC55MiA9IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgIH0KCiAgICAvKiBIYWxmLWxpZmUgZG9lcyBhIEJsdCBmcm9tIHRoZSBiYWNrIGJ1ZmZlciB0byB0aGUgZnJvbnQgYnVmZmVyLAogICAgICogRnVsbCBzdXJmYWNlIHNpemUsIG5vIGZsYWdzLi4uIFVzZSBwcmVzZW50IGluc3RlYWQKICAgICAqLwogICAgaWYoU3JjKQogICAgewogICAgICAgIC8qIEZpcnN0LCBjaGVjayBpZiB3ZSBjYW4gZG8gYSBGbGlwICovCgogICAgICAgIC8qIENoZWNrIHJlY3RzIC0gSVdpbmVEM0REZXZpY2VfUHJlc2VudCBkb2Vzbid0IGhhbmRsZSB0aGVtICovCiAgICAgICAgaWYoIFNyY1JlY3QgKSB7CiAgICAgICAgICAgIGlmKCAoU3JjUmVjdC0+bGVmdCA9PSAwKSAmJiAoU3JjUmVjdC0+dG9wID09IDApICYmCiAgICAgICAgICAgICAgICAoU3JjUmVjdC0+cmlnaHQgPT0gU3JjLT5jdXJyZW50RGVzYy5XaWR0aCkgJiYgKFNyY1JlY3QtPmJvdHRvbSA9PSBTcmMtPmN1cnJlbnREZXNjLkhlaWdodCkgKSB7CiAgICAgICAgICAgICAgICBTcmNPSyA9IFRSVUU7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBTcmNPSyA9IFRSVUU7CiAgICAgICAgfQoKICAgICAgICAvKiBDaGVjayB0aGUgRGVzdGluYXRpb24gcmVjdCBhbmQgdGhlIHN1cmZhY2Ugc2l6ZXMgKi8KICAgICAgICBpZihTcmNPSyAmJgogICAgICAgICAgIChyZWN0LngxID09IDApICYmIChyZWN0LnkxID09IDApICYmCiAgICAgICAgICAgKHJlY3QueDIgPT0gIFRoaXMtPmN1cnJlbnREZXNjLldpZHRoKSAmJiAocmVjdC55MiA9PSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQpICYmCiAgICAgICAgICAgKFRoaXMtPmN1cnJlbnREZXNjLldpZHRoID09IFNyYy0+Y3VycmVudERlc2MuV2lkdGgpICYmCiAgICAgICAgICAgKFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodCA9PSBTcmMtPmN1cnJlbnREZXNjLkhlaWdodCkpIHsKICAgICAgICAgICAgLyogVGhlc2UgZmxhZ3MgYXJlIHVuaW1wb3J0YW50IGZvciB0aGUgZmxhZyBjaGVjaywgcmVtb3ZlIHRoZW0gKi8KCiAgICAgICAgICAgIGlmKChGbGFncyAmIH4oRERCTFRfRE9OT1RXQUlUIHwgRERCTFRfV0FJVCkpID09IDApIHsKICAgICAgICAgICAgICAgIGlmKCBzd2FwY2hhaW4tPmJhY2tCdWZmZXIgJiYgKChJV2luZUQzRFN1cmZhY2UgKikgVGhpcyA9PSBzd2FwY2hhaW4tPmZyb250QnVmZmVyKSAmJiAoKElXaW5lRDNEU3VyZmFjZSAqKSBTcmMgPT0gc3dhcGNoYWluLT5iYWNrQnVmZmVyWzBdKSApIHsKCiAgICAgICAgICAgICAgICAgICAgRDNEU1dBUEVGRkVDVCBvcmlnX3N3YXAgPSBzd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5Td2FwRWZmZWN0OwoKICAgICAgICAgICAgICAgICAgICAvKiBUaGUgaWRlYSBiZWhpbmQgdGhpcyBpcyB0aGF0IGEgZ2xSZWFkUGl4ZWxzIGFuZCBhIGdsRHJhd1BpeGVscyBjYWxsCiAgICAgICAgICAgICAgICAgICAgICogdGFrZSB2ZXJ5IGxvbmcsIHdoaWxlIGEgZmxpcCBpcyBmYXN0LgogICAgICAgICAgICAgICAgICAgICAqIFRoaXMgYXBwbGllcyB0byBIYWxmLUxpZmUsIHdoaWNoIGRvZXMgc3VjaCBCbHRzIGV2ZXJ5IHRpbWUgaXQgZmluaXNoZWQKICAgICAgICAgICAgICAgICAgICAgKiBhIGZyYW1lLCBhbmQgdG8gUHJpbmNlIG9mIFBlcnNpYSAzRCwgd2hpY2ggdXNlcyB0aGlzIHRvIGRyYXcgYXQgbGVhc3QgdGhlIG1haW4KICAgICAgICAgICAgICAgICAgICAgKiBtZW51LiBUaGlzIGlzIGFsc28gdXNlZCBieSBhbGwgYXBwcyB3aGVuIHRoZXkgZG8gd2luZG93ZWQgcmVuZGVyaW5nCiAgICAgICAgICAgICAgICAgICAgICoKICAgICAgICAgICAgICAgICAgICAgKiBUaGUgcHJvYmxlbSBpcyB0aGF0IGZsaXBwaW5nIGlzIG5vdCByZWFsbHkgdGhlIHNhbWUgYXMgY29weWluZy4gQWZ0ZXIgYQogICAgICAgICAgICAgICAgICAgICAqIEJsdCB0aGUgZnJvbnQgYnVmZmVyIGlzIGEgY29weSBvZiB0aGUgYmFjayBidWZmZXIsIGFuZCB0aGUgYmFjayBidWZmZXIgaXMKICAgICAgICAgICAgICAgICAgICAgKiB1bnRvdWNoZWQuIFRoZXJlZm9yZSBpdCdzIG5lY2Vzc2FyeSB0byBvdmVycmlkZSB0aGUgc3dhcCBlZmZlY3QKICAgICAgICAgICAgICAgICAgICAgKiBhbmQgdG8gc2V0IGl0IGJhY2sgYWZ0ZXIgdGhlIGZsaXAuCiAgICAgICAgICAgICAgICAgICAgICovCgogICAgICAgICAgICAgICAgICAgIHN3YXBjaGFpbi0+cHJlc2VudFBhcm1zLlN3YXBFZmZlY3QgPSBXSU5FRDNEU1dBUEVGRkVDVF9DT1BZOwoKICAgICAgICAgICAgICAgICAgICBUUkFDRSgiRnVsbCBzY3JlZW4gYmFjayBidWZmZXIgLT4gZnJvbnQgYnVmZmVyIGJsdCwgcGVyZm9ybWluZyBhIGZsaXAgaW5zdGVhZFxuIik7CiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfUHJlc2VudCgoSVdpbmVEM0REZXZpY2UgKikgVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCBOVUxMLCAwLCBOVUxMKTsKCiAgICAgICAgICAgICAgICAgICAgc3dhcGNoYWluLT5wcmVzZW50UGFybXMuU3dhcEVmZmVjdCA9IG9yaWdfc3dhcDsKCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qIEJsdCBmcm9tIHRleHR1cmUgdG8gcmVuZGVydGFyZ2V0PyAqLwogICAgICAgIGlmKCAoICggKElXaW5lRDNEU3VyZmFjZSAqKSBUaGlzID09IHN3YXBjaGFpbi0+ZnJvbnRCdWZmZXIpIHx8CiAgICAgICAgICAgICAgKCBzd2FwY2hhaW4tPmJhY2tCdWZmZXIgJiYgKElXaW5lRDNEU3VyZmFjZSAqKSBUaGlzID09IHN3YXBjaGFpbi0+YmFja0J1ZmZlclswXSkgKQogICAgICAgICAgICAgICYmCiAgICAgICAgICAgICAgKCAoIChJV2luZUQzRFN1cmZhY2UgKikgU3JjICE9IHN3YXBjaGFpbi0+ZnJvbnRCdWZmZXIpICYmCiAgICAgICAgICAgICAgICAoIHN3YXBjaGFpbi0+YmFja0J1ZmZlciAmJiAoSVdpbmVEM0RTdXJmYWNlICopIFNyYyAhPSBzd2FwY2hhaW4tPmJhY2tCdWZmZXJbMF0pICkgKSB7CiAgICAgICAgICAgIGZsb2F0IGdsVGV4Q29vcmRbNF07CiAgICAgICAgICAgIERXT1JEIG9sZENLZXk7CiAgICAgICAgICAgIEREQ09MT1JLRVkgb2xkQmx0Q0tleSA9IHswLDB9OwogICAgICAgICAgICBHTGludCBvbGRMaWdodCwgb2xkRm9nLCBvbGREZXB0aCwgb2xkQmxlbmQsIG9sZEN1bGwsIG9sZEFscGhhOwogICAgICAgICAgICBHTGludCBvbGRTdGVuY2lsLCBvbGROVlJlZ2lzdGVyQ29tYmluZXJzID0gMDsKICAgICAgICAgICAgR0xpbnQgYWxwaGFmdW5jOwogICAgICAgICAgICBHTGNsYW1wZiBhbHBoYXJlZjsKICAgICAgICAgICAgUkVDVCBTb3VyY2VSZWN0YW5nbGU7CiAgICAgICAgICAgIEdMaW50IG9sZERyYXc7CgogICAgICAgICAgICBUUkFDRSgiQmx0IGZyb20gc3VyZmFjZSAlcCB0byByZW5kZXJ0YXJnZXQgJXBcbiIsIFNyYywgVGhpcyk7CgogICAgICAgICAgICBpZihTcmNSZWN0KSB7CiAgICAgICAgICAgICAgICBTb3VyY2VSZWN0YW5nbGUubGVmdCA9IFNyY1JlY3QtPmxlZnQ7CiAgICAgICAgICAgICAgICBTb3VyY2VSZWN0YW5nbGUucmlnaHQgPSBTcmNSZWN0LT5yaWdodDsKICAgICAgICAgICAgICAgIFNvdXJjZVJlY3RhbmdsZS50b3AgPSBTcmNSZWN0LT50b3A7CiAgICAgICAgICAgICAgICBTb3VyY2VSZWN0YW5nbGUuYm90dG9tID0gU3JjUmVjdC0+Ym90dG9tOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgU291cmNlUmVjdGFuZ2xlLmxlZnQgPSAwOwogICAgICAgICAgICAgICAgU291cmNlUmVjdGFuZ2xlLnJpZ2h0ID0gU3JjLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICAgICAgICAgIFNvdXJjZVJlY3RhbmdsZS50b3AgPSAwOwogICAgICAgICAgICAgICAgU291cmNlUmVjdGFuZ2xlLmJvdHRvbSA9IFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0OwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZighQ2FsY3VsYXRlVGV4UmVjdChTcmMsICZTb3VyY2VSZWN0YW5nbGUsIGdsVGV4Q29vcmQpKSB7CiAgICAgICAgICAgICAgICAvKiBGYWxsIGJhY2sgdG8gc29mdHdhcmUgKi8KICAgICAgICAgICAgICAgIFdBUk4oIiglcCkgU291cmNlIHRleHR1cmUgYXJlYSAoJWQsJWQpLSglZCwlZCkgaXMgdG9vIGJpZ1xuIiwgU3JjLAogICAgICAgICAgICAgICAgICAgICBTb3VyY2VSZWN0YW5nbGUubGVmdCwgU291cmNlUmVjdGFuZ2xlLnRvcCwKICAgICAgICAgICAgICAgICAgICAgU291cmNlUmVjdGFuZ2xlLnJpZ2h0LCBTb3VyY2VSZWN0YW5nbGUuYm90dG9tKTsKICAgICAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKiBDb2xvciBrZXlpbmc6IENoZWNrIGlmIHdlIGhhdmUgdG8gZG8gYSBjb2xvciBrZXllZCBibHQsCiAgICAgICAgICAgICAqIGFuZCBpZiBub3QgY2hlY2sgaWYgYSBjb2xvciBrZXkgaXMgYWN0aXZhdGVkLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgb2xkQ0tleSA9IFNyYy0+Q0tleUZsYWdzOwogICAgICAgICAgICBpZighKEZsYWdzICYgRERCTFRfS0VZU1JDKSAmJiAKICAgICAgICAgICAgICAgU3JjLT5DS2V5RmxhZ3MgJiBERFNEX0NLU1JDQkxUKSB7CiAgICAgICAgICAgICAgICAvKiBPaywgdGhlIHN1cmZhY2UgaGFzIGEgY29sb3Iga2V5LCBidXQgd2Ugc2hhbGwgbm90IHVzZSBpdCAtCiAgICAgICAgICAgICAgICAgKiBEZWFjdGl2YXRlIGl0IGZvciBub3csIExvYWRUZXh0dXJlIHdpbGwgY2F0Y2ggdGhpcwogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBTcmMtPkNLZXlGbGFncyAmPSB+RERTRF9DS1NSQ0JMVDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyogQ29sb3Iga2V5aW5nICovCiAgICAgICAgICAgIGlmKEZsYWdzICYgRERCTFRfS0VZREVTVCkgewogICAgICAgICAgICAgICAgb2xkQmx0Q0tleSA9IFRoaXMtPlNyY0JsdENLZXk7CiAgICAgICAgICAgICAgICAvKiBUZW1wb3JhcnkgcmVwbGFjZSB0aGUgc291cmNlIGNvbG9yIGtleSB3aXRoIHRoZSBkZXN0aW5hdGlvbiBvbmUuIFdlIGRvIHRoaXMgYmVjYXVzZSB0aGUgY29sb3IgY29udmVyc2lvbiBjb2RlIHdoaWNoCiAgICAgICAgICAgICAgICAgKiBpcyBpbiB0aGUgZW5kIGNhbGxlZCBmcm9tIExvYWRUZXh0dXJlIHdvcmtzIHdpdGggdGhlIHNvdXJjZSBjb2xvci4gQXQgdGhlIGVuZCBvZiB0aGlzIGZ1bmN0aW9uIHdlIHJlc3RvcmUgdGhlIGNvbG9yIGtleS4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgVGhpcy0+U3JjQmx0Q0tleSA9IFRoaXMtPkRlc3RCbHRDS2V5OwogICAgICAgICAgICB9IGVsc2UgaWYgKEZsYWdzICYgRERCTFRfS0VZU1JDKQogICAgICAgICAgICAgICAgb2xkQmx0Q0tleSA9IFRoaXMtPlNyY0JsdENLZXk7CgogICAgICAgICAgICAvKiBOb3cgbG9hZCB0aGUgc3VyZmFjZSAqLwogICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfUHJlTG9hZCgoSVdpbmVEM0RTdXJmYWNlICopIFNyYyk7CgogICAgICAgICAgICBFTlRFUl9HTCgpOwoKICAgICAgICAgICAgLyogU2F2ZSBhbGwgdGhlIG9sZCBzdHVmZiB1bnRpbCB3ZSBoYXZlIGEgcHJvcGVyIG9wZW5nbCBzdGF0ZSBtYW5hZ2VyICovCiAgICAgICAgICAgIG9sZExpZ2h0ID0gZ2xJc0VuYWJsZWQoR0xfTElHSFRJTkcpOwogICAgICAgICAgICBvbGRGb2cgPSBnbElzRW5hYmxlZChHTF9GT0cpOwogICAgICAgICAgICBvbGREZXB0aCA9IGdsSXNFbmFibGVkKEdMX0RFUFRIX1RFU1QpOwogICAgICAgICAgICBvbGRCbGVuZCA9IGdsSXNFbmFibGVkKEdMX0JMRU5EKTsKICAgICAgICAgICAgb2xkQ3VsbCA9IGdsSXNFbmFibGVkKEdMX0NVTExfRkFDRSk7CiAgICAgICAgICAgIG9sZEFscGhhID0gZ2xJc0VuYWJsZWQoR0xfQUxQSEFfVEVTVCk7CiAgICAgICAgICAgIG9sZFN0ZW5jaWwgPSBnbElzRW5hYmxlZChHTF9TVEVOQ0lMX1RFU1QpOwoKICAgICAgICAgICAgaWYgKEdMX1NVUFBPUlQoTlZfUkVHSVNURVJfQ09NQklORVJTKSkgewogICAgICAgICAgICAgICAgb2xkTlZSZWdpc3RlckNvbWJpbmVycyA9IGdsSXNFbmFibGVkKEdMX1JFR0lTVEVSX0NPTUJJTkVSU19OVik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGdsR2V0SW50ZWdlcnYoR0xfQUxQSEFfVEVTVF9GVU5DLCAmYWxwaGFmdW5jKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsR2V0RmxvYXR2IEdMX0FMUEhBX1RFU1RfRlVOQyIpOwogICAgICAgICAgICBnbEdldEZsb2F0dihHTF9BTFBIQV9URVNUX1JFRiwgJmFscGhhcmVmKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsR2V0RmxvYXR2IEdMX0FMUEhBX1RFU1RfUkVGIik7CgogICAgICAgICAgICBnbEdldEludGVnZXJ2KEdMX0RSQVdfQlVGRkVSLCAmb2xkRHJhdyk7CiAgICAgICAgICAgIGlmKFRoaXMgPT0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgc3dhcGNoYWluLT5mcm9udEJ1ZmZlcikgewogICAgICAgICAgICAgICAgVFJBQ0UoIkRyYXdpbmcgdG8gZnJvbnQgYnVmZmVyXG4iKTsKICAgICAgICAgICAgICAgIGdsRHJhd0J1ZmZlcihHTF9GUk9OVCk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEcmF3QnVmZmVyIEdMX0ZST05UIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIFVuYmluZCB0aGUgb2xkIHRleHR1cmUgKi8KICAgICAgICAgICAgZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCAwKTsKCiAgICAgICAgICAgIGlmIChHTF9TVVBQT1JUKEFSQl9NVUxUSVRFWFRVUkUpKSB7CiAgICAgICAgICAgIC8qIFdlIHVzZSB0ZXh0dXJlIHVuaXQgMCBmb3IgYmx0cyAqLwogICAgICAgICAgICAgICAgR0xfRVhUQ0FMTChnbEFjdGl2ZVRleHR1cmVBUkIoR0xfVEVYVFVSRTBfQVJCKSk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xBY3RpdmVUZXh0dXJlQVJCIik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBXQVJOKCJNdWx0aS10ZXh0dXJpbmcgaXMgdW5zdXBwb3J0ZWQgaW4gdGhlIGxvY2FsIE9wZW5HTCBpbXBsZW1lbnRhdGlvblxuIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIERpc2FibGUgc29tZSBmYW5jeSBncmFwaGljcyBlZmZlY3RzICovCiAgICAgICAgICAgIGdsRGlzYWJsZShHTF9MSUdIVElORyk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUgR0xfTElHSFRJTkciKTsKICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX0RFUFRIX1RFU1QpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlIEdMX0RFUFRIX1RFU1QiKTsKICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX0ZPRyk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUgR0xfRk9HIik7CiAgICAgICAgICAgIGdsRGlzYWJsZShHTF9CTEVORCk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUgR0xfQkxFTkQiKTsKICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX0NVTExfRkFDRSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUgR0xfQ1VMTF9GQUNFIik7CiAgICAgICAgICAgIGdsRGlzYWJsZShHTF9TVEVOQ0lMX1RFU1QpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlIEdMX1NURU5DSUxfVEVTVCIpOwogICAgICAgICAgICBpZiAoR0xfU1VQUE9SVChOVl9SRUdJU1RFUl9DT01CSU5FUlMpKSB7CiAgICAgICAgICAgICAgICBnbERpc2FibGUoR0xfUkVHSVNURVJfQ09NQklORVJTX05WKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUgR0xfUkVHSVNURVJfQ09NQklORVJTX05WIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIE9rLCB3ZSBuZWVkIDJkIHRleHR1cmVzLCBidXQgbm90IDFEIG9yIDNEICovCiAgICAgICAgICAgIGdsRGlzYWJsZShHTF9URVhUVVJFXzFEKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9URVhUVVJFXzFEIik7CiAgICAgICAgICAgIGdsRW5hYmxlKEdMX1RFWFRVUkVfMkQpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUgR0xfVEVYVFVSRV8yRCIpOwogICAgICAgICAgICBnbERpc2FibGUoR0xfVEVYVFVSRV8zRCk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUgR0xfVEVYVFVSRV8zRCIpOwoKICAgICAgICAgICAgLyogQmluZCB0aGUgdGV4dHVyZSAqLwogICAgICAgICAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIFNyYy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRUZXh0dXJlIik7CgogICAgICAgICAgICBnbEVuYWJsZShHTF9TQ0lTU09SX1RFU1QpOwoKICAgICAgICAgICAgZ2xUZXhFbnZpKEdMX1RFWFRVUkVfRU5WLCBHTF9URVhUVVJFX0VOVl9NT0RFLCBHTF9SRVBMQUNFKTsKCiAgICAgICAgICAgIC8qIE5vIGZpbHRlcmluZyBmb3IgYmx0cyAqLwogICAgICAgICAgICBnbFRleFBhcmFtZXRlcmkoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9NQUdfRklMVEVSLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdMX05FQVJFU1QpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xUZXhQYXJhbWV0ZXJpIik7CiAgICAgICAgICAgIGdsVGV4UGFyYW1ldGVyaShHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX01JTl9GSUxURVIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgR0xfTkVBUkVTVCk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFRleFBhcmFtZXRlcmkiKTsKICAgICAgICAgICAgZ2xUZXhQYXJhbWV0ZXJpKEdMX1RFWFRVUkVfMkQsIEdMX1RFWFRVUkVfV1JBUF9TLCBHTF9DTEFNUCk7CiAgICAgICAgICAgIGdsVGV4UGFyYW1ldGVyaShHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX1dSQVBfVCwgR0xfQ0xBTVApOwogICAgICAgICAgICBnbFRleEVudmkoR0xfVEVYVFVSRV9FTlYsIEdMX1RFWFRVUkVfRU5WX01PREUsIEdMX1JFUExBQ0UpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xUZXhFbnZpIik7CgogICAgICAgICAgICAvKiBUaGlzIGlzIGZvciBjb2xvciBrZXlpbmcgKi8KICAgICAgICAgICAgaWYoRmxhZ3MgJiBEREJMVF9LRVlTUkMpIHsKICAgICAgICAgICAgICAgIGdsRW5hYmxlKEdMX0FMUEhBX1RFU1QpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlIEdMX0FMUEhBX1RFU1QiKTsKICAgICAgICAgICAgICAgIGdsQWxwaGFGdW5jKEdMX05PVEVRVUFMLCAwLjApOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsQWxwaGFGdW5jXG4iKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGdsRGlzYWJsZShHTF9BTFBIQV9URVNUKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUgR0xfQUxQSEFfVEVTVCIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKiBEcmF3IGEgdGV4dHVyZWQgcXVhZAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgZDNkZGV2aWNlX3NldF9vcnRobyhUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlKTsKCiAgICAgICAgICAgIGdsQmVnaW4oR0xfUVVBRFMpOwoKICAgICAgICAgICAgZ2xDb2xvcjNkKDEuMGYsIDEuMGYsIDEuMGYpOwogICAgICAgICAgICBnbFRleENvb3JkMmYoZ2xUZXhDb29yZFswXSwgZ2xUZXhDb29yZFsyXSk7CiAgICAgICAgICAgIGdsVmVydGV4M2YocmVjdC54MSwKICAgICAgICAgICAgICAgICAgICAgICByZWN0LnkxLAogICAgICAgICAgICAgICAgICAgICAgIDAuMCk7CgogICAgICAgICAgICBnbFRleENvb3JkMmYoZ2xUZXhDb29yZFswXSwgZ2xUZXhDb29yZFszXSk7CiAgICAgICAgICAgIGdsVmVydGV4M2YocmVjdC54MSwgcmVjdC55MiwgMC4wKTsKCiAgICAgICAgICAgIGdsVGV4Q29vcmQyZihnbFRleENvb3JkWzFdLCBnbFRleENvb3JkWzNdKTsKICAgICAgICAgICAgZ2xWZXJ0ZXgzZihyZWN0LngyLAogICAgICAgICAgICAgICAgICAgICAgIHJlY3QueTIsCiAgICAgICAgICAgICAgICAgICAgICAgMC4wKTsKCiAgICAgICAgICAgIGdsVGV4Q29vcmQyZihnbFRleENvb3JkWzFdLCBnbFRleENvb3JkWzJdKTsKICAgICAgICAgICAgZ2xWZXJ0ZXgzZihyZWN0LngyLAogICAgICAgICAgICAgICAgICAgICAgIHJlY3QueTEsCiAgICAgICAgICAgICAgICAgICAgICAgMC4wKTsKICAgICAgICAgICAgZ2xFbmQoKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRW5kIik7CgogICAgICAgICAgICAvKiBVbmJpbmQgdGhlIHRleHR1cmUgKi8KICAgICAgICAgICAgZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCAwKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlIGdsQmluZFRleHR1cmUiKTsKCiAgICAgICAgICAgIC8qIFJlc3RvcmUgdGhlIG9sZCBzZXR0aW5ncyAqLwogICAgICAgICAgICBpZihvbGRMaWdodCkgewogICAgICAgICAgICAgICAgZ2xFbmFibGUoR0xfTElHSFRJTkcpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlIEdMX0xJR0hUSU5HIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYob2xkRm9nKSB7CiAgICAgICAgICAgICAgICBnbEVuYWJsZShHTF9GT0cpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlIEdMX0ZPRyIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKG9sZERlcHRoKSB7CiAgICAgICAgICAgICAgICBnbEVuYWJsZShHTF9ERVBUSF9URVNUKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZSBHTF9ERVBUSF9URVNUIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYob2xkQmxlbmQpIHsKICAgICAgICAgICAgICAgIGdsRW5hYmxlKEdMX0JMRU5EKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZSBHTF9CTEVORCIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKG9sZEN1bGwpIHsKICAgICAgICAgICAgICAgIGdsRW5hYmxlKEdMX0NVTExfRkFDRSk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUgR0xfQ1VMTF9GQUNFIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYob2xkU3RlbmNpbCkgewogICAgICAgICAgICAgICAgZ2xFbmFibGUoR0xfU1RFTkNJTF9URVNUKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZSBHTF9TVEVOQ0lMX1RFU1QiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZighb2xkQWxwaGEpIHsKICAgICAgICAgICAgICAgIGdsRGlzYWJsZShHTF9BTFBIQV9URVNUKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUgR0xfQUxQSEFfVEVTVCIpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZ2xFbmFibGUoR0xfQUxQSEFfVEVTVCk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUgR0xfQUxQSEFfVEVTVCIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChHTF9TVVBQT1JUKE5WX1JFR0lTVEVSX0NPTUJJTkVSUykgJiYgb2xkTlZSZWdpc3RlckNvbWJpbmVycykgewogICAgICAgICAgICAgICAgZ2xFbmFibGUoR0xfUkVHSVNURVJfQ09NQklORVJTX05WKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZSBHTF9SRUdJU1RFUl9DT01CSU5FUlNfTlYiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZ2xBbHBoYUZ1bmMoYWxwaGFmdW5jLCBhbHBoYXJlZik7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEFscGhhRnVuY1xuIik7CgogICAgICAgICAgICBpZihUaGlzID09IChJV2luZUQzRFN1cmZhY2VJbXBsICopIHN3YXBjaGFpbi0+ZnJvbnRCdWZmZXIgJiYgb2xkRHJhdyA9PSBHTF9CQUNLKSB7CiAgICAgICAgICAgICAgICBnbERyYXdCdWZmZXIob2xkRHJhdyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIFJlc3RvcmUgdGhlIGNvbG9yIGtleSBmbGFncyAqLwogICAgICAgICAgICBpZihvbGRDS2V5ICE9IFNyYy0+Q0tleUZsYWdzKSB7CiAgICAgICAgICAgICAgICBTcmMtPkNLZXlGbGFncyA9IG9sZENLZXk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIFJlc3RvcmUgdGhlIG9sZCBjb2xvciBrZXkgKi8KICAgICAgICAgICAgaWYgKEZsYWdzICYgKEREQkxUX0tFWVNSQyB8IEREQkxUX0tFWURFU1QpKQogICAgICAgICAgICAgICAgVGhpcy0+U3JjQmx0Q0tleSA9IG9sZEJsdENLZXk7CgogICAgICAgICAgICBMRUFWRV9HTCgpOwoKICAgICAgICAgICAgLyogVE9ETzogSWYgdGhlIHN1cmZhY2UgaXMgbG9ja2VkIG9mdGVuLCBwZXJmb3JtIHRoZSBCbHQgaW4gc29mdHdhcmUgb24gdGhlIG1lbW9yeSBpbnN0ZWFkICovCiAgICAgICAgICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX0dMRElSVFk7CgogICAgICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgICAgICB9CgoKICAgICAgICAvKiBCbHQgZnJvbSByZW5kZXJ0YXJnZXQgdG8gdGV4dHVyZT8gKi8KICAgICAgICBpZiggKFNyY1N1cmZhY2UgPT0gc3dhcGNoYWluLT5mcm9udEJ1ZmZlcikgfHwKICAgICAgICAgICAgKHN3YXBjaGFpbi0+YmFja0J1ZmZlciAmJiBTcmNTdXJmYWNlID09IHN3YXBjaGFpbi0+YmFja0J1ZmZlclswXSkgKSB7CiAgICAgICAgICAgIGlmKCAoIChJV2luZUQzRFN1cmZhY2UgKikgVGhpcyAhPSBzd2FwY2hhaW4tPmZyb250QnVmZmVyKSAmJgogICAgICAgICAgICAgICAgKCBzd2FwY2hhaW4tPmJhY2tCdWZmZXIgJiYgKElXaW5lRDNEU3VyZmFjZSAqKSBUaGlzICE9IHN3YXBjaGFpbi0+YmFja0J1ZmZlclswXSkgKSB7CiAgICAgICAgICAgICAgICBVSU5UIHJvdzsKICAgICAgICAgICAgICAgIEQzRFJFQ1Qgc3JlY3Q7CiAgICAgICAgICAgICAgICBmbG9hdCB4cmVsLCB5cmVsOwoKICAgICAgICAgICAgICAgIFRSQUNFKCJCbHQgZnJvbSByZW5kZXJ0YXJnZXQgdG8gdGV4dHVyZVxuIik7CgogICAgICAgICAgICAgICAgLyogQ2FsbCBwcmVsb2FkIGZvciB0aGUgc3VyZmFjZSB0byBtYWtlIHN1cmUgaXQgaXNuJ3QgZGlydHkgKi8KICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9QcmVMb2FkKChJV2luZUQzRFN1cmZhY2UgKikgVGhpcyk7CgogICAgICAgICAgICAgICAgaWYoU3JjUmVjdCkgewogICAgICAgICAgICAgICAgICAgIHNyZWN0LngxID0gU3JjUmVjdC0+bGVmdDsKICAgICAgICAgICAgICAgICAgICBzcmVjdC55MSA9IFNyY1JlY3QtPnRvcDsKICAgICAgICAgICAgICAgICAgICBzcmVjdC54MiA9IFNyY1JlY3QtPnJpZ2h0OwogICAgICAgICAgICAgICAgICAgIHNyZWN0LnkyID0gU3JjUmVjdC0+Ym90dG9tOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBzcmVjdC54MSA9IDA7CiAgICAgICAgICAgICAgICAgICAgc3JlY3QueTEgPSAwOwogICAgICAgICAgICAgICAgICAgIHNyZWN0LngyID0gU3JjLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICAgICAgICAgICAgICBzcmVjdC55MiA9IFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0OwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIEVOVEVSX0dMKCk7CgogICAgICAgICAgICAgICAgLyogQmluZCB0aGUgdGFyZ2V0IHRleHR1cmUgKi8KICAgICAgICAgICAgICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xCaW5kVGV4dHVyZSIpOwogICAgICAgICAgICAgICAgaWYoc3dhcGNoYWluLT5iYWNrQnVmZmVyICYmIFNyY1N1cmZhY2UgPT0gc3dhcGNoYWluLT5iYWNrQnVmZmVyWzBdKSB7CiAgICAgICAgICAgICAgICAgICAgZ2xSZWFkQnVmZmVyKEdMX0JBQ0spOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBnbFJlYWRCdWZmZXIoR0xfRlJPTlQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsUmVhZEJ1ZmZlciIpOwoKICAgICAgICAgICAgICAgIHhyZWwgPSAoZmxvYXQpIChzcmVjdC54MiAtIHNyZWN0LngxKSAvIChmbG9hdCkgKHJlY3QueDIgLSByZWN0LngxKTsKICAgICAgICAgICAgICAgIHlyZWwgPSAoZmxvYXQpIChzcmVjdC55MiAtIHNyZWN0LnkxKSAvIChmbG9hdCkgKHJlY3QueTIgLSByZWN0LnkxKTsKCiAgICAgICAgICAgICAgICAvKiBJIGhhdmUgdG8gcHJvY2VzcyB0aGlzIHJvdyBieSByb3cgdG8gc3dhcCB0aGUgaW1hZ2UsCiAgICAgICAgICAgICAgICAgKiBvdGhlcndpc2UgaXQgd291bGQgYmUgdXBzaWRlIGRvd24sIHNvIHN0cmVjaGluZyBpbiB5IGRpcmVjdGlvbgogICAgICAgICAgICAgICAgICogZG9lc24ndCBjb3N0IGV4dHJhIHRpbWUKICAgICAgICAgICAgICAgICAqCiAgICAgICAgICAgICAgICAgKiBIb3dldmVyLCBzdHJlY2hpbmcgaW4geCBkaXJlY3Rpb24gY2FuIGJlIGF2b2lkZWQgaWYgbm90IG5lY2Vzc2FyeQogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBmb3Iocm93ID0gcmVjdC55MTsgcm93IDwgcmVjdC55Mjsgcm93KyspIHsKICAgICAgICAgICAgICAgICAgICBpZiggKHhyZWwgLSAxLjAgPCAtZXBzKSB8fCAoeHJlbCAtIDEuMCA+IGVwcykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogV2VsbCwgdGhhdCBzdHVmZiB3b3JrcywgYnV0IGl0J3MgdmVyeSBzbG93LgogICAgICAgICAgICAgICAgICAgICAgICAgKiBmaW5kIGEgYmV0dGVyIHdheSBpbnN0ZWFkCiAgICAgICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgICAgICBVSU5UIGNvbDsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yKGNvbCA9IHJlY3QueDE7IGNvbCA8IHJlY3QueDI7IGNvbCsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnbENvcHlUZXhTdWJJbWFnZTJEKEdMX1RFWFRVUkVfMkQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIC8qIGxldmVsICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlY3QueDEgKyBjb2wsIFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodCAtIHJvdyAtIDEsIC8qIHhvZmZzZXQsIHlvZmZzZXQgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3JlY3QueDEgKyBjb2wgKiB4cmVsLCBTcmMtPmN1cnJlbnREZXNjLkhlaWdodCAtIHNyZWN0LnkyICsgcm93ICogeXJlbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMSwgMSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBnbENvcHlUZXhTdWJJbWFnZTJEKEdMX1RFWFRVUkVfMkQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgLyogbGV2ZWwgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWN0LngxLCBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQgLSByb3cgLSAxLCAvKiB4b2Zmc2V0LCB5b2Zmc2V0ICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3JlY3QueDEsIFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0IC0gc3JlY3QueTIgKyByb3cgKiB5cmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlY3QueDIsIDEpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB2Y2hlY2tHTGNhbGwoImdsQ29weVRleFN1YkltYWdlMkQiKTsKICAgICAgICAgICAgICAgIExFQVZFX0dMKCk7CgogICAgICAgICAgICAgICAgaWYoIShUaGlzLT5GbGFncyAmIFNGTEFHX0RPTk9URlJFRSkpIHsKICAgICAgICAgICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpOwogICAgICAgICAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IE5VTEw7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX0dMRElSVFk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgaWYgKEZsYWdzICYgRERCTFRfQ09MT1JGSUxMKSB7CiAgICAgICAgLyogVGhpcyBpcyBlYXN5IHRvIGhhbmRsZSBmb3IgdGhlIEQzRCBEZXZpY2UuLi4gKi8KICAgICAgICBEV09SRCBjb2xvcjsKICAgICAgICBJV2luZUQzRFN3YXBDaGFpbkltcGwgKmltcGxTd2FwQ2hhaW47CgogICAgICAgIFRSQUNFKCJDb2xvcmZpbGxcbiIpOwoKICAgICAgICAvKiBUaGUgY29sb3IgYXMgZ2l2ZW4gaW4gdGhlIEJsdCBmdW5jdGlvbiBpcyBpbiB0aGUgZm9ybWF0IG9mIHRoZSBmcmFtZS1idWZmZXIuLi4KICAgICAgICAgKiAnY2xlYXInIGV4cGVjdCBpdCBpbiBBUkdCIGZvcm1hdCA9PiB3ZSBuZWVkIHRvIGRvIHNvbWUgY29udmVyc2lvbiA6LSkKICAgICAgICAgKi8KICAgICAgICBpZiAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfUDgpIHsKICAgICAgICAgICAgaWYgKFRoaXMtPnBhbGV0dGUpIHsKICAgICAgICAgICAgICAgIGNvbG9yID0gKCgweEZGMDAwMDAwKSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgKFRoaXMtPnBhbGV0dGUtPnBhbGVudHNbRERCbHRGeC0+dTUuZHdGaWxsQ29sb3JdLnBlUmVkIDw8IDE2KSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgKFRoaXMtPnBhbGV0dGUtPnBhbGVudHNbRERCbHRGeC0+dTUuZHdGaWxsQ29sb3JdLnBlR3JlZW4gPDwgOCkgfAogICAgICAgICAgICAgICAgICAgICAgICAgIChUaGlzLT5wYWxldHRlLT5wYWxlbnRzW0REQmx0RngtPnU1LmR3RmlsbENvbG9yXS5wZUJsdWUpKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGNvbG9yID0gMHhGRjAwMDAwMDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9SNUc2QjUpIHsKICAgICAgICAgICAgaWYgKEREQmx0RngtPnU1LmR3RmlsbENvbG9yID09IDB4RkZGRikgewogICAgICAgICAgICAgICAgY29sb3IgPSAweEZGRkZGRkZGOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgY29sb3IgPSAoKDB4RkYwMDAwMDApIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAoKEREQmx0RngtPnU1LmR3RmlsbENvbG9yICYgMHhGODAwKSA8PCA4KSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgKChEREJsdEZ4LT51NS5kd0ZpbGxDb2xvciAmIDB4MDdFMCkgPDwgNSkgfAogICAgICAgICAgICAgICAgICAgICAgICAgICgoRERCbHRGeC0+dTUuZHdGaWxsQ29sb3IgJiAweDAwMUYpIDw8IDMpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlIGlmICgoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfUjhHOEI4KSB8fAogICAgICAgICAgICAgICAgICAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfWDhSOEc4QjgpICkgewogICAgICAgICAgICBjb2xvciA9IDB4RkYwMDAwMDAgfCBEREJsdEZ4LT51NS5kd0ZpbGxDb2xvcjsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfQThSOEc4QjgpIHsKICAgICAgICAgICAgY29sb3IgPSBEREJsdEZ4LT51NS5kd0ZpbGxDb2xvcjsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIEVSUigiV3Jvbmcgc3VyZmFjZSB0eXBlIGZvciBCTFQgb3ZlcnJpZGUoRm9ybWF0IGRvZXNuJ3QgbWF0Y2gpICFcbiIpOwogICAgICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgICAgICB9CgogICAgICAgIFRSQUNFKCJDYWxsaW5nIEdldFN3YXBDaGFpbiB3aXRoIG15ZGV2aWNlID0gJXBcbiIsIG15RGV2aWNlKTsKICAgICAgICBJV2luZUQzRERldmljZV9HZXRTd2FwQ2hhaW4oKElXaW5lRDNERGV2aWNlICopbXlEZXZpY2UsIDAsIChJV2luZUQzRFN3YXBDaGFpbiAqKikmaW1wbFN3YXBDaGFpbik7CiAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZSggKElXaW5lRDNEU3dhcENoYWluICopIGltcGxTd2FwQ2hhaW4gKTsKICAgICAgICBpZihpbXBsU3dhcENoYWluLT5iYWNrQnVmZmVyICYmIFRoaXMgPT0gKElXaW5lRDNEU3VyZmFjZUltcGwqKSBpbXBsU3dhcENoYWluLT5iYWNrQnVmZmVyWzBdKSB7CiAgICAgICAgICAgIGdsRHJhd0J1ZmZlcihHTF9CQUNLKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlcihHTF9CQUNLKSIpOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChUaGlzID09IChJV2luZUQzRFN1cmZhY2VJbXBsKikgaW1wbFN3YXBDaGFpbi0+ZnJvbnRCdWZmZXIpIHsKICAgICAgICAgICAgZ2xEcmF3QnVmZmVyKEdMX0ZST05UKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlcihHTF9GUk9OVCkiKTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIEVSUigiV3Jvbmcgc3VyZmFjZSB0eXBlIGZvciBCTFQgb3ZlcnJpZGUobm90IG9uIHN3YXBjaGFpbikgIVxuIik7CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgICAgIH0KCiAgICAgICAgVFJBQ0UoIiglcCkgZXhlY3V0aW5nIFJlbmRlciBUYXJnZXQgb3ZlcnJpZGUsIGNvbG9yID0gJXhcbiIsIFRoaXMsIGNvbG9yKTsKCiAgICAgICAgSVdpbmVEM0REZXZpY2VfQ2xlYXIoIChJV2luZUQzRERldmljZSAqKSBteURldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMSAvKiBOdW1iZXIgb2YgcmVjdGFuZ2xlcyAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnJlY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRENMRUFSX1RBUkdFVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAuMCAvKiBaICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwIC8qIFN0ZW5jaWwgKi8pOwoKICAgICAgICAvKiBSZXN0b3JlIHRoZSBvcmlnaW5hbCBkcmF3IGJ1ZmZlciAqLwogICAgICAgIGlmKGltcGxTd2FwQ2hhaW4tPmJhY2tCdWZmZXIgJiYgaW1wbFN3YXBDaGFpbi0+YmFja0J1ZmZlclswXSkgewogICAgICAgICAgICBnbERyYXdCdWZmZXIoR0xfQkFDSyk7CiAgICAgICAgICAgIHZjaGVja0dMY2FsbCgiZ2xEcmF3QnVmZmVyIik7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICAvKiBEZWZhdWx0OiBGYWxsIGJhY2sgdG8gdGhlIGdlbmVyaWMgYmx0ICovCiAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfQmx0KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIFJFQ1QgKkRlc3RSZWN0LCBJV2luZUQzRFN1cmZhY2UgKlNyY1N1cmZhY2UsIFJFQ1QgKlNyY1JlY3QsIERXT1JEIEZsYWdzLCBEREJMVEZYICpEREJsdEZ4KSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlNyYyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIFNyY1N1cmZhY2U7CiAgICBUUkFDRSgiKCVwKS0+KCVwLCVwLCVwLCV4LCVwKVxuIiwgVGhpcywgRGVzdFJlY3QsIFNyY1N1cmZhY2UsIFNyY1JlY3QsIEZsYWdzLCBEREJsdEZ4KTsKICAgIFRSQUNFKCIoJXApOiBVc2FnZSBpcyAlc1xuIiwgVGhpcywgZGVidWdfZDNkdXNhZ2UoVGhpcy0+cmVzb3VyY2UudXNhZ2UpKTsKCiAgICAvKiBTcGVjaWFsIGNhc2VzIGZvciBSZW5kZXJUYXJnZXRzICovCiAgICBpZiggKFRoaXMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkgfHwKICAgICAgICAoIFNyYyAmJiAoU3JjLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQpICkpIHsKICAgICAgICBpZihJV2luZUQzRFN1cmZhY2VJbXBsX0JsdE92ZXJyaWRlKFRoaXMsIERlc3RSZWN0LCBTcmNTdXJmYWNlLCBTcmNSZWN0LCBGbGFncywgRERCbHRGeCkgPT0gV0lORUQzRF9PSykgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgLyogRm9yIHRoZSByZXN0IGNhbGwgdGhlIFgxMSBzdXJmYWNlIGltcGxlbWVudGF0aW9uLgogICAgICogRm9yIFJlbmRlclRhcmdldHMgdGhpcyBzaG91bGQgYmUgaW1wbGVtZW50ZWQgT3BlbkdMIGFjY2VsZXJhdGVkIGluIEJsdE92ZXJyaWRlLAogICAgICogb3RoZXIgQmx0cyBhcmUgcmF0aGVyIHJhcmUKICAgICAqLwogICAgcmV0dXJuIElXaW5lR0RJU3VyZmFjZUltcGxfQmx0KGlmYWNlLCBEZXN0UmVjdCwgU3JjU3VyZmFjZSwgU3JjUmVjdCwgRmxhZ3MsIEREQmx0RngpOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0dldEJsdFN0YXR1cyhJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBEV09SRCBGbGFncykgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKS0+KCV4KVxuIiwgVGhpcywgRmxhZ3MpOwoKICAgIHN3aXRjaCAoRmxhZ3MpCiAgICB7CiAgICBjYXNlIERER0JTX0NBTkJMVDoKICAgIGNhc2UgRERHQlNfSVNCTFRET05FOgogICAgICAgIHJldHVybiBERF9PSzsKCiAgICBkZWZhdWx0OgogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgfQp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0dldEZsaXBTdGF0dXMoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgRFdPUkQgRmxhZ3MpIHsKICAgIC8qIFhYWDogRERFUlJfSU5WQUxJRFNVUkZBQ0VUWVBFICovCgogICAgVFJBQ0UoIiglcCktPiglMDh4KVxuIixpZmFjZSxGbGFncyk7CiAgICBzd2l0Y2ggKEZsYWdzKSB7CiAgICBjYXNlIERER0ZTX0NBTkZMSVA6CiAgICBjYXNlIERER0ZTX0lTRkxJUERPTkU6CiAgICAgICAgcmV0dXJuIEREX09LOwoKICAgIGRlZmF1bHQ6CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfSXNMb3N0KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBpZmFjZTsKICAgIFRSQUNFKCIoJXApXG4iLCBUaGlzKTsKCiAgICByZXR1cm4gVGhpcy0+RmxhZ3MgJiBTRkxBR19MT1NUID8gRERFUlJfU1VSRkFDRUxPU1QgOiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1Jlc3RvcmUoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwoKICAgIC8qIFNvIGZhciB3ZSBkb24ndCBsb3NlIGFueXRoaW5nIDopICovCiAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfTE9TVDsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0JsdEZhc3QoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgRFdPUkQgZHN0eCwgRFdPUkQgZHN0eSwgSVdpbmVEM0RTdXJmYWNlICpTb3VyY2UsIFJFQ1QgKnJzcmMsIERXT1JEIHRyYW5zKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpzcmNJbXBsID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgU291cmNlOwogICAgVFJBQ0UoIiglcCktPiglZCwgJWQsICVwLCAlcCwgJTA4eFxuIiwgaWZhY2UsIGRzdHgsIGRzdHksIFNvdXJjZSwgcnNyYywgdHJhbnMpOwoKICAgIC8qIFNwZWNpYWwgY2FzZXMgZm9yIFJlbmRlclRhcmdldHMgKi8KICAgIGlmKCAoVGhpcy0+cmVzb3VyY2UudXNhZ2UgJiBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUKSB8fAogICAgICAgICggc3JjSW1wbCAmJiAoc3JjSW1wbC0+cmVzb3VyY2UudXNhZ2UgJiBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUKSApKSB7CgogICAgICAgIFJFQ1QgU3JjUmVjdCwgRHN0UmVjdDsKICAgICAgICBEV09SRCBGbGFncz0wOwoKICAgICAgICBpZihyc3JjKSB7CiAgICAgICAgICAgIFNyY1JlY3QubGVmdCA9IHJzcmMtPmxlZnQ7CiAgICAgICAgICAgIFNyY1JlY3QudG9wPSByc3JjLT50b3A7CiAgICAgICAgICAgIFNyY1JlY3QuYm90dG9tID0gcnNyYy0+Ym90dG9tOwogICAgICAgICAgICBTcmNSZWN0LnJpZ2h0ID0gcnNyYy0+cmlnaHQ7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgU3JjUmVjdC5sZWZ0ID0gMDsKICAgICAgICAgICAgU3JjUmVjdC50b3AgPSAwOwogICAgICAgICAgICBTcmNSZWN0LnJpZ2h0ID0gc3JjSW1wbC0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAgICAgICAgIFNyY1JlY3QuYm90dG9tID0gc3JjSW1wbC0+Y3VycmVudERlc2MuSGVpZ2h0OwogICAgICAgIH0KCiAgICAgICAgRHN0UmVjdC5sZWZ0ID0gZHN0eDsKICAgICAgICBEc3RSZWN0LnRvcD1kc3R5OwogICAgICAgIERzdFJlY3QucmlnaHQgPSBkc3R4ICsgU3JjUmVjdC5yaWdodCAtIFNyY1JlY3QubGVmdDsKICAgICAgICBEc3RSZWN0LmJvdHRvbSA9IGRzdHkgKyBTcmNSZWN0LmJvdHRvbSAtIFNyY1JlY3QudG9wOwoKICAgICAgICAvKiBDb252ZXJ0IEJsdEZhc3QgZmxhZ3MgaW50byBCdGwgb25lcyBiZWNhdXNlIGl0IGlzIGNhbGxlZCBmcm9tIFN1cmZhY2VJbXBsX0JsdCBhcyB3ZWxsICovCiAgICAgICAgaWYodHJhbnMgJiBEREJMVEZBU1RfU1JDQ09MT1JLRVkpCiAgICAgICAgICAgIEZsYWdzIHw9IEREQkxUX0tFWVNSQzsKICAgICAgICBpZih0cmFucyAmIEREQkxURkFTVF9ERVNUQ09MT1JLRVkpCiAgICAgICAgICAgIEZsYWdzIHw9IEREQkxUX0tFWURFU1Q7CiAgICAgICAgaWYodHJhbnMgJiBEREJMVEZBU1RfV0FJVCkKICAgICAgICAgICAgRmxhZ3MgfD0gRERCTFRfV0FJVDsKICAgICAgICBpZih0cmFucyAmIEREQkxURkFTVF9ET05PVFdBSVQpCiAgICAgICAgICAgIEZsYWdzIHw9IEREQkxUX0RPTk9UV0FJVDsKCiAgICAgICAgaWYoSVdpbmVEM0RTdXJmYWNlSW1wbF9CbHRPdmVycmlkZShUaGlzLCAmRHN0UmVjdCwgU291cmNlLCAmU3JjUmVjdCwgRmxhZ3MsIE5VTEwpID09IFdJTkVEM0RfT0spIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKCiAgICByZXR1cm4gSVdpbmVHRElTdXJmYWNlSW1wbF9CbHRGYXN0KGlmYWNlLCBkc3R4LCBkc3R5LCBTb3VyY2UsIHJzcmMsIHRyYW5zKTsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRQYWxldHRlKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIElXaW5lRDNEUGFsZXR0ZSAqKlBhbCkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwogICAgVFJBQ0UoIiglcCktPiglcClcbiIsIFRoaXMsIFBhbCk7CgogICAgKlBhbCA9IChJV2luZUQzRFBhbGV0dGUgKikgVGhpcy0+cGFsZXR0ZTsKICAgIHJldHVybiBERF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9SZWFsaXplUGFsZXR0ZShJV2luZUQzRFN1cmZhY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CiAgICBSR0JRVUFEIGNvbFsyNTZdOwogICAgSVdpbmVEM0RQYWxldHRlSW1wbCAqcGFsID0gVGhpcy0+cGFsZXR0ZTsKICAgIHVuc2lnbmVkIGludCBuOwogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwoKICAgIGlmKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX1A4IHx8CiAgICAgICBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9BOFA4KQogICAgewogICAgICAgIFRSQUNFKCJEaXJ0aWZ5aW5nIHN1cmZhY2VcbiIpOwogICAgICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX0RJUlRZOwogICAgfQoKICAgIGlmKFRoaXMtPkZsYWdzICYgU0ZMQUdfRElCU0VDVElPTikgewogICAgICAgIFRSQUNFKCIoJXApOiBVcGRhdGluZyB0aGUgaGRjJ3MgcGFsZXR0ZVxuIiwgVGhpcyk7CiAgICAgICAgZm9yIChuPTA7IG48MjU2OyBuKyspIHsKICAgICAgICAgICAgaWYocGFsKSB7CiAgICAgICAgICAgICAgICBjb2xbbl0ucmdiUmVkICAgPSBwYWwtPnBhbGVudHNbbl0ucGVSZWQ7CiAgICAgICAgICAgICAgICBjb2xbbl0ucmdiR3JlZW4gPSBwYWwtPnBhbGVudHNbbl0ucGVHcmVlbjsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JCbHVlICA9IHBhbC0+cGFsZW50c1tuXS5wZUJsdWU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZUltcGwgKmRldmljZSA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CiAgICAgICAgICAgICAgICAvKiBVc2UgdGhlIGRlZmF1bHQgZGV2aWNlIHBhbGV0dGUgKi8KICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JSZWQgICA9IGRldmljZS0+cGFsZXR0ZXNbZGV2aWNlLT5jdXJyZW50UGFsZXR0ZV1bbl0ucGVSZWQ7CiAgICAgICAgICAgICAgICBjb2xbbl0ucmdiR3JlZW4gPSBkZXZpY2UtPnBhbGV0dGVzW2RldmljZS0+Y3VycmVudFBhbGV0dGVdW25dLnBlR3JlZW47CiAgICAgICAgICAgICAgICBjb2xbbl0ucmdiQmx1ZSAgPSBkZXZpY2UtPnBhbGV0dGVzW2RldmljZS0+Y3VycmVudFBhbGV0dGVdW25dLnBlQmx1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjb2xbbl0ucmdiUmVzZXJ2ZWQgPSAwOwogICAgICAgIH0KICAgICAgICBTZXRESUJDb2xvclRhYmxlKFRoaXMtPmhEQywgMCwgMjU2LCBjb2wpOwogICAgfQoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1NldFBhbGV0dGUoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgSVdpbmVEM0RQYWxldHRlICpQYWwpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBpZmFjZTsKICAgIElXaW5lRDNEUGFsZXR0ZUltcGwgKlBhbEltcGwgPSAoSVdpbmVEM0RQYWxldHRlSW1wbCAqKSBQYWw7CiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIiwgVGhpcywgUGFsKTsKCiAgICBpZihUaGlzLT5wYWxldHRlICE9IE5VTEwpIAogICAgICAgIGlmKFRoaXMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkKICAgICAgICAgICAgVGhpcy0+cGFsZXR0ZS0+RmxhZ3MgJj0gfkREUENBUFNfUFJJTUFSWVNVUkZBQ0U7CgogICAgaWYoUGFsSW1wbCAhPSBOVUxMKSB7CiAgICAgICAgaWYoVGhpcy0+cmVzb3VyY2UudXNhZ2UgJiBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUKSB7CiAgICAgICAgICAgIC8qIFNldCB0aGUgZGV2aWNlJ3MgbWFpbiBwYWxldHRlIGlmIHRoZSBwYWxldHRlCiAgICAgICAgICAgICAqIHdhc24ndCBhIHByaW1hcnkgcGFsZXR0ZSBiZWZvcmUKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmKCEoUGFsSW1wbC0+RmxhZ3MgJiBERFBDQVBTX1BSSU1BUllTVVJGQUNFKSkgewogICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsICpkZXZpY2UgPSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOwogICAgICAgICAgICAgICAgdW5zaWduZWQgaW50IGk7CgogICAgICAgICAgICAgICAgZm9yKGk9MDsgaSA8IDI1NjsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgZGV2aWNlLT5wYWxldHRlc1tkZXZpY2UtPmN1cnJlbnRQYWxldHRlXVtpXSA9IFBhbEltcGwtPnBhbGVudHNbaV07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIChQYWxJbXBsKS0+RmxhZ3MgfD0gRERQQ0FQU19QUklNQVJZU1VSRkFDRTsKICAgICAgICB9CiAgICB9CiAgICBUaGlzLT5wYWxldHRlID0gUGFsSW1wbDsKCiAgICByZXR1cm4gSVdpbmVEM0RTdXJmYWNlX1JlYWxpemVQYWxldHRlKGlmYWNlKTsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRDb2xvcktleShJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBEV09SRCBGbGFncywgRERDT0xPUktFWSAqQ0tleSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwogICAgVFJBQ0UoIiglcCktPiglMDh4LCVwKVxuIiwgVGhpcywgRmxhZ3MsIENLZXkpOwoKICAgIGlmICgoRmxhZ3MgJiBERENLRVlfQ09MT1JTUEFDRSkgIT0gMCkgewogICAgICAgIEZJWE1FKCIgY29sb3JrZXkgdmFsdWUgbm90IHN1cHBvcnRlZCAoJTA4eCkgIVxuIiwgRmxhZ3MpOwogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgfQoKICAgIC8qIERpcnRpZnkgdGhlIHN1cmZhY2UsIGJ1dCBvbmx5IGlmIGEga2V5IHdhcyBjaGFuZ2VkICovCiAgICBpZihDS2V5KSB7CiAgICAgICAgc3dpdGNoIChGbGFncyAmIH5ERENLRVlfQ09MT1JTUEFDRSkgewogICAgICAgICAgICBjYXNlIEREQ0tFWV9ERVNUQkxUOgogICAgICAgICAgICAgICAgVGhpcy0+RGVzdEJsdENLZXkgPSAqQ0tleTsKICAgICAgICAgICAgICAgIFRoaXMtPkNLZXlGbGFncyB8PSBERFNEX0NLREVTVEJMVDsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBERENLRVlfREVTVE9WRVJMQVk6CiAgICAgICAgICAgICAgICBUaGlzLT5EZXN0T3ZlcmxheUNLZXkgPSAqQ0tleTsKICAgICAgICAgICAgICAgIFRoaXMtPkNLZXlGbGFncyB8PSBERFNEX0NLREVTVE9WRVJMQVk7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgRERDS0VZX1NSQ09WRVJMQVk6CiAgICAgICAgICAgICAgICBUaGlzLT5TcmNPdmVybGF5Q0tleSA9ICpDS2V5OwogICAgICAgICAgICAgICAgVGhpcy0+Q0tleUZsYWdzIHw9IEREU0RfQ0tTUkNPVkVSTEFZOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIEREQ0tFWV9TUkNCTFQ6CiAgICAgICAgICAgICAgICBUaGlzLT5TcmNCbHRDS2V5ID0gKkNLZXk7CiAgICAgICAgICAgICAgICBUaGlzLT5DS2V5RmxhZ3MgfD0gRERTRF9DS1NSQ0JMVDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KICAgIGVsc2UgewogICAgICAgIHN3aXRjaCAoRmxhZ3MgJiB+RERDS0VZX0NPTE9SU1BBQ0UpIHsKICAgICAgICAgICAgY2FzZSBERENLRVlfREVTVEJMVDoKICAgICAgICAgICAgICAgIFRoaXMtPkNLZXlGbGFncyAmPSB+RERTRF9DS0RFU1RCTFQ7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgRERDS0VZX0RFU1RPVkVSTEFZOgogICAgICAgICAgICAgICAgVGhpcy0+Q0tleUZsYWdzICY9IH5ERFNEX0NLREVTVE9WRVJMQVk7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgRERDS0VZX1NSQ09WRVJMQVk6CiAgICAgICAgICAgICAgICBUaGlzLT5DS2V5RmxhZ3MgJj0gfkREU0RfQ0tTUkNPVkVSTEFZOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIEREQ0tFWV9TUkNCTFQ6CiAgICAgICAgICAgICAgICBUaGlzLT5DS2V5RmxhZ3MgJj0gfkREU0RfQ0tTUkNCTFQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1ByaXZhdGVTZXR1cChJV2luZUQzRFN1cmZhY2UgKmlmYWNlKSB7CiAgICAvKiogQ2hlY2sgYWdhaW5zdCB0aGUgbWF4aW11bSB0ZXh0dXJlIHNpemVzIHN1cHBvcnRlZCBieSB0aGUgdmlkZW8gY2FyZCAqKi8KICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBpZmFjZTsKCiAgICBUUkFDRSgiJXBcbiIsIFRoaXMpOwogICAgaWYgKChUaGlzLT5wb3cyV2lkdGggPiBHTF9MSU1JVFModGV4dHVyZV9zaXplKSB8fCBUaGlzLT5wb3cySGVpZ2h0ID4gR0xfTElNSVRTKHRleHR1cmVfc2l6ZSkpICYmICEoVGhpcy0+cmVzb3VyY2UudXNhZ2UgJiAoV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCB8IFdJTkVEM0RVU0FHRV9ERVBUSFNURU5DSUwpKSkgewogICAgICAgIC8qIG9uZSBvZiB0aHJlZSBvcHRpb25zCiAgICAgICAgMTogRG8gdGhlIHNhbWUgYXMgd2UgZG8gd2l0aCBub25wb3cgMiBhbmQgc2NhbGUgdGhlIHRleHR1cmUsIChhbnkgdGV4dHVyZSBvcHMgd291bGQgcmVxdWlyZSB0aGUgdGV4dHVyZSB0byBiZSBzY2FsZWQgd2hpY2ggaXMgcG90ZW50aWFsbHkgc2xvdykKICAgICAgICAyOiBTZXQgdGhlIHRleHR1cmUgdG8gdGhlIG1heGl1bSBzaXplIChiYWQgaWRlYSkKICAgICAgICAzOiAgICBXQVJOIGFuZCByZXR1cm4gV0lORUQzREVSUl9OT1RBVkFJTEFCTEU7CiAgICAgICAgNDogQ3JlYXRlIHRoZSBzdXJmYWNlLCBidXQgYWxsb3cgaXQgdG8gYmUgdXNlZCBvbmx5IGZvciBEaXJlY3REcmF3IEJsdHMuIFNvbWUgYXBwcyhlLmcuIFN3YXQgMykgY3JlYXRlIHRleHR1cmVzIHdpdGggYSBIZWlnaHQgb2YgMTYgYW5kIGEgV2lkdGggPiAzMDAwIGFuZCBibHQgMTZ4MTYgbGV0dGVyIGFyZWFzIGZyb20gdGhlbSB0byB0aGUgcmVuZGVyIHRhcmdldC4KICAgICAgICAqLwogICAgICAgIFdBUk4oIiglcCkgQ3JlYXRpbmcgYW4gb3ZlcnNpemVkIHN1cmZhY2VcbiIsIFRoaXMpOwogICAgICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX09WRVJTSVpFOwoKICAgICAgICAvKiBUaGlzIHdpbGwgYmUgaW5pdGlhbGl6ZWQgb24gdGhlIGZpcnN0IGJsdCAqLwogICAgICAgIFRoaXMtPmdsUmVjdC5sZWZ0ID0gMDsKICAgICAgICBUaGlzLT5nbFJlY3QudG9wID0gMDsKICAgICAgICBUaGlzLT5nbFJlY3QucmlnaHQgPSAwOwogICAgICAgIFRoaXMtPmdsUmVjdC5ib3R0b20gPSAwOwogICAgfSBlbHNlIHsKICAgICAgICAvKiBObyBvdmVyc2l6ZSwgZ2wgcmVjdCBpcyB0aGUgZnVsbCB0ZXh0dXJlIHNpemUgKi8KICAgICAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfT1ZFUlNJWkU7CiAgICAgICAgVGhpcy0+Z2xSZWN0LmxlZnQgPSAwOwogICAgICAgIFRoaXMtPmdsUmVjdC50b3AgPSAwOwogICAgICAgIFRoaXMtPmdsUmVjdC5yaWdodCA9IFRoaXMtPnBvdzJXaWR0aDsKICAgICAgICBUaGlzLT5nbFJlY3QuYm90dG9tID0gVGhpcy0+cG93MkhlaWdodDsKICAgIH0KCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKRFdPUkQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0UGl0Y2goSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwogICAgRFdPUkQgcmV0OwogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwoKICAgIC8qIERYVG4gZm9ybWF0cyBkb24ndCBoYXZlIGV4YWN0IHBpdGNoZXMgYXMgdGhleSBhcmUgdG8gdGhlIG5ldyByb3cgb2YgYmxvY2tzLAogICAgICAgICB3aGVyZSBlYWNoIGJsb2NrIGlzIDR4NCBwaXhlbHMsIDggYnl0ZXMgKGR4dDEpIGFuZCAxNiBieXRlcyAoZHh0Mi8zLzQvNSkKICAgICAgICAgIGllIHBpdGNoID0gKHdpZHRoLzQpICogYnl0ZXMgcGVyIGJsb2NrICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICBpZiAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMSkgLyogRFhUMSBpcyA4IGJ5dGVzIHBlciBibG9jayAqLwogICAgICAgIHJldCA9IChUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCA+PiAyKSA8PCAzOwogICAgZWxzZSBpZiAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMiB8fCBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQzIHx8CiAgICAgICAgICAgICBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQ0IHx8IFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDUpIC8qIERYVDIvMy80LzUgaXMgMTYgYnl0ZXMgcGVyIGJsb2NrICovCiAgICAgICAgcmV0ID0gKFRoaXMtPmN1cnJlbnREZXNjLldpZHRoID4+IDIpIDw8IDQ7CiAgICBlbHNlIHsKICAgICAgICBpZiAoTlAyX1JFUEFDSyA9PSB3aW5lZDNkX3NldHRpbmdzLm5vbnBvd2VyMl9tb2RlIHx8IFRoaXMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkgewogICAgICAgICAgICAvKiBGcm9udCBhbmQgYmFjayBidWZmZXJzIGFyZSBhbHdheXMgbG9ja2VzL3VubG9ja2VkIG9uIGN1cnJlbnREZXNjLldpZHRoICovCiAgICAgICAgICAgIHJldCA9IFRoaXMtPmJ5dGVzUGVyUGl4ZWwgKiBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aDsgIC8qIEJ5dGVzIC8gcm93ICovCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0ID0gVGhpcy0+Ynl0ZXNQZXJQaXhlbCAqIFRoaXMtPnBvdzJXaWR0aDsKICAgICAgICB9CiAgICAgICAgLyogU3VyZmFjZXMgYXJlIDMyIGJpdCBhbGlnbmVkICovCiAgICAgICAgcmV0ID0gKHJldCArIFNVUkZBQ0VfQUxJR05NRU5UIC0gMSkgJiB+KFNVUkZBQ0VfQUxJR05NRU5UIC0gMSk7CiAgICB9CiAgICBUUkFDRSgiKCVwKSBSZXR1cm5pbmcgJWRcbiIsIFRoaXMsIHJldCk7CiAgICByZXR1cm4gcmV0Owp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1NldE92ZXJsYXlQb3NpdGlvbihJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBMT05HIFgsIExPTkcgWSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwoKICAgIEZJWE1FKCIoJXApLT4oJWQsJWQpIFN0dWIhXG4iLCBUaGlzLCBYLCBZKTsKCiAgICBpZighKFRoaXMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX09WRVJMQVkpKQogICAgewogICAgICAgIFRSQUNFKCIoJXApOiBOb3QgYW4gb3ZlcmxheSBzdXJmYWNlXG4iLCBUaGlzKTsKICAgICAgICByZXR1cm4gRERFUlJfTk9UQU9WRVJMQVlTVVJGQUNFOwogICAgfQoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0dldE92ZXJsYXlQb3NpdGlvbihJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBMT05HICpYLCBMT05HICpZKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CgogICAgRklYTUUoIiglcCktPiglcCwlcCkgU3R1YiFcbiIsIFRoaXMsIFgsIFkpOwoKICAgIGlmKCEoVGhpcy0+cmVzb3VyY2UudXNhZ2UgJiBXSU5FRDNEVVNBR0VfT1ZFUkxBWSkpCiAgICB7CiAgICAgICAgVFJBQ0UoIiglcCk6IE5vdCBhbiBvdmVybGF5IHN1cmZhY2VcbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBEREVSUl9OT1RBT1ZFUkxBWVNVUkZBQ0U7CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfVXBkYXRlT3ZlcmxheVpPcmRlcihJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBEV09SRCBGbGFncywgSVdpbmVEM0RTdXJmYWNlICpSZWYpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBpZmFjZTsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlJlZkltcGwgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBSZWY7CgogICAgRklYTUUoIiglcCktPiglMDh4LCVwKSBTdHViIVxuIiwgVGhpcywgRmxhZ3MsIFJlZkltcGwpOwoKICAgIGlmKCEoVGhpcy0+cmVzb3VyY2UudXNhZ2UgJiBXSU5FRDNEVVNBR0VfT1ZFUkxBWSkpCiAgICB7CiAgICAgICAgVFJBQ0UoIiglcCk6IE5vdCBhbiBvdmVybGF5IHN1cmZhY2VcbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBEREVSUl9OT1RBT1ZFUkxBWVNVUkZBQ0U7CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfVXBkYXRlT3ZlcmxheShJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBSRUNUICpTcmNSZWN0LCBJV2luZUQzRFN1cmZhY2UgKkRzdFN1cmZhY2UsIFJFQ1QgKkRzdFJlY3QsIERXT1JEIEZsYWdzLCBXSU5FRERPVkVSTEFZRlggKkZYKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpEc3QgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBEc3RTdXJmYWNlOwogICAgRklYTUUoIiglcCktPiglcCwgJXAsICVwLCAlMDh4LCAlcClcbiIsIFRoaXMsIFNyY1JlY3QsIERzdCwgRHN0UmVjdCwgRmxhZ3MsIEZYKTsKCiAgICBpZighKFRoaXMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX09WRVJMQVkpKQogICAgewogICAgICAgIFRSQUNFKCIoJXApOiBOb3QgYW4gb3ZlcmxheSBzdXJmYWNlXG4iLCBUaGlzKTsKICAgICAgICByZXR1cm4gRERFUlJfTk9UQU9WRVJMQVlTVVJGQUNFOwogICAgfQoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9Cgpjb25zdCBJV2luZUQzRFN1cmZhY2VWdGJsIElXaW5lRDNEU3VyZmFjZV9WdGJsID0KewogICAgLyogSVVua25vd24gKi8KICAgIElXaW5lRDNEU3VyZmFjZUltcGxfUXVlcnlJbnRlcmZhY2UsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0FkZFJlZiwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfUmVsZWFzZSwKICAgIC8qIElXaW5lRDNEUmVzb3VyY2UgKi8KICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0UGFyZW50LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXREZXZpY2UsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1NldFByaXZhdGVEYXRhLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRQcml2YXRlRGF0YSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfRnJlZVByaXZhdGVEYXRhLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRQcmlvcml0eSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0UHJpb3JpdHksCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1ByZUxvYWQsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldFR5cGUsCiAgICAvKiBJV2luZUQzRFN1cmZhY2UgKi8KICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0Q29udGFpbmVyUGFyZW50LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRDb250YWluZXIsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldERlc2MsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0xvY2tSZWN0LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9VbmxvY2tSZWN0LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXREQywKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfUmVsZWFzZURDLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9GbGlwLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9CbHQsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldEJsdFN0YXR1cywKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0RmxpcFN0YXR1cywKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfSXNMb3N0LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9SZXN0b3JlLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9CbHRGYXN0LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRQYWxldHRlLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRQYWxldHRlLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9SZWFsaXplUGFsZXR0ZSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0Q29sb3JLZXksCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldFBpdGNoLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRNZW0sCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1NldE92ZXJsYXlQb3NpdGlvbiwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0T3ZlcmxheVBvc2l0aW9uLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9VcGRhdGVPdmVybGF5Wk9yZGVyLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9VcGRhdGVPdmVybGF5LAogICAgLyogSW50ZXJuYWwgdXNlOiAqLwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9DbGVhbkRpcnR5UmVjdCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfQWRkRGlydHlSZWN0LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9Mb2FkVGV4dHVyZSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfU2F2ZVNuYXBzaG90LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRDb250YWluZXIsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1NldFBCdWZmZXJTdGF0ZSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0R2xUZXh0dXJlRGVzYywKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0R2xEZXNjLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXREYXRhLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRGb3JtYXQsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1ByaXZhdGVTZXR1cAp9Owo=