LyoKICogSVdpbmVEM0RTdXJmYWNlIEltcGxlbWVudGF0aW9uCiAqCiAqIENvcHlyaWdodCAxOTk4IExpb25lbCBVbG1lcgogKiBDb3B5cmlnaHQgMjAwMC0yMDAxIFRyYW5zR2FtaW5nIFRlY2hub2xvZ2llcyBJbmMuCiAqIENvcHlyaWdodCAyMDAyLTIwMDUgSmFzb24gRWRtZWFkZXMKICogQ29weXJpZ2h0IDIwMDItMjAwMyBSYXBoYWVsIEp1bnF1ZWlyYQogKiBDb3B5cmlnaHQgMjAwNCBDaHJpc3RpYW4gQ29zdGEKICogQ29weXJpZ2h0IDIwMDUgT2xpdmVyIFN0aWViZXIKICogQ29weXJpZ2h0IDIwMDYgU3RlZmFuIET2c2luZ2VyIGZvciBDb2RlV2VhdmVycwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCiNpbmNsdWRlICJ3aW5lL3BvcnQuaCIKI2luY2x1ZGUgIndpbmVkM2RfcHJpdmF0ZS5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoZDNkX3N1cmZhY2UpOwojZGVmaW5lIEdMSU5GT19MT0NBVElPTiAoKElXaW5lRDNESW1wbCAqKSgoKElXaW5lRDNERGV2aWNlSW1wbCAqKVRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2UpLT53aW5lRDNEKSktPmdsX2luZm8KCnR5cGVkZWYgZW51bSB7CiAgICBOT19DT05WRVJTSU9OLAogICAgQ09OVkVSVF9QQUxFVFRFRCwKICAgIENPTlZFUlRfUEFMRVRURURfQ0ssCiAgICBDT05WRVJUX0NLXzU2NSwKICAgIENPTlZFUlRfQ0tfNTU1MSwKICAgIENPTlZFUlRfQ0tfNDQ0NCwKICAgIENPTlZFUlRfQ0tfNDQ0NF9BUkdCLAogICAgQ09OVkVSVF9DS18xNTU1LAogICAgQ09OVkVSVF81NTUsCiAgICBDT05WRVJUX0NLX1JHQjI0LAogICAgQ09OVkVSVF9DS184ODg4LAogICAgQ09OVkVSVF9DS184ODg4X0FSR0IsCiAgICBDT05WRVJUX1JHQjMyXzg4OAp9IENPTlZFUlRfVFlQRVM7CgpIUkVTVUxUIGQzZGZtdF9jb252ZXJ0X3N1cmZhY2UoQllURSAqc3JjLCBCWVRFICpkc3QsIHVuc2lnbmVkIGxvbmcgbGVuLCBDT05WRVJUX1RZUEVTIGNvbnZlcnQsIElXaW5lRDNEU3VyZmFjZUltcGwgKnN1cmYpOwoKc3RhdGljIHZvaWQgc3VyZmFjZV9kb3dubG9hZF9kYXRhKElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMpIHsKICAgIGlmIChUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQxIHx8CiAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDIgfHwgVGhpcy0+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+Z2xSZWN0LmJvdHRvbSAtIFRoaXMtPmdsUmVjdC50b3A7CiAgICAgICAgICAgIHR5cGUgPSBHTF9VTlNJR05FRF9CWVRFOwogICAgICAgICAgICBmbXQgPSBHTF9SR0JBOwoKICAgICAgICAgICAgbWVtID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnJlc291cmNlLnNpemUgKiBzaXplb2YoRFdPUkQpKTsKICAgICAgICAgICAgaWYoIW1lbSkgewogICAgICAgICAgICAgICAgRVJSKCJPdXQgb2YgbWVtb3J5XG4iKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICBkM2RmbXRfY29udmVydF9zdXJmYWNlKFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGl0Y2gqaGVpZ2h0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTlZFUlRfUEFMRVRURUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcyk7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBGSVhNRSgiVW5zdXBwb3J0ZWQgRm9ybWF0ICV1IGluIGxvY2tpbmcgZnVuY1xuIiwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0KTsKCiAgICAgICAgICAgIC8qIEdpdmUgaXQgYSB0cnkgKi8KICAgICAgICAgICAgdHlwZSA9IFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xUeXBlOwogICAgICAgICAgICBmbXQgPSBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0OwogICAgICAgICAgICBtZW0gPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnk7CiAgICB9CgogICAgZ2xEcmF3UGl4ZWxzKFRoaXMtPmxvY2tlZFJlY3QucmlnaHQgLSBUaGlzLT5sb2NrZWRSZWN0LmxlZnQsCiAgICAgICAgICAgICAgICAgKFRoaXMtPmxvY2tlZFJlY3QuYm90dG9tIC0gVGhpcy0+bG9ja2VkUmVjdC50b3ApLTEsCiAgICAgICAgICAgICAgICAgZm10LCB0eXBlLAogICAgICAgICAgICAgICAgIG1lbSk7CiAgICBjaGVja0dMY2FsbCgiZ2xEcmF3UGl4ZWxzIik7CiAgICBnbFBpeGVsWm9vbSgxLjAsMS4wKTsKICAgIHZjaGVja0dMY2FsbCgiZ2xQaXhlbFpvb20iKTsKCiAgICBnbFJhc3RlclBvczNpdigmcHJldl9yYXN0ZXJwb3NbMF0pOwogICAgdmNoZWNrR0xjYWxsKCJnbFJhc3RlclBvczNpdiIpOwoKICAgIC8qIFJlc2V0IHRvIHByZXZpb3VzIHBhY2sgcm93IGxlbmd0aCAqLwogICAgZ2xQaXhlbFN0b3JlaShHTF9VTlBBQ0tfUk9XX0xFTkdUSCwgc2tpcEJ5dGVzKTsKICAgIHZjaGVja0dMY2FsbCgiZ2xQaXhlbFN0b3JlaSBHTF9VTlBBQ0tfUk9XX0xFTkdUSCIpOwogICAgaWYoc3RvcmVjaGFuZ2VkKSB7CiAgICAgICAgZ2xQaXhlbFN0b3JlaShHTF9QQUNLX1NXQVBfQllURVMsIHByZXZfc3RvcmUpOwogICAgICAgIHZjaGVja0dMY2FsbCgiZ2xQaXhlbFN0b3JlaSBHTF9QQUNLX1NXQVBfQllURVMiKTsKICAgIH0KCiAgICBpZihtZW0gIT0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KSBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBtZW0pOwogICAgcmV0dXJuOwp9CgpzdGF0aWMgdm9pZCBmbHVzaF90b19mcmFtZWJ1ZmZlcl90ZXh0dXJlKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgZmxvYXQgZ2xUZXhDb29yZFs0XTsKCiAgICBnbFRleENvb3JkWzBdID0gMC4wOyAvKiBsZWZ0ICovCiAgICBnbFRleENvb3JkWzFdID0gKGZsb2F0KSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCAvIChmbG9hdCkgVGhpcy0+cG93MldpZHRoOyAvKiByaWdodCAqLwogICAgZ2xUZXhDb29yZFsyXSA9IDAuMDsgLyogdG9wICovCiAgICBnbFRleENvb3JkWzNdID0gKGZsb2F0KSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQgLyAoZmxvYXQpIFRoaXMtPnBvdzJIZWlnaHQ7IC8qIGJvdHRvbSAqLwoKICAgIElXaW5lRDNEU3VyZmFjZV9QcmVMb2FkKGlmYWNlKTsKCiAgICBFTlRFUl9HTCgpOwoKICAgIC8qIERpc2FibGUgc29tZSBmYW5jeSBncmFwaGljcyBlZmZlY3RzICovCiAgICBnbERpc2FibGUoR0xfTElHSFRJTkcpOwogICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9MSUdIVElORyIpOwogICAgZ2xEaXNhYmxlKEdMX0RFUFRIX1RFU1QpOwogICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9ERVBUSF9URVNUIik7CiAgICBnbERpc2FibGUoR0xfRk9HKTsKICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUgR0xfRk9HIik7CiAgICBnbERpc2FibGUoR0xfQ1VMTF9GQUNFKTsKICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUgR0xfQ1VMTF9GQUNFIik7CiAgICBnbERpc2FibGUoR0xfQkxFTkQpOwogICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9CTEVORCIpOwogICAgZ2xEaXNhYmxlKEdMX1NURU5DSUxfVEVTVCk7CiAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlIEdMX1NURU5DSUxfVEVTVCIpOwoKICAgIGdsRW5hYmxlKEdMX1RFWFRVUkVfMkQpOwogICAgZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCBUaGlzLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lKTsKICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZSBnbEJpbmRUZXh0dXJlIik7CgogICAgLyogTm8gZmlsdGVyaW5nIGZvciBibHRzICovCiAgICBnbFRleFBhcmFtZXRlcmkoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9NQUdfRklMVEVSLCBHTF9ORUFSRVNUKTsKICAgIGNoZWNrR0xjYWxsKCJnbFRleFBhcmFtZXRlcmkiKTsKICAgIGdsVGV4UGFyYW1ldGVyaShHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX01JTl9GSUxURVIsIEdMX05FQVJFU1QpOwogICAgY2hlY2tHTGNhbGwoImdsVGV4UGFyYW1ldGVyaSIpOwoKICAgIC8qIFN0YXJ0IGRyYXdpbmcgYSBxdWFkICovCiAgICBnbEJlZ2luKEdMX1FVQURTKTsKCiAgICBnbENvbG9yM2QoMS4wZiwgMS4wZiwgMS4wZik7CiAgICBnbFRleENvb3JkMmYoZ2xUZXhDb29yZFswXSwgZ2xUZXhDb29yZFsyXSk7CiAgICBnbFZlcnRleDNmKDAsIDAsIDAuMCk7CgogICAgZ2xUZXhDb29yZDJmKGdsVGV4Q29vcmRbMF0sIGdsVGV4Q29vcmRbM10pOwogICAgZ2xWZXJ0ZXgzZigwLCBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQsIDAuMCk7CgogICAgZ2xUZXhDb29yZDJmKGdsVGV4Q29vcmRbMV0sIGdsVGV4Q29vcmRbM10pOwogICAgZ2xWZXJ0ZXgzZChUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCwgVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0LCAwLjApOwoKICAgIGdsVGV4Q29vcmQyZihnbFRleENvb3JkWzFdLCBnbFRleENvb3JkWzJdKTsKICAgIGdsVmVydGV4M2YoVGhpcy0+Y3VycmVudERlc2MuV2lkdGgsIDAsIDAuMCk7CgogICAgZ2xFbmQoKTsKICAgIGNoZWNrR0xjYWxsKCJnbEVuZCIpOwoKICAgIC8qIFVuYmluZCB0aGUgdGV4dHVyZSAqLwogICAgZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCAwKTsKICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZSBnbEJpbmRUZXh0dXJlIik7CgogICAgTEVBVkVfR0woKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfVW5sb2NrUmVjdChJV2luZUQzRFN1cmZhY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAgKm15RGV2aWNlID0gVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZTsKICAgIGNvbnN0IGNoYXIgKmJ1ZmZlcm5hbWUgPSAiIjsKICAgIElXaW5lRDNEU3dhcENoYWluSW1wbCAqc3dhcGNoYWluID0gTlVMTDsKICAgIEJPT0wgYmFja2J1ZiA9IEZBTFNFOwoKICAgIGlmICghKFRoaXMtPkZsYWdzICYgU0ZMQUdfTE9DS0VEKSkgewogICAgICAgIFdBUk4oInRyeWluZyB0byBVbmxvY2sgYW4gdW5sb2NrZWQgc3VyZkAlcFxuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgaWYgKFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQgJiBUaGlzLT5yZXNvdXJjZS51c2FnZSkgewogICAgICAgIElXaW5lRDNEU3VyZmFjZV9HZXRDb250YWluZXIoaWZhY2UsICZJSURfSVdpbmVEM0RTd2FwQ2hhaW4sICh2b2lkICoqKSZzd2FwY2hhaW4pOwoKICAgICAgICBpZihzd2FwY2hhaW4pIHsKICAgICAgICAgICAgaW50IGk7CiAgICAgICAgICAgIGZvcihpID0gMDsgaSA8IHN3YXBjaGFpbi0+cHJlc2VudFBhcm1zLkJhY2tCdWZmZXJDb3VudDsgaSsrKSB7CiAgICAgICAgICAgICAgICBpZihpZmFjZSA9PSBzd2FwY2hhaW4tPmJhY2tCdWZmZXJbaV0pIHsKICAgICAgICAgICAgICAgICAgICBiYWNrYnVmID0gVFJVRTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKGJhY2tidWYpIHsKICAgICAgICAgICAgICAgIGJ1ZmZlcm5hbWUgPSAiYmFja0J1ZmZlciI7CiAgICAgICAgfSBlbHNlIGlmICgoc3dhcGNoYWluICE9IE5VTEwpICYmIGlmYWNlID09ICBzd2FwY2hhaW4tPmZyb250QnVmZmVyKSB7CiAgICAgICAgICAgICAgICBidWZmZXJuYW1lID0gImZyb250QnVmZmVyIjsKICAgICAgICB9IGVsc2UgaWYgKGlmYWNlID09IG15RGV2aWNlLT5kZXB0aFN0ZW5jaWxCdWZmZXIpIHsKICAgICAgICAgICAgICAgIGJ1ZmZlcm5hbWUgPSAiZGVwdGhTdGVuY2lsQnVmZmVyIjsKICAgICAgICB9IGVsc2UgaWYgKGlmYWNlID09IG15RGV2aWNlLT5yZW5kZXJUYXJnZXQpIHsKICAgICAgICAgICAgICAgIGJ1ZmZlcm5hbWUgPSAicmVuZGVyVGFyZ2V0IjsKICAgICAgICB9CiAgICB9CgogICAgaWYgKHN3YXBjaGFpbiAhPSBOVUxMKSB7CiAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZSgoSVdpbmVEM0RTd2FwQ2hhaW4gKilzd2FwY2hhaW4pOwogICAgfQoKICAgIFRSQUNFKCIoJXAgJXMpIDogZGlydHlmaWVkKCVkKVxuIiwgVGhpcywgYnVmZmVybmFtZSwgVGhpcy0+RmxhZ3MgJiBTRkxBR19ESVJUWSA/IDEgOiAwKTsKCiAgICBpZiAoIShUaGlzLT5GbGFncyAmIFNGTEFHX0RJUlRZKSkgewogICAgICAgIFRSQUNFKCIoJXApIDogTm90IERpcnRpZmllZCBzbyBub3RoaW5nIHRvIGRvLCByZXR1cm4gbm93XG4iLCBUaGlzKTsKICAgICAgICBnb3RvIHVubG9ja19lbmQ7CiAgICB9CgogICAgaWYgKDAgPT0gVGhpcy0+cmVzb3VyY2UudXNhZ2UpIHsgLyogY2xhc3NpYyBzdXJmYWNlICovCiAgICAgICAgLyoqCiAgICAgICAgICogbm90aGluZyB0byBkbwogICAgICAgICAqIHdhaXRpbmcgdG8gcmVsb2FkIHRoZSBzdXJmYWNlIHZpYSBJRGlyZWN0M0REZXZpY2U4OjpVcGRhdGVUZXh0dXJlCiAgICAgICAgICovCiAgICB9IGVsc2UgaWYgKFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQgJiBUaGlzLT5yZXNvdXJjZS51c2FnZSkgeyAvKiByZW5kZXIgc3VyZmFjZXMgKi8KCiAgICAgICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioKICAgICAgICAqIFRPRE86IFJlbmRlciB0YXJnZXRzIGFyZSAnc3BlY2lhbCcgYW5kCiAgICAgICAgKiA/c29tZT8gbG9ja2luZyBuZWVkcyB0byBiZSBwYXNzZWQgb250byB0aGUgY29udGV4dCBtYW5hZ2VyCiAgICAgICAgKiBzbyB0aGF0IGl0IGJlY29tZXMgcG9zc2libGUgdG8gdXNlIGF1eGlsaWFyeSBidWZmZXJzLCBwYnVmZmVycwogICAgICAgICogcmVuZGVyLXRvLXRleHR1cmUsIHNoYXJlZCwgY2FjaGVkIGNvbnRleHRzIGV0Yy4uLgogICAgICAgICogKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KICAgICAgICBJV2luZUQzRFN3YXBDaGFpbkltcGwgKmltcGxTd2FwQ2hhaW47CiAgICAgICAgSVdpbmVEM0REZXZpY2VfR2V0U3dhcENoYWluKChJV2luZUQzRERldmljZSAqKW15RGV2aWNlLCAwLCAoSVdpbmVEM0RTd2FwQ2hhaW4gKiopJmltcGxTd2FwQ2hhaW4pOwoKICAgICAgICBpZiAoYmFja2J1ZiB8fCBpZmFjZSA9PSAgaW1wbFN3YXBDaGFpbi0+ZnJvbnRCdWZmZXIgfHwgaWZhY2UgPT0gbXlEZXZpY2UtPnJlbmRlclRhcmdldCkgewogICAgICAgICAgICBpbnQgdGV4OwoKICAgICAgICAgICAgRU5URVJfR0woKTsKCiAgICAgICAgICAgIC8qIGdsRHJhd1BpeGVscyB0cmFuc2Zvcm1zIHRoZSByYXN0ZXIgcG9zaXRpb24gYXMgdGhvdWdoIGl0IHdhcyBhIHZlcnRleCAtCiAgICAgICAgICAgICAgIHdlIHdhbnQgdG8gZHJhdyBhdCBzY3JlZW4gcG9zaXRpb24gMCwwIC0gU2V0IHVwIG9ydGhvIChyaHcpIG1vZGUgYXMKICAgICAgICAgICAgICAgcGVyIGRyYXdwcmltIChhbmQgbGVhdmUgc2V0IC0gaXQgd2lsbCBzb3J0IGl0c2VsZiBvdXQgZHVlIHRvIGxhc3Rfd2FzX3JodyAqLwogICAgICAgICAgICBkM2RkZXZpY2Vfc2V0X29ydGhvKFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2UpOwoKICAgICAgICAgICAgaWYgKGlmYWNlID09ICBpbXBsU3dhcENoYWluLT5mcm9udEJ1ZmZlcikgewogICAgICAgICAgICAgICAgZ2xEcmF3QnVmZmVyKEdMX0ZST05UKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERyYXdCdWZmZXIgR0xfRlJPTlQiKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChiYWNrYnVmIHx8IGlmYWNlID09IG15RGV2aWNlLT5yZW5kZXJUYXJnZXQpIHsKICAgICAgICAgICAgICAgIGdsRHJhd0J1ZmZlcihHTF9CQUNLKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERyYXdCdWZmZXIgR0xfQkFDSyIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKiBEaXNhYmxlIGhpZ2hlciB0ZXh0dXJlcyBiZWZvcmUgY2FsbGluZyBnbERyYXdQaXhlbHMgKi8KICAgICAgICAgICAgZm9yKHRleCA9IDE7IHRleCA8IEdMX0xJTUlUUyhzYW1wbGVycyk7IHRleCsrKSB7CiAgICAgICAgICAgICAgICBpZiAoR0xfU1VQUE9SVChBUkJfTVVMVElURVhUVVJFKSkgewogICAgICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xBY3RpdmVUZXh0dXJlQVJCKEdMX1RFWFRVUkUwX0FSQiArIHRleCkpOwogICAgICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEFjdGl2ZVRleHR1cmVBUkIiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGdsRGlzYWJsZShHTF9URVhUVVJFXzJEKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUgR0xfVEVYVFVSRV8yRCIpOwogICAgICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX1RFWFRVUkVfMUQpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9URVhUVVJFXzFEIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyogQWN0aXZhdGUgdGV4dHVyZSAwLCBidXQgZG9uJ3QgZGlzYWJsZSBpdCBuZWNlc3NhcmlsbHkgKi8KICAgICAgICAgICAgaWYgKEdMX1NVUFBPUlQoQVJCX01VTFRJVEVYVFVSRSkpIHsKICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xBY3RpdmVUZXh0dXJlQVJCKEdMX1RFWFRVUkUwX0FSQikpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsQWN0aXZlVGV4dHVyZUFSQiIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKiBBbmQgYmFjayBidWZmZXJzIGFyZSBub3QgYmxlbmRlZC4gRGlzYWJsZSB0aGUgZGVwdGggdGVzdCwgCiAgICAgICAgICAgICAgIHRoYXQgaGVscHMgcGVyZm9ybWFuY2UgKi8KICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX0JMRU5EKTsKICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX0RFUFRIX1RFU1QpOwogICAgICAgICAgICBnbERpc2FibGUoR0xfRk9HKTsKCiAgICAgICAgICAgIHN3aXRjaCh3aW5lZDNkX3NldHRpbmdzLnJlbmRlcnRhcmdldGxvY2tfbW9kZSkgewogICAgICAgICAgICAgICAgY2FzZSBSVExfQVVUTzoKICAgICAgICAgICAgICAgIGNhc2UgUlRMX1JFQUREUkFXOgogICAgICAgICAgICAgICAgY2FzZSBSVExfVEVYRFJBVzoKICAgICAgICAgICAgICAgICAgICBmbHVzaF90b19mcmFtZWJ1ZmZlcl9kcmF3cGl4ZWxzKFRoaXMpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgUlRMX1JFQURURVg6CiAgICAgICAgICAgICAgICBjYXNlIFJUTF9URVhURVg6CiAgICAgICAgICAgICAgICAgICAgZmx1c2hfdG9fZnJhbWVidWZmZXJfdGV4dHVyZShpZmFjZSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSBSVExfRElTQUJMRToKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzdGF0aWMgQk9PTCB3YXJuZWQgPSBGQUxTRTsKICAgICAgICAgICAgICAgICAgICBpZighd2FybmVkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIEVSUigiVGhlIGFwcGxpY2F0aW9uIHRyaWVzIHRvIHdyaXRlIHRvIHRoZSByZW5kZXIgdGFyZ2V0LCBidXQgcmVuZGVyIHRhcmdldCBsb2NraW5nIGlzIGRpc2FibGVkXG4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgd2FybmVkID0gVFJVRTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYoaW1wbFN3YXBDaGFpbi0+YmFja0J1ZmZlciAmJiBpbXBsU3dhcENoYWluLT5iYWNrQnVmZmVyWzBdKSB7CiAgICAgICAgICAgICAgICBnbERyYXdCdWZmZXIoR0xfQkFDSyk7CiAgICAgICAgICAgICAgICB2Y2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlciIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKG15RGV2aWNlLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtEM0RSU19aRU5BQkxFXSA9PSBEM0RaQl9UUlVFIHx8CiAgICAgICAgICAgICAgIG15RGV2aWNlLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtEM0RSU19aRU5BQkxFXSA9PSBEM0RaQl9VU0VXKSBnbEVuYWJsZShHTF9ERVBUSF9URVNUKTsKICAgICAgICAgICAgaWYgKG15RGV2aWNlLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtEM0RSU19BTFBIQUJMRU5ERU5BQkxFXSkgZ2xFbmFibGUoR0xfQkxFTkQpOwogICAgICAgICAgICBpZiAobXlEZXZpY2UtPnN0YXRlQmxvY2stPnJlbmRlclN0YXRlW0QzRFJTX0ZPR0VOQUJMRV0pIGdsRW5hYmxlKEdMX0ZPRyk7CgogICAgICAgICAgICBMRUFWRV9HTCgpOwoKICAgICAgICAgICAgLyoqIHJlc3RvcmUgY2xlYW4gZGlydHkgc3RhdGUgKi8KICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0NsZWFuRGlydHlSZWN0KGlmYWNlKTsKCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgRklYTUUoInVuc3VwcG9ydGVkIHVubG9ja2luZyB0byBSZW5kZXJpbmcgc3VyZmFjZSBzdXJmQCVwIHVzYWdlKCVzKVxuIiwgVGhpcywgZGVidWdfZDNkdXNhZ2UoVGhpcy0+cmVzb3VyY2UudXNhZ2UpKTsKICAgICAgICB9CiAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZSgoSVdpbmVEM0RTd2FwQ2hhaW4gKilpbXBsU3dhcENoYWluKTsKCiAgICB9IGVsc2UgaWYgKFdJTkVEM0RVU0FHRV9ERVBUSFNURU5DSUwgJiBUaGlzLT5yZXNvdXJjZS51c2FnZSkgeyAvKiBzdGVuY2lsIHN1cmZhY2VzICovCgogICAgICAgIGlmIChpZmFjZSA9PSBteURldmljZS0+ZGVwdGhTdGVuY2lsQnVmZmVyKSB7CiAgICAgICAgICAgIEZJWE1FKCJUT0RPIHN0ZW5jaWwgZGVwdGggc3VyZmFjZSB1bmxvY2tpbmcgc3VyZkAlcCB1c2FnZSglcylcbiIsIFRoaXMsIGRlYnVnX2QzZHVzYWdlKFRoaXMtPnJlc291cmNlLnVzYWdlKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgRklYTUUoInVuc3VwcG9ydGVkIHVubG9ja2luZyB0byBTdGVuY2lsRGVwdGggc3VyZmFjZSBzdXJmQCVwIHVzYWdlKCVzKVxuIiwgVGhpcywgZGVidWdfZDNkdXNhZ2UoVGhpcy0+cmVzb3VyY2UudXNhZ2UpKTsKICAgICAgICB9CgogICAgfSBlbHNlIHsKICAgICAgICBGSVhNRSgidW5zdXBwb3J0ZWQgdW5sb2NraW5nIHRvIHN1cmZhY2Ugc3VyZkAlcCB1c2FnZSglcylcbiIsIFRoaXMsIGRlYnVnX2QzZHVzYWdlKFRoaXMtPnJlc291cmNlLnVzYWdlKSk7CiAgICB9CgogICAgdW5sb2NrX2VuZDoKICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19MT0NLRUQ7CiAgICBtZW1zZXQoJlRoaXMtPmxvY2tlZFJlY3QsIDAsIHNpemVvZihSRUNUKSk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXREQyhJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBIREMgKnBIREMpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgV0lORUQzRExPQ0tFRF9SRUNUIGxvY2s7CiAgICBVSU5UIHVzYWdlOwogICAgQklUTUFQSU5GTyogYl9pbmZvOwogICAgSERDIGRkYzsKICAgIERXT1JEICptYXNrczsKICAgIEhSRVNVTFQgaHI7CiAgICBSR0JRVUFEIGNvbFsyNTZdOwogICAgY29uc3QgUGl4ZWxGb3JtYXREZXNjICpmb3JtYXRFbnRyeSA9IGdldEZvcm1hdERlc2NFbnRyeShUaGlzLT5yZXNvdXJjZS5mb3JtYXQpOwoKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLFRoaXMscEhEQyk7CgogICAgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19VU0VSUFRSKSB7CiAgICAgICAgRVJSKCJOb3Qgc3VwcG9ydGVkIG9uIHN1cmZhY2VzIHdpdGggYW4gYXBwbGljYXRpb24tcHJvdmlkZWQgc3VyZmFjZXNcbiIpOwogICAgICAgIHJldHVybiBEREVSUl9OT0RDOwogICAgfQoKICAgIC8qIEdpdmUgbW9yZSBkZXRhaWxlZCBpbmZvIGZvciBkZHJhdyAqLwogICAgaWYgKFRoaXMtPkZsYWdzICYgU0ZMQUdfRENJTlVTRSkKICAgICAgICByZXR1cm4gRERFUlJfRENBTFJFQURZQ1JFQVRFRDsKCiAgICAvKiBDYW4ndCBHZXREQyBpZiB0aGUgc3VyZmFjZSBpcyBsb2NrZWQgKi8KICAgIGlmIChUaGlzLT5GbGFncyAmIFNGTEFHX0xPQ0tFRCkKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKCiAgICBtZW1zZXQoJmxvY2ssIDAsIHNpemVvZihsb2NrKSk7IC8qIFRvIGJlIHN1cmUgKi8KCiAgICAvKiBDcmVhdGUgYSBESUIgc2VjdGlvbiBpZiB0aGVyZSBpc24ndCBhIGhkYyB5ZXQgKi8KICAgIGlmKCFUaGlzLT5oREMpIHsKICAgICAgICBpbnQgZXh0cmFsaW5lID0gMDsKICAgICAgICBTWVNURU1fSU5GTyBzeXNJbmZvOwoKICAgICAgICBpZihUaGlzLT5GbGFncyAmIFNGTEFHX0FDVElWRUxPQ0spIHsKICAgICAgICAgICAgRVJSKCJDcmVhdGluZyBhIERJQiBzZWN0aW9uIHdoaWxlIGEgbG9jayBpcyBhY3RpdmUuIFVuY2VydGFpbiBjb25zZXF1ZW5jZXNcbiIpOwogICAgICAgIH0KCiAgICAgICAgc3dpdGNoIChUaGlzLT5ieXRlc1BlclBpeGVsKSB7CiAgICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgY2FzZSA0OgogICAgICAgICAgICAgICAgLyogQWxsb2NhdGUgZXh0cmEgc3BhY2UgdG8gc3RvcmUgdGhlIFJHQiBiaXQgbWFza3MuICovCiAgICAgICAgICAgICAgICBiX2luZm8gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKEJJVE1BUElORk9IRUFERVIpICsgMyAqIHNpemVvZihEV09SRCkpOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgICAgICBiX2luZm8gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKEJJVE1BUElORk9IRUFERVIpKTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIC8qIEFsbG9jYXRlIGV4dHJhIHNwYWNlIGZvciBhIHBhbGV0dGUuICovCiAgICAgICAgICAgICAgICBiX2luZm8gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihCSVRNQVBJTkZPSEVBREVSKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBzaXplb2YoUkdCUVVBRCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogKDEgPDwgKFRoaXMtPmJ5dGVzUGVyUGl4ZWwgKiA4KSkpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWJfaW5mbykKICAgICAgICAgICAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CgogICAgICAgIC8qIFNvbWUgYXBwcyBhY2Nlc3MgdGhlIHN1cmZhY2UgaW4gdmlhIERXT1JEcywgYW5kIGRvIG5vdCB0YWtlIHRoZSBuZWNlc3NhcnkgY2FyZSBhdCB0aGUgZW5kIG9mIHRoZQogICAgICAgICAqIHN1cmZhY2UuIFNvIHdlIG5lZWQgYXQgbGVhc3QgZXh0cmEgNCBieXRlcyBhdCB0aGUgZW5kIG9mIHRoZSBzdXJmYWNlLiBDaGVjayBhZ2FpbnN0IHRoZSBwYWdlIHNpemUsCiAgICAgICAgICogaWYgdGhlIGxhc3QgcGFnZSB1c2VkIGZvciB0aGUgc3VyZmFjZSBoYXMgYXQgbGVhc3QgNCBzcGFyZSBieXRlcyB3ZSdyZSBzYWZlLCBvdGhlcndpc2UKICAgICAgICAgKiBhZGQgYW4gZXh0cmEgbGluZSB0byB0aGUgZGliIHNlY3Rpb24KICAgICAgICAgKi8KICAgICAgICBHZXRTeXN0ZW1JbmZvKCZzeXNJbmZvKTsKICAgICAgICBpZiggKChUaGlzLT5yZXNvdXJjZS5zaXplICsgMykgJSBzeXNJbmZvLmR3UGFnZVNpemUpIDwgNCkgewogICAgICAgICAgICBleHRyYWxpbmUgPSAxOwogICAgICAgICAgICBUUkFDRSgiQWRkaW5nIGFuIGV4dHJhIGxpbmUgdG8gdGhlIGRpYiBzZWN0aW9uXG4iKTsKICAgICAgICB9CgogICAgICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpU2l6ZSA9IHNpemVvZihCSVRNQVBJTkZPSEVBREVSKTsKICAgICAgICBpZiggKE5QMl9SRVBBQ0sgPT0gd2luZWQzZF9zZXR0aW5ncy5ub25wb3dlcjJfbW9kZSB8fCBUaGlzLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQpKSB7CiAgICAgICAgICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpV2lkdGggPSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICAgICAgYl9pbmZvLT5ibWlIZWFkZXIuYmlIZWlnaHQgPSAtVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0IC1leHRyYWxpbmU7CiAgICAgICAgICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpU2l6ZUltYWdlID0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGggKiBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQgKiBUaGlzLT5ieXRlc1BlclBpeGVsOwogICAgICAgICAgICAvKiBVc2UgdGhlIGZ1bGwgcG93MiBpbWFnZSBzaXplKGFzc2lnbmVkIGJlbG93KSBiZWNhdXNlIExvY2tSZWN0CiAgICAgICAgICAgICAqIHdpbGwgbmVlZCBpdCBmb3IgYSBmdWxsIGdsR2V0VGV4SW1hZ2UgY2FsbAogICAgICAgICAgICAgKi8KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBiX2luZm8tPmJtaUhlYWRlci5iaVdpZHRoID0gVGhpcy0+cG93MldpZHRoOwogICAgICAgICAgICBiX2luZm8tPmJtaUhlYWRlci5iaUhlaWdodCA9IC1UaGlzLT5wb3cySGVpZ2h0IC1leHRyYWxpbmU7CiAgICAgICAgICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpU2l6ZUltYWdlID0gVGhpcy0+cmVzb3VyY2Uuc2l6ZTsKICAgICAgICB9CiAgICAgICAgYl9pbmZvLT5ibWlIZWFkZXIuYmlQbGFuZXMgPSAxOwogICAgICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpQml0Q291bnQgPSBUaGlzLT5ieXRlc1BlclBpeGVsICogODsKCiAgICAgICAgYl9pbmZvLT5ibWlIZWFkZXIuYmlYUGVsc1Blck1ldGVyID0gMDsKICAgICAgICBiX2luZm8tPmJtaUhlYWRlci5iaVlQZWxzUGVyTWV0ZXIgPSAwOwogICAgICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpQ2xyVXNlZCA9IDA7CiAgICAgICAgYl9pbmZvLT5ibWlIZWFkZXIuYmlDbHJJbXBvcnRhbnQgPSAwOwoKICAgICAgICAvKiBHZXQgdGhlIGJpdCBtYXNrcyAqLwogICAgICAgIG1hc2tzID0gKERXT1JEICopICYoYl9pbmZvLT5ibWlDb2xvcnMpOwogICAgICAgIHN3aXRjaCAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0KSB7CiAgICAgICAgICAgIGNhc2UgV0lORUQzREZNVF9SOEc4Qjg6CiAgICAgICAgICAgICAgICB1c2FnZSA9IERJQl9SR0JfQ09MT1JTOwogICAgICAgICAgICAgICAgYl9pbmZvLT5ibWlIZWFkZXIuYmlDb21wcmVzc2lvbiA9IEJJX1JHQjsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBXSU5FRDNERk1UX1gxUjVHNUI1OgogICAgICAgICAgICBjYXNlIFdJTkVEM0RGTVRfQTFSNUc1QjU6CiAgICAgICAgICAgIGNhc2UgV0lORUQzREZNVF9BNFI0RzRCNDoKICAgICAgICAgICAgY2FzZSBXSU5FRDNERk1UX1g0UjRHNEI0OgogICAgICAgICAgICBjYXNlIFdJTkVEM0RGTVRfUjNHM0IyOgogICAgICAgICAgICBjYXNlIFdJTkVEM0RGTVRfQThSM0czQjI6CiAgICAgICAgICAgIGNhc2UgV0lORUQzREZNVF9BMkIxMEcxMFIxMDoKICAgICAgICAgICAgY2FzZSBXSU5FRDNERk1UX0E4QjhHOFI4OgogICAgICAgICAgICBjYXNlIFdJTkVEM0RGTVRfWDhCOEc4Ujg6CiAgICAgICAgICAgIGNhc2UgV0lORUQzREZNVF9BMlIxMEcxMEIxMDoKICAgICAgICAgICAgY2FzZSBXSU5FRDNERk1UX1I1RzZCNToKICAgICAgICAgICAgY2FzZSBXSU5FRDNERk1UX0ExNkIxNkcxNlIxNjoKICAgICAgICAgICAgICAgIHVzYWdlID0gMDsKICAgICAgICAgICAgICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpQ29tcHJlc3Npb24gPSBCSV9CSVRGSUVMRFM7CiAgICAgICAgICAgICAgICBtYXNrc1swXSA9IGZvcm1hdEVudHJ5LT5yZWRNYXNrOwogICAgICAgICAgICAgICAgbWFza3NbMV0gPSBmb3JtYXRFbnRyeS0+Z3JlZW5NYXNrOwogICAgICAgICAgICAgICAgbWFza3NbMl0gPSBmb3JtYXRFbnRyeS0+Ymx1ZU1hc2s7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAvKiBEb24ndCBrbm93IHBhbGV0dGUgKi8KICAgICAgICAgICAgICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpQ29tcHJlc3Npb24gPSBCSV9SR0I7CiAgICAgICAgICAgICAgICB1c2FnZSA9IDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGRkYyA9IENyZWF0ZURDQSgiRElTUExBWSIsIE5VTEwsIE5VTEwsIE5VTEwpOwogICAgICAgIGlmIChkZGMgPT0gMCkgewogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBiX2luZm8pOwogICAgICAgICAgICByZXR1cm4gSFJFU1VMVF9GUk9NX1dJTjMyKEdldExhc3RFcnJvcigpKTsKICAgICAgICB9CgogICAgICAgIFRSQUNFKCJDcmVhdGluZyBhIERJQiBzZWN0aW9uIHdpdGggc2l6ZSAlZHglZHglZCwgc2l6ZT0lZFxuIiwgYl9pbmZvLT5ibWlIZWFkZXIuYmlXaWR0aCwgYl9pbmZvLT5ibWlIZWFkZXIuYmlIZWlnaHQsIGJfaW5mby0+Ym1pSGVhZGVyLmJpQml0Q291bnQsIGJfaW5mby0+Ym1pSGVhZGVyLmJpU2l6ZUltYWdlKTsKICAgICAgICBUaGlzLT5kaWIuRElCc2VjdGlvbiA9IENyZWF0ZURJQlNlY3Rpb24oZGRjLCBiX2luZm8sIHVzYWdlLCAmVGhpcy0+ZGliLmJpdG1hcF9kYXRhLCAwIC8qIEhhbmRsZSAqLywgMCAvKiBPZmZzZXQgKi8pOwogICAgICAgIERlbGV0ZURDKGRkYyk7CgogICAgICAgIGlmICghVGhpcy0+ZGliLkRJQnNlY3Rpb24pIHsKICAgICAgICAgICAgRVJSKCJDcmVhdGVESUJTZWN0aW9uIGZhaWxlZCFcbiIpOwogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBiX2luZm8pOwogICAgICAgICAgICByZXR1cm4gSFJFU1VMVF9GUk9NX1dJTjMyKEdldExhc3RFcnJvcigpKTsKICAgICAgICB9CgogICAgICAgIFRSQUNFKCJESUJTZWN0aW9uIGF0IDogJXBcbiIsIFRoaXMtPmRpYi5iaXRtYXBfZGF0YSk7CgogICAgICAgIC8qIGNvcHkgdGhlIGV4aXN0aW5nIHN1cmZhY2UgdG8gdGhlIGRpYiBzZWN0aW9uICovCiAgICAgICAgaWYoVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KSB7CiAgICAgICAgICAgIG1lbWNweShUaGlzLT5kaWIuYml0bWFwX2RhdGEsIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSwgYl9pbmZvLT5ibWlIZWFkZXIuYmlTaXplSW1hZ2UpOwogICAgICAgICAgICAvKiBXZSB3b24ndCBuZWVkIHRoYXQgYW55IG1vcmUgKi8KICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvKiBUaGlzIGlzIHRvIG1ha2UgTG9ja1JlY3QgcmVhZCB0aGUgZ2wgVGV4dHVyZSBhbHRob3VnaCBtZW1vcnkgaXMgYWxsb2NhdGVkICovCiAgICAgICAgICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX0dMRElSVFk7CiAgICAgICAgfQoKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBiX2luZm8pOwoKICAgICAgICAvKiBVc2UgdGhlIGRpYiBzZWN0aW9uIGZyb20gbm93IG9uICovCiAgICAgICAgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gVGhpcy0+ZGliLmJpdG1hcF9kYXRhOwoKICAgICAgICAvKiBOb3cgYWxsb2NhdGUgYSBIREMgKi8KICAgICAgICBUaGlzLT5oREMgPSBDcmVhdGVDb21wYXRpYmxlREMoMCk7CiAgICAgICAgVGhpcy0+ZGliLmhvbGRiaXRtYXAgPSBTZWxlY3RPYmplY3QoVGhpcy0+aERDLCBUaGlzLT5kaWIuRElCc2VjdGlvbik7CiAgICAgICAgVFJBQ0UoInVzaW5nIHdpbmVkM2QgcGFsZXR0ZSAlcFxuIiwgVGhpcy0+cGFsZXR0ZSk7CiAgICAgICAgU2VsZWN0UGFsZXR0ZShUaGlzLT5oREMsCiAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5wYWxldHRlID8gVGhpcy0+cGFsZXR0ZS0+aHBhbCA6IDAsCiAgICAgICAgICAgICAgICAgICAgICBGQUxTRSk7CgogICAgICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX0RJQlNFQ1RJT047CiAgICB9CgogICAgLyogTG9jayB0aGUgc3VyZmFjZSAqLwogICAgaHIgPSBJV2luZUQzRFN1cmZhY2VfTG9ja1JlY3QoaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbG9jaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwKTsKICAgIGlmKEZBSUxFRChocikpIHsKICAgICAgICBFUlIoIklXaW5lRDNEU3VyZmFjZV9Mb2NrUmVjdCBmYWlsZWQgd2l0aCBociA9ICUwOHhcbiIsIGhyKTsKICAgICAgICAvKiBrZWVwIHRoZSBkaWIgc2VjdGlvbiAqLwogICAgICAgIHJldHVybiBocjsKICAgIH0KCiAgICBpZihUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9QOCB8fAogICAgICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0E4UDgpIHsKICAgICAgICB1bnNpZ25lZCBpbnQgbjsKICAgICAgICBpZihUaGlzLT5wYWxldHRlKSB7CiAgICAgICAgICAgIFBBTEVUVEVFTlRSWSBlbnRbMjU2XTsKCiAgICAgICAgICAgIEdldFBhbGV0dGVFbnRyaWVzKFRoaXMtPnBhbGV0dGUtPmhwYWwsIDAsIDI1NiwgZW50KTsKICAgICAgICAgICAgZm9yIChuPTA7IG48MjU2OyBuKyspIHsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JSZWQgICA9IGVudFtuXS5wZVJlZDsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JHcmVlbiA9IGVudFtuXS5wZUdyZWVuOwogICAgICAgICAgICAgICAgY29sW25dLnJnYkJsdWUgID0gZW50W25dLnBlQmx1ZTsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JSZXNlcnZlZCA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBJV2luZUQzRERldmljZUltcGwgKmRldmljZSA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CgogICAgICAgICAgICBmb3IgKG49MDsgbjwyNTY7IG4rKykgewogICAgICAgICAgICAgICAgY29sW25dLnJnYlJlZCAgID0gZGV2aWNlLT5wYWxldHRlc1tkZXZpY2UtPmN1cnJlbnRQYWxldHRlXVtuXS5wZVJlZDsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JHcmVlbiA9IGRldmljZS0+cGFsZXR0ZXNbZGV2aWNlLT5jdXJyZW50UGFsZXR0ZV1bbl0ucGVHcmVlbjsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JCbHVlICA9IGRldmljZS0+cGFsZXR0ZXNbZGV2aWNlLT5jdXJyZW50UGFsZXR0ZV1bbl0ucGVCbHVlOwogICAgICAgICAgICAgICAgY29sW25dLnJnYlJlc2VydmVkID0gMDsKICAgICAgICAgICAgfQoKICAgICAgICB9CiAgICAgICAgU2V0RElCQ29sb3JUYWJsZShUaGlzLT5oREMsIDAsIDI1NiwgY29sKTsKICAgIH0KCiAgICAqcEhEQyA9IFRoaXMtPmhEQzsKICAgIFRSQUNFKCJyZXR1cm5pbmcgJXBcbiIsKnBIREMpOwogICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfRENJTlVTRTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9SZWxlYXNlREMoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgSERDIGhEQykgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CgogICAgVFJBQ0UoIiglcCktPiglcClcbiIsVGhpcyxoREMpOwoKICAgIGlmICghKFRoaXMtPkZsYWdzICYgU0ZMQUdfRENJTlVTRSkpCiAgICAgICAgcmV0dXJuIEQzREVSUl9JTlZBTElEQ0FMTDsKCiAgICAvKiB3ZSBsb2NrZWQgZmlyc3QsIHNvIHVubG9jayBub3cgKi8KICAgIElXaW5lRDNEU3VyZmFjZV9VbmxvY2tSZWN0KGlmYWNlKTsKCiAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfRENJTlVTRTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgIElXaW5lRDNEU3VyZmFjZSBJbnRlcm5hbCAoTm8gbWFwcGluZyB0byBkaXJlY3R4IGFwaSkgcGFydHMgZm9sbG93CiAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqLwoKSFJFU1VMVCBkM2RmbXRfZ2V0X2NvbnYoSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcywgQk9PTCBuZWVkX2FscGhhX2NrLCBCT09MIHVzZV90ZXh0dXJpbmcsIEdMZW51bSAqZm9ybWF0LCBHTGVudW0gKmludGVybmFsLCBHTGVudW0gKnR5cGUsIENPTlZFUlRfVFlQRVMgKmNvbnZlcnQsIGludCAqdGFyZ2V0X2JwcCkgewogICAgQk9PTCBjb2xvcmtleV9hY3RpdmUgPSBuZWVkX2FscGhhX2NrICYmIChUaGlzLT5DS2V5RmxhZ3MgJiBERFNEX0NLU1JDQkxUKTsKICAgIGNvbnN0IFBpeGVsRm9ybWF0RGVzYyAqZm9ybWF0RW50cnkgPSBnZXRGb3JtYXREZXNjRW50cnkoVGhpcy0+cmVzb3VyY2UuZm9ybWF0KTsKCiAgICAvKiBEZWZhdWx0IHZhbHVlczogRnJvbSB0aGUgc3VyZmFjZSAqLwogICAgKmZvcm1hdCA9IGZvcm1hdEVudHJ5LT5nbEZvcm1hdDsKICAgICppbnRlcm5hbCA9IGZvcm1hdEVudHJ5LT5nbEludGVybmFsOwogICAgKnR5cGUgPSBmb3JtYXRFbnRyeS0+Z2xUeXBlOwogICAgKmNvbnZlcnQgPSBOT19DT05WRVJTSU9OOwogICAgKnRhcmdldF9icHAgPSBUaGlzLT5ieXRlc1BlclBpeGVsOwoKICAgIC8qIE9rLCBub3cgbG9vayBpZiB3ZSBoYXZlIHRvIGRvIGFueSBjb252ZXJzaW9uICovCiAgICBzd2l0Y2goVGhpcy0+cmVzb3VyY2UuZm9ybWF0KSB7CiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1A4OgogICAgICAgICAgICAvKiAqKioqKioqKioqKioqKioqCiAgICAgICAgICAgICAgICBQYWxldHRlZCBUZXh0dXJlCiAgICAgICAgICAgICAgICAqKioqKioqKioqKioqKioqICovCiAgICAgICAgICAgIC8qIFVzZSBjb252ZXJzaW9uIHdoZW4gdGhlIHBhbGV0dGVkIHRleHR1cmUgZXh0ZW5zaW9uIGlzIG5vdCBhdmFpbGFibGUsIG9yIHdoZW4gaXQgaXMgYXZhaWxhYmxlIG1ha2Ugc3VyZSBpdCBpcyB1c2VkCiAgICAgICAgICAgICAqIGZvciB0ZXh0dXJpbmcgYXMgaXQgd29uJ3Qgd29yayBmb3IgY2FsbHMgbGlrZSBnbERyYXctL2dsUmVhZFBpeGVscyBhbmQgZnVydGhlciBhbHNvIHVzZSBjb252ZXJzaW9uIGluIGNhc2Ugb2YgY29sb3Iga2V5aW5nLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYoIUdMX1NVUFBPUlQoRVhUX1BBTEVUVEVEX1RFWFRVUkUpIHx8IGNvbG9ya2V5X2FjdGl2ZSB8fCAoIXVzZV90ZXh0dXJpbmcgJiYgR0xfU1VQUE9SVChFWFRfUEFMRVRURURfVEVYVFVSRSkpICkgewogICAgICAgICAgICAgICAgKmZvcm1hdCA9IEdMX1JHQkE7CiAgICAgICAgICAgICAgICAqaW50ZXJuYWwgPSBHTF9SR0JBOwogICAgICAgICAgICAgICAgKnR5cGUgPSBHTF9VTlNJR05FRF9CWVRFOwogICAgICAgICAgICAgICAgKnRhcmdldF9icHAgPSA0OwogICAgICAgICAgICAgICAgaWYoY29sb3JrZXlfYWN0aXZlKSB7CiAgICAgICAgICAgICAgICAgICAgKmNvbnZlcnQgPSBDT05WRVJUX1BBTEVUVEVEX0NLOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAqY29udmVydCA9IENPTlZFUlRfUEFMRVRURUQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfUjNHM0IyOgogICAgICAgICAgICAvKiAqKioqKioqKioqKioqKioqKioqKioqCiAgICAgICAgICAgICAgICBHTF9VTlNJR05FRF9CWVRFXzNfM18yCiAgICAgICAgICAgICAgICAqKioqKioqKioqKioqKioqKioqKioqICovCiAgICAgICAgICAgIGlmIChjb2xvcmtleV9hY3RpdmUpIHsKICAgICAgICAgICAgICAgIC8qIFRoaXMgdGV4dHVyZSBmb3JtYXQgd2lsbCBuZXZlciBiZSB1c2VkLi4gU28gZG8gbm90IGNhcmUgYWJvdXQgY29sb3Iga2V5aW5nCiAgICAgICAgICAgICAgICAgICAgdXAgdW50aWwgdGhlIHBvaW50IGluIHRpbWUgaXQgd2lsbCBiZSBuZWVkZWQgOi0pICovCiAgICAgICAgICAgICAgICBGSVhNRSgiIENvbG9yS2V5aW5nIG5vdCBzdXBwb3J0ZWQgaW4gdGhlIFJHQiAzMzIgZm9ybWF0ICFcbiIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfUjVHNkI1OgogICAgICAgICAgICBpZiAoY29sb3JrZXlfYWN0aXZlKSB7CiAgICAgICAgICAgICAgICAqY29udmVydCA9IENPTlZFUlRfQ0tfNTY1OwogICAgICAgICAgICAgICAgKmZvcm1hdCA9IEdMX1JHQkE7CiAgICAgICAgICAgICAgICAqaW50ZXJuYWwgPSBHTF9SR0JBOwogICAgICAgICAgICAgICAgKnR5cGUgPSBHTF9VTlNJR05FRF9TSE9SVF81XzVfNV8xOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfUjhHOEI4OgogICAgICAgICAgICBpZiAoY29sb3JrZXlfYWN0aXZlKSB7CiAgICAgICAgICAgICAgICAqY29udmVydCA9IENPTlZFUlRfQ0tfUkdCMjQ7CiAgICAgICAgICAgICAgICAqZm9ybWF0ID0gR0xfUkdCQTsKICAgICAgICAgICAgICAgICppbnRlcm5hbCA9IEdMX1JHQkE7CiAgICAgICAgICAgICAgICAqdHlwZSA9IEdMX1VOU0lHTkVEX0lOVF84XzhfOF84OwogICAgICAgICAgICAgICAgKnRhcmdldF9icHAgPSA0OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfWDhSOEc4Qjg6CiAgICAgICAgICAgIGlmIChjb2xvcmtleV9hY3RpdmUpIHsKICAgICAgICAgICAgICAgICpjb252ZXJ0ID0gQ09OVkVSVF9SR0IzMl84ODg7CiAgICAgICAgICAgICAgICAqZm9ybWF0ID0gR0xfUkdCQTsKICAgICAgICAgICAgICAgICppbnRlcm5hbCA9IEdMX1JHQkE7CiAgICAgICAgICAgICAgICAqdHlwZSA9IEdMX1VOU0lHTkVEX0lOVF84XzhfOF84OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwojaWYgMAogICAgICAgIC8qIE5vdCBzdXJlIGlmIHdlIHNob3VsZCBkbyBjb2xvciBrZXlpbmcgb24gQWxwaGEtRW5hYmxlZCBzdXJmYWNlcyAqLwogICAgICAgIGNhc2UgV0lORUQzREZNVF9BNFI0RzRCNDoKICAgICAgICAgICAgaWYgKGNvbG9ya2V5X2FjdGl2ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgKmNvbnZlcnQgPSBDT05WRVJUX0NLXzQ0NDRfQVJHQjsKICAgICAgICAgICAgICAgICpmb3JtYXQgPSBHTF9SR0JBOwogICAgICAgICAgICAgICAgKmludGVybmFsID0gR0xfUkdCQTsKICAgICAgICAgICAgICAgICp0eXBlID0gR0xfVU5TSUdORURfU0hPUlRfNF80XzRfNDsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBXSU5FRDNERk1UX0ExUjVHNUI1OgogICAgICAgICAgICBpZiAoY29sb3JrZXlfYWN0aXZlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAqY29udmVydCA9IENPTlZFUlRfQ0tfMTU1NTsKICAgICAgICAgICAgfQoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfQThSOEc4Qjg6CiAgICAgICAgICAgIGlmIChjb2xvcmtleV9hY3RpdmUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICpjb252ZXJ0ID0gQ09OVkVSVF9DS184ODg4X0FSR0I7CiAgICAgICAgICAgICAgICAqZm9ybWF0ID0gR0xfUkdCQTsKICAgICAgICAgICAgICAgICppbnRlcm5hbCA9IEdMX1JHQkE7CiAgICAgICAgICAgICAgICAqdHlwZSA9IEdMX1VOU0lHTkVEX0lOVF84XzhfOF84OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwojZW5kaWYKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBicmVhazsKICAgIH0KCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBkM2RmbXRfY29udmVydF9zdXJmYWNlKEJZVEUgKnNyYywgQllURSAqZHN0LCB1bnNpZ25lZCBsb25nIGxlbiwgQ09OVkVSVF9UWVBFUyBjb252ZXJ0LCBJV2luZUQzRFN1cmZhY2VJbXBsICpzdXJmKSB7CiAgICBUUkFDRSgiKCVwKS0+KCVwKSwoJWxkLCVkLCVwKVxuIiwgc3JjLCBkc3QsIGxlbiwgY29udmVydCwgc3VyZik7CgogICAgc3dpdGNoIChjb252ZXJ0KSB7CiAgICAgICAgY2FzZSBOT19DT05WRVJTSU9OOgogICAgICAgIHsKICAgICAgICAgICAgbWVtY3B5KGRzdCwgc3JjLCBsZW4gKiBzdXJmLT5ieXRlc1BlclBpeGVsKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGNhc2UgQ09OVkVSVF9QQUxFVFRFRDoKICAgICAgICBjYXNlIENPTlZFUlRfUEFMRVRURURfQ0s6CiAgICAgICAgewogICAgICAgICAgICBJV2luZUQzRFBhbGV0dGVJbXBsKiBwYWwgPSBzdXJmLT5wYWxldHRlOwogICAgICAgICAgICBCWVRFIHRhYmxlWzI1Nl1bNF07CiAgICAgICAgICAgIHVuc2lnbmVkIGludCBpOwogICAgICAgICAgICB1bnNpZ25lZCBpbnQgeDsKCiAgICAgICAgICAgIGlmKCBwYWwgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgLyogVE9ETzogSWYgd2UgYXJlIGEgc3VibGV2ZWwsIHRyeSB0byBnZXQgdGhlIHBhbGV0dGUgZnJvbSBsZXZlbCAwICovCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChwYWwgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgLyogU3RpbGwgbm8gcGFsZXR0ZT8gVXNlIHRoZSBkZXZpY2UncyBwYWxldHRlICovCiAgICAgICAgICAgICAgICAvKiBHZXQgdGhlIHN1cmZhY2UncyBwYWxldHRlICovCiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgMjU2OyBpKyspIHsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZUltcGwgKmRldmljZSA9IHN1cmYtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CgogICAgICAgICAgICAgICAgICAgIHRhYmxlW2ldWzBdID0gZGV2aWNlLT5wYWxldHRlc1tkZXZpY2UtPmN1cnJlbnRQYWxldHRlXVtpXS5wZVJlZDsKICAgICAgICAgICAgICAgICAgICB0YWJsZVtpXVsxXSA9IGRldmljZS0+cGFsZXR0ZXNbZGV2aWNlLT5jdXJyZW50UGFsZXR0ZV1baV0ucGVHcmVlbjsKICAgICAgICAgICAgICAgICAgICB0YWJsZVtpXVsyXSA9IGRldmljZS0+cGFsZXR0ZXNbZGV2aWNlLT5jdXJyZW50UGFsZXR0ZV1baV0ucGVCbHVlOwogICAgICAgICAgICAgICAgICAgIGlmICgoY29udmVydCA9PSBDT05WRVJUX1BBTEVUVEVEX0NLKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAoaSA+PSBzdXJmLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUxvd1ZhbHVlKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAoaSA8PSBzdXJmLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUhpZ2hWYWx1ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogV2Ugc2hvdWxkIG1heWJlIGhlcmUgcHV0IGEgbW9yZSAnbmV1dHJhbCcgY29sb3IgdGhhbiB0aGUgc3RhbmRhcmQgYnJpZ2h0IHB1cnBsZQogICAgICAgICAgICAgICAgICAgICAgICAgIG9uZSBvZnRlbiB1c2VkIGJ5IGFwcGxpY2F0aW9uIHRvIHByZXZlbnQgdGhlIG5pY2UgcHVycGxlIGJvcmRlcnMgd2hlbiBiaS1saW5lYXIKICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXJpbmcgaXMgb24gKi8KICAgICAgICAgICAgICAgICAgICAgICAgdGFibGVbaV1bM10gPSAweDAwOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRhYmxlW2ldWzNdID0gMHhGRjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBUUkFDRSgiVXNpbmcgc3VyZmFjZSBwYWxldHRlICVwXG4iLCBwYWwpOwogICAgICAgICAgICAgICAgLyogR2V0IHRoZSBzdXJmYWNlJ3MgcGFsZXR0ZSAqLwogICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IDI1NjsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgdGFibGVbaV1bMF0gPSBwYWwtPnBhbGVudHNbaV0ucGVSZWQ7CiAgICAgICAgICAgICAgICAgICAgdGFibGVbaV1bMV0gPSBwYWwtPnBhbGVudHNbaV0ucGVHcmVlbjsKICAgICAgICAgICAgICAgICAgICB0YWJsZVtpXVsyXSA9IHBhbC0+cGFsZW50c1tpXS5wZUJsdWU7CiAgICAgICAgICAgICAgICAgICAgaWYgKChjb252ZXJ0ID09IENPTlZFUlRfUEFMRVRURURfQ0spICYmCiAgICAgICAgICAgICAgICAgICAgICAgIChpID49IHN1cmYtPlNyY0JsdENLZXkuZHdDb2xvclNwYWNlTG93VmFsdWUpICYmCiAgICAgICAgICAgICAgICAgICAgICAgIChpIDw9IHN1cmYtPlNyY0JsdENLZXkuZHdDb2xvclNwYWNlSGlnaFZhbHVlKSkgewogICAgICAgICAgICAgICAgICAgICAgICAvKiBXZSBzaG91bGQgbWF5YmUgaGVyZSBwdXQgYSBtb3JlICduZXV0cmFsJyBjb2xvciB0aGFuIHRoZSBzdGFuZGFyZCBicmlnaHQgcHVycGxlCiAgICAgICAgICAgICAgICAgICAgICAgICAgb25lIG9mdGVuIHVzZWQgYnkgYXBwbGljYXRpb24gdG8gcHJldmVudCB0aGUgbmljZSBwdXJwbGUgYm9yZGVycyB3aGVuIGJpLWxpbmVhcgogICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcmluZyBpcyBvbiAqLwogICAgICAgICAgICAgICAgICAgICAgICB0YWJsZVtpXVszXSA9IDB4MDA7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGFibGVbaV1bM10gPSAweEZGOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yICh4ID0gMDsgeCA8IGxlbjsgeCsrKSB7CiAgICAgICAgICAgICAgICBCWVRFIGNvbG9yID0gKnNyYysrOwogICAgICAgICAgICAgICAgKmRzdCsrID0gdGFibGVbY29sb3JdWzBdOwogICAgICAgICAgICAgICAgKmRzdCsrID0gdGFibGVbY29sb3JdWzFdOwogICAgICAgICAgICAgICAgKmRzdCsrID0gdGFibGVbY29sb3JdWzJdOwogICAgICAgICAgICAgICAgKmRzdCsrID0gdGFibGVbY29sb3JdWzNdOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIENPTlZFUlRfQ0tfNTY1OgogICAgICAgIHsKICAgICAgICAgICAgLyogQ29udmVydGluZyB0aGUgNTY1IGZvcm1hdCBpbiA1NTUxIHBhY2tlZCB0byBlbXVsYXRlIGNvbG9yLWtleWluZy4KCiAgICAgICAgICAgICAgTm90ZSA6IGluIGFsbCB0aGVzZSBjb252ZXJzaW9uLCBpdCB3b3VsZCBiZSBiZXN0IHRvIGF2ZXJhZ2UgdGhlIGF2ZXJhZ2luZwogICAgICAgICAgICAgICAgICAgICAgcGl4ZWxzIHRvIGdldCB0aGUgY29sb3Igb2YgdGhlIHBpeGVsIHRoYXQgd2lsbCBiZSBjb2xvci1rZXllZCB0bwogICAgICAgICAgICAgICAgICAgICAgcHJldmVudCAnY29sb3IgYmxlZWRpbmcnLiBUaGlzIHdpbGwgYmUgZG9uZSBsYXRlciBvbiBpZiBldmVyIGl0IGlzCiAgICAgICAgICAgICAgICAgICAgICB0b28gdmlzaWJsZS4KCiAgICAgICAgICAgICAgTm90ZTI6IHdoZW4gdXNpbmcgY29sb3Ita2V5aW5nICsgYWxwaGEsIGFyZSB0aGUgYWxwaGEgYml0cyBwYXJ0IG9mIHRoZQogICAgICAgICAgICAgICAgICAgICAgY29sb3Itc3BhY2Ugb3Igbm90ID8KICAgICAgICAgICAgKi8KICAgICAgICAgICAgdW5zaWduZWQgaW50IHg7CiAgICAgICAgICAgIFdPUkQgKlNvdXJjZSA9IChXT1JEICopIHNyYzsKICAgICAgICAgICAgV09SRCAqRGVzdCA9IChXT1JEICopIGRzdDsKCiAgICAgICAgICAgIFRSQUNFKCJDb2xvciBrZXllZCA1NjVcbiIpOwoKICAgICAgICAgICAgZm9yICh4ID0gMDsgeCA8IGxlbjsgeCsrICkgewogICAgICAgICAgICAgICAgV09SRCBjb2xvciA9ICpTb3VyY2UrKzsKICAgICAgICAgICAgICAgICpEZXN0ID0gKChjb2xvciAmIDB4RkZDMCkgfCAoKGNvbG9yICYgMHgxRikgPDwgMSkpOwogICAgICAgICAgICAgICAgaWYgKChjb2xvciA8IHN1cmYtPlNyY0JsdENLZXkuZHdDb2xvclNwYWNlTG93VmFsdWUpIHx8CiAgICAgICAgICAgICAgICAgICAgKGNvbG9yID4gc3VyZi0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VIaWdoVmFsdWUpKSB7CiAgICAgICAgICAgICAgICAgICAgKkRlc3QgfD0gMHgwMDAxOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgRGVzdCsrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIENPTlZFUlRfQ0tfMTU1NToKICAgICAgICB7CiAgICAgICAgICAgIHVuc2lnbmVkIGludCB4OwogICAgICAgICAgICBXT1JEICpTb3VyY2UgPSAoV09SRCAqKSBzcmM7CiAgICAgICAgICAgIFdPUkQgKkRlc3QgPSAoV09SRCAqKSBkc3Q7CgogICAgICAgICAgICBmb3IgKHggPSAwOyB4IDwgbGVuICogc2l6ZW9mKFdPUkQpOyB4Kz1zaXplb2YoV09SRCkpIHsKICAgICAgICAgICAgICAgIFdPUkQgY29sb3IgPSAqU291cmNlKys7CiAgICAgICAgICAgICAgICAqRGVzdCA9IChjb2xvciAmIDB4N0ZGRik7CiAgICAgICAgICAgICAgICBpZiAoKGNvbG9yIDwgc3VyZi0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VMb3dWYWx1ZSkgfHwKICAgICAgICAgICAgICAgICAgICAoY29sb3IgPiBzdXJmLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUhpZ2hWYWx1ZSkpCiAgICAgICAgICAgICAgICAgICAgKkRlc3QgfD0gKGNvbG9yICYgMHg4MDAwKTsKICAgICAgICAgICAgICAgIERlc3QrKzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBDT05WRVJUX0NLXzQ0NDRfQVJHQjoKICAgICAgICB7CiAgICAgICAgICAgIC8qIE1vdmUgdGhlIGZvdXIgQWxwaGEgYml0cy4uLiAqLwogICAgICAgICAgICB1bnNpZ25lZCBpbnQgeDsKICAgICAgICAgICAgV09SRCAqU291cmNlID0gKFdPUkQgKikgc3JjOwogICAgICAgICAgICBXT1JEICpEZXN0ID0gKFdPUkQgKikgZHN0OwoKICAgICAgICAgICAgZm9yICh4ID0gMDsgeCA8IGxlbjsgeCsrKSB7CiAgICAgICAgICAgICAgICBXT1JEIGNvbG9yID0gKlNvdXJjZSsrOwogICAgICAgICAgICAgICAgKmRzdCA9IChjb2xvciAmIDB4MEZGRikgPDwgNDsKICAgICAgICAgICAgICAgIGlmICgoY29sb3IgPCBzdXJmLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUxvd1ZhbHVlKSB8fAogICAgICAgICAgICAgICAgICAgIChjb2xvciA+IHN1cmYtPlNyY0JsdENLZXkuZHdDb2xvclNwYWNlSGlnaFZhbHVlKSkKICAgICAgICAgICAgICAgICAgICAqRGVzdCB8PSAoY29sb3IgJiAweEYwMDApID4+IDEyOwogICAgICAgICAgICAgICAgRGVzdCsrOwogICAgICAgICAgICB9CiAgICAgICAgfSBicmVhazsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRVJSKCJVbnN1cHBvcnRlZCBjb252ZXJzYXRpb24gdHlwZSAlZFxuIiwgY29udmVydCk7CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCBpbiBjYXNlIG9mIDhiaXQgcGFsZXR0ZWQgdGV4dHVyZXMgdG8gdXBsb2FkIHRoZSBwYWxldHRlLgogICBGb3Igbm93IGl0IG9ubHkgc3VwcG9ydHMgR0xfRVhUX3BhbGV0dGVkX3RleHR1cmUgZXh0ZW5zaW9uIGJ1dCBzdXBwb3J0IGZvciBvdGhlcgogICBleHRlbnNpb25zIGxpa2UgQVJCX2ZyYWdtZW50X3Byb2dyYW0gYW5kIEFUSV9mcmFnbWVudF9zaGFkZXJzIHdpbGwgYmUgYWRkZWQgYXN3ZWxsLgoqLwp2b2lkIGQzZGZtdF9wOF91cGxvYWRfcGFsZXR0ZShJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBDT05WRVJUX1RZUEVTIGNvbnZlcnQpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RQYWxldHRlSW1wbCogcGFsID0gVGhpcy0+cGFsZXR0ZTsKICAgIEJZVEUgdGFibGVbMjU2XVs0XTsKICAgIGludCBpOwoKICAgIGlmIChwYWwgPT0gTlVMTCkgewogICAgICAgIC8qIFN0aWxsIG5vIHBhbGV0dGU/IFVzZSB0aGUgZGV2aWNlJ3MgcGFsZXR0ZSAqLwogICAgICAgIC8qIEdldCB0aGUgc3VyZmFjZSdzIHBhbGV0dGUgKi8KICAgICAgICBmb3IgKGkgPSAwOyBpIDwgMjU2OyBpKyspIHsKICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsICpkZXZpY2UgPSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOwoKICAgICAgICAgICAgdGFibGVbaV1bMF0gPSBkZXZpY2UtPnBhbGV0dGVzW2RldmljZS0+Y3VycmVudFBhbGV0dGVdW2ldLnBlUmVkOwogICAgICAgICAgICB0YWJsZVtpXVsxXSA9IGRldmljZS0+cGFsZXR0ZXNbZGV2aWNlLT5jdXJyZW50UGFsZXR0ZV1baV0ucGVHcmVlbjsKICAgICAgICAgICAgdGFibGVbaV1bMl0gPSBkZXZpY2UtPnBhbGV0dGVzW2RldmljZS0+Y3VycmVudFBhbGV0dGVdW2ldLnBlQmx1ZTsKICAgICAgICAgICAgaWYgKChjb252ZXJ0ID09IENPTlZFUlRfUEFMRVRURURfQ0spICYmCiAgICAgICAgICAgICAgICAoaSA+PSBUaGlzLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUxvd1ZhbHVlKSAmJgogICAgICAgICAgICAgICAgKGkgPD0gVGhpcy0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VIaWdoVmFsdWUpKSB7CiAgICAgICAgICAgICAgICAvKiBXZSBzaG91bGQgbWF5YmUgaGVyZSBwdXQgYSBtb3JlICduZXV0cmFsJyBjb2xvciB0aGFuIHRoZSBzdGFuZGFyZCBicmlnaHQgcHVycGxlCiAgICAgICAgICAgICAgICAgICBvbmUgb2Z0ZW4gdXNlZCBieSBhcHBsaWNhdGlvbiB0byBwcmV2ZW50IHRoZSBuaWNlIHB1cnBsZSBib3JkZXJzIHdoZW4gYmktbGluZWFyCiAgICAgICAgICAgICAgICAgICBmaWx0ZXJpbmcgaXMgb24gKi8KICAgICAgICAgICAgICAgIHRhYmxlW2ldWzNdID0gMHgwMDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHRhYmxlW2ldWzNdID0gMHhGRjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgVFJBQ0UoIlVzaW5nIHN1cmZhY2UgcGFsZXR0ZSAlcFxuIiwgcGFsKTsKICAgICAgICAvKiBHZXQgdGhlIHN1cmZhY2UncyBwYWxldHRlICovCiAgICAgICAgZm9yIChpID0gMDsgaSA8IDI1NjsgaSsrKSB7CiAgICAgICAgICAgIHRhYmxlW2ldWzBdID0gcGFsLT5wYWxlbnRzW2ldLnBlUmVkOwogICAgICAgICAgICB0YWJsZVtpXVsxXSA9IHBhbC0+cGFsZW50c1tpXS5wZUdyZWVuOwogICAgICAgICAgICB0YWJsZVtpXVsyXSA9IHBhbC0+cGFsZW50c1tpXS5wZUJsdWU7CiAgICAgICAgICAgIGlmICgoY29udmVydCA9PSBDT05WRVJUX1BBTEVUVEVEX0NLKSAmJgogICAgICAgICAgICAgICAgKGkgPj0gVGhpcy0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VMb3dWYWx1ZSkgJiYKICAgICAgICAgICAgICAgIChpIDw9IFRoaXMtPlNyY0JsdENLZXkuZHdDb2xvclNwYWNlSGlnaFZhbHVlKSkgewogICAgICAgICAgICAgICAgLyogV2Ugc2hvdWxkIG1heWJlIGhlcmUgcHV0IGEgbW9yZSAnbmV1dHJhbCcgY29sb3IgdGhhbiB0aGUgc3RhbmRhcmQgYnJpZ2h0IHB1cnBsZQogICAgICAgICAgICAgICAgICAgb25lIG9mdGVuIHVzZWQgYnkgYXBwbGljYXRpb24gdG8gcHJldmVudCB0aGUgbmljZSBwdXJwbGUgYm9yZGVycyB3aGVuIGJpLWxpbmVhcgogICAgICAgICAgICAgICAgICAgZmlsdGVyaW5nIGlzIG9uICovCiAgICAgICAgICAgICAgICB0YWJsZVtpXVszXSA9IDB4MDA7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0YWJsZVtpXVszXSA9IDB4RkY7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICBHTF9FWFRDQUxMKGdsQ29sb3JUYWJsZUVYVChHTF9URVhUVVJFXzJELEdMX1JHQkEsMjU2LEdMX1JHQkEsR0xfVU5TSUdORURfQllURSwgdGFibGUpKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfTG9hZFRleHR1cmUoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBHTGVudW0gZm9ybWF0LCBpbnRlcm5hbCwgdHlwZTsKICAgIENPTlZFUlRfVFlQRVMgY29udmVydDsKICAgIGludCBicHA7CiAgICBpbnQgd2lkdGg7CiAgICBCWVRFICptZW07CgogICAgaWYgKFRoaXMtPkZsYWdzICYgU0ZMQUdfSU5URVhUVVJFKSB7CiAgICAgICAgVFJBQ0UoIlN1cmZhY2UgYWxyZWFkeSBpbiB0ZXh0dXJlXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KICAgIGlmIChUaGlzLT5GbGFncyAmIFNGTEFHX0RJUlRZKSB7CiAgICAgICAgVFJBQ0UoIlJlbG9hZGluZyBiZWNhdXNlIHN1cmZhY2UgaXMgZGlydHlcbiIpOwogICAgfSBlbHNlIGlmKC8qIFJlbG9hZDogZ2wgdGV4dHVyZSBoYXMgY2ssIG5vdyBubyBja2V5IGlzIHNldCBPUiAqLwogICAgICAgICAgICAgICgoVGhpcy0+RmxhZ3MgJiBTRkxBR19HTENLRVkpICYmICghKFRoaXMtPkNLZXlGbGFncyAmIEREU0RfQ0tTUkNCTFQpKSkgfHwKICAgICAgICAgICAgICAvKiBSZWxvYWQ6IHZpY2UgdmVyc2EgIE9SICovCiAgICAgICAgICAgICAgKCghKFRoaXMtPkZsYWdzICYgU0ZMQUdfR0xDS0VZKSkgJiYgKFRoaXMtPkNLZXlGbGFncyAmIEREU0RfQ0tTUkNCTFQpKSB8fAogICAgICAgICAgICAgIC8qIEFsc28gcmVsb2FkOiBDb2xvciBrZXkgaXMgYWN0aXZlIEFORCB0aGUgY29sb3Iga2V5IGhhcyBjaGFuZ2VkICovCiAgICAgICAgICAgICAgKChUaGlzLT5DS2V5RmxhZ3MgJiBERFNEX0NLU1JDQkxUKSAmJiAoCiAgICAgICAgICAgICAgICAoVGhpcy0+Z2xDS2V5LmR3Q29sb3JTcGFjZUxvd1ZhbHVlICE9IFRoaXMtPlNyY0JsdENLZXkuZHdDb2xvclNwYWNlTG93VmFsdWUpIHx8CiAgICAgICAgICAgICAgICAoVGhpcy0+Z2xDS2V5LmR3Q29sb3JTcGFjZUhpZ2hWYWx1ZSAhPSBUaGlzLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUhpZ2hWYWx1ZSkpKSkgewogICAgICAgIFRSQUNFKCJSZWxvYWRpbmcgYmVjYXVzZSBvZiBjb2xvciBrZXlpbmdcbiIpOwogICAgfSBlbHNlIHsKICAgICAgICBUUkFDRSgic3VyZmFjZSBpc24ndCBkaXJ0eVxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgVGhpcy0+RmxhZ3MgJj0gflNGTEFHX0RJUlRZOwoKICAgIC8qIFJlc291cmNlcyBhcmUgcGxhY2VkIGluIHN5c3RlbSBSQU0gYW5kIGRvIG5vdCBuZWVkIHRvIGJlIHJlY3JlYXRlZCB3aGVuIGEgZGV2aWNlIGlzIGxvc3QuCiAgICAqICBUaGVzZSByZXNvdXJjZXMgYXJlIG5vdCBib3VuZCBieSBkZXZpY2Ugc2l6ZSBvciBmb3JtYXQgcmVzdHJpY3Rpb25zLiBCZWNhdXNlIG9mIHRoaXMsCiAgICAqICB0aGVzZSByZXNvdXJjZXMgY2Fubm90IGJlIGFjY2Vzc2VkIGJ5IHRoZSBEaXJlY3QzRCBkZXZpY2Ugbm9yIHNldCBhcyB0ZXh0dXJlcyBvciByZW5kZXIgdGFyZ2V0cy4KICAgICogIEhvd2V2ZXIsIHRoZXNlIHJlc291cmNlcyBjYW4gYWx3YXlzIGJlIGNyZWF0ZWQsIGxvY2tlZCwgYW5kIGNvcGllZC4KICAgICovCiAgICBpZiAoVGhpcy0+cmVzb3VyY2UucG9vbCA9PSBXSU5FRDNEUE9PTF9TQ1JBVENIICYmICEoVGhpcy0+RmxhZ3MgJiBTRkxBR19GT1JDRUxPQUQpICkKICAgIHsKICAgICAgICBGSVhNRSgiKCVwKSBPcGVyYXRpb24gbm90IHN1cHBvcnRlZCBmb3Igc2NyYXRjaCB0ZXh0dXJlc1xuIixUaGlzKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBpZiAoVGhpcy0+RmxhZ3MgJiBTRkxBR19JTlBCVUZGRVIpIHsKICAgICAgICBpZiAoVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCAhPSAwKQogICAgICAgICAgICBGSVhNRSgiU3VyZmFjZSBpbiB0ZXh0dXJlIGlzIG9ubHkgc3VwcG9ydGVkIGZvciBsZXZlbCAwXG4iKTsKICAgICAgICBlbHNlIGlmIChUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9QOCB8fCBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9BOFA4IHx8CiAgICAgICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMSB8fCBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQyIHx8CiAgICAgICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMyB8fCBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQ0IHx8CiAgICAgICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNSkKICAgICAgICAgICAgRklYTUUoIkZvcm1hdCAlZCBub3Qgc3VwcG9ydGVkXG4iLCBUaGlzLT5yZXNvdXJjZS5mb3JtYXQpOwogICAgICAgIGVsc2UgewogICAgICAgICAgICBHTGludCBwcmV2UmVhZDsKCiAgICAgICAgICAgIEVOVEVSX0dMKCk7CgogICAgICAgICAgICBnbEdldEludGVnZXJ2KEdMX1JFQURfQlVGRkVSLCAmcHJldlJlYWQpOwogICAgICAgICAgICB2Y2hlY2tHTGNhbGwoImdsR2V0SW50ZWdlcnYiKTsKICAgICAgICAgICAgZ2xSZWFkQnVmZmVyKEdMX0JBQ0spOwogICAgICAgICAgICB2Y2hlY2tHTGNhbGwoImdsUmVhZEJ1ZmZlciIpOwoKICAgICAgICAgICAgZ2xDb3B5VGV4SW1hZ2UyRChUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xGb3JtYXRJbnRlcm5hbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+Y3VycmVudERlc2MuV2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIDApOwoKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsQ29weVRleEltYWdlMkQiKTsKICAgICAgICAgICAgZ2xSZWFkQnVmZmVyKHByZXZSZWFkKTsKICAgICAgICAgICAgdmNoZWNrR0xjYWxsKCJnbFJlYWRCdWZmZXIiKTsKCiAgICAgICAgICAgIExFQVZFX0dMKCk7CgogICAgICAgICAgICBUUkFDRSgiVXBkYXRpbmcgdGFyZ2V0ICVkXG4iLCBUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCk7CiAgICAgICAgICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX0lOVEVYVFVSRTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgaWYoVGhpcy0+Q0tleUZsYWdzICYgRERTRF9DS1NSQ0JMVCkgewogICAgICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX0dMQ0tFWTsKICAgICAgICBUaGlzLT5nbENLZXkgPSBUaGlzLT5TcmNCbHRDS2V5OwogICAgfQogICAgZWxzZSBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfR0xDS0VZOwoKICAgIGQzZGZtdF9nZXRfY29udihUaGlzLCBUUlVFIC8qIFdlIG5lZWQgY29sb3Iga2V5aW5nICovLCBUUlVFIC8qIFdlIHdpbGwgdXNlIHRleHR1cmVzICovLCAmZm9ybWF0LCAmaW50ZXJuYWwsICZ0eXBlLCAmY29udmVydCwgJmJwcCk7CgogICAgLyogVGhlIHdpZHRoIGlzIGluICdsZW5ndGgnIG5vdCBpbiBieXRlcyAqLwogICAgaWYgKE5QMl9SRVBBQ0sgPT0gd2luZWQzZF9zZXR0aW5ncy5ub25wb3dlcjJfbW9kZSB8fCBUaGlzLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQpCiAgICAgICAgd2lkdGggPSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgIGVsc2UKICAgICAgICB3aWR0aCA9IFRoaXMtPnBvdzJXaWR0aDsKCiAgICBpZigoY29udmVydCAhPSBOT19DT05WRVJTSU9OKSAmJiBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpIHsKICAgICAgICBpbnQgaGVpZ2h0ID0gVGhpcy0+Z2xSZWN0LmJvdHRvbSAtIFRoaXMtPmdsUmVjdC50b3A7CgogICAgICAgIG1lbSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCB3aWR0aCAqIGhlaWdodCAqIGJwcCk7CiAgICAgICAgaWYoIW1lbSkgewogICAgICAgICAgICBFUlIoIk91dCBvZiBtZW1vcnkgJWQsICVkIVxuIiwgd2lkdGgsIGhlaWdodCk7CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX09VVE9GVklERU9NRU1PUlk7CiAgICAgICAgfQogICAgICAgIGQzZGZtdF9jb252ZXJ0X3N1cmZhY2UoVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5LCBtZW0sIHdpZHRoICogaGVpZ2h0LCBjb252ZXJ0LCBUaGlzKTsKCiAgICAgICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfQ09OVkVSVEVEOwogICAgfSBlbHNlIGlmIChUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9QOCAmJiBHTF9TVVBQT1JUKEVYVF9QQUxFVFRFRF9URVhUVVJFKSkgewogICAgICAgIGQzZGZtdF9wOF91cGxvYWRfcGFsZXR0ZShpZmFjZSwgY29udmVydCk7CiAgICAgICAgVGhpcy0+RmxhZ3MgJj0gflNGTEFHX0NPTlZFUlRFRDsKICAgICAgICBtZW0gPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnk7CiAgICB9IGVsc2UgewogICAgICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19DT05WRVJURUQ7CiAgICAgICAgbWVtID0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5OwogICAgfQoKICAgIC8qIE1ha2Ugc3VyZSB0aGUgY29ycmVjdCBwaXRjaCBpcyB1c2VkICovCiAgICBnbFBpeGVsU3RvcmVpKEdMX1VOUEFDS19ST1dfTEVOR1RILCB3aWR0aCk7CgogICAgaWYgKE5QMl9SRVBBQ0sgPT0gd2luZWQzZF9zZXR0aW5ncy5ub25wb3dlcjJfbW9kZSAmJiAoVGhpcy0+RmxhZ3MgJiBTRkxBR19OT05QT1cyKSAmJiAhKFRoaXMtPkZsYWdzICYgU0ZMQUdfT1ZFUlNJWkUpKSB7CiAgICAgICAgVFJBQ0UoIm5vbiBwb3dlciBvZiB0d28gc3VwcG9ydFxuIik7CiAgICAgICAgc3VyZmFjZV9hbGxvY2F0ZV9zdXJmYWNlKFRoaXMsIGludGVybmFsLCBUaGlzLT5wb3cyV2lkdGgsIFRoaXMtPnBvdzJIZWlnaHQsIGZvcm1hdCwgdHlwZSk7CiAgICAgICAgaWYgKG1lbSkgewogICAgICAgICAgICBzdXJmYWNlX3VwbG9hZF9kYXRhKFRoaXMsIFRoaXMtPnBvdzJXaWR0aCwgVGhpcy0+cG93MkhlaWdodCwgZm9ybWF0LCB0eXBlLCBtZW0pOwogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgc3VyZmFjZV9hbGxvY2F0ZV9zdXJmYWNlKFRoaXMsIGludGVybmFsLCBUaGlzLT5nbFJlY3QucmlnaHQgLSBUaGlzLT5nbFJlY3QubGVmdCwgVGhpcy0+Z2xSZWN0LmJvdHRvbSAtIFRoaXMtPmdsUmVjdC50b3AsIGZvcm1hdCwgdHlwZSk7CiAgICAgICAgaWYgKG1lbSkgewogICAgICAgICAgICBzdXJmYWNlX3VwbG9hZF9kYXRhKFRoaXMsIFRoaXMtPmdsUmVjdC5yaWdodCAtIFRoaXMtPmdsUmVjdC5sZWZ0LCBUaGlzLT5nbFJlY3QuYm90dG9tIC0gVGhpcy0+Z2xSZWN0LnRvcCwgZm9ybWF0LCB0eXBlLCBtZW0pOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBSZXN0b3JlIHRoZSBkZWZhdWx0IHBpdGNoICovCiAgICBnbFBpeGVsU3RvcmVpKEdMX1VOUEFDS19ST1dfTEVOR1RILCAwKTsKCiAgICBpZiAobWVtICE9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSkKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBtZW0pOwoKI2lmIDAKICAgIHsKICAgICAgICBzdGF0aWMgdW5zaWduZWQgaW50IGdlbiA9IDA7CiAgICAgICAgY2hhciBidWZmZXJbNDA5Nl07CiAgICAgICAgKytnZW47CiAgICAgICAgaWYgKChnZW4gJSAxMCkgPT0gMCkgewogICAgICAgICAgICBzbnByaW50ZihidWZmZXIsIHNpemVvZihidWZmZXIpLCAiL3RtcC9zdXJmYWNlJXBfdHlwZSV1X2xldmVsJXVfJXUucHBtIiwgVGhpcywgVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsIGdlbik7CiAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZUltcGxfU2F2ZVNuYXBzaG90KGlmYWNlLCBidWZmZXIpOwogICAgICAgIH0KICAgICAgICAvKgogICAgICAgICAqIGRlYnVnZ2luZyBjcmFzaCBjb2RlCiAgICAgICAgIGlmIChnZW4gPT0gMjUwKSB7CiAgICAgICAgIHZvaWQqKiB0ZXN0ID0gTlVMTDsKICAgICAgICAgKnRlc3QgPSAwOwogICAgICAgICB9CiAgICAgICAgICovCiAgICB9CiNlbmRpZgoKICAgIGlmICghKFRoaXMtPkZsYWdzICYgU0ZMQUdfRE9OT1RGUkVFKSkgewogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSk7CiAgICAgICAgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gTlVMTDsKICAgIH0KCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKI2luY2x1ZGUgPGVycm5vLmg+CiNpbmNsdWRlIDxzdGRpby5oPgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1NhdmVTbmFwc2hvdChJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBjb25zdCBjaGFyKiBmaWxlbmFtZSkgewogICAgRklMRSogZiA9IE5VTEw7CiAgICBVSU5UIGksIHk7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIGNoYXIgKmFsbG9jYXRlZE1lbW9yeTsKICAgIGNoYXIgKnRleHR1cmVSb3c7CiAgICBJV2luZUQzRFN3YXBDaGFpbiAqc3dhcENoYWluID0gTlVMTDsKICAgIGludCB3aWR0aCwgaGVpZ2h0OwogICAgR0x1aW50IHRtcFRleHR1cmUgPSAwOwogICAgRFdPUkQgY29sb3I7CiAgICAvKkZJWE1FOgogICAgVGV4dHVyZXMgbXkgbm90IGJlIHN0b3JlZCBpbiAtPmFsbG9jYXRlZGdNZW1vcnkgYW5kIGEgR2xUZXh0dXJlCiAgICBzbyB3ZSBzaG91bGQgbG9jayB0aGUgc3VyZmFjZSBiZWZvcmUgc2F2aW5nIGEgc25hcHNob3QsIG9yIGF0IGxlYXN0IGNoZWNrIHRoYXQKICAgICovCiAgICAvKiBUT0RPOiBDb21wcmVzc2VkIHRleHR1cmUgaW1hZ2VzIGNhbiBiZSBvYnRhaW5lZCBmcm9tIHRoZSBHTCBpbiB1bmNvbXByZXNzZWQgZm9ybQogICAgYnkgY2FsbGluZyBHZXRUZXhJbWFnZSBhbmQgaW4gY29tcHJlc3NlZCBmb3JtIGJ5IGNhbGxpbmcKICAgIEdldENvbXByZXNzZWRUZXhJbWFnZUFSQi4gIFF1ZXJpZWQgY29tcHJlc3NlZCBpbWFnZXMgY2FuIGJlIHNhdmVkIGFuZAogICAgbGF0ZXIgcmV1c2VkIGJ5IGNhbGxpbmcgQ29tcHJlc3NlZFRleEltYWdlWzEyM11EQVJCLiAgUHJlLWNvbXByZXNzZWQKICAgIHRleHR1cmUgaW1hZ2VzIGRvIG5vdCBuZWVkIHRvIGJlIHByb2Nlc3NlZCBieSB0aGUgR0wgYW5kIHNob3VsZAogICAgc2lnbmlmaWNhbnRseSBpbXByb3ZlIHRleHR1cmUgbG9hZGluZyBwZXJmb3JtYW5jZSByZWxhdGl2ZSB0byB1bmNvbXByZXNzZWQKICAgIGltYWdlcy4gKi8KCi8qIFNldHVwIHRoZSB3aWR0aCBhbmQgaGVpZ2h0IHRvIGJlIHRoZSBpbnRlcm5hbCB0ZXh0dXJlIHdpZHRoIGFuZCBoZWlnaHQuICovCiAgICB3aWR0aCAgPSBUaGlzLT5wb3cyV2lkdGg7CiAgICBoZWlnaHQgPSBUaGlzLT5wb3cySGVpZ2h0OwovKiBjaGVjayB0byBzZWUgaWYgd2VyZSBhICd2aXJ0dWFsJyB0ZXh0dXJlIGUuZy4gd2VyZSBub3QgYSBwYnVmZmVyIG9mIHRleHR1cmUgd2VyZSBhIGJhY2sgYnVmZmVyKi8KICAgIElXaW5lRDNEU3VyZmFjZV9HZXRDb250YWluZXIoaWZhY2UsICZJSURfSVdpbmVEM0RTd2FwQ2hhaW4sICh2b2lkICoqKSZzd2FwQ2hhaW4pOwoKICAgIGlmIChzd2FwQ2hhaW4gfHwgKFRoaXMtPkZsYWdzICYgU0ZMQUdfSU5QQlVGRkVSKSkgeyAvKiBpZiB3ZXJlIG5vdCBhIHJlYWwgdGV4dHVyZSB0aGVuIHJlYWQgdGhlIGJhY2sgYnVmZmVyIGludG8gYSByZWFsIHRleHR1cmUqLwovKiB3ZSBkb24ndCB3YW50IHRvIGludGVyZmVyZSB3aXRoIHRoZSBiYWNrIGJ1ZmZlciBzbyByZWFkIHRoZSBkYXRhIGludG8gYSB0ZW1wb3JhcnkgdGV4dHVyZSBhbmQgdGhlbiBzYXZlIHRoZSBkYXRhIG91dCBvZiB0aGUgdGVtcG9yYXJ5IHRleHR1cmUgKi8KICAgICAgICBHTGludCBwcmV2UmVhZDsKICAgICAgICBFTlRFUl9HTCgpOwogICAgICAgIEZJWE1FKCIoJXApIFRoaXMgc3VyZmFjZSBuZWVkcyB0byBiZSBsb2NrZWQgYmVmb3JlIGEgc25hcHNob3QgY2FuIGJlIHRha2VuXG4iLCBUaGlzKTsKICAgICAgICBnbEVuYWJsZShHTF9URVhUVVJFXzJEKTsKCiAgICAgICAgZ2xHZW5UZXh0dXJlcygxLCAmdG1wVGV4dHVyZSk7CiAgICAgICAgZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCB0bXBUZXh0dXJlKTsKCiAgICAgICAgZ2xUZXhJbWFnZTJEKEdMX1RFWFRVUkVfMkQsCiAgICAgICAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgICAgICAgIEdMX1JHQkEsCiAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgICAgIDAvKmJvcmRlciovLAogICAgICAgICAgICAgICAgICAgICAgICBHTF9SR0JBLAogICAgICAgICAgICAgICAgICAgICAgICBHTF9VTlNJR05FRF9JTlRfOF84XzhfOF9SRVYsCiAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwoKICAgICAgICBnbEdldEludGVnZXJ2KEdMX1JFQURfQlVGRkVSLCAmcHJldlJlYWQpOwogICAgICAgIHZjaGVja0dMY2FsbCgiZ2xHZXRJbnRlZ2VydiIpOwogICAgICAgIGdsUmVhZEJ1ZmZlcihHTF9CQUNLKTsKICAgICAgICB2Y2hlY2tHTGNhbGwoImdsUmVhZEJ1ZmZlciIpOwogICAgICAgIGdsQ29weVRleEltYWdlMkQoR0xfVEVYVFVSRV8yRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBHTF9SR0JBLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIDApOwoKICAgICAgICBjaGVja0dMY2FsbCgiZ2xDb3B5VGV4SW1hZ2UyRCIpOwogICAgICAgIGdsUmVhZEJ1ZmZlcihwcmV2UmVhZCk7CiAgICAgICAgTEVBVkVfR0woKTsKCiAgICB9IGVsc2UgeyAvKiBiaW5kIHRoZSByZWFsIHRleHR1cmUgKi8KICAgICAgICBJV2luZUQzRFN1cmZhY2VfUHJlTG9hZChpZmFjZSk7CiAgICB9CiAgICBhbGxvY2F0ZWRNZW1vcnkgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgd2lkdGggICogaGVpZ2h0ICogNCk7CiAgICBFTlRFUl9HTCgpOwogICAgRklYTUUoIlNhdmluZyB0ZXh0dXJlIGxldmVsICVkIHdpZHRoICVkIGhlaWdodCAlZFxuIiwgVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCwgd2lkdGgsIGhlaWdodCk7CiAgICBnbEdldFRleEltYWdlKEdMX1RFWFRVUkVfMkQsCiAgICAgICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLAogICAgICAgICAgICAgICAgR0xfUkdCQSwKICAgICAgICAgICAgICAgIEdMX1VOU0lHTkVEX0lOVF84XzhfOF84X1JFViwKICAgICAgICAgICAgICAgIGFsbG9jYXRlZE1lbW9yeSk7CiAgICBjaGVja0dMY2FsbCgiZ2xUZXhJbWFnZTJEIik7CiAgICBpZiAodG1wVGV4dHVyZSkgewogICAgICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgMCk7CiAgICAgICAgZ2xEZWxldGVUZXh0dXJlcygxLCAmdG1wVGV4dHVyZSk7CiAgICB9CiAgICBMRUFWRV9HTCgpOwoKICAgIGYgPSBmb3BlbihmaWxlbmFtZSwgIncrIik7CiAgICBpZiAoTlVMTCA9PSBmKSB7CiAgICAgICAgRVJSKCJvcGVuaW5nIG9mICVzIGZhaWxlZCB3aXRoOiAlc1xuIiwgZmlsZW5hbWUsIHN0cmVycm9yKGVycm5vKSk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9Ci8qIFNhdmUgdGhlIGRhdCBvdXQgdG8gYSBUR0EgZmlsZSBiZWNhdXNlIDE6IGl0J3MgYW4gZWFzeSByYXcgZm9ybWF0LCAyOiBpdCBzdXBwb3J0cyBhbiBhbHBoYSBjaGFuZWwqLwogICAgVFJBQ0UoIiglcCkgb3BlbmVkICVzIHdpdGggZm9ybWF0ICVzXG4iLCBUaGlzLCBmaWxlbmFtZSwgZGVidWdfZDNkZm9ybWF0KFRoaXMtPnJlc291cmNlLmZvcm1hdCkpOwovKiBUR0EgaGVhZGVyICovCiAgICBmcHV0YygwLGYpOwogICAgZnB1dGMoMCxmKTsKICAgIGZwdXRjKDIsZik7CiAgICBmcHV0YygwLGYpOwogICAgZnB1dGMoMCxmKTsKICAgIGZwdXRjKDAsZik7CiAgICBmcHV0YygwLGYpOwogICAgZnB1dGMoMCxmKTsKICAgIGZwdXRjKDAsZik7CiAgICBmcHV0YygwLGYpOwogICAgZnB1dGMoMCxmKTsKICAgIGZwdXRjKDAsZik7Ci8qIHNob3J0IHdpZHRoKi8KICAgIGZ3cml0ZSgmd2lkdGgsMiwxLGYpOwovKiBzaG9ydCBoZWlnaHQgKi8KICAgIGZ3cml0ZSgmaGVpZ2h0LDIsMSxmKTsKLyogZm9ybWF0IHJnYmEgKi8KICAgIGZwdXRjKDB4MjAsZik7CiAgICBmcHV0YygweDI4LGYpOwovKiByYXcgZGF0YSAqLwogICAgLyogaWYgIHRoZSBkYXRhIGlzIHVwc2lkZSBkb3duIGlmIHdlJ3ZlIGZldGNoZWQgaXQgZnJvbSBhIGJhY2sgYnVmZmVyLCBzbyBpdCBuZWVkcyBmbGlwcGluZyBhZ2FpbiB0byBtYWtlIGl0IHRoZSBjb3JyZWN0IHdheSB1cCovCiAgICBpZihzd2FwQ2hhaW4pCiAgICAgICAgdGV4dHVyZVJvdyA9IGFsbG9jYXRlZE1lbW9yeSArICh3aWR0aCAqIChoZWlnaHQgLSAxKSAqNCk7CiAgICBlbHNlCiAgICAgICAgdGV4dHVyZVJvdyA9IGFsbG9jYXRlZE1lbW9yeTsKICAgIGZvciAoeSA9IDAgOyB5IDwgaGVpZ2h0OyB5KyspIHsKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgd2lkdGg7ICBpKyspIHsKICAgICAgICAgICAgY29sb3IgPSAqKChEV09SRCopdGV4dHVyZVJvdyk7CiAgICAgICAgICAgIGZwdXRjKChjb2xvciA+PiAxNikgJiAweEZGLCBmKTsgLyogQiAqLwogICAgICAgICAgICBmcHV0YygoY29sb3IgPj4gIDgpICYgMHhGRiwgZik7IC8qIEcgKi8KICAgICAgICAgICAgZnB1dGMoKGNvbG9yID4+ICAwKSAmIDB4RkYsIGYpOyAvKiBSICovCiAgICAgICAgICAgIGZwdXRjKChjb2xvciA+PiAyNCkgJiAweEZGLCBmKTsgLyogQSAqLwogICAgICAgICAgICB0ZXh0dXJlUm93ICs9IDQ7CiAgICAgICAgfQogICAgICAgIC8qIHRha2UgdHdvIHJvd3Mgb2YgdGhlIHBvaW50ZXIgdG8gdGhlIHRleHR1cmUgbWVtb3J5ICovCiAgICAgICAgaWYoc3dhcENoYWluKQogICAgICAgICAgICAodGV4dHVyZVJvdy09IHdpZHRoIDw8IDMpOwoKICAgIH0KICAgIFRSQUNFKCJDbG9zaW5nIGZpbGVcbiIpOwogICAgZmNsb3NlKGYpOwoKICAgIGlmKHN3YXBDaGFpbikgewogICAgICAgIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2Uoc3dhcENoYWluKTsKICAgIH0KICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGFsbG9jYXRlZE1lbW9yeSk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9DbGVhbkRpcnR5UmVjdChJV2luZUQzRFN1cmZhY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19ESVJUWTsKICAgIFRoaXMtPmRpcnR5UmVjdC5sZWZ0ICAgPSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgIFRoaXMtPmRpcnR5UmVjdC50b3AgICAgPSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICBUaGlzLT5kaXJ0eVJlY3QucmlnaHQgID0gMDsKICAgIFRoaXMtPmRpcnR5UmVjdC5ib3R0b20gPSAwOwogICAgVFJBQ0UoIiglcCkgOiBEaXJ0eT8lZCwgUmVjdDooJWQsJWQsJWQsJWQpXG4iLCBUaGlzLCBUaGlzLT5GbGFncyAmIFNGTEFHX0RJUlRZID8gMSA6IDAsIFRoaXMtPmRpcnR5UmVjdC5sZWZ0LAogICAgICAgICAgVGhpcy0+ZGlydHlSZWN0LnRvcCwgVGhpcy0+ZGlydHlSZWN0LnJpZ2h0LCBUaGlzLT5kaXJ0eVJlY3QuYm90dG9tKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKioKICogICBTbGlnaHRseSBpbmVmZmljaWVudCB3YXkgdG8gaGFuZGxlIG11bHRpcGxlIGRpcnR5IHJlY3RzIGJ1dCBpdCB3b3JrcyA6KQogKi8KZXh0ZXJuIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfQWRkRGlydHlSZWN0KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIENPTlNUIFJFQ1QqIHBEaXJ0eVJlY3QpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RCYXNlVGV4dHVyZSAqYmFzZVRleHR1cmUgPSBOVUxMOwogICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfRElSVFk7CiAgICBpZiAoTlVMTCAhPSBwRGlydHlSZWN0KSB7CiAgICAgICAgVGhpcy0+ZGlydHlSZWN0LmxlZnQgICA9IG1pbihUaGlzLT5kaXJ0eVJlY3QubGVmdCwgICBwRGlydHlSZWN0LT5sZWZ0KTsKICAgICAgICBUaGlzLT5kaXJ0eVJlY3QudG9wICAgID0gbWluKFRoaXMtPmRpcnR5UmVjdC50b3AsICAgIHBEaXJ0eVJlY3QtPnRvcCk7CiAgICAgICAgVGhpcy0+ZGlydHlSZWN0LnJpZ2h0ICA9IG1heChUaGlzLT5kaXJ0eVJlY3QucmlnaHQsICBwRGlydHlSZWN0LT5yaWdodCk7CiAgICAgICAgVGhpcy0+ZGlydHlSZWN0LmJvdHRvbSA9IG1heChUaGlzLT5kaXJ0eVJlY3QuYm90dG9tLCBwRGlydHlSZWN0LT5ib3R0b20pOwogICAgfSBlbHNlIHsKICAgICAgICBUaGlzLT5kaXJ0eVJlY3QubGVmdCAgID0gMDsKICAgICAgICBUaGlzLT5kaXJ0eVJlY3QudG9wICAgID0gMDsKICAgICAgICBUaGlzLT5kaXJ0eVJlY3QucmlnaHQgID0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAgICAgVGhpcy0+ZGlydHlSZWN0LmJvdHRvbSA9IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgIH0KICAgIFRSQUNFKCIoJXApIDogRGlydHk/JWQsIFJlY3Q6KCVkLCVkLCVkLCVkKVxuIiwgVGhpcywgVGhpcy0+RmxhZ3MgJiBTRkxBR19ESVJUWSwgVGhpcy0+ZGlydHlSZWN0LmxlZnQsCiAgICAgICAgICBUaGlzLT5kaXJ0eVJlY3QudG9wLCBUaGlzLT5kaXJ0eVJlY3QucmlnaHQsIFRoaXMtPmRpcnR5UmVjdC5ib3R0b20pOwogICAgLyogaWYgdGhlIGNvbnRhaW5lciBpcyBhIGJhc2V0ZXh0dXJlIHRoZW4gbWFyayBpdCBkaXJ0eS4gKi8KICAgIGlmIChJV2luZUQzRFN1cmZhY2VfR2V0Q29udGFpbmVyKGlmYWNlLCAmSUlEX0lXaW5lRDNEQmFzZVRleHR1cmUsICh2b2lkICoqKSZiYXNlVGV4dHVyZSkgPT0gV0lORUQzRF9PSykgewogICAgICAgIFRSQUNFKCJQYXNzaW5nIHRvIGNvbmF0aW5lclxuIik7CiAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9TZXREaXJ0eShiYXNlVGV4dHVyZSwgVFJVRSk7CiAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9SZWxlYXNlKGJhc2VUZXh0dXJlKTsKICAgIH0KICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1NldENvbnRhaW5lcihJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBJV2luZUQzREJhc2UgKmNvbnRhaW5lcikgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CgogICAgVFJBQ0UoIlRoaXMgJXAsIGNvbnRhaW5lciAlcFxuIiwgVGhpcywgY29udGFpbmVyKTsKCiAgICAvKiBXZSBjYW4ndCBrZWVwIGEgcmVmZXJlbmNlIHRvIHRoZSBjb250YWluZXIsIHNpbmNlIHRoZSBjb250YWluZXIgYWxyZWFkeSBrZWVwcyBhIHJlZmVyZW5jZSB0byB1cy4gKi8KCiAgICBUUkFDRSgiU2V0dGluZyBjb250YWluZXIgdG8gJXAgZnJvbSAlcFxuIiwgY29udGFpbmVyLCBUaGlzLT5jb250YWluZXIpOwogICAgVGhpcy0+Y29udGFpbmVyID0gY29udGFpbmVyOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1NldEZvcm1hdChJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBXSU5FRDNERk9STUFUIGZvcm1hdCkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBjb25zdCBQaXhlbEZvcm1hdERlc2MgKmZvcm1hdEVudHJ5ID0gZ2V0Rm9ybWF0RGVzY0VudHJ5KGZvcm1hdCk7CgogICAgaWYgKFRoaXMtPnJlc291cmNlLmZvcm1hdCAhPSBXSU5FRDNERk1UX1VOS05PV04pIHsKICAgICAgICBGSVhNRSgiKCVwKSA6IFRoZSBmb3JhbXQgb2YgdGhlIHN1cmZhY2UgbXVzdCBiZSBXSU5FRDNERk9STUFUX1VOS05PV05cbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIFRSQUNFKCIoJXApIDogU2V0dGluZyB0ZXh0dXJlIGZvcmFtdCB0byAoJWQsJXMpXG4iLCBUaGlzLCBmb3JtYXQsIGRlYnVnX2QzZGZvcm1hdChmb3JtYXQpKTsKICAgIGlmIChmb3JtYXQgPT0gV0lORUQzREZNVF9VTktOT1dOKSB7CiAgICAgICAgVGhpcy0+cmVzb3VyY2Uuc2l6ZSA9IDA7CiAgICB9IGVsc2UgaWYgKGZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDEpIHsKICAgICAgICAvKiBEWFQxIGlzIGhhbGYgYnl0ZSBwZXIgcGl4ZWwgKi8KICAgICAgICBUaGlzLT5yZXNvdXJjZS5zaXplID0gKChtYXgoVGhpcy0+cG93MldpZHRoLCA0KSAqIGZvcm1hdEVudHJ5LT5icHApICogbWF4KFRoaXMtPnBvdzJIZWlnaHQsIDQpKSA+PiAxOwoKICAgIH0gZWxzZSBpZiAoZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMiB8fCBmb3JtYXQgPT0gV0lORUQzREZNVF9EWFQzIHx8CiAgICAgICAgICAgICAgIGZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDQgfHwgZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNSkgewogICAgICAgIFRoaXMtPnJlc291cmNlLnNpemUgPSAoKG1heChUaGlzLT5wb3cyV2lkdGgsIDQpICogZm9ybWF0RW50cnktPmJwcCkgKiBtYXgoVGhpcy0+cG93MkhlaWdodCwgNCkpOwogICAgfSBlbHNlIHsKICAgICAgICBUaGlzLT5yZXNvdXJjZS5zaXplID0gKChUaGlzLT5wb3cyV2lkdGggKiBmb3JtYXRFbnRyeS0+YnBwKSArIDMpICYgfjM7CiAgICAgICAgVGhpcy0+cmVzb3VyY2Uuc2l6ZSAqPSBUaGlzLT5wb3cySGVpZ2h0OwogICAgfQoKCiAgICAvKiBTZXR1cCBzb21lIGdsZm9ybWF0IGRlZmF1bHRzICovCiAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0ICAgICAgICAgPSBmb3JtYXRFbnRyeS0+Z2xGb3JtYXQ7CiAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0SW50ZXJuYWwgPSBmb3JtYXRFbnRyeS0+Z2xJbnRlcm5hbDsKICAgIFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xUeXBlICAgICAgICAgICA9IGZvcm1hdEVudHJ5LT5nbFR5cGU7CgogICAgaWYgKGZvcm1hdCAhPSBXSU5FRDNERk1UX1VOS05PV04pIHsKICAgICAgICBUaGlzLT5ieXRlc1BlclBpeGVsID0gZm9ybWF0RW50cnktPmJwcDsKICAgICAgICBUaGlzLT5wb3cyU2l6ZSAgICAgID0gKFRoaXMtPnBvdzJXaWR0aCAqIFRoaXMtPmJ5dGVzUGVyUGl4ZWwpICogVGhpcy0+cG93MkhlaWdodDsKICAgIH0gZWxzZSB7CiAgICAgICAgVGhpcy0+Ynl0ZXNQZXJQaXhlbCA9IDA7CiAgICAgICAgVGhpcy0+cG93MlNpemUgICAgICA9IDA7CiAgICB9CgogICAgVGhpcy0+RmxhZ3MgfD0gKFdJTkVEM0RGTVRfRDE2X0xPQ0tBQkxFID09IGZvcm1hdCkgPyBTRkxBR19MT0NLQUJMRSA6IDA7CgogICAgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID0gZm9ybWF0OwoKICAgIFRSQUNFKCIoJXApIDogU2l6ZSAlZCwgcG93MlNpemUgJWQsIGJ5dGVzUGVyUGl4ZWwgJWQsIGdsRm9ybWF0ICVkLCBnbEZvdG1hdEludGVybmFsICVkLCBnbFR5cGUgJWRcbiIsIFRoaXMsIFRoaXMtPnJlc291cmNlLnNpemUsIFRoaXMtPnBvdzJTaXplLCBUaGlzLT5ieXRlc1BlclBpeGVsLCBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0LCBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0SW50ZXJuYWwsIFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xUeXBlKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRNZW0oSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgdm9pZCAqTWVtKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CgogICAgLyogUmVuZGVyIHRhcmdldHMgZGVwZW5kIG9uIHRoZWlyIGhkYywgYW5kIHdlIGNhbid0IGNyZWF0ZSBhIGhkYyBvbiBhIHVzZXIgcG9pbnRlciAqLwogICAgaWYoVGhpcy0+cmVzb3VyY2UudXNhZ2UgJiBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUKSB7CiAgICAgICAgRVJSKCJOb3Qgc3VwcG9ydGVkIG9uIHJlbmRlciB0YXJnZXRzXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBpZihUaGlzLT5GbGFncyAmIChTRkxBR19MT0NLRUQgfCBTRkxBR19EQ0lOVVNFKSkgewogICAgICAgIFdBUk4oIlN1cmZhY2UgaXMgbG9ja2VkIG9yIHRoZSBIREMgaXMgaW4gdXNlXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBpZihNZW0gJiYgTWVtICE9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSkgewoKICAgICAgICAvKiBEbyBJIGhhdmUgdG8gY29weSB0aGUgb2xkIHN1cmZhY2UgY29udGVudD8gKi8KICAgICAgICBpZihUaGlzLT5GbGFncyAmIFNGTEFHX0RJQlNFQ1RJT04pIHsKICAgICAgICAgICAgICAgIC8qIFJlbGVhc2UgdGhlIERDLiBObyBuZWVkIHRvIGhvbGQgdGhlIGNyaXRpY2FsIHNlY3Rpb24gZm9yIHRoZSB1cGRhdGUKICAgICAgICAgICAgICAgICAqIFRocmVhZCBiZWNhdXNlIHRoaXMgdGhyZWFkIHJ1bnMgb25seSBvbiBmcm9udCBidWZmZXJzLCBidXQgdGhpcyBtZXRob2QKICAgICAgICAgICAgICAgICAqIGZhaWxzIGZvciByZW5kZXIgdGFyZ2V0cyBpbiB0aGUgY2hlY2sgYWJvdmUuCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIFNlbGVjdE9iamVjdChUaGlzLT5oREMsIFRoaXMtPmRpYi5ob2xkYml0bWFwKTsKICAgICAgICAgICAgICAgIERlbGV0ZURDKFRoaXMtPmhEQyk7CiAgICAgICAgICAgICAgICAvKiBSZWxlYXNlIHRoZSBESUIgc2VjdGlvbiAqLwogICAgICAgICAgICAgICAgRGVsZXRlT2JqZWN0KFRoaXMtPmRpYi5ESUJzZWN0aW9uKTsKICAgICAgICAgICAgICAgIFRoaXMtPmRpYi5iaXRtYXBfZGF0YSA9IE5VTEw7CiAgICAgICAgICAgICAgICBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgPSBOVUxMOwogICAgICAgICAgICAgICAgVGhpcy0+aERDID0gTlVMTDsKICAgICAgICAgICAgICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19ESUJTRUNUSU9OOwogICAgICAgIH0gZWxzZSBpZighKFRoaXMtPkZsYWdzICYgU0ZMQUdfVVNFUlBUUikpIHsKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKICAgICAgICB9CiAgICAgICAgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gTWVtOwogICAgICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX1VTRVJQVFI7CiAgICB9IGVsc2UgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19VU0VSUFRSKSB7CiAgICAgICAgLyogTG9ja3JlY3QgYW5kIEdldERDIHdpbGwgcmUtY3JlYXRlIHRoZSBkaWIgc2VjdGlvbiBhbmQgYWxsb2NhdGVkIG1lbW9yeSAqLwogICAgICAgIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IE5VTEw7CiAgICAgICAgVGhpcy0+RmxhZ3MgJj0gflNGTEFHX1VTRVJQVFI7CiAgICB9CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyogVE9ETzogcmVwbGFjZSB0aGlzIGZ1bmN0aW9uIHdpdGggY29udGV4dCBtYW5hZ2VtZW50IHJvdXRpbmVzICovCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0UEJ1ZmZlclN0YXRlKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIEJPT0wgaW5QQnVmZmVyLCBCT09MICBpblRleHR1cmUpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwoKICAgIGlmKGluUEJ1ZmZlcikgewogICAgICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX0lOUEJVRkZFUjsKICAgIH0gZWxzZSB7CiAgICAgICAgVGhpcy0+RmxhZ3MgJj0gflNGTEFHX0lOUEJVRkZFUjsKICAgIH0KCiAgICBpZihpblRleHR1cmUpIHsKICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19JTlRFWFRVUkU7CiAgICB9IGVsc2UgewogICAgICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19JTlRFWFRVUkU7CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0ZsaXAoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgSVdpbmVEM0RTdXJmYWNlICpvdmVycmlkZSwgRFdPUkQgRmxhZ3MpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0REZXZpY2UgKkQzRCA9IChJV2luZUQzRERldmljZSAqKSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOwogICAgVFJBQ0UoIiglcCktPiglcCwleClcbiIsIFRoaXMsIG92ZXJyaWRlLCBGbGFncyk7CgogICAgLyogRmxpcHBpbmcgaXMgb25seSBzdXBwb3J0ZWQgb24gUmVuZGVyVGFyZ2V0cyAqLwogICAgaWYoICEoVGhpcy0+cmVzb3VyY2UudXNhZ2UgJiBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUKSApIHJldHVybiBEREVSUl9OT1RGTElQUEFCTEU7CgogICAgaWYob3ZlcnJpZGUpIHsKICAgICAgICAvKiBERHJhdyBzZXRzIHRoaXMgZm9yIHRoZSBYMTEgc3VyZmFjZXMsIHNvIGRvbid0IGNvbmZ1c2UgdGhlIHVzZXIgCiAgICAgICAgICogRklYTUUoIiglcCkgVGFyZ2V0IG92ZXJyaWRlIGlzIG5vdCBzdXBwb3J0ZWQgYnkgbm93XG4iLCBUaGlzKTsKICAgICAgICAgKiBBZGRpdGlvbmFsbHksIGl0IGlzbid0IHJlYWxseSBwb3NzaWJsZSB0byBzdXBwb3J0IHRyaXBsZS1idWZmZXJpbmcKICAgICAgICAgKiBwcm9wZXJseSBvbiBvcGVuZ2wgYXQgYWxsCiAgICAgICAgICovCiAgICB9CgogICAgLyogRmxpcHBpbmcgYSBPcGVuR0wgc3VyZmFjZSAtPiBVc2UgV2luZUQzRERldmljZTo6UHJlc2VudCAqLwogICAgcmV0dXJuIElXaW5lRDNERGV2aWNlX1ByZXNlbnQoRDNELCBOVUxMLCBOVUxMLCAwLCBOVUxMKTsKfQoKLyogTm90IGNhbGxlZCBmcm9tIHRoZSBWVGFibGUgKi8Kc3RhdGljIEhSRVNVTFQgSVdpbmVEM0RTdXJmYWNlSW1wbF9CbHRPdmVycmlkZShJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzLCBSRUNUICpEZXN0UmVjdCwgSVdpbmVEM0RTdXJmYWNlICpTcmNTdXJmYWNlLCBSRUNUICpTcmNSZWN0LCBEV09SRCBGbGFncywgRERCTFRGWCAqRERCbHRGeCkgewogICAgRDNEUkVDVCByZWN0OwogICAgSVdpbmVEM0REZXZpY2VJbXBsICpteURldmljZSA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CiAgICBJV2luZUQzRFN3YXBDaGFpbkltcGwgKnN3YXBjaGFpbiA9IE5VTEw7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpTcmMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBTcmNTdXJmYWNlOwogICAgQk9PTCBTcmNPSyA9IFRSVUU7CgogICAgVFJBQ0UoIiglcCktPiglcCwlcCwlcCwlMDh4LCVwKVxuIiwgVGhpcywgRGVzdFJlY3QsIFNyY1N1cmZhY2UsIFNyY1JlY3QsIEZsYWdzLCBEREJsdEZ4KTsKCiAgICAvKiBHZXQgdGhlIHN3YXBjaGFpbi4gT25lIG9mIHRoZSBzdXJmYWNlcyBoYXMgdG8gYmUgYSBwcmltYXJ5IHN1cmZhY2UgKi8KICAgIElXaW5lRDNEU3VyZmFjZV9HZXRDb250YWluZXIoIChJV2luZUQzRFN1cmZhY2UgKikgVGhpcywgJklJRF9JV2luZUQzRFN3YXBDaGFpbiwgKHZvaWQgKiopJnN3YXBjaGFpbik7CiAgICBpZihzd2FwY2hhaW4pIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2UoKElXaW5lRDNEU3dhcENoYWluICopIHN3YXBjaGFpbik7CiAgICBlbHNlIGlmKFNyYykgewogICAgICAgIElXaW5lRDNEU3VyZmFjZV9HZXRDb250YWluZXIoIChJV2luZUQzRFN1cmZhY2UgKikgU3JjLCAmSUlEX0lXaW5lRDNEU3dhcENoYWluLCAodm9pZCAqKikmc3dhcGNoYWluKTsKICAgICAgICBpZihzd2FwY2hhaW4pIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2UoKElXaW5lRDNEU3dhcENoYWluICopIHN3YXBjaGFpbik7CiAgICAgICAgZWxzZSByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0gZWxzZSB7CiAgICAgICAgc3dhcGNoYWluID0gTlVMTDsKICAgIH0KCiAgICBpZiAoRGVzdFJlY3QpIHsKICAgICAgICByZWN0LngxID0gRGVzdFJlY3QtPmxlZnQ7CiAgICAgICAgcmVjdC55MSA9IERlc3RSZWN0LT50b3A7CiAgICAgICAgcmVjdC54MiA9IERlc3RSZWN0LT5yaWdodDsKICAgICAgICByZWN0LnkyID0gRGVzdFJlY3QtPmJvdHRvbTsKICAgIH0gZWxzZSB7CiAgICAgICAgcmVjdC54MSA9IDA7CiAgICAgICAgcmVjdC55MSA9IDA7CiAgICAgICAgcmVjdC54MiA9IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoOwogICAgICAgIHJlY3QueTIgPSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICB9CgogICAgLyogSGFsZi1saWZlIGRvZXMgYSBCbHQgZnJvbSB0aGUgYmFjayBidWZmZXIgdG8gdGhlIGZyb250IGJ1ZmZlciwKICAgICAqIEZ1bGwgc3VyZmFjZSBzaXplLCBubyBmbGFncy4uLiBVc2UgcHJlc2VudCBpbnN0ZWFkCiAgICAgKi8KICAgIGlmKFNyYykKICAgIHsKICAgICAgICAvKiBGaXJzdCwgY2hlY2sgaWYgd2UgY2FuIGRvIGEgRmxpcCAqLwoKICAgICAgICAvKiBDaGVjayByZWN0cyAtIElXaW5lRDNERGV2aWNlX1ByZXNlbnQgZG9lc24ndCBoYW5kbGUgdGhlbSAqLwogICAgICAgIGlmKCBTcmNSZWN0ICkgewogICAgICAgICAgICBpZiggKFNyY1JlY3QtPmxlZnQgPT0gMCkgJiYgKFNyY1JlY3QtPnRvcCA9PSAwKSAmJgogICAgICAgICAgICAgICAgKFNyY1JlY3QtPnJpZ2h0ID09IFNyYy0+Y3VycmVudERlc2MuV2lkdGgpICYmIChTcmNSZWN0LT5ib3R0b20gPT0gU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQpICkgewogICAgICAgICAgICAgICAgU3JjT0sgPSBUUlVFOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgU3JjT0sgPSBUUlVFOwogICAgICAgIH0KCiAgICAgICAgLyogQ2hlY2sgdGhlIERlc3RpbmF0aW9uIHJlY3QgYW5kIHRoZSBzdXJmYWNlIHNpemVzICovCiAgICAgICAgaWYoU3JjT0sgJiYKICAgICAgICAgICAocmVjdC54MSA9PSAwKSAmJiAocmVjdC55MSA9PSAwKSAmJgogICAgICAgICAgIChyZWN0LngyID09ICBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCkgJiYgKHJlY3QueTIgPT0gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0KSAmJgogICAgICAgICAgIChUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCA9PSBTcmMtPmN1cnJlbnREZXNjLldpZHRoKSAmJgogICAgICAgICAgIChUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQgPT0gU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQpKSB7CiAgICAgICAgICAgIC8qIFRoZXNlIGZsYWdzIGFyZSB1bmltcG9ydGFudCBmb3IgdGhlIGZsYWcgY2hlY2ssIHJlbW92ZSB0aGVtICovCgogICAgICAgICAgICBpZigoRmxhZ3MgJiB+KEREQkxUX0RPTk9UV0FJVCB8IEREQkxUX1dBSVQpKSA9PSAwKSB7CiAgICAgICAgICAgICAgICBpZiggc3dhcGNoYWluLT5iYWNrQnVmZmVyICYmICgoSVdpbmVEM0RTdXJmYWNlICopIFRoaXMgPT0gc3dhcGNoYWluLT5mcm9udEJ1ZmZlcikgJiYgKChJV2luZUQzRFN1cmZhY2UgKikgU3JjID09IHN3YXBjaGFpbi0+YmFja0J1ZmZlclswXSkgKSB7CgogICAgICAgICAgICAgICAgICAgIEQzRFNXQVBFRkZFQ1Qgb3JpZ19zd2FwID0gc3dhcGNoYWluLT5wcmVzZW50UGFybXMuU3dhcEVmZmVjdDsKCiAgICAgICAgICAgICAgICAgICAgLyogVGhlIGlkZWEgYmVoaW5kIHRoaXMgaXMgdGhhdCBhIGdsUmVhZFBpeGVscyBhbmQgYSBnbERyYXdQaXhlbHMgY2FsbAogICAgICAgICAgICAgICAgICAgICAqIHRha2UgdmVyeSBsb25nLCB3aGlsZSBhIGZsaXAgaXMgZmFzdC4KICAgICAgICAgICAgICAgICAgICAgKiBUaGlzIGFwcGxpZXMgdG8gSGFsZi1MaWZlLCB3aGljaCBkb2VzIHN1Y2ggQmx0cyBldmVyeSB0aW1lIGl0IGZpbmlzaGVkCiAgICAgICAgICAgICAgICAgICAgICogYSBmcmFtZSwgYW5kIHRvIFByaW5jZSBvZiBQZXJzaWEgM0QsIHdoaWNoIHVzZXMgdGhpcyB0byBkcmF3IGF0IGxlYXN0IHRoZSBtYWluCiAgICAgICAgICAgICAgICAgICAgICogbWVudS4gVGhpcyBpcyBhbHNvIHVzZWQgYnkgYWxsIGFwcHMgd2hlbiB0aGV5IGRvIHdpbmRvd2VkIHJlbmRlcmluZwogICAgICAgICAgICAgICAgICAgICAqCiAgICAgICAgICAgICAgICAgICAgICogVGhlIHByb2JsZW0gaXMgdGhhdCBmbGlwcGluZyBpcyBub3QgcmVhbGx5IHRoZSBzYW1lIGFzIGNvcHlpbmcuIEFmdGVyIGEKICAgICAgICAgICAgICAgICAgICAgKiBCbHQgdGhlIGZyb250IGJ1ZmZlciBpcyBhIGNvcHkgb2YgdGhlIGJhY2sgYnVmZmVyLCBhbmQgdGhlIGJhY2sgYnVmZmVyIGlzCiAgICAgICAgICAgICAgICAgICAgICogdW50b3VjaGVkLiBUaGVyZWZvcmUgaXQncyBuZWNlc3NhcnkgdG8gb3ZlcnJpZGUgdGhlIHN3YXAgZWZmZWN0CiAgICAgICAgICAgICAgICAgICAgICogYW5kIHRvIHNldCBpdCBiYWNrIGFmdGVyIHRoZSBmbGlwLgogICAgICAgICAgICAgICAgICAgICAqLwoKICAgICAgICAgICAgICAgICAgICBzd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5Td2FwRWZmZWN0ID0gV0lORUQzRFNXQVBFRkZFQ1RfQ09QWTsKCiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIkZ1bGwgc2NyZWVuIGJhY2sgYnVmZmVyIC0+IGZyb250IGJ1ZmZlciBibHQsIHBlcmZvcm1pbmcgYSBmbGlwIGluc3RlYWRcbiIpOwogICAgICAgICAgICAgICAgICAgIElXaW5lRDNERGV2aWNlX1ByZXNlbnQoKElXaW5lRDNERGV2aWNlICopIFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgTlVMTCwgMCwgTlVMTCk7CgogICAgICAgICAgICAgICAgICAgIHN3YXBjaGFpbi0+cHJlc2VudFBhcm1zLlN3YXBFZmZlY3QgPSBvcmlnX3N3YXA7CgogICAgICAgICAgICAgICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKiBCbHQgZnJvbSB0ZXh0dXJlIHRvIHJlbmRlcnRhcmdldD8gKi8KICAgICAgICBpZiggKCAoIChJV2luZUQzRFN1cmZhY2UgKikgVGhpcyA9PSBzd2FwY2hhaW4tPmZyb250QnVmZmVyKSB8fAogICAgICAgICAgICAgICggc3dhcGNoYWluLT5iYWNrQnVmZmVyICYmIChJV2luZUQzRFN1cmZhY2UgKikgVGhpcyA9PSBzd2FwY2hhaW4tPmJhY2tCdWZmZXJbMF0pICkKICAgICAgICAgICAgICAmJgogICAgICAgICAgICAgICggKCAoSVdpbmVEM0RTdXJmYWNlICopIFNyYyAhPSBzd2FwY2hhaW4tPmZyb250QnVmZmVyKSAmJgogICAgICAgICAgICAgICAgKCBzd2FwY2hhaW4tPmJhY2tCdWZmZXIgJiYgKElXaW5lRDNEU3VyZmFjZSAqKSBTcmMgIT0gc3dhcGNoYWluLT5iYWNrQnVmZmVyWzBdKSApICkgewogICAgICAgICAgICBmbG9hdCBnbFRleENvb3JkWzRdOwogICAgICAgICAgICBEV09SRCBvbGRDS2V5OwogICAgICAgICAgICBERENPTE9SS0VZIG9sZEJsdENLZXkgPSB7MCwwfTsKICAgICAgICAgICAgR0xpbnQgb2xkTGlnaHQsIG9sZEZvZywgb2xkRGVwdGgsIG9sZEJsZW5kLCBvbGRDdWxsLCBvbGRBbHBoYTsKICAgICAgICAgICAgR0xpbnQgYWxwaGFmdW5jOwogICAgICAgICAgICBHTGNsYW1wZiBhbHBoYXJlZjsKICAgICAgICAgICAgR0xpbnQgb2xkU3RlbmNpbDsKICAgICAgICAgICAgUkVDVCBTb3VyY2VSZWN0YW5nbGU7CiAgICAgICAgICAgIEdMaW50IG9sZERyYXc7CgogICAgICAgICAgICBUUkFDRSgiQmx0IGZyb20gc3VyZmFjZSAlcCB0byByZW5kZXJ0YXJnZXQgJXBcbiIsIFNyYywgVGhpcyk7CgogICAgICAgICAgICBpZihTcmNSZWN0KSB7CiAgICAgICAgICAgICAgICBTb3VyY2VSZWN0YW5nbGUubGVmdCA9IFNyY1JlY3QtPmxlZnQ7CiAgICAgICAgICAgICAgICBTb3VyY2VSZWN0YW5nbGUucmlnaHQgPSBTcmNSZWN0LT5yaWdodDsKICAgICAgICAgICAgICAgIFNvdXJjZVJlY3RhbmdsZS50b3AgPSBTcmNSZWN0LT50b3A7CiAgICAgICAgICAgICAgICBTb3VyY2VSZWN0YW5nbGUuYm90dG9tID0gU3JjUmVjdC0+Ym90dG9tOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgU291cmNlUmVjdGFuZ2xlLmxlZnQgPSAwOwogICAgICAgICAgICAgICAgU291cmNlUmVjdGFuZ2xlLnJpZ2h0ID0gU3JjLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICAgICAgICAgIFNvdXJjZVJlY3RhbmdsZS50b3AgPSAwOwogICAgICAgICAgICAgICAgU291cmNlUmVjdGFuZ2xlLmJvdHRvbSA9IFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0OwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZighQ2FsY3VsYXRlVGV4UmVjdChTcmMsICZTb3VyY2VSZWN0YW5nbGUsIGdsVGV4Q29vcmQpKSB7CiAgICAgICAgICAgICAgICAvKiBGYWxsIGJhY2sgdG8gc29mdHdhcmUgKi8KICAgICAgICAgICAgICAgIFdBUk4oIiglcCkgU291cmNlIHRleHR1cmUgYXJlYSAoJWQsJWQpLSglZCwlZCkgaXMgdG9vIGJpZ1xuIiwgU3JjLAogICAgICAgICAgICAgICAgICAgICBTb3VyY2VSZWN0YW5nbGUubGVmdCwgU291cmNlUmVjdGFuZ2xlLnRvcCwKICAgICAgICAgICAgICAgICAgICAgU291cmNlUmVjdGFuZ2xlLnJpZ2h0LCBTb3VyY2VSZWN0YW5nbGUuYm90dG9tKTsKICAgICAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKiBDb2xvciBrZXlpbmc6IENoZWNrIGlmIHdlIGhhdmUgdG8gZG8gYSBjb2xvciBrZXllZCBibHQsCiAgICAgICAgICAgICAqIGFuZCBpZiBub3QgY2hlY2sgaWYgYSBjb2xvciBrZXkgaXMgYWN0aXZhdGVkLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgb2xkQ0tleSA9IFNyYy0+Q0tleUZsYWdzOwogICAgICAgICAgICBpZighKEZsYWdzICYgRERCTFRfS0VZU1JDKSAmJiAKICAgICAgICAgICAgICAgU3JjLT5DS2V5RmxhZ3MgJiBERFNEX0NLU1JDQkxUKSB7CiAgICAgICAgICAgICAgICAvKiBPaywgdGhlIHN1cmZhY2UgaGFzIGEgY29sb3Iga2V5LCBidXQgd2Ugc2hhbGwgbm90IHVzZSBpdCAtCiAgICAgICAgICAgICAgICAgKiBEZWFjdGl2YXRlIGl0IGZvciBub3csIExvYWRUZXh0dXJlIHdpbGwgY2F0Y2ggdGhpcwogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBTcmMtPkNLZXlGbGFncyAmPSB+RERTRF9DS1NSQ0JMVDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyogQ29sb3Iga2V5aW5nICovCiAgICAgICAgICAgIGlmKEZsYWdzICYgRERCTFRfS0VZREVTVCkgewogICAgICAgICAgICAgICAgb2xkQmx0Q0tleSA9IFRoaXMtPlNyY0JsdENLZXk7CiAgICAgICAgICAgICAgICAvKiBUZW1wb3JhcnkgcmVwbGFjZSB0aGUgc291cmNlIGNvbG9yIGtleSB3aXRoIHRoZSBkZXN0aW5hdGlvbiBvbmUuIFdlIGRvIHRoaXMgYmVjYXVzZSB0aGUgY29sb3IgY29udmVyc2lvbiBjb2RlIHdoaWNoCiAgICAgICAgICAgICAgICAgKiBpcyBpbiB0aGUgZW5kIGNhbGxlZCBmcm9tIExvYWRUZXh0dXJlIHdvcmtzIHdpdGggdGhlIHNvdXJjZSBjb2xvci4gQXQgdGhlIGVuZCBvZiB0aGlzIGZ1bmN0aW9uIHdlIHJlc3RvcmUgdGhlIGNvbG9yIGtleS4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgVGhpcy0+U3JjQmx0Q0tleSA9IFRoaXMtPkRlc3RCbHRDS2V5OwogICAgICAgICAgICB9IGVsc2UgaWYgKEZsYWdzICYgRERCTFRfS0VZU1JDKQogICAgICAgICAgICAgICAgb2xkQmx0Q0tleSA9IFRoaXMtPlNyY0JsdENLZXk7CgogICAgICAgICAgICAvKiBOb3cgbG9hZCB0aGUgc3VyZmFjZSAqLwogICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfUHJlTG9hZCgoSVdpbmVEM0RTdXJmYWNlICopIFNyYyk7CgogICAgICAgICAgICBFTlRFUl9HTCgpOwoKICAgICAgICAgICAgLyogU2F2ZSBhbGwgdGhlIG9sZCBzdHVmZiB1bnRpbCB3ZSBoYXZlIGEgcHJvcGVyIG9wZW5nbCBzdGF0ZSBtYW5hZ2VyICovCiAgICAgICAgICAgIG9sZExpZ2h0ID0gZ2xJc0VuYWJsZWQoR0xfTElHSFRJTkcpOwogICAgICAgICAgICBvbGRGb2cgPSBnbElzRW5hYmxlZChHTF9GT0cpOwogICAgICAgICAgICBvbGREZXB0aCA9IGdsSXNFbmFibGVkKEdMX0RFUFRIX1RFU1QpOwogICAgICAgICAgICBvbGRCbGVuZCA9IGdsSXNFbmFibGVkKEdMX0JMRU5EKTsKICAgICAgICAgICAgb2xkQ3VsbCA9IGdsSXNFbmFibGVkKEdMX0NVTExfRkFDRSk7CiAgICAgICAgICAgIG9sZEFscGhhID0gZ2xJc0VuYWJsZWQoR0xfQUxQSEFfVEVTVCk7CiAgICAgICAgICAgIG9sZFN0ZW5jaWwgPSBnbElzRW5hYmxlZChHTF9TVEVOQ0lMX1RFU1QpOwoKICAgICAgICAgICAgZ2xHZXRJbnRlZ2VydihHTF9BTFBIQV9URVNUX0ZVTkMsICZhbHBoYWZ1bmMpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xHZXRGbG9hdHYgR0xfQUxQSEFfVEVTVF9GVU5DIik7CiAgICAgICAgICAgIGdsR2V0RmxvYXR2KEdMX0FMUEhBX1RFU1RfUkVGLCAmYWxwaGFyZWYpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xHZXRGbG9hdHYgR0xfQUxQSEFfVEVTVF9SRUYiKTsKCiAgICAgICAgICAgIGdsR2V0SW50ZWdlcnYoR0xfRFJBV19CVUZGRVIsICZvbGREcmF3KTsKICAgICAgICAgICAgaWYoVGhpcyA9PSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBzd2FwY2hhaW4tPmZyb250QnVmZmVyKSB7CiAgICAgICAgICAgICAgICBUUkFDRSgiRHJhd2luZyB0byBmcm9udCBidWZmZXJcbiIpOwogICAgICAgICAgICAgICAgZ2xEcmF3QnVmZmVyKEdMX0ZST05UKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERyYXdCdWZmZXIgR0xfRlJPTlQiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyogVW5iaW5kIHRoZSBvbGQgdGV4dHVyZSAqLwogICAgICAgICAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIDApOwoKICAgICAgICAgICAgaWYgKEdMX1NVUFBPUlQoQVJCX01VTFRJVEVYVFVSRSkpIHsKICAgICAgICAgICAgLyogV2UgdXNlIHRleHR1cmUgdW5pdCAwIGZvciBibHRzICovCiAgICAgICAgICAgICAgICBHTF9FWFRDQUxMKGdsQWN0aXZlVGV4dHVyZUFSQihHTF9URVhUVVJFMF9BUkIpKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEFjdGl2ZVRleHR1cmVBUkIiKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIFdBUk4oIk11bHRpLXRleHR1cmluZyBpcyB1bnN1cHBvcnRlZCBpbiB0aGUgbG9jYWwgT3BlbkdMIGltcGxlbWVudGF0aW9uXG4iKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyogRGlzYWJsZSBzb21lIGZhbmN5IGdyYXBoaWNzIGVmZmVjdHMgKi8KICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX0xJR0hUSU5HKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9MSUdIVElORyIpOwogICAgICAgICAgICBnbERpc2FibGUoR0xfREVQVEhfVEVTVCk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUgR0xfREVQVEhfVEVTVCIpOwogICAgICAgICAgICBnbERpc2FibGUoR0xfRk9HKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9GT0ciKTsKICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX0JMRU5EKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9CTEVORCIpOwogICAgICAgICAgICBnbERpc2FibGUoR0xfQ1VMTF9GQUNFKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9DVUxMX0ZBQ0UiKTsKICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX1NURU5DSUxfVEVTVCk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUgR0xfU1RFTkNJTF9URVNUIik7CgogICAgICAgICAgICAvKiBPaywgd2UgbmVlZCAyZCB0ZXh0dXJlcywgYnV0IG5vdCAxRCBvciAzRCAqLwogICAgICAgICAgICBnbERpc2FibGUoR0xfVEVYVFVSRV8xRCk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUgR0xfVEVYVFVSRV8xRCIpOwogICAgICAgICAgICBnbEVuYWJsZShHTF9URVhUVVJFXzJEKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlIEdMX1RFWFRVUkVfMkQiKTsKICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX1RFWFRVUkVfM0QpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlIEdMX1RFWFRVUkVfM0QiKTsKCiAgICAgICAgICAgIC8qIEJpbmQgdGhlIHRleHR1cmUgKi8KICAgICAgICAgICAgZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCBTcmMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xCaW5kVGV4dHVyZSIpOwoKICAgICAgICAgICAgZ2xFbmFibGUoR0xfU0NJU1NPUl9URVNUKTsKCiAgICAgICAgICAgIGdsVGV4RW52aShHTF9URVhUVVJFX0VOViwgR0xfVEVYVFVSRV9FTlZfTU9ERSwgR0xfUkVQTEFDRSk7CgogICAgICAgICAgICAvKiBObyBmaWx0ZXJpbmcgZm9yIGJsdHMgKi8KICAgICAgICAgICAgZ2xUZXhQYXJhbWV0ZXJpKEdMX1RFWFRVUkVfMkQsIEdMX1RFWFRVUkVfTUFHX0ZJTFRFUiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBHTF9ORUFSRVNUKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsVGV4UGFyYW1ldGVyaSIpOwogICAgICAgICAgICBnbFRleFBhcmFtZXRlcmkoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9NSU5fRklMVEVSLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdMX05FQVJFU1QpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xUZXhQYXJhbWV0ZXJpIik7CiAgICAgICAgICAgIGdsVGV4UGFyYW1ldGVyaShHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX1dSQVBfUywgR0xfQ0xBTVApOwogICAgICAgICAgICBnbFRleFBhcmFtZXRlcmkoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9XUkFQX1QsIEdMX0NMQU1QKTsKICAgICAgICAgICAgZ2xUZXhFbnZpKEdMX1RFWFRVUkVfRU5WLCBHTF9URVhUVVJFX0VOVl9NT0RFLCBHTF9SRVBMQUNFKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsVGV4RW52aSIpOwoKICAgICAgICAgICAgLyogVGhpcyBpcyBmb3IgY29sb3Iga2V5aW5nICovCiAgICAgICAgICAgIGlmKEZsYWdzICYgRERCTFRfS0VZU1JDKSB7CiAgICAgICAgICAgICAgICBnbEVuYWJsZShHTF9BTFBIQV9URVNUKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZSBHTF9BTFBIQV9URVNUIik7CiAgICAgICAgICAgICAgICBnbEFscGhhRnVuYyhHTF9OT1RFUVVBTCwgMC4wKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEFscGhhRnVuY1xuIik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBnbERpc2FibGUoR0xfQUxQSEFfVEVTVCk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlIEdMX0FMUEhBX1RFU1QiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyogRHJhdyBhIHRleHR1cmVkIHF1YWQKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGQzZGRldmljZV9zZXRfb3J0aG8oVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZSk7CgogICAgICAgICAgICBnbEJlZ2luKEdMX1FVQURTKTsKCiAgICAgICAgICAgIGdsQ29sb3IzZCgxLjBmLCAxLjBmLCAxLjBmKTsKICAgICAgICAgICAgZ2xUZXhDb29yZDJmKGdsVGV4Q29vcmRbMF0sIGdsVGV4Q29vcmRbMl0pOwogICAgICAgICAgICBnbFZlcnRleDNmKHJlY3QueDEsCiAgICAgICAgICAgICAgICAgICAgICAgcmVjdC55MSwKICAgICAgICAgICAgICAgICAgICAgICAwLjApOwoKICAgICAgICAgICAgZ2xUZXhDb29yZDJmKGdsVGV4Q29vcmRbMF0sIGdsVGV4Q29vcmRbM10pOwogICAgICAgICAgICBnbFZlcnRleDNmKHJlY3QueDEsIHJlY3QueTIsIDAuMCk7CgogICAgICAgICAgICBnbFRleENvb3JkMmYoZ2xUZXhDb29yZFsxXSwgZ2xUZXhDb29yZFszXSk7CiAgICAgICAgICAgIGdsVmVydGV4M2YocmVjdC54MiwKICAgICAgICAgICAgICAgICAgICAgICByZWN0LnkyLAogICAgICAgICAgICAgICAgICAgICAgIDAuMCk7CgogICAgICAgICAgICBnbFRleENvb3JkMmYoZ2xUZXhDb29yZFsxXSwgZ2xUZXhDb29yZFsyXSk7CiAgICAgICAgICAgIGdsVmVydGV4M2YocmVjdC54MiwKICAgICAgICAgICAgICAgICAgICAgICByZWN0LnkxLAogICAgICAgICAgICAgICAgICAgICAgIDAuMCk7CiAgICAgICAgICAgIGdsRW5kKCk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEVuZCIpOwoKICAgICAgICAgICAgLyogVW5iaW5kIHRoZSB0ZXh0dXJlICovCiAgICAgICAgICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgMCk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZSBnbEJpbmRUZXh0dXJlIik7CgogICAgICAgICAgICAvKiBSZXN0b3JlIHRoZSBvbGQgc2V0dGluZ3MgKi8KICAgICAgICAgICAgaWYob2xkTGlnaHQpIHsKICAgICAgICAgICAgICAgIGdsRW5hYmxlKEdMX0xJR0hUSU5HKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZSBHTF9MSUdIVElORyIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKG9sZEZvZykgewogICAgICAgICAgICAgICAgZ2xFbmFibGUoR0xfRk9HKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZSBHTF9GT0ciKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZihvbGREZXB0aCkgewogICAgICAgICAgICAgICAgZ2xFbmFibGUoR0xfREVQVEhfVEVTVCk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUgR0xfREVQVEhfVEVTVCIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKG9sZEJsZW5kKSB7CiAgICAgICAgICAgICAgICBnbEVuYWJsZShHTF9CTEVORCk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUgR0xfQkxFTkQiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZihvbGRDdWxsKSB7CiAgICAgICAgICAgICAgICBnbEVuYWJsZShHTF9DVUxMX0ZBQ0UpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlIEdMX0NVTExfRkFDRSIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKG9sZFN0ZW5jaWwpIHsKICAgICAgICAgICAgICAgIGdsRW5hYmxlKEdMX1NURU5DSUxfVEVTVCk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUgR0xfU1RFTkNJTF9URVNUIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYoIW9sZEFscGhhKSB7CiAgICAgICAgICAgICAgICBnbERpc2FibGUoR0xfQUxQSEFfVEVTVCk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlIEdMX0FMUEhBX1RFU1QiKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGdsRW5hYmxlKEdMX0FMUEhBX1RFU1QpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlIEdMX0FMUEhBX1RFU1QiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZ2xBbHBoYUZ1bmMoYWxwaGFmdW5jLCBhbHBoYXJlZik7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEFscGhhRnVuY1xuIik7CgogICAgICAgICAgICBpZihUaGlzID09IChJV2luZUQzRFN1cmZhY2VJbXBsICopIHN3YXBjaGFpbi0+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+Ynl0ZXNQZXJQaXhlbCAqIFRoaXMtPnBvdzJXaWR0aDsKICAgICAgICB9CiAgICAgICAgLyogU3VyZmFjZXMgYXJlIDMyIGJpdCBhbGlnbmVkICovCiAgICAgICAgcmV0ID0gKHJldCArIDMpICYgfjM7CiAgICB9CiAgICBUUkFDRSgiKCVwKSBSZXR1cm5pbmcgJWRcbiIsIFRoaXMsIHJldCk7CiAgICByZXR1cm4gcmV0Owp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1NldE92ZXJsYXlQb3NpdGlvbihJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBMT05HIFgsIExPTkcgWSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwoKICAgIEZJWE1FKCIoJXApLT4oJWQsJWQpIFN0dWIhXG4iLCBUaGlzLCBYLCBZKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRPdmVybGF5UG9zaXRpb24oSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgTE9ORyAqWCwgTE9ORyAqWSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwoKICAgIEZJWE1FKCIoJXApLT4oJXAsJXApIFN0dWIhXG4iLCBUaGlzLCBYLCBZKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9VcGRhdGVPdmVybGF5Wk9yZGVyKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIERXT1JEIEZsYWdzLCBJV2luZUQzRFN1cmZhY2UgKlJlZikgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqUmVmSW1wbCA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIFJlZjsKCiAgICBGSVhNRSgiKCVwKS0+KCUwOHgsJXApIFN0dWIhXG4iLCBUaGlzLCBGbGFncywgUmVmSW1wbCk7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfVXBkYXRlT3ZlcmxheShJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBSRUNUICpTcmNSZWN0LCBJV2luZUQzRFN1cmZhY2UgKkRzdFN1cmZhY2UsIFJFQ1QgKkRzdFJlY3QsIERXT1JEIEZsYWdzLCBXSU5FRERPVkVSTEFZRlggKkZYKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpEc3QgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBEc3RTdXJmYWNlOwogICAgRklYTUUoIiglcCktPiglcCwgJXAsICVwLCAlMDh4LCAlcClcbiIsIFRoaXMsIFNyY1JlY3QsIERzdCwgRHN0UmVjdCwgRmxhZ3MsIEZYKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKY29uc3QgSVdpbmVEM0RTdXJmYWNlVnRibCBJV2luZUQzRFN1cmZhY2VfVnRibCA9CnsKICAgIC8qIElVbmtub3duICovCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1F1ZXJ5SW50ZXJmYWNlLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9BZGRSZWYsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1JlbGVhc2UsCiAgICAvKiBJV2luZUQzRFJlc291cmNlICovCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldFBhcmVudCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0RGV2aWNlLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRQcml2YXRlRGF0YSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0UHJpdmF0ZURhdGEsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0ZyZWVQcml2YXRlRGF0YSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0UHJpb3JpdHksCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldFByaW9yaXR5LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9QcmVMb2FkLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRUeXBlLAogICAgLyogSVdpbmVEM0RTdXJmYWNlICovCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldENvbnRhaW5lclBhcmVudCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0Q29udGFpbmVyLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXREZXNjLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9Mb2NrUmVjdCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfVW5sb2NrUmVjdCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0REMsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1JlbGVhc2VEQywKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfRmxpcCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfQmx0LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRCbHRTdGF0dXMsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldEZsaXBTdGF0dXMsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0lzTG9zdCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfUmVzdG9yZSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfQmx0RmFzdCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0UGFsZXR0ZSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0UGFsZXR0ZSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfUmVhbGl6ZVBhbGV0dGUsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1NldENvbG9yS2V5LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRQaXRjaCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0TWVtLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRPdmVybGF5UG9zaXRpb24sCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldE92ZXJsYXlQb3NpdGlvbiwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfVXBkYXRlT3ZlcmxheVpPcmRlciwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfVXBkYXRlT3ZlcmxheSwKICAgIC8qIEludGVybmFsIHVzZTogKi8KICAgIElXaW5lRDNEU3VyZmFjZUltcGxfQ2xlYW5EaXJ0eVJlY3QsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0FkZERpcnR5UmVjdCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfTG9hZFRleHR1cmUsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1NhdmVTbmFwc2hvdCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0Q29udGFpbmVyLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRQQnVmZmVyU3RhdGUsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1NldEdsVGV4dHVyZURlc2MsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldEdsRGVzYywKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0RGF0YSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0Rm9ybWF0LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9Qcml2YXRlU2V0dXAKfTsK