LyoKICogSVdpbmVEM0RTdXJmYWNlIEltcGxlbWVudGF0aW9uCiAqCiAqIENvcHlyaWdodCAxOTk4IExpb25lbCBVbG1lcgogKiBDb3B5cmlnaHQgMjAwMC0yMDAxIFRyYW5zR2FtaW5nIFRlY2hub2xvZ2llcyBJbmMuCiAqIENvcHlyaWdodCAyMDAyLTIwMDUgSmFzb24gRWRtZWFkZXMKICogQ29weXJpZ2h0IDIwMDItMjAwMyBSYXBoYWVsIEp1bnF1ZWlyYQogKiBDb3B5cmlnaHQgMjAwNCBDaHJpc3RpYW4gQ29zdGEKICogQ29weXJpZ2h0IDIwMDUgT2xpdmVyIFN0aWViZXIKICogQ29weXJpZ2h0IDIwMDYgU3RlZmFuIET2c2luZ2VyIGZvciBDb2RlV2VhdmVycwogKiBDb3B5cmlnaHQgMjAwNyBIZW5yaSBWZXJiZWV0CiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgIndpbmUvcG9ydC5oIgojaW5jbHVkZSAid2luZWQzZF9wcml2YXRlLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChkM2Rfc3VyZmFjZSk7CiNkZWZpbmUgR0xJTkZPX0xPQ0FUSU9OICgoSVdpbmVEM0RJbXBsICopKCgoSVdpbmVEM0REZXZpY2VJbXBsICopVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZSktPndpbmVEM0QpKS0+Z2xfaW5mbwoKdHlwZWRlZiBlbnVtIHsKICAgIE5PX0NPTlZFUlNJT04sCiAgICBDT05WRVJUX1BBTEVUVEVELAogICAgQ09OVkVSVF9QQUxFVFRFRF9DSywKICAgIENPTlZFUlRfQ0tfNTY1LAogICAgQ09OVkVSVF9DS181NTUxLAogICAgQ09OVkVSVF9DS180NDQ0LAogICAgQ09OVkVSVF9DS180NDQ0X0FSR0IsCiAgICBDT05WRVJUX0NLXzE1NTUsCiAgICBDT05WRVJUXzU1NSwKICAgIENPTlZFUlRfQ0tfUkdCMjQsCiAgICBDT05WRVJUX0NLXzg4ODgsCiAgICBDT05WRVJUX0NLXzg4ODhfQVJHQiwKICAgIENPTlZFUlRfUkdCMzJfODg4LAogICAgQ09OVkVSVF9WOFU4LAogICAgQ09OVkVSVF9YOEw4VjhVOCwKICAgIENPTlZFUlRfUThXOFY4VTgsCiAgICBDT05WRVJUX1YxNlUxNgp9IENPTlZFUlRfVFlQRVM7CgpIUkVTVUxUIGQzZGZtdF9jb252ZXJ0X3N1cmZhY2UoQllURSAqc3JjLCBCWVRFICpkc3QsIFVJTlQgcGl0Y2gsIFVJTlQgd2lkdGgsIFVJTlQgaGVpZ2h0LCBVSU5UIG91dHBpdGNoLCBDT05WRVJUX1RZUEVTIGNvbnZlcnQsIElXaW5lRDNEU3VyZmFjZUltcGwgKnN1cmYpOwoKc3RhdGljIHZvaWQgc3VyZmFjZV9kb3dubG9hZF9kYXRhKElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMpIHsKICAgIGlmIChUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQxIHx8CiAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDIgfHwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMyB8fAogICAgICAgICAgICBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQ0IHx8IFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDUpIHsKICAgICAgICBpZiAoIUdMX1NVUFBPUlQoRVhUX1RFWFRVUkVfQ09NUFJFU1NJT05fUzNUQykpIHsgLyogV2UgY2FuIGFzc3VtZSB0aGlzIGFzIHRoZSB0ZXh0dXJlIHdvdWxkIG5vdCBoYXZlIGJlZW4gY3JlYXRlZCBvdGhlcndpc2UgKi8KICAgICAgICAgICAgRklYTUUoIiglcCkgOiBBdHRlbXB0aW5nIHRvIGxvY2sgYSBjb21wcmVzc2VkIHRleHR1cmUgd2hlbiB0ZXh0dXJlIGNvbXByZXNzaW9uIGlzbid0IHN1cHBvcnRlZCBieSBvcGVuZ2xcbiIsIFRoaXMpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIFRSQUNFKCIoJXApIDogQ2FsbGluZyBnbEdldENvbXByZXNzZWRUZXhJbWFnZUFSQiBsZXZlbCAlZCwgZm9ybWF0ICUjeCwgdHlwZSAlI3gsIGRhdGEgJXBcbiIsIFRoaXMsIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsCiAgICAgICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0LCBUaGlzLT5nbERlc2NyaXB0aW9uLmdsVHlwZSwgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKCiAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xHZXRDb21wcmVzc2VkVGV4SW1hZ2VBUkIoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSkpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xHZXRDb21wcmVzc2VkVGV4SW1hZ2VBUkIoKSIpOwogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgdm9pZCAqbWVtOwogICAgICAgIGludCBzcmNfcGl0Y2ggPSAwOwogICAgICAgIGludCBkc3RfcGl0Y2ggPSAwOwoKICAgICAgICAgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19DT05WRVJURUQpIHsKICAgICAgICAgICAgIEZJWE1FKCJSZWFkIGJhY2sgY29udmVydGVkIHRleHR1cmVzIHVuc3VwcG9ydGVkXG4iKTsKICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgfQoKICAgICAgICBpZiAoVGhpcy0+RmxhZ3MgJiBTRkxBR19OT05QT1cyKSB7CiAgICAgICAgICAgIHNyY19waXRjaCA9IFRoaXMtPmJ5dGVzUGVyUGl4ZWwgKiBUaGlzLT5wb3cyV2lkdGg7CiAgICAgICAgICAgIGRzdF9waXRjaCA9IElXaW5lRDNEU3VyZmFjZV9HZXRQaXRjaCgoSVdpbmVEM0RTdXJmYWNlICopIFRoaXMpOwogICAgICAgICAgICBzcmNfcGl0Y2ggPSAoc3JjX3BpdGNoICsgU1VSRkFDRV9BTElHTk1FTlQgLSAxKSAmIH4oU1VSRkFDRV9BTElHTk1FTlQgLSAxKTsKICAgICAgICAgICAgbWVtID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNyY19waXRjaCAqIFRoaXMtPnBvdzJIZWlnaHQpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG1lbSA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeTsKICAgICAgICB9CgogICAgICAgIFRSQUNFKCIoJXApIDogQ2FsbGluZyBnbEdldFRleEltYWdlIGxldmVsICVkLCBmb3JtYXQgJSN4LCB0eXBlICUjeCwgZGF0YSAlcFxuIiwgVGhpcywgVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCwKICAgICAgICAgICAgICAgIFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xGb3JtYXQsIFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xUeXBlLCBtZW0pOwoKICAgICAgICBnbEdldFRleEltYWdlKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLCBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0LAogICAgICAgICAgICAgICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbFR5cGUsIG1lbSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsR2V0VGV4SW1hZ2UoKSIpOwoKICAgICAgICBpZiAoVGhpcy0+RmxhZ3MgJiBTRkxBR19OT05QT1cyKSB7CiAgICAgICAgICAgIExQQllURSBzcmNfZGF0YSwgZHN0X2RhdGE7CiAgICAgICAgICAgIGludCB5OwogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBTb21lIGdhbWVzIChlLmcuIHdhcmhhbW1lciA0MGspIGRvbid0IHdvcmsgcHJvcGVybHkgd2l0aCB0aGUgb2RkIHBpdGNoZXMsIHByZXZlbnRpbmcKICAgICAgICAgICAgICogdGhlIHN1cmZhY2UgcGl0Y2ggZnJvbSBiZWluZyB1c2VkIHRvIGJveCBub24tcG93ZXIyIHRleHR1cmVzLiBJbnN0ZWFkIHdlIGhhdmUgdG8gdXNlIGEgaGFjayB0bwogICAgICAgICAgICAgKiByZXBhY2sgdGhlIHRleHR1cmUgc28gdGhhdCB0aGUgYnBwICogd2lkdGggcGl0Y2ggY2FuIGJlIHVzZWQgaW5zdGVhZCBvZiBicHAgKiBwb3cyd2lkdGguCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIFdlJ3JlIGRvaW5nIHRoaXMuLi4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogaW5zdGVhZCBvZiBib3hpbmcgdGhlIHRleHR1cmUgOgogICAgICAgICAgICAgKiB8PC10ZXh0dXJlIHdpZHRoIC0+fCAgLS0+cG93MndpZHRofCAgIC9cCiAgICAgICAgICAgICAqIHwxMTExMTExMTExMTExMTExMTF8ICAgICAgICAgICAgICB8ICAgfAogICAgICAgICAgICAgKiB8MjIyIFRleHR1cmUgMjIyMjIyfCBib3hlZCBlbXB0eSAgfCB0ZXh0dXJlIGhlaWdodAogICAgICAgICAgICAgKiB8MzMzMyBEYXRhIDMzMzMzMzMzfCAgICAgICAgICAgICAgfCAgIHwKICAgICAgICAgICAgICogfDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NHwgICAgICAgICAgICAgIHwgICBcLwogICAgICAgICAgICAgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAgIHwKICAgICAgICAgICAgICogfCAgICAgYm94ZWQgIGVtcHR5IHwgYm94ZWQgZW1wdHkgIHwgcG93MmhlaWdodAogICAgICAgICAgICAgKiB8ICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgfCAgIFwvCiAgICAgICAgICAgICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIHdlJ3JlIHJlcGFja2luZyB0aGUgZGF0YSB0byB0aGUgZXhwZWN0ZWQgdGV4dHVyZSB3aWR0aAogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiB8PC10ZXh0dXJlIHdpZHRoIC0+fCAgLS0+cG93MndpZHRofCAgIC9cCiAgICAgICAgICAgICAqIHwxMTExMTExMTExMTExMTExMTEyMjIyMjIyMjIyMjIyMjJ8ICAgfAogICAgICAgICAgICAgKiB8MjIyMzMzMzMzMzMzMzMzMzMzMzMzNDQ0NDQ0NDQ0NDQ0fCB0ZXh0dXJlIGhlaWdodAogICAgICAgICAgICAgKiB8NDQ0NDQ0ICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgIHwKICAgICAgICAgICAgICogfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICBcLwogICAgICAgICAgICAgKiB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgIHwKICAgICAgICAgICAgICogfCAgICAgICAgICAgIGVtcHR5ICAgICAgICAgICAgICAgIHwgcG93MmhlaWdodAogICAgICAgICAgICAgKiB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgIFwvCiAgICAgICAgICAgICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqID09IGlzIHRoZSBzYW1lIGFzCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIHw8LXRleHR1cmUgd2lkdGggLT58ICAgIC9cCiAgICAgICAgICAgICAqIHwxMTExMTExMTExMTExMTExMTF8CiAgICAgICAgICAgICAqIHwyMjIyMjIyMjIyMjIyMjIyMjJ8dGV4dHVyZSBoZWlnaHQKICAgICAgICAgICAgICogfDMzMzMzMzMzMzMzMzMzMzMzM3wKICAgICAgICAgICAgICogfDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NHwgICAgXC8KICAgICAgICAgICAgICogLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogdGhpcyBhbHNvIG1lYW5zIHRoYXQgYW55IHJlZmVyZW5jZXMgdG8gYWxsb2NhdGVkTWVtb3J5IHNob3VsZCB3b3JrIHdpdGggdGhlIGRhdGEgYXMgaWYgd2VyZSBhCiAgICAgICAgICAgICAqIHN0YW5kYXJkIHRleHR1cmUgd2l0aCBhIG5vbi1wb3dlcjIgd2lkdGggaW5zdGVhZCBvZiB0ZXh0dXJlIGJveGVkIHVwIHRvIGJlIGEgcG93ZXIyIHRleHR1cmUuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIGludGVybmFsbHkgdGhlIHRleHR1cmUgaXMgc3RpbGwgc3RvcmVkIGluIGEgYm94ZWQgZm9ybWF0IHNvIGFueSByZWZlcmVuY2VzIHRvIHRleHR1cmVOYW1lIHdpbGwKICAgICAgICAgICAgICogZ2V0IGEgYm94ZWQgdGV4dHVyZSB3aXRoIHdpZHRoIHBvdzJ3aWR0aCBhbmQgbm90IGEgdGV4dHVyZSBvZiB3aWR0aCBjdXJyZW50RGVzYy5XaWR0aC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogUGVyZm9ybWFuY2Ugc2hvdWxkIG5vdCBiZSBhbiBpc3N1ZSwgYmVjYXVzZSBhcHBsaWNhdGlvbnMgbm9ybWFsbHkgZG8gbm90IGxvY2sgdGhlIHN1cmZhY2VzIHdoZW4KICAgICAgICAgICAgICogcmVuZGVyaW5nLiBJZiBhbiBhcHAgZG9lcywgdGhlIFNGTEFHX0RZTkxPQ0sgZmxhZyB3aWxsIGtpY2sgaW4gYW5kIHRoZSBtZW1vcnkgY29weSB3b24ndCBiZSByZWxlYXNlZCwKICAgICAgICAgICAgICogYW5kIGRvZXNuJ3QgaGF2ZSB0byBiZSByZS1yZWFkLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc3JjX2RhdGEgPSBtZW07CiAgICAgICAgICAgIGRzdF9kYXRhID0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5OwogICAgICAgICAgICBUUkFDRSgiKCVwKSA6IFJlcGFja2luZyB0aGUgc3VyZmFjZSBkYXRhIGZyb20gcGl0Y2ggJWQgdG8gcGl0Y2ggJWRcbiIsIFRoaXMsIHNyY19waXRjaCwgZHN0X3BpdGNoKTsKICAgICAgICAgICAgZm9yICh5ID0gMSA7IHkgPCBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQ7IHkrKykgewogICAgICAgICAgICAgICAgLyogc2tpcCB0aGUgZmlyc3Qgcm93ICovCiAgICAgICAgICAgICAgICBzcmNfZGF0YSArPSBzcmNfcGl0Y2g7CiAgICAgICAgICAgICAgICBkc3RfZGF0YSArPSBkc3RfcGl0Y2g7CiAgICAgICAgICAgICAgICBtZW1jcHkoZHN0X2RhdGEsIHNyY19kYXRhLCBkc3RfcGl0Y2gpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBtZW0pOwogICAgICAgIH0KICAgIH0KfQoKc3RhdGljIHZvaWQgc3VyZmFjZV91cGxvYWRfZGF0YShJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzLCBHTHNpemVpIHdpZHRoLCBHTHNpemVpIGhlaWdodCwgR0xlbnVtIGZvcm1hdCwgR0xlbnVtIHR5cGUsIGNvbnN0IEdMdm9pZCAqZGF0YSkgewogICAgaWYgKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDEgfHwKICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMiB8fCBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQzIHx8CiAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDQgfHwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNSkgewogICAgICAgIGlmICghR0xfU1VQUE9SVChFWFRfVEVYVFVSRV9DT01QUkVTU0lPTl9TM1RDKSkgewogICAgICAgICAgICBGSVhNRSgiVXNpbmcgRFhUMS8zLzUgd2l0aG91dCBhZHZlcnRpemVkIHN1cHBvcnRcbiIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmKEdMX1NVUFBPUlQoQVBQTEVfQ0xJRU5UX1NUT1JBR0UpKSB7CiAgICAgICAgICAgICAgICAvKiBOZWl0aGVyIE5PTlBPVzIsIERJQlNFQ1RJT04gbm9yIE9WRVJTSVpFIGZsYWdzIGNhbiBiZSBzZXQgb24gY29tcHJlc3NlZCB0ZXh0dXJlcyAqLwogICAgICAgICAgICAgICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfQ0xJRU5UOwogICAgICAgICAgICB9CgogICAgICAgICAgICBUUkFDRSgiKCVwKSA6IENhbGxpbmcgZ2xDb21wcmVzc2VkVGV4U3ViSW1hZ2UyRCB3ICVkLCBoICVkLCBkYXRhICVwXG4iLCBUaGlzLCB3aWR0aCwgaGVpZ2h0LCBkYXRhKTsKICAgICAgICAgICAgRU5URVJfR0woKTsKICAgICAgICAgICAgLyogZ2xDb21wcmVzc2VkVGV4U3ViSW1hZ2UyRCBmb3IgdXBsb2FkaW5nIGFuZCBnbFRleEltYWdlMkQgZm9yIGFsbG9jYXRpbmcgZG9lcyBub3Qgd29yayB3ZWxsIG9uIHNvbWUgZHJpdmVycyhyMjAwIGRyaSwgTWFjT1MgQVRJIGRyaXZlcikKICAgICAgICAgICAgICogZ2xDb21wcmVzc2VkVGV4SW1hZ2UyRCBkb2VzIG5vdCBhY2NlcHQgTlVMTCBwb2ludGVycy4gU28gZm9yIGNvbXByZXNzZWQgdGV4dHVyZXMgc3VyZmFjZV9hbGxvY2F0ZV9zdXJmYWNlIGRvZXMgbm90aGluZywgYW5kIHRoaXMKICAgICAgICAgICAgICogZnVuY3Rpb24gdXNlcyBnbENvbXByZXNzZWRUZXhJbWFnZTJEIGluc3RlYWQgb2YgdGhlIFN1YkltYWdlIGNhbGwKICAgICAgICAgICAgICovCiAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xDb21wcmVzc2VkVGV4SW1hZ2UyREFSQihUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCwgVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCwgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdEludGVybmFsLAogICAgICAgICAgICAgICAgICAgICAgIHdpZHRoLCBoZWlnaHQsIDAgLyogYm9yZGVyICovLCBUaGlzLT5yZXNvdXJjZS5zaXplLCBkYXRhKSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbENvbXByZXNzZWRUZXhTdWJJbWFnZTJEIik7CiAgICAgICAgICAgIExFQVZFX0dMKCk7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICBUUkFDRSgiKCVwKSA6IENhbGxpbmcgZ2xUZXhTdWJJbWFnZTJEIHcgJWQsICBoICVkLCBkYXRhLCAlcFxuIiwgVGhpcywgd2lkdGgsIGhlaWdodCwgZGF0YSk7CiAgICAgICAgRU5URVJfR0woKTsKICAgICAgICBnbFRleFN1YkltYWdlMkQoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsIDAsIDAsIHdpZHRoLCBoZWlnaHQsIGZvcm1hdCwgdHlwZSwgZGF0YSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsVGV4U3ViSW1hZ2UyRCIpOwogICAgICAgIExFQVZFX0dMKCk7CiAgICB9Cn0KCnN0YXRpYyB2b2lkIHN1cmZhY2VfYWxsb2NhdGVfc3VyZmFjZShJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzLCBHTGVudW0gaW50ZXJuYWwsIEdMc2l6ZWkgd2lkdGgsIEdMc2l6ZWkgaGVpZ2h0LCBHTGVudW0gZm9ybWF0LCBHTGVudW0gdHlwZSkgewogICAgQk9PTCBlbmFibGVfY2xpZW50X3N0b3JhZ2UgPSBGQUxTRTsKCiAgICBUUkFDRSgiKCVwKSA6IENyZWF0aW5nIHN1cmZhY2UgKHRhcmdldCAlI3gpICBsZXZlbCAlZCwgZDNkIGZvcm1hdCAlcywgaW50ZXJuYWwgZm9ybWF0ICUjeCwgd2lkdGggJWQsIGhlaWdodCAlZCwgZ2wgZm9ybWF0ICUjeCwgZ2wgdHlwZT0lI3hcbiIsIFRoaXMsCiAgICAgICAgICAgIFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLCBkZWJ1Z19kM2Rmb3JtYXQoVGhpcy0+cmVzb3VyY2UuZm9ybWF0KSwgaW50ZXJuYWwsIHdpZHRoLCBoZWlnaHQsIGZvcm1hdCwgdHlwZSk7CgogICAgaWYgKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDEgfHwKICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMiB8fCBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQzIHx8CiAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDQgfHwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNSkgewogICAgICAgIC8qIGdsQ29tcHJlc3NlZFRleEltYWdlMkQgZG9lcyBub3QgYWNjZXB0IE5VTEwgcG9pbnRlcnMsIHNvIHdlIGNhbm5vdCBhbGxvY2F0ZSBhIGNvbXByZXNzZWQgdGV4dHVyZSB3aXRob3V0IHVwbG9hZGluZyBkYXRhICovCiAgICAgICAgVFJBQ0UoIk5vdCBhbGxvY2F0aW5nIGNvbXByZXNzZWQgc3VyZmFjZXMsIHN1cmZhY2VfdXBsb2FkX2RhdGEgd2lsbCBzcGVjaWZ5IHRoZW1cbiIpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBFTlRFUl9HTCgpOwoKICAgIGlmKEdMX1NVUFBPUlQoQVBQTEVfQ0xJRU5UX1NUT1JBR0UpKSB7CiAgICAgICAgaWYoVGhpcy0+RmxhZ3MgJiAoU0ZMQUdfTk9OUE9XMiB8IFNGTEFHX0RJQlNFQ1RJT04gfCBTRkxBR19PVkVSU0laRSB8IFNGTEFHX0NPTlZFUlRFRCkgfHwgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID09IE5VTEwpIHsKICAgICAgICAgICAgLyogSW4gc29tZSBjYXNlcyB3ZSB3YW50IHRvIGRpc2FibGUgY2xpZW50IHN0b3JhZ2UuCiAgICAgICAgICAgICAqIFNGTEFHX05PTlBPVzIgaGFzIGEgYmlnZ2VyIG9wZW5nbCB0ZXh0dXJlIHRoYW4gdGhlIGNsaWVudCBtZW1vcnksIGFuZCBkaWZmZXJlbnQgcGl0Y2hlcwogICAgICAgICAgICAgKiBTRkxBR19ESUJTRUNUSU9OOiBEaWJzZWN0aW9ucyBtYXkgaGF2ZSByZWFkIC8gd3JpdGUgcHJvdGVjdGlvbnMgb24gdGhlIG1lbW9yeS4gQXZvaWQgaXNzdWVzLi4uCiAgICAgICAgICAgICAqIFNGTEFHX09WRVJTSVpFOiBUaGUgZ2wgdGV4dHVyZSBpcyBzbWFsbGVyIHRoYW4gdGhlIGFsbG9jYXRlZCBtZW1vcnkKICAgICAgICAgICAgICogU0ZMQUdfQ09OVkVSVEVEOiBUaGUgY29udmVyc2lvbiBkZXN0aW5hdGlvbiBtZW1vcnkgaXMgZnJlZWQgYWZ0ZXIgbG9hZGluZyB0aGUgc3VyZmFjZQogICAgICAgICAgICAgKiBhbGxvY2F0ZWRNZW1vcnkgPT0gTlVMTDogTm90IGRlZmluZWQgaW4gdGhlIGV4dGVuc2lvbi4gU2VlbXMgdG8gZGlzYWJsZSBjbGllbnQgc3RvcmFnZSBlZmZlY3RpdmVseQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgZ2xQaXhlbFN0b3JlaShHTF9VTlBBQ0tfQ0xJRU5UX1NUT1JBR0VfQVBQTEUsIEdMX0ZBTFNFKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsUGl4ZWxTdG9yZWkoR0xfVU5QQUNLX0NMSUVOVF9TVE9SQUdFX0FQUExFLCBHTF9GQUxTRSkiKTsKICAgICAgICAgICAgVGhpcy0+RmxhZ3MgJj0gU0ZMQUdfQ0xJRU5UOwogICAgICAgICAgICBlbmFibGVfY2xpZW50X3N0b3JhZ2UgPSBUUlVFOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX0NMSUVOVDsKICAgICAgICAgICAgLyogQmVsb3cgcG9pbnQgb3BlbmdsIHRvIG91ciBhbGxvY2F0ZWQgdGV4dHVyZSBtZW1vcnkgKi8KICAgICAgICB9CiAgICB9CiAgICBnbFRleEltYWdlMkQoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsIGludGVybmFsLCB3aWR0aCwgaGVpZ2h0LCAwLCBmb3JtYXQsIHR5cGUsCiAgICAgICAgICAgICAgICAgVGhpcy0+RmxhZ3MgJiBTRkxBR19DTElFTlQgPyBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgOiBOVUxMKTsKICAgIGNoZWNrR0xjYWxsKCJnbFRleEltYWdlMkQiKTsKCiAgICBpZihlbmFibGVfY2xpZW50X3N0b3JhZ2UpIHsKICAgICAgICBnbFBpeGVsU3RvcmVpKEdMX1VOUEFDS19DTElFTlRfU1RPUkFHRV9BUFBMRSwgR0xfVFJVRSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsUGl4ZWxTdG9yZWkoR0xfVU5QQUNLX0NMSUVOVF9TVE9SQUdFX0FQUExFLCBHTF9UUlVFKSIpOwogICAgfQogICAgTEVBVkVfR0woKTsKCiAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19BTExPQ0FURUQ7Cn0KCi8qIEluIEQzRCB0aGUgZGVwdGggc3RlbmNpbCBkaW1lbnNpb25zIGhhdmUgdG8gYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIHRoZQogKiByZW5kZXIgdGFyZ2V0IGRpbWVuc2lvbnMuIFdpdGggRkJPcywgdGhlIGRpbWVuc2lvbnMgaGF2ZSB0byBiZSBhbiBleGFjdCBtYXRjaC4gKi8KLyogVE9ETzogV2Ugc2hvdWxkIHN5bmNocm9uaXplIHRoZSByZW5kZXJidWZmZXIncyBjb250ZW50IHdpdGggdGhlIHRleHR1cmUncyBjb250ZW50LiAqLwp2b2lkIHN1cmZhY2Vfc2V0X2NvbXBhdGlibGVfcmVuZGVyYnVmZmVyKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIHVuc2lnbmVkIGludCB3aWR0aCwgdW5zaWduZWQgaW50IGhlaWdodCkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICByZW5kZXJidWZmZXJfZW50cnlfdCAqZW50cnk7CiAgICBHTHVpbnQgcmVuZGVyYnVmZmVyID0gMDsKICAgIHVuc2lnbmVkIGludCBzcmNfd2lkdGgsIHNyY19oZWlnaHQ7CgogICAgc3JjX3dpZHRoID0gVGhpcy0+cG93MldpZHRoOwogICAgc3JjX2hlaWdodCA9IFRoaXMtPnBvdzJIZWlnaHQ7CgogICAgLyogQSBkZXB0aCBzdGVuY2lsIHNtYWxsZXIgdGhhbiB0aGUgcmVuZGVyIHRhcmdldCBpcyBub3QgdmFsaWQgKi8KICAgIGlmICh3aWR0aCA+IHNyY193aWR0aCB8fCBoZWlnaHQgPiBzcmNfaGVpZ2h0KSByZXR1cm47CgogICAgLyogUmVtb3ZlIGFueSByZW5kZXJidWZmZXIgc2V0IGlmIHRoZSBzaXplcyBtYXRjaCAqLwogICAgaWYgKHdpZHRoID09IHNyY193aWR0aCAmJiBoZWlnaHQgPT0gc3JjX2hlaWdodCkgewogICAgICAgIFRoaXMtPmN1cnJlbnRfcmVuZGVyYnVmZmVyID0gTlVMTDsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgLyogTG9vayBpZiB3ZSd2ZSBhbHJlYWR5IGdvdCBhIHJlbmRlcmJ1ZmZlciBvZiB0aGUgY29ycmVjdCBkaW1lbnNpb25zICovCiAgICBMSVNUX0ZPUl9FQUNIX0VOVFJZKGVudHJ5LCAmVGhpcy0+cmVuZGVyYnVmZmVycywgcmVuZGVyYnVmZmVyX2VudHJ5X3QsIGVudHJ5KSB7CiAgICAgICAgaWYgKGVudHJ5LT53aWR0aCA9PSB3aWR0aCAmJiBlbnRyeS0+aGVpZ2h0ID09IGhlaWdodCkgewogICAgICAgICAgICByZW5kZXJidWZmZXIgPSBlbnRyeS0+aWQ7CiAgICAgICAgICAgIFRoaXMtPmN1cnJlbnRfcmVuZGVyYnVmZmVyID0gZW50cnk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoIXJlbmRlcmJ1ZmZlcikgewogICAgICAgIGNvbnN0IFBpeGVsRm9ybWF0RGVzYyAqZm9ybWF0X2VudHJ5ID0gZ2V0Rm9ybWF0RGVzY0VudHJ5KFRoaXMtPnJlc291cmNlLmZvcm1hdCk7CgogICAgICAgIEdMX0VYVENBTEwoZ2xHZW5SZW5kZXJidWZmZXJzRVhUKDEsICZyZW5kZXJidWZmZXIpKTsKICAgICAgICBHTF9FWFRDQUxMKGdsQmluZFJlbmRlcmJ1ZmZlckVYVChHTF9SRU5ERVJCVUZGRVJfRVhULCByZW5kZXJidWZmZXIpKTsKICAgICAgICBHTF9FWFRDQUxMKGdsUmVuZGVyYnVmZmVyU3RvcmFnZUVYVChHTF9SRU5ERVJCVUZGRVJfRVhULCBmb3JtYXRfZW50cnktPmdsRm9ybWF0LCB3aWR0aCwgaGVpZ2h0KSk7CgogICAgICAgIGVudHJ5ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZihyZW5kZXJidWZmZXJfZW50cnlfdCkpOwogICAgICAgIGVudHJ5LT53aWR0aCA9IHdpZHRoOwogICAgICAgIGVudHJ5LT5oZWlnaHQgPSBoZWlnaHQ7CiAgICAgICAgZW50cnktPmlkID0gcmVuZGVyYnVmZmVyOwogICAgICAgIGxpc3RfYWRkX2hlYWQoJlRoaXMtPnJlbmRlcmJ1ZmZlcnMsICZlbnRyeS0+ZW50cnkpOwoKICAgICAgICBUaGlzLT5jdXJyZW50X3JlbmRlcmJ1ZmZlciA9IGVudHJ5OwogICAgfQoKICAgIGNoZWNrR0xjYWxsKCJzZXRfY29tcGF0aWJsZV9yZW5kZXJidWZmZXIiKTsKfQoKR0xlbnVtIHN1cmZhY2VfZ2V0X2dsX2J1ZmZlcihJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBJV2luZUQzRFN3YXBDaGFpbiAqc3dhcGNoYWluKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEU3dhcENoYWluSW1wbCAqc3dhcGNoYWluX2ltcGwgPSAoSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICopc3dhcGNoYWluOwoKICAgIFRSQUNFKCIoJXApIDogc3dhcGNoYWluICVwXG4iLCBUaGlzLCBzd2FwY2hhaW4pOwoKICAgIGlmIChzd2FwY2hhaW5faW1wbC0+YmFja0J1ZmZlciAmJiBzd2FwY2hhaW5faW1wbC0+YmFja0J1ZmZlclswXSA9PSBpZmFjZSkgewogICAgICAgIFRSQUNFKCJSZXR1cm5pbmcgR0xfQkFDS1xuIik7CiAgICAgICAgcmV0dXJuIEdMX0JBQ0s7CiAgICB9IGVsc2UgaWYgKHN3YXBjaGFpbl9pbXBsLT5mcm9udEJ1ZmZlciA9PSBpZmFjZSkgewogICAgICAgIFRSQUNFKCJSZXR1cm5pbmcgR0xfRlJPTlRcbiIpOwogICAgICAgIHJldHVybiBHTF9GUk9OVDsKICAgIH0KCiAgICBGSVhNRSgiSGlnaGVyIGJhY2sgYnVmZmVyLCByZXR1cm5pbmcgR0xfQkFDS1xuIik7CiAgICByZXR1cm4gR0xfQkFDSzsKfQoKLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogICBJV2luZUQzRFN1cmZhY2UgSVVua25vd24gcGFydHMgZm9sbG93CiAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi8KSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9RdWVyeUludGVyZmFjZShJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBSRUZJSUQgcmlpZCwgTFBWT0lEICpwcG9iaikKewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICAvKiBXYXJuICxidXQgYmUgbmljZSBhYm91dCB0aGluZ3MgKi8KICAgIFRSQUNFKCIoJXApLT4oJXMsJXApXG4iLCBUaGlzLGRlYnVnc3RyX2d1aWQocmlpZCkscHBvYmopOwoKICAgIGlmIChJc0VxdWFsR1VJRChyaWlkLCAmSUlEX0lVbmtub3duKQogICAgICAgIHx8IElzRXF1YWxHVUlEKHJpaWQsICZJSURfSVdpbmVEM0RCYXNlKQogICAgICAgIHx8IElzRXF1YWxHVUlEKHJpaWQsICZJSURfSVdpbmVEM0RSZXNvdXJjZSkKICAgICAgICB8fCBJc0VxdWFsR1VJRChyaWlkLCAmSUlEX0lXaW5lRDNEU3VyZmFjZSkpIHsKICAgICAgICBJVW5rbm93bl9BZGRSZWYoKElVbmtub3duKilpZmFjZSk7CiAgICAgICAgKnBwb2JqID0gVGhpczsKICAgICAgICByZXR1cm4gU19PSzsKICAgIH0KICAgICpwcG9iaiA9IE5VTEw7CiAgICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKfQoKVUxPTkcgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfQWRkUmVmKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgVUxPTkcgcmVmID0gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPnJlc291cmNlLnJlZik7CiAgICBUUkFDRSgiKCVwKSA6IEFkZFJlZiBpbmNyZWFzaW5nIGZyb20gJWRcbiIsIFRoaXMscmVmIC0gMSk7CiAgICByZXR1cm4gcmVmOwp9CgpVTE9ORyBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9SZWxlYXNlKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgVUxPTkcgcmVmID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJlRoaXMtPnJlc291cmNlLnJlZik7CiAgICBUUkFDRSgiKCVwKSA6IFJlbGVhc2luZyBmcm9tICVkXG4iLCBUaGlzLCByZWYgKyAxKTsKICAgIGlmIChyZWYgPT0gMCkgewogICAgICAgIElXaW5lRDNERGV2aWNlSW1wbCAqZGV2aWNlID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOwogICAgICAgIHJlbmRlcmJ1ZmZlcl9lbnRyeV90ICplbnRyeSwgKmVudHJ5MjsKICAgICAgICBUUkFDRSgiKCVwKSA6IGNsZWFuaW5nIHVwXG4iLCBUaGlzKTsKCiAgICAgICAgaWYoaWZhY2UgPT0gZGV2aWNlLT5sYXN0QWN0aXZlUmVuZGVyVGFyZ2V0KSB7CiAgICAgICAgICAgIElXaW5lRDNEU3dhcENoYWluSW1wbCAqc3dhcGNoYWluID0gZGV2aWNlLT5zd2FwY2hhaW5zID8gKElXaW5lRDNEU3dhcENoYWluSW1wbCAqKSBkZXZpY2UtPnN3YXBjaGFpbnNbMF0gOiBOVUxMOwoKICAgICAgICAgICAgVFJBQ0UoIkxhc3QgYWN0aXZlIHJlbmRlciB0YXJnZXQgZGVzdHJveWVkXG4iKTsKICAgICAgICAgICAgLyogRmluZCBhIHJlcGxhY2VtZW50IHN1cmZhY2UgZm9yIHRoZSBjdXJyZW50bHkgYWN0aXZlIGJhY2sgYnVmZmVyLiBUaGUgY29udGV4dCBtYW5hZ2VyIGRvZXMgbm90IGRvIE5VTEwKICAgICAgICAgICAgICogY2hlY2tzLCBzbyBzd2l0Y2ggdG8gYSB2YWxpZCB0YXJnZXQgYXMgbG9uZyBhcyB0aGUgY3VycmVudGx5IHNldCBzdXJmYWNlIGlzIHN0aWxsIHZhbGlkLiBVc2UgdGhlCiAgICAgICAgICAgICAqIHN1cmZhY2Ugb2YgdGhlIGltcGxpY2l0IHN3cGNoYWluLiBJZiB0aGF0IGlzIHRoZSBzYW1lIGFzIHRoZSBkZXN0cm95ZWQgc3VyZmFjZSB0aGUgZGV2aWNlIGlzIGRlc3Ryb3llZAogICAgICAgICAgICAgKiBhbmQgdGhlIGxhc3RBY3RpdmVSZW5kZXJUYXJnZXQgbWVtYmVyIHNob3VsZG4ndCBtYXR0ZXIKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmKHN3YXBjaGFpbikgewogICAgICAgICAgICAgICAgRU5URVJfR0woKTsgLyogRm9yIEFjdGl2YXRlQ29udGV4dCAqLwogICAgICAgICAgICAgICAgaWYoc3dhcGNoYWluLT5iYWNrQnVmZmVyICYmIHN3YXBjaGFpbi0+YmFja0J1ZmZlclswXSAhPSBpZmFjZSkgewogICAgICAgICAgICAgICAgICAgIFRSQUNFKCJBY3RpdmF0aW5nIHByaW1hcnkgYmFjayBidWZmZXJcbiIpOwogICAgICAgICAgICAgICAgICAgIEFjdGl2YXRlQ29udGV4dChkZXZpY2UsIHN3YXBjaGFpbi0+YmFja0J1ZmZlclswXSwgQ1RYVVNBR0VfUkVTT1VSQ0VMT0FEKTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZighc3dhcGNoYWluLT5iYWNrQnVmZmVyICYmIHN3YXBjaGFpbi0+ZnJvbnRCdWZmZXIgIT0gaWZhY2UpIHsKICAgICAgICAgICAgICAgICAgICAvKiBTaW5nbGUgYnVmZmVyaW5nIGVudmlyb25tZW50ICovCiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIkFjdGl2YXRpbmcgcHJpbWFyeSBmcm9udCBidWZmZXJcbiIpOwogICAgICAgICAgICAgICAgICAgIEFjdGl2YXRlQ29udGV4dChkZXZpY2UsIHN3YXBjaGFpbi0+ZnJvbnRCdWZmZXIsIENUWFVTQUdFX1JFU09VUkNFTE9BRCk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIFRSQUNFKCJEZXZpY2UgaXMgYmVpbmcgZGVzdHJveWVkLCBzZXR0aW5nIGxhc3RBY3RpdmVSZW5kZXJUYXJnZXQgPSAweGRlYWRiYWJlXG4iKTsKICAgICAgICAgICAgICAgICAgICAvKiBJbXBsaWNpdCByZW5kZXIgdGFyZ2V0IGRlc3Ryb3llZCwgdGhhdCBtZWFucyB0aGUgZGV2aWNlIGlzIGJlaW5nIGRlc3Ryb3llZAogICAgICAgICAgICAgICAgICAgICAqIHdoYXRldmVyIHdlIHNldCBoZXJlLCBpdCBzaG91bGRuJ3QgbWF0dGVyCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgZGV2aWNlLT5sYXN0QWN0aXZlUmVuZGVyVGFyZ2V0ID0gKElXaW5lRDNEU3VyZmFjZSAqKSAweGRlYWRiYWJlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgTEVBVkVfR0woKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8qIE1heSBoYXBwZW4gZHVyaW5nIGRkcmF3IHVuaW5pdGlhbGl6YXRpb24gKi8KICAgICAgICAgICAgICAgIFRSQUNFKCJSZW5kZXIgdGFyZ2V0IHNldCwgYnV0IHN3YXBjaGFpbiBkb2VzIG5vdCBleGlzdCFcbiIpOwogICAgICAgICAgICAgICAgZGV2aWNlLT5sYXN0QWN0aXZlUmVuZGVyVGFyZ2V0ID0gKElXaW5lRDNEU3VyZmFjZSAqKSAweGRlYWRjYWZlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSAhPSAwKSB7IC8qIHJlbGVhc2UgdGhlIG9wZW5HTCB0ZXh0dXJlLi4gKi8KICAgICAgICAgICAgRU5URVJfR0woKTsKCiAgICAgICAgICAgIC8qIE5lZWQgYSBjb250ZXh0IHRvIGRlc3Ryb3kgdGhlIHRleHR1cmUuIFVzZSB0aGUgY3VycmVudGx5IGFjdGl2ZSByZW5kZXIgdGFyZ2V0LCBidXQgb25seSBpZgogICAgICAgICAgICAgKiB0aGUgcHJpbWFyeSByZW5kZXIgdGFyZ2V0IGV4aXN0cy4gT3RoZXJ3aXNlIGxhc3RBY3RpdmVSZW5kZXJUYXJnZXQgaXMgZ2FyYmFnZSwgc2VlIGFib3ZlLgogICAgICAgICAgICAgKiBXaGVuIGRlc3Ryb3lpbmcgdGhlIHByaW1hcnkgcnQsIFVuaW5pdDNEIHdpbGwgYWN0aXZhdGUgYSBjb250ZXh0IGJlZm9yZSBkb2luZyBhbnl0aGluZwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYoZGV2aWNlLT5yZW5kZXJfdGFyZ2V0c1swXSkgewogICAgICAgICAgICAgICAgQWN0aXZhdGVDb250ZXh0KGRldmljZSwgZGV2aWNlLT5sYXN0QWN0aXZlUmVuZGVyVGFyZ2V0LCBDVFhVU0FHRV9SRVNPVVJDRUxPQUQpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBUUkFDRSgiRGVsZXRpbmcgdGV4dHVyZSAlZFxuIiwgVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSk7CiAgICAgICAgICAgIGdsRGVsZXRlVGV4dHVyZXMoMSwgJlRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpOwogICAgICAgICAgICBMRUFWRV9HTCgpOwogICAgICAgIH0KCiAgICAgICAgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19ESUJTRUNUSU9OKSB7CiAgICAgICAgICAgIC8qIFJlbGVhc2UgdGhlIERDICovCiAgICAgICAgICAgIFNlbGVjdE9iamVjdChUaGlzLT5oREMsIFRoaXMtPmRpYi5ob2xkYml0bWFwKTsKICAgICAgICAgICAgRGVsZXRlREMoVGhpcy0+aERDKTsKICAgICAgICAgICAgLyogUmVsZWFzZSB0aGUgRElCIHNlY3Rpb24gKi8KICAgICAgICAgICAgRGVsZXRlT2JqZWN0KFRoaXMtPmRpYi5ESUJzZWN0aW9uKTsKICAgICAgICAgICAgVGhpcy0+ZGliLmJpdG1hcF9kYXRhID0gTlVMTDsKICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gTlVMTDsKICAgICAgICB9CiAgICAgICAgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19VU0VSUFRSKSBJV2luZUQzRFN1cmZhY2VfU2V0TWVtKGlmYWNlLCBOVUxMKTsKCiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+cGFsZXR0ZTkpOwoKICAgICAgICBJV2luZUQzRFJlc291cmNlSW1wbF9DbGVhblVwKChJV2luZUQzRFJlc291cmNlICopaWZhY2UpOwogICAgICAgIGlmKGlmYWNlID09IGRldmljZS0+ZGRyYXdfcHJpbWFyeSkKICAgICAgICAgICAgZGV2aWNlLT5kZHJhd19wcmltYXJ5ID0gTlVMTDsKCiAgICAgICAgTElTVF9GT1JfRUFDSF9FTlRSWV9TQUZFKGVudHJ5LCBlbnRyeTIsICZUaGlzLT5yZW5kZXJidWZmZXJzLCByZW5kZXJidWZmZXJfZW50cnlfdCwgZW50cnkpIHsKICAgICAgICAgICAgR0xfRVhUQ0FMTChnbERlbGV0ZVJlbmRlcmJ1ZmZlcnNFWFQoMSwgJmVudHJ5LT5pZCkpOwogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBlbnRyeSk7CiAgICAgICAgfQoKICAgICAgICBUUkFDRSgiKCVwKSBSZWxlYXNlZFxuIiwgVGhpcyk7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcyk7CgogICAgfQogICAgcmV0dXJuIHJlZjsKfQoKLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogICBJV2luZUQzRFN1cmZhY2UgSVdpbmVEM0RSZXNvdXJjZSBwYXJ0cyBmb2xsb3cKICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqLwpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0dldERldmljZShJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBJV2luZUQzRERldmljZSoqIHBwRGV2aWNlKSB7CiAgICByZXR1cm4gSVdpbmVEM0RSZXNvdXJjZUltcGxfR2V0RGV2aWNlKChJV2luZUQzRFJlc291cmNlICopaWZhY2UsIHBwRGV2aWNlKTsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRQcml2YXRlRGF0YShJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBSRUZHVUlEIHJlZmd1aWQsIENPTlNUIHZvaWQqIHBEYXRhLCBEV09SRCBTaXplT2ZEYXRhLCBEV09SRCBGbGFncykgewogICAgcmV0dXJuIElXaW5lRDNEUmVzb3VyY2VJbXBsX1NldFByaXZhdGVEYXRhKChJV2luZUQzRFJlc291cmNlICopaWZhY2UsIHJlZmd1aWQsIHBEYXRhLCBTaXplT2ZEYXRhLCBGbGFncyk7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0UHJpdmF0ZURhdGEoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgUkVGR1VJRCByZWZndWlkLCB2b2lkKiBwRGF0YSwgRFdPUkQqIHBTaXplT2ZEYXRhKSB7CiAgICByZXR1cm4gSVdpbmVEM0RSZXNvdXJjZUltcGxfR2V0UHJpdmF0ZURhdGEoKElXaW5lRDNEUmVzb3VyY2UgKilpZmFjZSwgcmVmZ3VpZCwgcERhdGEsIHBTaXplT2ZEYXRhKTsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9GcmVlUHJpdmF0ZURhdGEoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgUkVGR1VJRCByZWZndWlkKSB7CiAgICByZXR1cm4gSVdpbmVEM0RSZXNvdXJjZUltcGxfRnJlZVByaXZhdGVEYXRhKChJV2luZUQzRFJlc291cmNlICopaWZhY2UsIHJlZmd1aWQpOwp9CgpEV09SRCAgIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1NldFByaW9yaXR5KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIERXT1JEIFByaW9yaXR5TmV3KSB7CiAgICByZXR1cm4gSVdpbmVEM0RSZXNvdXJjZUltcGxfU2V0UHJpb3JpdHkoKElXaW5lRDNEUmVzb3VyY2UgKilpZmFjZSwgUHJpb3JpdHlOZXcpOwp9CgpEV09SRCAgIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0dldFByaW9yaXR5KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpIHsKICAgIHJldHVybiBJV2luZUQzRFJlc291cmNlSW1wbF9HZXRQcmlvcml0eSgoSVdpbmVEM0RSZXNvdXJjZSAqKWlmYWNlKTsKfQoKdm9pZCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9QcmVMb2FkKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpIHsKICAgIC8qIFRPRE86IGNoZWNrIGZvciBsb2NrcyAqLwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzREJhc2VUZXh0dXJlICpiYXNlVGV4dHVyZSA9IE5VTEw7CiAgICBJV2luZUQzRERldmljZUltcGwgKmRldmljZSA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CgogICAgVFJBQ0UoIiglcClDaGVja2luZyB0byBzZWUgaWYgdGhlIGNvbnRhaW5lciBpcyBhIGJhc2UgdGV4dHVyZVxuIiwgVGhpcyk7CiAgICBpZiAoSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lcihpZmFjZSwgJklJRF9JV2luZUQzREJhc2VUZXh0dXJlLCAodm9pZCAqKikmYmFzZVRleHR1cmUpID09IFdJTkVEM0RfT0spIHsKICAgICAgICBUUkFDRSgiUGFzc2luZyB0byBjb25hdGluZXJcbiIpOwogICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVfUHJlTG9hZChiYXNlVGV4dHVyZSk7CiAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9SZWxlYXNlKGJhc2VUZXh0dXJlKTsKICAgIH0gZWxzZSB7CiAgICBUUkFDRSgiKCVwKSA6IEFib3V0IHRvIGxvYWQgc3VyZmFjZVxuIiwgVGhpcyk7CgogICAgRU5URVJfR0woKTsKICAgIGlmKCFkZXZpY2UtPmlzSW5EcmF3KSB7CiAgICAgICAgQWN0aXZhdGVDb250ZXh0KGRldmljZSwgZGV2aWNlLT5sYXN0QWN0aXZlUmVuZGVyVGFyZ2V0LCBDVFhVU0FHRV9SRVNPVVJDRUxPQUQpOwogICAgfQoKICAgIGdsRW5hYmxlKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0KTsvKiBtYWtlIHN1cmUgdGV4dHVyZSBzdXBwb3J0IGlzIGVuYWJsZWQgaW4gdGhpcyBjb250ZXh0ICovCiAgICBpZiAoIVRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwpIHsKICAgICAgICBpZiAoIVRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpIHsKICAgICAgICAgICAgZ2xHZW5UZXh0dXJlcygxLCAmVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEdlblRleHR1cmVzIik7CiAgICAgICAgICAgIFRSQUNFKCJTdXJmYWNlICVwIGdpdmVuIG5hbWUgJWRcbiIsIFRoaXMsIFRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpOwogICAgICAgIH0KICAgICAgICBnbEJpbmRUZXh0dXJlKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCBUaGlzLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xCaW5kVGV4dHVyZSIpOwogICAgICAgIElXaW5lRDNEU3VyZmFjZV9Mb2FkVGV4dHVyZShpZmFjZSk7CiAgICAgICAgLyogVGhpcyBpcyB3aGVyZSB3ZSBzaG91bGQgYmUgcmVkdWNpbmcgdGhlIGFtb3VudCBvZiBHTE1lbW9yeVVzZWQgKi8KICAgIH0gZWxzZSBpZiAoVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSkgeyAvKiBOT1RFOiB0aGUgbGV2ZWwgMCBzdXJmYWNlIG9mIGEgbXBtYXBwZWQgdGV4dHVyZSBtdXN0IGJlIGxvYWRlZCBmaXJzdCEgKi8KICAgICAgICAvKiBhc3N1bWUgdGhpcyBpcyBhIGNvZGluZyBlcnJvciBub3QgYSByZWFsIGVycm9yIGZvciBub3cgKi8KICAgICAgICBGSVhNRSgiTWlwbWFwIHN1cmZhY2UgaGFzIGEgZ2xUZXh0dXJlIGJvdW5kIHRvIGl0IVxuIik7CiAgICB9CiAgICBpZiAoVGhpcy0+cmVzb3VyY2UucG9vbCA9PSBXSU5FRDNEUE9PTF9ERUZBVUxUKSB7CiAgICAgICAvKiBUZWxsIG9wZW5nbCB0byB0cnkgYW5kIGtlZXAgdGhpcyB0ZXh0dXJlIGluIHZpZGVvIHJhbSAod2VsbCBtb3N0bHkpICovCiAgICAgICBHTGNsYW1wZiB0bXA7CiAgICAgICB0bXAgPSAwLjlmOwogICAgICAgIGdsUHJpb3JpdGl6ZVRleHR1cmVzKDEsICZUaGlzLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lLCAmdG1wKTsKICAgIH0KICAgIExFQVZFX0dMKCk7CiAgICB9CiAgICByZXR1cm47Cn0KCldJTkVEM0RSRVNPVVJDRVRZUEUgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0VHlwZShJV2luZUQzRFN1cmZhY2UgKmlmYWNlKSB7CiAgICBUUkFDRSgiKCVwKSA6IGNhbGxpbmcgcmVzb3VyY2VpbXBsX0dldFR5cGVcbiIsIGlmYWNlKTsKICAgIHJldHVybiBJV2luZUQzRFJlc291cmNlSW1wbF9HZXRUeXBlKChJV2luZUQzRFJlc291cmNlICopaWZhY2UpOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0dldFBhcmVudChJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBJVW5rbm93biAqKnBQYXJlbnQpIHsKICAgIFRSQUNFKCIoJXApIDogY2FsbGluZyByZXNvdXJjZWltcGxfR2V0UGFyZW50XG4iLCBpZmFjZSk7CiAgICByZXR1cm4gSVdpbmVEM0RSZXNvdXJjZUltcGxfR2V0UGFyZW50KChJV2luZUQzRFJlc291cmNlICopaWZhY2UsIHBQYXJlbnQpOwp9CgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICAgSVdpbmVEM0RTdXJmYWNlIElXaW5lRDNEU3VyZmFjZSBwYXJ0cyBmb2xsb3cKICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovCgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0dldENvbnRhaW5lcihJV2luZUQzRFN1cmZhY2UqIGlmYWNlLCBSRUZJSUQgcmlpZCwgdm9pZCoqIHBwQ29udGFpbmVyKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEQmFzZSAqY29udGFpbmVyID0gMDsKCiAgICBUUkFDRSgiKFRoaXMgJXAsIHJpaWQgJXMsIHBwQ29udGFpbmVyICVwKVxuIiwgVGhpcywgZGVidWdzdHJfZ3VpZChyaWlkKSwgcHBDb250YWluZXIpOwoKICAgIGlmICghcHBDb250YWluZXIpIHsKICAgICAgICBFUlIoIkNhbGxlZCB3aXRob3V0IGEgdmFsaWQgcHBDb250YWluZXIuXG4iKTsKICAgIH0KCiAgICAvKiogRnJvbSBNU0ROOgogICAgICogSWYgdGhlIHN1cmZhY2UgaXMgY3JlYXRlZCB1c2luZyBDcmVhdGVJbWFnZVN1cmZhY2UvQ3JlYXRlT2Zmc2NyZWVuUGxhaW5TdXJmYWNlLCBDcmVhdGVSZW5kZXJUYXJnZXQsCiAgICAgKiBvciBDcmVhdGVEZXB0aFN0ZW5jaWxTdXJmYWNlLCB0aGUgc3VyZmFjZSBpcyBjb25zaWRlcmVkIHN0YW5kIGFsb25lLiBJbiB0aGlzIGNhc2UsCiAgICAgKiBHZXRDb250YWluZXIgd2lsbCByZXR1cm4gdGhlIERpcmVjdDNEIGRldmljZSB1c2VkIHRvIGNyZWF0ZSB0aGUgc3VyZmFjZS4KICAgICAqLwogICAgaWYgKFRoaXMtPmNvbnRhaW5lcikgewogICAgICAgIGNvbnRhaW5lciA9IFRoaXMtPmNvbnRhaW5lcjsKICAgIH0gZWxzZSB7CiAgICAgICAgY29udGFpbmVyID0gKElXaW5lRDNEQmFzZSAqKVRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CiAgICB9CgogICAgVFJBQ0UoIlJlbGF5aW5nIHRvIFF1ZXJ5SW50ZXJmYWNlXG4iKTsKICAgIHJldHVybiBJVW5rbm93bl9RdWVyeUludGVyZmFjZShjb250YWluZXIsIHJpaWQsIHBwQ29udGFpbmVyKTsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXREZXNjKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIFdJTkVEM0RTVVJGQUNFX0RFU0MgKnBEZXNjKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKCiAgICBUUkFDRSgiKCVwKSA6IGNvcHlpbmcgaW50byAlcFxuIiwgVGhpcywgcERlc2MpOwogICAgaWYocERlc2MtPkZvcm1hdCAhPSBOVUxMKSAgICAgICAgICAgICAqKHBEZXNjLT5Gb3JtYXQpID0gVGhpcy0+cmVzb3VyY2UuZm9ybWF0OwogICAgaWYocERlc2MtPlR5cGUgIT0gTlVMTCkgICAgICAgICAgICAgICAqKHBEZXNjLT5UeXBlKSAgID0gVGhpcy0+cmVzb3VyY2UucmVzb3VyY2VUeXBlOwogICAgaWYocERlc2MtPlVzYWdlICE9IE5VTEwpICAgICAgICAgICAgICAqKHBEZXNjLT5Vc2FnZSkgICAgICAgICAgICAgID0gVGhpcy0+cmVzb3VyY2UudXNhZ2U7CiAgICBpZihwRGVzYy0+UG9vbCAhPSBOVUxMKSAgICAgICAgICAgICAgICoocERlc2MtPlBvb2wpICAgICAgICAgICAgICAgPSBUaGlzLT5yZXNvdXJjZS5wb29sOwogICAgaWYocERlc2MtPlNpemUgIT0gTlVMTCkgICAgICAgICAgICAgICAqKHBEZXNjLT5TaXplKSAgICAgICAgICAgICAgID0gVGhpcy0+cmVzb3VyY2Uuc2l6ZTsgICAvKiBkeDggb25seSAqLwogICAgaWYocERlc2MtPk11bHRpU2FtcGxlVHlwZSAhPSBOVUxMKSAgICAqKHBEZXNjLT5NdWx0aVNhbXBsZVR5cGUpICAgID0gVGhpcy0+Y3VycmVudERlc2MuTXVsdGlTYW1wbGVUeXBlOwogICAgaWYocERlc2MtPk11bHRpU2FtcGxlUXVhbGl0eSAhPSBOVUxMKSAqKHBEZXNjLT5NdWx0aVNhbXBsZVF1YWxpdHkpID0gVGhpcy0+Y3VycmVudERlc2MuTXVsdGlTYW1wbGVRdWFsaXR5OwogICAgaWYocERlc2MtPldpZHRoICE9IE5VTEwpICAgICAgICAgICAgICAqKHBEZXNjLT5XaWR0aCkgICAgICAgICAgICAgID0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICBpZihwRGVzYy0+SGVpZ2h0ICE9IE5VTEwpICAgICAgICAgICAgICoocERlc2MtPkhlaWdodCkgICAgICAgICAgICAgPSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKdm9pZCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRHbFRleHR1cmVEZXNjKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIFVJTlQgdGV4dHVyZU5hbWUsIGludCB0YXJnZXQpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCkgOiBzZXR0aW5nIHRleHR1cmVOYW1lICV1LCB0YXJnZXQgJWlcbiIsIFRoaXMsIHRleHR1cmVOYW1lLCB0YXJnZXQpOwogICAgaWYgKFRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUgPT0gMCAmJiB0ZXh0dXJlTmFtZSAhPSAwKSB7CiAgICAgICAgVGhpcy0+RmxhZ3MgJj0gflNGTEFHX0lOVEVYVFVSRTsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfQWRkRGlydHlSZWN0KGlmYWNlLCBOVUxMKTsKICAgIH0KICAgIFRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUgPSB0ZXh0dXJlTmFtZTsKICAgIFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0ICAgICAgPSB0YXJnZXQ7CiAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfQUxMT0NBVEVEOwp9Cgp2b2lkIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0dldEdsRGVzYyhJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBnbERlc2NyaXB0b3IgKipnbERlc2NyaXB0aW9uKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIFRSQUNFKCIoJXApIDogcmV0dXJuaW5nICVwXG4iLCBUaGlzLCAmVGhpcy0+Z2xEZXNjcmlwdGlvbik7CiAgICAqZ2xEZXNjcmlwdGlvbiA9ICZUaGlzLT5nbERlc2NyaXB0aW9uOwp9CgovKiBUT0RPOiB0aGluayBhYm91dCBtb3ZpbmcgdGhpcyBkb3duIHRvIHJlc291cmNlPyAqLwpjb25zdCB2b2lkICpXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXREYXRhKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgLyogVGhpcyBzaG91bGQgb25seSBiZSBjYWxsZWQgZm9yIHN5c21lbSB0ZXh0dXJlcywgaXQgbWF5IGJlIGEgZ29vZCBpZGVhIHRvIGV4dGVuZCB0aGlzIHRvIGFsbCBwb29scyBhdCBzb21lIHBvaW50IGluIHRoZSBmdXR0dXJlICAqLwogICAgaWYgKFRoaXMtPnJlc291cmNlLnBvb2wgIT0gV0lORUQzRFBPT0xfU1lTVEVNTUVNKSB7CiAgICAgICAgRklYTUUoIiAoJXApQXR0ZW1wdGluZyB0byBnZXQgc3lzdGVtIG1lbW9yeSBmb3IgYSBub24tc3lzdGVtIG1lbW9yeSB0ZXh0dXJlXG4iLCBpZmFjZSk7CiAgICB9CiAgICByZXR1cm4gKENPTlNUIHZvaWQqKShUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpOwp9CgpzdGF0aWMgdm9pZCByZWFkX2Zyb21fZnJhbWVidWZmZXIoSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcywgQ09OU1QgUkVDVCAqcmVjdCwgdm9pZCAqZGVzdCwgVUlOVCBwaXRjaCwgQk9PTCBzcmNVcHNpZGVEb3duKSB7CiAgICBCWVRFICptZW07CiAgICBHTGludCBmbXQ7CiAgICBHTGludCB0eXBlOwogICAgQllURSAqcm93LCAqdG9wLCAqYm90dG9tOwogICAgaW50IGk7CiAgICBCT09MIGJwcDsKCiAgICBzd2l0Y2goVGhpcy0+cmVzb3VyY2UuZm9ybWF0KQogICAgewogICAgICAgIGNhc2UgV0lORUQzREZNVF9QODoKICAgICAgICB7CiAgICAgICAgICAgIC8qIEdMIGNhbid0IHJldHVybiBwYWxldHRpemVkIGRhdGEsIHNvIHJlYWQgQVJHQiBwaXhlbHMgaW50byBhCiAgICAgICAgICAgICAqIHNlcGFyYXRlIGJsb2NrIG9mIG1lbW9yeSBhbmQgY29udmVydCB0aGVtIGludG8gcGFsZXR0aXplZCBmb3JtYXQKICAgICAgICAgICAgICogaW4gc29mdHdhcmUuIFNsb3csIGJ1dCBpZiB0aGUgYXBwIG1lYW5zIHRvIHVzZSBwYWxldHRpemVkIHJlbmRlcgogICAgICAgICAgICAgKiB0YXJnZXRzIGFuZCBsb2NrcyBpdC4uLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBVc2UgR0xfUkdCLCBHTF9VTlNJR05FRF9CWVRFIHRvIHJlYWQgdGhlIHN1cmZhY2UgZm9yIHBlcmZvcm1hbmNlIHJlYXNvbnMKICAgICAgICAgICAgICogRG9uJ3QgdXNlIEdMX0JHUiBhcyBpbiB0aGUgV0lORUQzREZNVF9SOEc4QjggY2FzZSwgaW5zdGVhZCB3YXRjaCBvdXQKICAgICAgICAgICAgICogZm9yIHRoZSBjb2xvciBjaGFubmVscyB3aGVuIHBhbGV0dGl6aW5nIHRoZSBjb2xvcnMuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBmbXQgPSBHTF9SR0I7CiAgICAgICAgICAgIHR5cGUgPSBHTF9VTlNJR05FRF9CWVRFOwogICAgICAgICAgICBwaXRjaCAqPSAzOwogICAgICAgICAgICBtZW0gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+cmVzb3VyY2Uuc2l6ZSAqIDMpOwogICAgICAgICAgICBpZighbWVtKSB7CiAgICAgICAgICAgICAgICBFUlIoIk91dCBvZiBtZW1vcnlcbiIpOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJwcCA9IFRoaXMtPmJ5dGVzUGVyUGl4ZWwgKiAzOwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgbWVtID0gZGVzdDsKICAgICAgICAgICAgZm10ID0gVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdDsKICAgICAgICAgICAgdHlwZSA9IFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xUeXBlOwogICAgICAgICAgICBicHAgPSBUaGlzLT5ieXRlc1BlclBpeGVsOwogICAgfQoKICAgIGdsUmVhZFBpeGVscyhyZWN0LT5sZWZ0LCByZWN0LT50b3AsCiAgICAgICAgICAgICAgICAgcmVjdC0+cmlnaHQgLSByZWN0LT5sZWZ0LAogICAgICAgICAgICAgICAgIHJlY3QtPmJvdHRvbSAtIHJlY3QtPnRvcCwKICAgICAgICAgICAgICAgICBmbXQsIHR5cGUsIG1lbSk7CiAgICB2Y2hlY2tHTGNhbGwoImdsUmVhZFBpeGVscyIpOwoKICAgIC8qIFRPRE86IE1lcmdlIHRoaXMgd2l0aCB0aGUgcGFsZXR0aXphdGlvbiBsb29wIGJlbG93IGZvciBQOCB0YXJnZXRzICovCgogICAgaWYoIXNyY1Vwc2lkZURvd24pIHsKICAgICAgICBVSU5UIGxlbiwgb2ZmOwogICAgICAgIC8qIGdsUmVhZFBpeGVscyByZXR1cm5zIHRoZSBpbWFnZSB1cHNpZGUgZG93biwgYW5kIHRoZXJlIGlzIG5vIHdheSB0byBwcmV2ZW50IHRoaXMuCiAgICAgICAgICAgIEZsaXAgdGhlIGxpbmVzIGluIHNvZnR3YXJlICovCiAgICAgICAgbGVuID0gKHJlY3QtPnJpZ2h0IC0gcmVjdC0+bGVmdCkgKiBicHA7CiAgICAgICAgb2ZmID0gcmVjdC0+bGVmdCAqIGJwcDsKCiAgICAgICAgcm93ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGxlbik7CiAgICAgICAgaWYoIXJvdykgewogICAgICAgICAgICBFUlIoIk91dCBvZiBtZW1vcnlcbiIpOwogICAgICAgICAgICBpZihUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9QOCkgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbWVtKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgdG9wID0gbWVtICsgcGl0Y2ggKiByZWN0LT50b3A7CiAgICAgICAgYm90dG9tID0gKChCWVRFICopIG1lbSkgKyBwaXRjaCAqICggcmVjdC0+Ym90dG9tIC0gcmVjdC0+dG9wIC0gMSk7CiAgICAgICAgZm9yKGkgPSAwOyBpIDwgKHJlY3QtPmJvdHRvbSAtIHJlY3QtPnRvcCkgLyAyOyBpKyspIHsKICAgICAgICAgICAgbWVtY3B5KHJvdywgdG9wICsgb2ZmLCBsZW4pOwogICAgICAgICAgICBtZW1jcHkodG9wICsgb2ZmLCBib3R0b20gKyBvZmYsIGxlbik7CiAgICAgICAgICAgIG1lbWNweShib3R0b20gKyBvZmYsIHJvdywgbGVuKTsKICAgICAgICAgICAgdG9wICs9IHBpdGNoOwogICAgICAgICAgICBib3R0b20gLT0gcGl0Y2g7CiAgICAgICAgfQogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHJvdyk7CiAgICB9CgogICAgaWYoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfUDgpIHsKICAgICAgICBQQUxFVFRFRU5UUlkgKnBhbDsKICAgICAgICBEV09SRCB3aWR0aCA9IHBpdGNoIC8gMzsKICAgICAgICBpbnQgeCwgeSwgYzsKICAgICAgICBpZihUaGlzLT5wYWxldHRlKSB7CiAgICAgICAgICAgIHBhbCA9IFRoaXMtPnBhbGV0dGUtPnBhbGVudHM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcGFsID0gVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZS0+cGFsZXR0ZXNbVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZS0+Y3VycmVudFBhbGV0dGVdOwogICAgICAgIH0KCiAgICAgICAgZm9yKHkgPSByZWN0LT50b3A7IHkgPCByZWN0LT5ib3R0b207IHkrKykgewogICAgICAgICAgICBmb3IoeCA9IHJlY3QtPmxlZnQ7IHggPCByZWN0LT5yaWdodDsgeCsrKSB7CiAgICAgICAgICAgICAgICAvKiAgICAgICAgICAgICAgICAgICAgICBzdGFydCAgICAgICAgICAgICAgbGluZXMgICAgICAgICAgICBwaXhlbHMgICAgICAqLwogICAgICAgICAgICAgICAgQllURSAqYmx1ZSA9ICAoQllURSAqKSAoKEJZVEUgKikgbWVtKSArIHkgKiBwaXRjaCArIHggKiAoc2l6ZW9mKEJZVEUpICogMyk7CiAgICAgICAgICAgICAgICBCWVRFICpncmVlbiA9IGJsdWUgICsgMTsKICAgICAgICAgICAgICAgIEJZVEUgKnJlZCA9ICAgZ3JlZW4gKyAxOwoKICAgICAgICAgICAgICAgIGZvcihjID0gMDsgYyA8IDI1NjsgYysrKSB7CiAgICAgICAgICAgICAgICAgICAgaWYoKnJlZCAgID09IHBhbFtjXS5wZVJlZCAgICYmCiAgICAgICAgICAgICAgICAgICAgICAgKmdyZWVuID09IHBhbFtjXS5wZUdyZWVuICYmCiAgICAgICAgICAgICAgICAgICAgICAgKmJsdWUgID09IHBhbFtjXS5wZUJsdWUpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAqKChCWVRFICopIGRlc3QgKyB5ICogd2lkdGggKyB4KSA9IGM7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBtZW0pOwogICAgfQp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9Mb2NrUmVjdChJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBXSU5FRDNETE9DS0VEX1JFQ1QqIHBMb2NrZWRSZWN0LCBDT05TVCBSRUNUKiBwUmVjdCwgRFdPUkQgRmxhZ3MpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0REZXZpY2VJbXBsICAqbXlEZXZpY2UgPSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOwogICAgSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICpzd2FwY2hhaW4gPSBOVUxMOwoKICAgIFRSQUNFKCIoJXApIDogcmVjdEAlcCBmbGFncyglMDh4KSwgb3V0cHV0IGxvY2tlZFJlY3RAJXAsIG1lbW9yeUAlcFxuIiwgVGhpcywgcFJlY3QsIEZsYWdzLCBwTG9ja2VkUmVjdCwgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKCiAgICBpZiAoIShUaGlzLT5GbGFncyAmIFNGTEFHX0xPQ0tBQkxFKSkgewogICAgICAgIC8qIE5vdGU6IFVwZGF0ZVRleHR1cmVzIGNhbGxzIENvcHlSZWN0cyB3aGljaCBjYWxscyB0aGlzIHJvdXRpbmUgdG8gcG9wdWxhdGUgdGhlCiAgICAgICAgICAgICAgdGV4dHVyZSByZWdpb25zLCBhbmQgc2luY2UgdGhlIGRlc3RpbmF0aW9uIGlzIGFuIHVubG9ja2FibGUgcmVnaW9uIHdlIG5lZWQKICAgICAgICAgICAgICB0byB0b2xlcmF0ZSB0aGlzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgIFRSQUNFKCJXYXJuaW5nOiB0cnlpbmcgdG8gbG9jayB1bmxvY2thYmxlIHN1cmZAJXBcbiIsIFRoaXMpOwogICAgICAgIC8qcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7ICovCiAgICB9CgogICAgcExvY2tlZFJlY3QtPlBpdGNoID0gSVdpbmVEM0RTdXJmYWNlX0dldFBpdGNoKGlmYWNlKTsKCiAgICAvKiBNYXJrIHRoZSBzdXJmYWNlIGxvY2tlZCAqLwogICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfTE9DS0VEOwoKICAgIC8qIFdoYXRldmVyIHN1cmZhY2Ugd2UgaGF2ZSwgbWFrZSBzdXJlIHRoYXQgdGhlcmUgaXMgbWVtb3J5IGFsbG9jYXRlZCBmb3IgdGhlIGRvd25sb2FkZWQgY29weSAqLwogICAgaWYoIVRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSkgewogICAgICAgIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpICwwICwgVGhpcy0+cmVzb3VyY2Uuc2l6ZSArIDQpOwogICAgICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19JTlNZU01FTTsgLyogVGhpcyBpcyB0aGUgbWFya2VyIHRoYXQgc3VyZmFjZSBkYXRhIGhhcyB0byBiZSBkb3dubG9hZGVkICovCiAgICB9CgogICAgLyogQ2FsY3VsYXRlIHRoZSBjb3JyZWN0IHN0YXJ0IGFkZHJlc3MgdG8gcmVwb3J0ICovCiAgICBpZiAoTlVMTCA9PSBwUmVjdCkgewogICAgICAgIHBMb2NrZWRSZWN0LT5wQml0cyA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeTsKICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LmxlZnQgICA9IDA7CiAgICAgICAgVGhpcy0+bG9ja2VkUmVjdC50b3AgICAgPSAwOwogICAgICAgIFRoaXMtPmxvY2tlZFJlY3QucmlnaHQgID0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAgICAgVGhpcy0+bG9ja2VkUmVjdC5ib3R0b20gPSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICAgICAgVFJBQ0UoIkxvY2tlZCBSZWN0ICglcCkgPSBsICVkLCB0ICVkLCByICVkLCBiICVkXG4iLCAmVGhpcy0+bG9ja2VkUmVjdCwgVGhpcy0+bG9ja2VkUmVjdC5sZWZ0LCBUaGlzLT5sb2NrZWRSZWN0LnRvcCwgVGhpcy0+bG9ja2VkUmVjdC5yaWdodCwgVGhpcy0+bG9ja2VkUmVjdC5ib3R0b20pOwogICAgfSBlbHNlIHsKICAgICAgICBUUkFDRSgiTG9jayBSZWN0ICglcCkgPSBsICVkLCB0ICVkLCByICVkLCBiICVkXG4iLCBwUmVjdCwgcFJlY3QtPmxlZnQsIHBSZWN0LT50b3AsIHBSZWN0LT5yaWdodCwgcFJlY3QtPmJvdHRvbSk7CgogICAgICAgIC8qIERYVG4gdGV4dHVyZXMgYXJlIGJhc2VkIG9uIGNvbXByZXNzZWQgYmxvY2tzIG9mIDR4NCBwaXhlbHMsIGVhY2gKICAgICAgICAgKiAxNiBieXRlcyBsYXJnZSAoOCBieXRlcyBpbiBjYXNlIG9mIERYVDEpLiBCZWNhdXNlIG9mIHRoYXQgUGl0Y2ggaGFzCiAgICAgICAgICogc2xpZ2h0bHkgZGlmZmVyZW50IG1lYW5pbmcgY29tcGFyZWQgdG8gcmVndWxhciB0ZXh0dXJlcy4gRm9yIERYVG4KICAgICAgICAgKiB0ZXh0dXJlcyBQaXRjaCBpcyB0aGUgc2l6ZSBvZiBhIHJvdyBvZiBibG9ja3MsIDQgaGlnaCBhbmQgIndpZHRoIgogICAgICAgICAqIGxvbmcuIFRoZSB4IG9mZnNldCBpcyBjYWxjdWxhdGVkIGRpZmZlcmVudGx5IGFzIHdlbGwsIHNpbmNlIG1vdmluZyA0CiAgICAgICAgICogcGl4ZWxzIHRvIHRoZSByaWdodCBhY3R1YWxseSBtb3ZlcyBhbiBlbnRpcmUgNHg0IGJsb2NrIHRvIHJpZ2h0LCBpZQogICAgICAgICAqIDE2IGJ5dGVzICg4IGluIGNhc2Ugb2YgRFhUMSkuICovCiAgICAgICAgaWYgKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDEpIHsKICAgICAgICAgICAgcExvY2tlZFJlY3QtPnBCaXRzID0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ICsgKHBMb2NrZWRSZWN0LT5QaXRjaCAqIHBSZWN0LT50b3AgLyA0KSArIChwUmVjdC0+bGVmdCAqIDIpOwogICAgICAgIH0gZWxzZSBpZiAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMiB8fCBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQzCiAgICAgICAgICAgICAgICB8fCBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQ0IHx8IFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDUpIHsKICAgICAgICAgICAgcExvY2tlZFJlY3QtPnBCaXRzID0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ICsgKHBMb2NrZWRSZWN0LT5QaXRjaCAqIHBSZWN0LT50b3AgLyA0KSArIChwUmVjdC0+bGVmdCAqIDQpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHBMb2NrZWRSZWN0LT5wQml0cyA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSArIChwTG9ja2VkUmVjdC0+UGl0Y2ggKiBwUmVjdC0+dG9wKSArIChwUmVjdC0+bGVmdCAqIFRoaXMtPmJ5dGVzUGVyUGl4ZWwpOwogICAgICAgIH0KICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LmxlZnQgICA9IHBSZWN0LT5sZWZ0OwogICAgICAgIFRoaXMtPmxvY2tlZFJlY3QudG9wICAgID0gcFJlY3QtPnRvcDsKICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LnJpZ2h0ICA9IHBSZWN0LT5yaWdodDsKICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LmJvdHRvbSA9IHBSZWN0LT5ib3R0b207CiAgICB9CgogICAgaWYgKFRoaXMtPkZsYWdzICYgU0ZMQUdfTk9OUE9XMikgewogICAgICAgIFRSQUNFKCJMb2NraW5nIG5vbi1wb3dlciAyIHRleHR1cmVcbiIpOwogICAgfQoKICAgIC8qIFBlcmZvcm1hbmNlIG9wdGltaXphdGlvbjogQ291bnQgaG93IG9mdGVuIGEgc3VyZmFjZSBpcyBsb2NrZWQsIGlmIGl0IGlzIGxvY2tlZCByZWd1bGFybHkgZG8gbm90IHRocm93IGF3YXkgdGhlIHN5c3RlbSBtZW1vcnkgY29weS4KICAgICAqIFRoaXMgYXZvaWRzIHRoZSBuZWVkIHRvIGRvd25sb2FkIHRoZSBzdXJmYWNlIGZyb20gb3BlbmdsIGFsbCB0aGUgdGltZS4gVGhlIHN1cmZhY2UgaXMgc3RpbGwgZG93bmxvYWRlZCBpZiB0aGUgb3BlbmdsIHRleHR1cmUgaXMKICAgICAqIGNoYW5nZWQKICAgICAqLwogICAgaWYoIShUaGlzLT5GbGFncyAmIFNGTEFHX0RZTkxPQ0spKSB7CiAgICAgICAgVGhpcy0+bG9ja0NvdW50Kys7CiAgICAgICAgLyogTUFYTE9DS0NPVU5UIGlzIGRlZmluZWQgaW4gd2luZWQzZF9wcml2YXRlLmggKi8KICAgICAgICBpZihUaGlzLT5sb2NrQ291bnQgPiBNQVhMT0NLQ09VTlQpIHsKICAgICAgICAgICAgVFJBQ0UoIlN1cmZhY2UgaXMgbG9ja2VkIHJlZ3VsYXJpbHksIG5vdCBmcmVlaW5nIHRoZSBzeXN0ZW0gbWVtb3J5IGNvcHkgYW55IG1vcmVcbiIpOwogICAgICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19EWU5MT0NLOwogICAgICAgIH0KICAgIH0KCiAgICBpZigoRmxhZ3MgJiBXSU5FRDNETE9DS19ESVNDQVJEKSB8fCAoVGhpcy0+RmxhZ3MgJiBTRkxBR19JTlNZU01FTSkpIHsKICAgICAgICBUUkFDRSgiV0lORUQzRExPQ0tfRElTQ0FSRCBmbGFnIHBhc3NlZCwgb3IgbG9jYWwgY29weSBpcyB1cCB0byBkYXRlLCBub3QgZG93bmxvYWRpbmcgZGF0YVxuIik7CiAgICAgICAgZ290byBsb2NrX2VuZDsKICAgIH0KCiAgICAvKiBOb3cgZG93bmxvYWQgdGhlIHN1cmZhY2UgY29udGVudCBmcm9tIG9wZW5nbAogICAgICogVXNlIHRoZSByZW5kZXIgdGFyZ2V0IHJlYWRiYWNrIGlmIHRoZSBzdXJmYWNlIGlzIG9uIGEgc3dhcGNoYWluKD1vbnNjcmVlbiByZW5kZXIgdGFyZ2V0KSBvciB0aGUgY3VycmVudCBwcmltYXJ5IHRhcmdldAogICAgICogT2Zmc2NyZWVuIHRhcmdldHMgd2hpY2ggYXJlIG5vdCBhY3RpdmUgYXQgdGhlIG1vbWVudCBvciBhcmUgaGlnaGVyIHRhcmdldHMoZmJvcykgY2FuIGJlIGxvY2tlZCB3aXRoIHRoZSB0ZXh0dXJlIHBhdGgKICAgICAqLwogICAgSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lcihpZmFjZSwgJklJRF9JV2luZUQzRFN3YXBDaGFpbiwgKHZvaWQgKiopJnN3YXBjaGFpbik7CiAgICBpZihzd2FwY2hhaW4gfHwgaWZhY2UgPT0gbXlEZXZpY2UtPnJlbmRlcl90YXJnZXRzWzBdKSB7CiAgICAgICAgQk9PTCBzcmNJc1Vwc2lkZURvd247CgogICAgICAgIGlmKHdpbmVkM2Rfc2V0dGluZ3MucmVuZGVydGFyZ2V0bG9ja19tb2RlID09IFJUTF9ESVNBQkxFKSB7CiAgICAgICAgICAgIHN0YXRpYyBCT09MIHdhcm5lZCA9IEZBTFNFOwogICAgICAgICAgICBpZighd2FybmVkKSB7CiAgICAgICAgICAgICAgICBFUlIoIlRoZSBhcHBsaWNhdGlvbiB0cmllcyB0byBsb2NrIHRoZSByZW5kZXIgdGFyZ2V0LCBidXQgcmVuZGVyIHRhcmdldCBsb2NraW5nIGlzIGRpc2FibGVkXG4iKTsKICAgICAgICAgICAgICAgIHdhcm5lZCA9IFRSVUU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYoc3dhcGNoYWluKSBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKChJV2luZUQzRFN3YXBDaGFpbiAqKSBzd2FwY2hhaW4pOwogICAgICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgICAgICB9CgogICAgICAgIC8qIEFjdGl2YXRlIHRoZSBzdXJmYWNlLiBTZXQgaXQgdXAgZm9yIGJsaXR0aW5nIG5vdywgYWx0aG91Z2ggbm90IG5lY2Vzc2FyaWx5IG5lZWRlZCBmb3IgTG9ja1JlY3QuCiAgICAgICAgICogQ2VydGFpbiBncmFwaGljcyBkcml2ZXJzIHNlZW0gdG8gZGlzbGlrZSBzb21lIGVuYWJsZWQgc3RhdGVzIHdoZW4gcmVhZGluZyBmcm9tIG9wZW5nbCwgdGhlIGJsaXR0aW5nIHVzYWdlCiAgICAgICAgICogc2hvdWxkIGhlbHAgaGVyZS4gRnVydGhlcm1vcmUgdW5sb2NrcmVjdCB3aWxsIG5lZWQgdGhlIGNvbnRleHQgc2V0IHVwIGZvciBibGl0dGluZy4gVGhlIGNvbnRleHQgbWFuYWdlciB3aWxsIGZpbmQKICAgICAgICAgKiBjb250ZXh0LT5sYXN0X3dhc19ibGl0IHNldCBvbiB0aGUgdW5sb2NrLgogICAgICAgICAqLwogICAgICAgIEVOVEVSX0dMKCk7CiAgICAgICAgQWN0aXZhdGVDb250ZXh0KG15RGV2aWNlLCBpZmFjZSwgQ1RYVVNBR0VfQkxJVCk7CgogICAgICAgIC8qIFNlbGVjdCB0aGUgY29ycmVjdCByZWFkIGJ1ZmZlciwgYW5kIGdpdmUgc29tZSBkZWJ1ZyBvdXRwdXQuCiAgICAgICAgICogVGhlcmUgaXMgbm8gbmVlZCB0byBrZWVwIHRyYWNrIG9mIHRoZSBjdXJyZW50IHJlYWQgYnVmZmVyIG9yIHJlc2V0IGl0LCBldmVyeSBwYXJ0IG9mIHRoZSBjb2RlCiAgICAgICAgICogdGhhdCByZWFkcyBzZXRzIHRoZSByZWFkIGJ1ZmZlciBhcyBkZXNpcmVkLgogICAgICAgICAqLwogICAgICAgIGlmKCFzd2FwY2hhaW4pIHsKICAgICAgICAgICAgLyogTG9ja2luZyB0aGUgcHJpbWFyeSByZW5kZXIgdGFyZ2V0IHdoaWNoIGlzIG5vdCBvbiBhIHN3YXBjaGFpbig9b2Zmc2NyZWVuIHJlbmRlciB0YXJnZXQpLgogICAgICAgICAgICAgKiBSZWFkIGZyb20gdGhlIGJhY2sgYnVmZmVyCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBUUkFDRSgiTG9ja2luZyBvZmZzY3JlZW4gcmVuZGVyIHRhcmdldFxuIik7CiAgICAgICAgICAgIGdsUmVhZEJ1ZmZlcihteURldmljZS0+b2Zmc2NyZWVuQnVmZmVyKTsKICAgICAgICAgICAgc3JjSXNVcHNpZGVEb3duID0gVFJVRTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBHTGVudW0gYnVmZmVyID0gc3VyZmFjZV9nZXRfZ2xfYnVmZmVyKGlmYWNlLCAoSVdpbmVEM0RTd2FwQ2hhaW4gKilzd2FwY2hhaW4pOwogICAgICAgICAgICBUUkFDRSgiTG9ja2luZyAlI3ggYnVmZmVyXG4iLCBidWZmZXIpOwogICAgICAgICAgICBnbFJlYWRCdWZmZXIoYnVmZmVyKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsUmVhZEJ1ZmZlciIpOwoKICAgICAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZSgoSVdpbmVEM0RTd2FwQ2hhaW4gKikgc3dhcGNoYWluKTsKICAgICAgICAgICAgc3JjSXNVcHNpZGVEb3duID0gRkFMU0U7CiAgICAgICAgfQoKICAgICAgICBzd2l0Y2god2luZWQzZF9zZXR0aW5ncy5yZW5kZXJ0YXJnZXRsb2NrX21vZGUpIHsKICAgICAgICAgICAgY2FzZSBSVExfQVVUTzoKICAgICAgICAgICAgY2FzZSBSVExfUkVBRERSQVc6CiAgICAgICAgICAgIGNhc2UgUlRMX1JFQURURVg6CiAgICAgICAgICAgICAgICByZWFkX2Zyb21fZnJhbWVidWZmZXIoVGhpcywgJlRoaXMtPmxvY2tlZFJlY3QsIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSwgcExvY2tlZFJlY3QtPlBpdGNoLCBzcmNJc1Vwc2lkZURvd24pOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIFJUTF9URVhEUkFXOgogICAgICAgICAgICBjYXNlIFJUTF9URVhURVg6CiAgICAgICAgICAgICAgICByZWFkX2Zyb21fZnJhbWVidWZmZXIoVGhpcywgJlRoaXMtPmxvY2tlZFJlY3QsIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSwgcExvY2tlZFJlY3QtPlBpdGNoLCBzcmNJc1Vwc2lkZURvd24pOwogICAgICAgICAgICAgICAgRklYTUUoIlJlYWRpbmcgZnJvbSByZW5kZXIgdGFyZ2V0IHdpdGggYSB0ZXh0dXJlIGlzbid0IGltcGxlbWVudGVkIHlldCwgZmFsbGluZyBiYWNrIHRvIGZyYW1lYnVmZmVyIHJlYWRpbmdcbiIpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIExFQVZFX0dMKCk7CgogICAgICAgIC8qIE1hcmsgdGhlIGxvY2FsIGNvcHkgdXAgdG8gZGF0ZSBpZiBhIGZ1bGwgZG93bmxvYWQgd2FzIGRvbmUgKi8KICAgICAgICBpZihUaGlzLT5sb2NrZWRSZWN0LmxlZnQgPT0gMCAmJgogICAgICAgICAgIFRoaXMtPmxvY2tlZFJlY3QudG9wID09IDAgJiYKICAgICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LnJpZ2h0ID09IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoICYmCiAgICAgICAgICAgVGhpcy0+bG9ja2VkUmVjdC5ib3R0b20gPT0gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0KSB7CiAgICAgICAgICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX0lOU1lTTUVNOwogICAgICAgIH0KICAgIH0gZWxzZSBpZihpZmFjZSA9PSBteURldmljZS0+c3RlbmNpbEJ1ZmZlclRhcmdldCkgewogICAgICAgIC8qKiB0aGUgZGVwdGggc3RlbmNpbCBpbiBvcGVuR0wgaGFzIGEgZm9ybWF0IG9mIEdMX0ZMT0FUCiAgICAgICAgICogd2hpY2ggc2hvdWxkIGJlIGdvb2QgZm9yIFdJTkVEM0RGTVRfRDE2X0xPQ0tBQkxFCiAgICAgICAgICogYW5kIFdJTkVEM0RGTVRfRDE2CiAgICAgICAgICogaXQgaXMgdW5jbGVhciB3aGF0IGZvcm1hdCB0aGUgc3RlbmNpbCBidWZmZXIgaXMgaW4gZXhjZXB0LgogICAgICAgICAqICdFYWNoIGluZGV4IGlzIGNvbnZlcnRlZCB0byBmaXhlZCBwb2ludC4uLgogICAgICAgICAqIElmIEdMX01BUF9TVEVOQ0lMIGlzIEdMX1RSVUUsIGluZGljZXMgYXJlIHJlcGxhY2VkIGJ5IHRoZWlyCiAgICAgICAgICogbWFwcGluZ3MgaW4gdGhlIHRhYmxlIEdMX1BJWEVMX01BUF9TX1RPX1MuCiAgICAgICAgICogZ2xSZWFkUGl4ZWxzKFRoaXMtPmxvY2tlZFJlY3QubGVmdCwKICAgICAgICAgKiAgICAgICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LmJvdHRvbSAtIGogLSAxLAogICAgICAgICAqICAgICAgICAgICAgIFRoaXMtPmxvY2tlZFJlY3QucmlnaHQgLSBUaGlzLT5sb2NrZWRSZWN0LmxlZnQsCiAgICAgICAgICogICAgICAgICAgICAgMSwKICAgICAgICAgKiAgICAgICAgICAgICBHTF9ERVBUSF9DT01QT05FTlQsCiAgICAgICAgICogICAgICAgICAgICAgdHlwZSwKICAgICAgICAgKiAgICAgICAgICAgICAoY2hhciAqKXBMb2NrZWRSZWN0LT5wQml0cyArIChwTG9ja2VkUmVjdC0+UGl0Y2ggKiAoai1UaGlzLT5sb2NrZWRSZWN0LnRvcCkpKTsKICAgICAgICAgKgogICAgICAgICAqIERlcHRoIFN0ZW5jaWwgc3VyZmFjZXMgd2hpY2ggYXJlIG5vdCB0aGUgY3VycmVudCBkZXB0aCBzdGVuY2lsIHRhcmdldCBzaG91bGQgaGF2ZSB0aGVpciBkYXRhIGluIGEKICAgICAgICAgKiBnbCB0ZXh0dXJlKG5leHQgcGF0aCksIG9yIGluIGxvY2FsIG1lbW9yeShlYXJseSByZXR1cm4gYmVjYXVzZSBvZiBzZXQgU0ZMQUdfSU5TWVNNRU0gYWJvdmUpLiBJZgogICAgICAgICAqIG5vbmUgb2YgdGhhdCBpcyB0aGUgY2FzZSB0aGUgcHJvYmxlbSBpcyBub3QgaW4gdGhpcyBmdW5jdGlvbiA6LSkKICAgICAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCiAgICAgICAgRklYTUUoIkRlcHRoIHN0ZW5jaWwgbG9ja2luZyBub3Qgc3VwcG9ydGVkIHlldFxuIik7CiAgICB9IGVsc2UgewogICAgICAgIC8qIFRoaXMgcGF0aCBpcyBmb3Igbm9ybWFsIHN1cmZhY2VzLCBvZmZzY3JlZW4gcmVuZGVyIHRhcmdldHMgYW5kIGV2ZXJ5dGhpbmcgZWxzZSB0aGF0IGlzIGluIGEgZ2wgdGV4dHVyZSAqLwogICAgICAgIFRSQUNFKCJsb2NraW5nIGFuIG9yZGluYXJhcnkgc3VyZmFjZVxuIik7CgogICAgICAgIGlmICgwICE9IFRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpIHsKICAgICAgICAgICAgLyogTm93IEkgaGF2ZSB0byBjb3B5IHRoaW5nIGJpdHMgYmFjayAqLwoKICAgICAgICAgICAgRU5URVJfR0woKTsKCiAgICAgICAgICAgIGlmKG15RGV2aWNlLT5jcmVhdGVQYXJtcy5CZWhhdmlvckZsYWdzICYgV0lORUQzRENSRUFURV9NVUxUSVRIUkVBREVEKSB7CiAgICAgICAgICAgICAgICBBY3RpdmF0ZUNvbnRleHQobXlEZXZpY2UsIG15RGV2aWNlLT5sYXN0QWN0aXZlUmVuZGVyVGFyZ2V0LCBDVFhVU0FHRV9SRVNPVVJDRUxPQUQpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKiBNYWtlIHN1cmUgdGhhdCBhIHByb3BlciB0ZXh0dXJlIHVuaXQgaXMgc2VsZWN0ZWQsIGJpbmQgdGhlIHRleHR1cmUgYW5kIGRpcnRpZnkgdGhlIHNhbXBsZXIgdG8gcmVzdG9yZSB0aGUgdGV4dHVyZSBvbiB0aGUgbmV4dCBkcmF3ICovCiAgICAgICAgICAgIGlmIChHTF9TVVBQT1JUKEFSQl9NVUxUSVRFWFRVUkUpKSB7CiAgICAgICAgICAgICAgICBHTF9FWFRDQUxMKGdsQWN0aXZlVGV4dHVyZUFSQihHTF9URVhUVVJFMF9BUkIpKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEFjdGl2ZVRleHR1cmVBUkIiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZSwgU1RBVEVfU0FNUExFUigwKSk7CiAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9QcmVMb2FkKGlmYWNlKTsKCiAgICAgICAgICAgIHN1cmZhY2VfZG93bmxvYWRfZGF0YShUaGlzKTsKICAgICAgICAgICAgTEVBVkVfR0woKTsKICAgICAgICB9CgogICAgICAgIC8qIFRoZSBsb2NhbCBjb3B5IGlzIG5vdyB1cCB0byBkYXRlIHRvIHRoZSBvcGVuZ2wgb25lIGJlY2F1c2UgYSBmdWxsIGRvd25sb2FkIHdhcyBkb25lICovCiAgICAgICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfSU5TWVNNRU07CiAgICB9Cgpsb2NrX2VuZDoKICAgIGlmIChGbGFncyAmIChXSU5FRDNETE9DS19OT19ESVJUWV9VUERBVEUgfCBXSU5FRDNETE9DS19SRUFET05MWSkpIHsKICAgICAgICAvKiBEb24ndCBkaXJ0aWZ5ICovCiAgICB9IGVsc2UgewogICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmUgKnBCYXNlVGV4dHVyZTsKICAgICAgICAvKioKICAgICAgICAgKiBEaXJ0aWZ5IG9uIGxvY2sKICAgICAgICAgKiBhcyBzZWVuIGluIG1zZG4gZG9jcwogICAgICAgICAqLwogICAgICAgIElXaW5lRDNEU3VyZmFjZV9BZGREaXJ0eVJlY3QoaWZhY2UsICZUaGlzLT5sb2NrZWRSZWN0KTsKCiAgICAgICAgLyoqIERpcnRpZnkgQ29udGFpbmVyIGlmIG5lZWRlZCAqLwogICAgICAgIGlmIChXSU5FRDNEX09LID09IElXaW5lRDNEU3VyZmFjZV9HZXRDb250YWluZXIoaWZhY2UsICZJSURfSVdpbmVEM0RCYXNlVGV4dHVyZSwgKHZvaWQgKiopJnBCYXNlVGV4dHVyZSkgJiYgcEJhc2VUZXh0dXJlICE9IE5VTEwpIHsKICAgICAgICAgICAgVFJBQ0UoIk1ha2luZyBjb250YWluZXIgZGlydHlcbiIpOwogICAgICAgICAgICBJV2luZUQzREJhc2VUZXh0dXJlX1NldERpcnR5KHBCYXNlVGV4dHVyZSwgVFJVRSk7CiAgICAgICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVfUmVsZWFzZShwQmFzZVRleHR1cmUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIFRSQUNFKCJTdXJmYWNlIGlzIHN0YW5kYWxvbmUsIG5vIG5lZWQgdG8gZGlydHkgdGhlIGNvbnRhaW5lclxuIik7CiAgICAgICAgfQogICAgfQoKICAgIFRSQUNFKCJyZXR1cm5pbmcgbWVtb3J5QCVwLCBwaXRjaCglZCkgZGlydHlmaWVkKCVkKVxuIiwgcExvY2tlZFJlY3QtPnBCaXRzLCBwTG9ja2VkUmVjdC0+UGl0Y2gsCiAgICAgICAgICBUaGlzLT5GbGFncyAmIChTRkxBR19JTkRSQVdBQkxFIHwgU0ZMQUdfSU5URVhUVVJFKSA/IDAgOiAxKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgdm9pZCBmbHVzaF90b19mcmFtZWJ1ZmZlcl9kcmF3cGl4ZWxzKElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMpIHsKICAgIEdMaW50ICBwcmV2X3N0b3JlOwogICAgR0xpbnQgIHByZXZfcmFzdGVycG9zWzRdOwogICAgR0xpbnQgc2tpcEJ5dGVzID0gMDsKICAgIEJPT0wgc3RvcmVjaGFuZ2VkID0gRkFMU0UsIG1lbW9yeV9hbGxvY2F0ZWQgPSBGQUxTRTsKICAgIEdMaW50IGZtdCwgdHlwZTsKICAgIEJZVEUgKm1lbTsKICAgIFVJTlQgYnBwOwogICAgVUlOVCBwaXRjaCA9IElXaW5lRDNEU3VyZmFjZV9HZXRQaXRjaCgoSVdpbmVEM0RTdXJmYWNlICopIFRoaXMpOyAgICAvKiB0YXJnZXQgaXMgYXJnYiwgNCBieXRlICovCgogICAgZ2xEaXNhYmxlKEdMX1RFWFRVUkVfMkQpOwogICAgdmNoZWNrR0xjYWxsKCJnbERpc2FibGUoR0xfVEVYVFVSRV8yRCkiKTsKCiAgICBnbEZsdXNoKCk7CiAgICB2Y2hlY2tHTGNhbGwoImdsRmx1c2giKTsKICAgIGdsR2V0SW50ZWdlcnYoR0xfUEFDS19TV0FQX0JZVEVTLCAmcHJldl9zdG9yZSk7CiAgICB2Y2hlY2tHTGNhbGwoImdsSW50ZWdlcnYiKTsKICAgIGdsR2V0SW50ZWdlcnYoR0xfQ1VSUkVOVF9SQVNURVJfUE9TSVRJT04sICZwcmV2X3Jhc3RlcnBvc1swXSk7CiAgICB2Y2hlY2tHTGNhbGwoImdsSW50ZWdlcnYiKTsKICAgIGdsUGl4ZWxab29tKDEuMCwgLTEuMCk7CiAgICB2Y2hlY2tHTGNhbGwoImdsUGl4ZWxab29tIik7CgogICAgLyogSWYgbm90IGZ1bGxzY3JlZW4sIHdlIG5lZWQgdG8gc2tpcCBhIG51bWJlciBvZiBieXRlcyB0byBmaW5kIHRoZSBuZXh0IHJvdyBvZiBkYXRhICovCiAgICBnbEdldEludGVnZXJ2KEdMX1VOUEFDS19ST1dfTEVOR1RILCAmc2tpcEJ5dGVzKTsKICAgIGdsUGl4ZWxTdG9yZWkoR0xfVU5QQUNLX1JPV19MRU5HVEgsIFRoaXMtPmN1cnJlbnREZXNjLldpZHRoKTsKCiAgICBnbFJhc3RlclBvczNpKFRoaXMtPmxvY2tlZFJlY3QubGVmdCwgVGhpcy0+bG9ja2VkUmVjdC50b3AsIDEpOwogICAgdmNoZWNrR0xjYWxsKCJnbFJhc3RlclBvczJmIik7CgogICAgLyogU29tZSBkcml2ZXJzKHJhZGVvbiBkcmksIG90aGVycz8pIGRvbid0IGxpa2UgZXhjZXB0aW9ucyBkdXJpbmcKICAgICAqIGdsRHJhd1BpeGVscy4gSWYgdGhlIHN1cmZhY2UgaXMgYSBESUIgc2VjdGlvbiwgaXQgbWlnaHQgYmUgaW4gR0RJTW9kZQogICAgICogYWZ0ZXIgUmVsZWFzZURDLiBSZWFkaW5nIGl0IHdpbGwgY2F1c2UgYW4gZXhjZXB0aW9uLCB3aGljaCB4MTFkcnYgd2lsbAogICAgICogY2F0Y2ggdG8gcHV0IHRoZSBkaWIgc2VjdGlvbiBpbiBJblN5bmMgbW9kZSwgd2hpY2ggbGVhZHMgdG8gYSBjcmFzaAogICAgICogYW5kIGEgYmxvY2tlZCB4IHNlcnZlciBvbiBteSByYWRlb24gY2FyZC4KICAgICAqCiAgICAgKiBUaGUgZm9sbG93aW5nIGxpbmVzIHJlYWQgdGhlIGRpYiBzZWN0aW9uIHNvIGl0IGlzIHB1dCBpbiBpblN5bmMgbW9kZQogICAgICogYmVmb3JlIGdsRHJhd1BpeGVscyBpcyBjYWxsZWQgYW5kIHRoZSBjcmFzaCBpcyBwcmV2ZW50ZWQuIFRoZXJlIHdvbid0CiAgICAgKiBiZSBhbnkgaW50ZXJmZXJpbmcgZ2RpIGFjY2Vzc2VzLCBiZWNhdXNlIFVubG9ja1JlY3QgaXMgY2FsbGVkIGZyb20KICAgICAqIFJlbGVhc2VEQywgYW5kIHRoZSBhcHAgd29uJ3QgdXNlIHRoZSBkYyBhbnkgbW9yZSBhZnRlcndhcmRzLgogICAgICovCiAgICBpZihUaGlzLT5GbGFncyAmIFNGTEFHX0RJQlNFQ1RJT04pIHsKICAgICAgICB2b2xhdGlsZSBCWVRFIHJlYWQ7CiAgICAgICAgcmVhZCA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeVswXTsKICAgIH0KCiAgICBzd2l0Y2ggKFRoaXMtPnJlc291cmNlLmZvcm1hdCkgewogICAgICAgIC8qIE5vIHNwZWNpYWwgY2FyZSBuZWVkZWQgKi8KICAgICAgICBjYXNlIFdJTkVEM0RGTVRfQTRSNEc0QjQ6CiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1I1RzZCNToKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfQTFSNUc1QjU6CiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1I4RzhCODoKICAgICAgICAgICAgdHlwZSA9IFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xUeXBlOwogICAgICAgICAgICBmbXQgPSBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0OwogICAgICAgICAgICBtZW0gPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnk7CiAgICAgICAgICAgIGJwcCA9IFRoaXMtPmJ5dGVzUGVyUGl4ZWw7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfWDRSNEc0QjQ6CiAgICAgICAgewogICAgICAgICAgICBpbnQgc2l6ZTsKICAgICAgICAgICAgdW5zaWduZWQgc2hvcnQgKmRhdGE7CiAgICAgICAgICAgIGRhdGEgPSAodW5zaWduZWQgc2hvcnQgKilUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnk7CiAgICAgICAgICAgIHNpemUgPSAoVGhpcy0+bG9ja2VkUmVjdC5ib3R0b20gLSBUaGlzLT5sb2NrZWRSZWN0LnRvcCkgKiAoVGhpcy0+bG9ja2VkUmVjdC5yaWdodCAtIFRoaXMtPmxvY2tlZFJlY3QubGVmdCk7CiAgICAgICAgICAgIHdoaWxlKHNpemUgPiAwKSB7CiAgICAgICAgICAgICAgICAqZGF0YSB8PSAweEYwMDA7CiAgICAgICAgICAgICAgICBkYXRhKys7CiAgICAgICAgICAgICAgICBzaXplLS07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdHlwZSA9IFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xUeXBlOwogICAgICAgICAgICBmbXQgPSBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0OwogICAgICAgICAgICBtZW0gPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnk7CiAgICAgICAgICAgIGJwcCA9IFRoaXMtPmJ5dGVzUGVyUGl4ZWw7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfWDFSNUc1QjU6CiAgICAgICAgewogICAgICAgICAgICBpbnQgc2l6ZTsKICAgICAgICAgICAgdW5zaWduZWQgc2hvcnQgKmRhdGE7CiAgICAgICAgICAgIGRhdGEgPSAodW5zaWduZWQgc2hvcnQgKilUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnk7CiAgICAgICAgICAgIHNpemUgPSAoVGhpcy0+bG9ja2VkUmVjdC5ib3R0b20gLSBUaGlzLT5sb2NrZWRSZWN0LnRvcCkgKiAoVGhpcy0+bG9ja2VkUmVjdC5yaWdodCAtIFRoaXMtPmxvY2tlZFJlY3QubGVmdCk7CiAgICAgICAgICAgIHdoaWxlKHNpemUgPiAwKSB7CiAgICAgICAgICAgICAgICAqZGF0YSB8PSAweDgwMDA7CiAgICAgICAgICAgICAgICBkYXRhKys7CiAgICAgICAgICAgICAgICBzaXplLS07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdHlwZSA9IFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xUeXBlOwogICAgICAgICAgICBmbXQgPSBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0OwogICAgICAgICAgICBtZW0gPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnk7CiAgICAgICAgICAgIGJwcCA9IFRoaXMtPmJ5dGVzUGVyUGl4ZWw7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfWDhSOEc4Qjg6CiAgICAgICAgewogICAgICAgICAgICAvKiBtYWtlIHN1cmUgdGhlIFggYnl0ZSBpcyBzZXQgdG8gYWxwaGEgb24sIHNpbmNlIGl0IAogICAgICAgICAgICAgICBjb3VsZCBiZSBhbnkgcmFuZG9tIHZhbHVlLiBUaGlzIGZpeGVzIHRoZSBpbnRybyBtb3ZpZSBpbiBQaXJhdGVzISAqLwogICAgICAgICAgICBpbnQgc2l6ZTsKICAgICAgICAgICAgdW5zaWduZWQgaW50ICpkYXRhOwogICAgICAgICAgICBkYXRhID0gKHVuc2lnbmVkIGludCAqKVRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeTsKICAgICAgICAgICAgc2l6ZSA9IChUaGlzLT5sb2NrZWRSZWN0LmJvdHRvbSAtIFRoaXMtPmxvY2tlZFJlY3QudG9wKSAqIChUaGlzLT5sb2NrZWRSZWN0LnJpZ2h0IC0gVGhpcy0+bG9ja2VkUmVjdC5sZWZ0KTsKICAgICAgICAgICAgd2hpbGUoc2l6ZSA+IDApIHsKICAgICAgICAgICAgICAgICpkYXRhIHw9IDB4RkYwMDAwMDA7CiAgICAgICAgICAgICAgICBkYXRhKys7CiAgICAgICAgICAgICAgICBzaXplLS07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLyogRmFsbCB0aHJvdWdoICovCgogICAgICAgIGNhc2UgV0lORUQzREZNVF9BOFI4RzhCODoKICAgICAgICB7CiAgICAgICAgICAgIGdsUGl4ZWxTdG9yZWkoR0xfUEFDS19TV0FQX0JZVEVTLCBUUlVFKTsKICAgICAgICAgICAgdmNoZWNrR0xjYWxsKCJnbFBpeGVsU3RvcmVpIik7CiAgICAgICAgICAgIHN0b3JlY2hhbmdlZCA9IFRSVUU7CiAgICAgICAgICAgIHR5cGUgPSBUaGlzLT5nbERlc2NyaXB0aW9uLmdsVHlwZTsKICAgICAgICAgICAgZm10ID0gVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdDsKICAgICAgICAgICAgbWVtID0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5OwogICAgICAgICAgICBicHAgPSBUaGlzLT5ieXRlc1BlclBpeGVsOwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBXSU5FRDNERk1UX0EyUjEwRzEwQjEwOgogICAgICAgIHsKICAgICAgICAgICAgZ2xQaXhlbFN0b3JlaShHTF9QQUNLX1NXQVBfQllURVMsIFRSVUUpOwogICAgICAgICAgICB2Y2hlY2tHTGNhbGwoImdsUGl4ZWxTdG9yZWkiKTsKICAgICAgICAgICAgc3RvcmVjaGFuZ2VkID0gVFJVRTsKICAgICAgICAgICAgdHlwZSA9IFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xUeXBlOwogICAgICAgICAgICBmbXQgPSBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0OwogICAgICAgICAgICBtZW0gPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnk7CiAgICAgICAgICAgIGJwcCA9IFRoaXMtPmJ5dGVzUGVyUGl4ZWw7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfUDg6CiAgICAgICAgewogICAgICAgICAgICBpbnQgaGVpZ2h0ID0gVGhpcy0+Z2xSZWN0LmJvdHRvbSAtIFRoaXMtPmdsUmVjdC50b3A7CiAgICAgICAgICAgIHR5cGUgPSBHTF9VTlNJR05FRF9CWVRFOwogICAgICAgICAgICBmbXQgPSBHTF9SR0JBOwoKICAgICAgICAgICAgbWVtID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnJlc291cmNlLnNpemUgKiBzaXplb2YoRFdPUkQpKTsKICAgICAgICAgICAgaWYoIW1lbSkgewogICAgICAgICAgICAgICAgRVJSKCJPdXQgb2YgbWVtb3J5XG4iKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgICAgICBtZW1vcnlfYWxsb2NhdGVkID0gVFJVRTsKICAgICAgICAgICAgZDNkZm10X2NvbnZlcnRfc3VyZmFjZShUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpdGNoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpdGNoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaXRjaCAqIDQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09OVkVSVF9QQUxFVFRFRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzKTsKICAgICAgICAgICAgYnBwID0gVGhpcy0+Ynl0ZXNQZXJQaXhlbCAqIDQ7CiAgICAgICAgICAgIHBpdGNoICo9IDQ7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBGSVhNRSgiVW5zdXBwb3J0ZWQgRm9ybWF0ICV1IGluIGxvY2tpbmcgZnVuY1xuIiwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0KTsKCiAgICAgICAgICAgIC8qIEdpdmUgaXQgYSB0cnkgKi8KICAgICAgICAgICAgdHlwZSA9IFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xUeXBlOwogICAgICAgICAgICBmbXQgPSBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0OwogICAgICAgICAgICBtZW0gPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnk7CiAgICAgICAgICAgIGJwcCA9IFRoaXMtPmJ5dGVzUGVyUGl4ZWw7CiAgICB9CgogICAgZ2xEcmF3UGl4ZWxzKFRoaXMtPmxvY2tlZFJlY3QucmlnaHQgLSBUaGlzLT5sb2NrZWRSZWN0LmxlZnQsCiAgICAgICAgICAgICAgICAgKFRoaXMtPmxvY2tlZFJlY3QuYm90dG9tIC0gVGhpcy0+bG9ja2VkUmVjdC50b3ApLTEsCiAgICAgICAgICAgICAgICAgZm10LCB0eXBlLAogICAgICAgICAgICAgICAgIG1lbSArIGJwcCAqIFRoaXMtPmxvY2tlZFJlY3QubGVmdCArIHBpdGNoICogVGhpcy0+bG9ja2VkUmVjdC50b3ApOwogICAgY2hlY2tHTGNhbGwoImdsRHJhd1BpeGVscyIpOwogICAgZ2xQaXhlbFpvb20oMS4wLDEuMCk7CiAgICB2Y2hlY2tHTGNhbGwoImdsUGl4ZWxab29tIik7CgogICAgZ2xSYXN0ZXJQb3MzaXYoJnByZXZfcmFzdGVycG9zWzBdKTsKICAgIHZjaGVja0dMY2FsbCgiZ2xSYXN0ZXJQb3MzaXYiKTsKCiAgICAvKiBSZXNldCB0byBwcmV2aW91cyBwYWNrIHJvdyBsZW5ndGggKi8KICAgIGdsUGl4ZWxTdG9yZWkoR0xfVU5QQUNLX1JPV19MRU5HVEgsIHNraXBCeXRlcyk7CiAgICB2Y2hlY2tHTGNhbGwoImdsUGl4ZWxTdG9yZWkgR0xfVU5QQUNLX1JPV19MRU5HVEgiKTsKICAgIGlmKHN0b3JlY2hhbmdlZCkgewogICAgICAgIGdsUGl4ZWxTdG9yZWkoR0xfUEFDS19TV0FQX0JZVEVTLCBwcmV2X3N0b3JlKTsKICAgICAgICB2Y2hlY2tHTGNhbGwoImdsUGl4ZWxTdG9yZWkgR0xfUEFDS19TV0FQX0JZVEVTIik7CiAgICB9CgogICAgLyogQmxpdHRpbmcgZW52aXJvbm1lbnQgcmVxdWlyZXMgdGhhdCAyRCB0ZXh0dXJpbmcgaXMgZW5hYmxlZC4gSXQgd2FzIHR1cm5lZCBvZmYgYmVmb3JlLAogICAgICogdHVybiBpdCBvbiBhZ2FpbgogICAgICovCiAgICBnbEVuYWJsZShHTF9URVhUVVJFXzJEKTsKICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZShHTF9URVhUVVJFXzJEKSIpOwoKICAgIGlmKG1lbW9yeV9hbGxvY2F0ZWQpIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG1lbSk7CiAgICByZXR1cm47Cn0KCnN0YXRpYyB2b2lkIGZsdXNoX3RvX2ZyYW1lYnVmZmVyX3RleHR1cmUoSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcykgewogICAgZmxvYXQgZ2xUZXhDb29yZFs0XTsKCiAgICBnbFRleENvb3JkWzBdID0gKGZsb2F0KSBUaGlzLT5sb2NrZWRSZWN0LmxlZnQgICAvIChmbG9hdCkgVGhpcy0+cG93MldpZHRoOyAvKiBsZWZ0ICovCiAgICBnbFRleENvb3JkWzFdID0gKGZsb2F0KSBUaGlzLT5sb2NrZWRSZWN0LnJpZ2h0ICAvIChmbG9hdCkgVGhpcy0+cG93MldpZHRoOyAvKiByaWdodCAqLwogICAgZ2xUZXhDb29yZFsyXSA9IChmbG9hdCkgVGhpcy0+bG9ja2VkUmVjdC50b3AgICAgLyAoZmxvYXQpIFRoaXMtPnBvdzJIZWlnaHQ7IC8qIHRvcCAqLwogICAgZ2xUZXhDb29yZFszXSA9IChmbG9hdCkgVGhpcy0+bG9ja2VkUmVjdC5ib3R0b20gLyAoZmxvYXQpIFRoaXMtPnBvdzJIZWlnaHQ7IC8qIGJvdHRvbSAqLwoKICAgIElXaW5lRDNEU3VyZmFjZV9QcmVMb2FkKChJV2luZUQzRFN1cmZhY2UgKikgVGhpcyk7CgogICAgRU5URVJfR0woKTsKCiAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIFRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpOwogICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlIGdsQmluZFRleHR1cmUiKTsKCiAgICAvKiBObyBmaWx0ZXJpbmcgZm9yIGJsdHMgKi8KICAgIGdsVGV4UGFyYW1ldGVyaShHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX01BR19GSUxURVIsIEdMX05FQVJFU1QpOwogICAgY2hlY2tHTGNhbGwoImdsVGV4UGFyYW1ldGVyaSIpOwogICAgZ2xUZXhQYXJhbWV0ZXJpKEdMX1RFWFRVUkVfMkQsIEdMX1RFWFRVUkVfTUlOX0ZJTFRFUiwgR0xfTkVBUkVTVCk7CiAgICBjaGVja0dMY2FsbCgiZ2xUZXhQYXJhbWV0ZXJpIik7CgogICAgLyogU3RhcnQgZHJhd2luZyBhIHF1YWQgKi8KICAgIGdsQmVnaW4oR0xfUVVBRFMpOwoKICAgIGdsQ29sb3IzZCgxLjBmLCAxLjBmLCAxLjBmKTsKICAgIGdsVGV4Q29vcmQyZihnbFRleENvb3JkWzBdLCBnbFRleENvb3JkWzJdKTsKICAgIGdsVmVydGV4M2YoVGhpcy0+bG9ja2VkUmVjdC5sZWZ0LCBUaGlzLT5sb2NrZWRSZWN0LnRvcCwgMC4wKTsKCiAgICBnbFRleENvb3JkMmYoZ2xUZXhDb29yZFswXSwgZ2xUZXhDb29yZFszXSk7CiAgICBnbFZlcnRleDNmKFRoaXMtPmxvY2tlZFJlY3QubGVmdCwgVGhpcy0+bG9ja2VkUmVjdC5ib3R0b20sIDAuMCk7CgogICAgZ2xUZXhDb29yZDJmKGdsVGV4Q29vcmRbMV0sIGdsVGV4Q29vcmRbM10pOwogICAgZ2xWZXJ0ZXgzZChUaGlzLT5sb2NrZWRSZWN0LnJpZ2h0LCBUaGlzLT5sb2NrZWRSZWN0LmJvdHRvbSwgMC4wKTsKCiAgICBnbFRleENvb3JkMmYoZ2xUZXhDb29yZFsxXSwgZ2xUZXhDb29yZFsyXSk7CiAgICBnbFZlcnRleDNmKFRoaXMtPmxvY2tlZFJlY3QucmlnaHQsIFRoaXMtPmxvY2tlZFJlY3QudG9wLCAwLjApOwoKICAgIGdsRW5kKCk7CiAgICBjaGVja0dMY2FsbCgiZ2xFbmQiKTsKCiAgICAvKiBVbmJpbmQgdGhlIHRleHR1cmUgKi8KICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgMCk7CiAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUgZ2xCaW5kVGV4dHVyZSIpOwoKICAgIExFQVZFX0dMKCk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1VubG9ja1JlY3QoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRERldmljZUltcGwgICpteURldmljZSA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CiAgICBJV2luZUQzRFN3YXBDaGFpbkltcGwgKnN3YXBjaGFpbiA9IE5VTEw7CgogICAgaWYgKCEoVGhpcy0+RmxhZ3MgJiBTRkxBR19MT0NLRUQpKSB7CiAgICAgICAgV0FSTigidHJ5aW5nIHRvIFVubG9jayBhbiB1bmxvY2tlZCBzdXJmQCVwXG4iLCBUaGlzKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBUUkFDRSgiKCVwKSA6IGRpcnR5ZmllZCglZClcbiIsIFRoaXMsIFRoaXMtPkZsYWdzICYgKFNGTEFHX0lORFJBV0FCTEUgfCBTRkxBR19JTlRFWFRVUkUpID8gMCA6IDEpOwoKICAgIGlmIChUaGlzLT5GbGFncyAmIChTRkxBR19JTkRSQVdBQkxFIHwgU0ZMQUdfSU5URVhUVVJFKSkgewogICAgICAgIFRSQUNFKCIoJXApIDogTm90IERpcnRpZmllZCBzbyBub3RoaW5nIHRvIGRvLCByZXR1cm4gbm93XG4iLCBUaGlzKTsKICAgICAgICBnb3RvIHVubG9ja19lbmQ7CiAgICB9CgogICAgSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lcihpZmFjZSwgJklJRF9JV2luZUQzRFN3YXBDaGFpbiwgKHZvaWQgKiopJnN3YXBjaGFpbik7CiAgICBpZihzd2FwY2hhaW4gfHwgaWZhY2UgPT0gbXlEZXZpY2UtPnJlbmRlcl90YXJnZXRzWzBdKSB7CiAgICAgICAgaWYod2luZWQzZF9zZXR0aW5ncy5yZW5kZXJ0YXJnZXRsb2NrX21vZGUgPT0gUlRMX0RJU0FCTEUpIHsKICAgICAgICAgICAgc3RhdGljIEJPT0wgd2FybmVkID0gRkFMU0U7CiAgICAgICAgICAgIGlmKCF3YXJuZWQpIHsKICAgICAgICAgICAgICAgIEVSUigiVGhlIGFwcGxpY2F0aW9uIHRyaWVzIHRvIHdyaXRlIHRvIHRoZSByZW5kZXIgdGFyZ2V0LCBidXQgcmVuZGVyIHRhcmdldCBsb2NraW5nIGlzIGRpc2FibGVkXG4iKTsKICAgICAgICAgICAgICAgIHdhcm5lZCA9IFRSVUU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYoc3dhcGNoYWluKSBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKChJV2luZUQzRFN3YXBDaGFpbiAqKSBzd2FwY2hhaW4pOwogICAgICAgICAgICBnb3RvIHVubG9ja19lbmQ7CiAgICAgICAgfQoKICAgICAgICAvKiBBY3RpdmF0ZSB0aGUgY29ycmVjdCBjb250ZXh0IGZvciB0aGUgcmVuZGVyIHRhcmdldCAqLwogICAgICAgIEVOVEVSX0dMKCk7CiAgICAgICAgQWN0aXZhdGVDb250ZXh0KG15RGV2aWNlLCBpZmFjZSwgQ1RYVVNBR0VfQkxJVCk7CgogICAgICAgIGlmKCFzd2FwY2hhaW4pIHsKICAgICAgICAgICAgLyogUHJpbWFyeSBvZmZzY3JlZW4gcmVuZGVyIHRhcmdldCAqLwogICAgICAgICAgICBUUkFDRSgiT2Zmc2NyZWVuIHJlbmRlciB0YXJnZXRcbiIpOwogICAgICAgICAgICBnbERyYXdCdWZmZXIobXlEZXZpY2UtPm9mZnNjcmVlbkJ1ZmZlcik7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERyYXdCdWZmZXIobXlEZXZpY2UtPm9mZnNjcmVlbkJ1ZmZlcikiKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBHTGVudW0gYnVmZmVyID0gc3VyZmFjZV9nZXRfZ2xfYnVmZmVyKGlmYWNlLCAoSVdpbmVEM0RTd2FwQ2hhaW4gKilzd2FwY2hhaW4pOwogICAgICAgICAgICBUUkFDRSgiVW5sb2NraW5nICUjeCBidWZmZXJcbiIsIGJ1ZmZlcik7CiAgICAgICAgICAgIGdsRHJhd0J1ZmZlcihidWZmZXIpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEcmF3QnVmZmVyIik7CgogICAgICAgICAgICBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKChJV2luZUQzRFN3YXBDaGFpbiAqKXN3YXBjaGFpbik7CiAgICAgICAgfQoKICAgICAgICBzd2l0Y2god2luZWQzZF9zZXR0aW5ncy5yZW5kZXJ0YXJnZXRsb2NrX21vZGUpIHsKICAgICAgICAgICAgY2FzZSBSVExfQVVUTzoKICAgICAgICAgICAgY2FzZSBSVExfUkVBRERSQVc6CiAgICAgICAgICAgIGNhc2UgUlRMX1RFWERSQVc6CiAgICAgICAgICAgICAgICBmbHVzaF90b19mcmFtZWJ1ZmZlcl9kcmF3cGl4ZWxzKFRoaXMpOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIFJUTF9SRUFEVEVYOgogICAgICAgICAgICBjYXNlIFJUTF9URVhURVg6CiAgICAgICAgICAgICAgICBmbHVzaF90b19mcmFtZWJ1ZmZlcl90ZXh0dXJlKFRoaXMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGlmKCFzd2FwY2hhaW4pIHsKICAgICAgICAgICAgZ2xEcmF3QnVmZmVyKG15RGV2aWNlLT5vZmZzY3JlZW5CdWZmZXIpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEcmF3QnVmZmVyKG15RGV2aWNlLT5vZmZzY3JlZW5CdWZmZXIpIik7CiAgICAgICAgfSBlbHNlIGlmKHN3YXBjaGFpbi0+YmFja0J1ZmZlcikgewogICAgICAgICAgICBnbERyYXdCdWZmZXIoR0xfQkFDSyk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERyYXdCdWZmZXIoR0xfQkFDSykiKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBnbERyYXdCdWZmZXIoR0xfRlJPTlQpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEcmF3QnVmZmVyKEdMX0ZST05UKSIpOwogICAgICAgIH0KICAgICAgICBMRUFWRV9HTCgpOwoKICAgICAgICBUaGlzLT5kaXJ0eVJlY3QubGVmdCAgID0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAgICAgVGhpcy0+ZGlydHlSZWN0LnRvcCAgICA9IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgICAgICBUaGlzLT5kaXJ0eVJlY3QucmlnaHQgID0gMDsKICAgICAgICBUaGlzLT5kaXJ0eVJlY3QuYm90dG9tID0gMDsKICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19JTkRSQVdBQkxFOwogICAgfSBlbHNlIGlmKGlmYWNlID09IG15RGV2aWNlLT5zdGVuY2lsQnVmZmVyVGFyZ2V0KSB7CiAgICAgICAgRklYTUUoIkRlcHRoIFN0ZW5jaWwgYnVmZmVyIGxvY2tpbmcgaXMgbm90IGltcGxlbWVudGVkXG4iKTsKICAgIH0gZWxzZSB7CiAgICAgICAgLyogVGhlIHJlc3Qgc2hvdWxkIGJlIGEgbm9ybWFsIHRleHR1cmUgKi8KICAgICAgICBJV2luZUQzREJhc2VUZXh0dXJlSW1wbCAqaW1wbDsKICAgICAgICAvKiBDaGVjayBpZiB0aGUgdGV4dHVyZSBpcyBib3VuZCwgaWYgeWVzIGRpcnRpZnkgdGhlIHNhbXBsZXIgdG8gZm9yY2UgYSByZS11cGxvYWQgb2YgdGhlIHRleHR1cmUKICAgICAgICAgKiBDYW4ndCBsb2FkIHRoZSB0ZXh0dXJlIGhlcmUgYmVjYXVzZSBQcmVMb2FkIG1heSBkZXN0cm95IGFuZCByZWNyZWF0ZSB0aGUgZ2wgdGV4dHVyZSwgc28gc2FtcGxlcgogICAgICAgICAqIHN0YXRlcyBuZWVkIHJlc2V0dGluZwogICAgICAgICAqLwogICAgICAgIGlmKElXaW5lRDNEU3VyZmFjZV9HZXRDb250YWluZXIoaWZhY2UsICZJSURfSVdpbmVEM0RCYXNlVGV4dHVyZSwgKHZvaWQgKiopJmltcGwpID09IFdJTkVEM0RfT0spIHsKICAgICAgICAgICAgaWYoaW1wbC0+YmFzZVRleHR1cmUuYmluZENvdW50KSB7CiAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkobXlEZXZpY2UsIFNUQVRFX1NBTVBMRVIoaW1wbC0+YmFzZVRleHR1cmUuc2FtcGxlcikpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVfUmVsZWFzZSgoSVdpbmVEM0RCYXNlVGV4dHVyZSAqKSBpbXBsKTsKICAgICAgICB9CiAgICB9CgogICAgdW5sb2NrX2VuZDoKICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19MT0NLRUQ7CiAgICBtZW1zZXQoJlRoaXMtPmxvY2tlZFJlY3QsIDAsIHNpemVvZihSRUNUKSk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXREQyhJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBIREMgKnBIREMpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgV0lORUQzRExPQ0tFRF9SRUNUIGxvY2s7CiAgICBVSU5UIHVzYWdlOwogICAgQklUTUFQSU5GTyogYl9pbmZvOwogICAgSERDIGRkYzsKICAgIERXT1JEICptYXNrczsKICAgIEhSRVNVTFQgaHI7CiAgICBSR0JRVUFEIGNvbFsyNTZdOwogICAgY29uc3QgUGl4ZWxGb3JtYXREZXNjICpmb3JtYXRFbnRyeSA9IGdldEZvcm1hdERlc2NFbnRyeShUaGlzLT5yZXNvdXJjZS5mb3JtYXQpOwoKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLFRoaXMscEhEQyk7CgogICAgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19VU0VSUFRSKSB7CiAgICAgICAgRVJSKCJOb3Qgc3VwcG9ydGVkIG9uIHN1cmZhY2VzIHdpdGggYW4gYXBwbGljYXRpb24tcHJvdmlkZWQgc3VyZmFjZXNcbiIpOwogICAgICAgIHJldHVybiBXSU5FRERFUlJfTk9EQzsKICAgIH0KCiAgICAvKiBHaXZlIG1vcmUgZGV0YWlsZWQgaW5mbyBmb3IgZGRyYXcgKi8KICAgIGlmIChUaGlzLT5GbGFncyAmIFNGTEFHX0RDSU5VU0UpCiAgICAgICAgcmV0dXJuIFdJTkVEREVSUl9EQ0FMUkVBRFlDUkVBVEVEOwoKICAgIC8qIENhbid0IEdldERDIGlmIHRoZSBzdXJmYWNlIGlzIGxvY2tlZCAqLwogICAgaWYgKFRoaXMtPkZsYWdzICYgU0ZMQUdfTE9DS0VEKQogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwoKICAgIG1lbXNldCgmbG9jaywgMCwgc2l6ZW9mKGxvY2spKTsgLyogVG8gYmUgc3VyZSAqLwoKICAgIC8qIENyZWF0ZSBhIERJQiBzZWN0aW9uIGlmIHRoZXJlIGlzbid0IGEgaGRjIHlldCAqLwogICAgaWYoIVRoaXMtPmhEQykgewogICAgICAgIGludCBleHRyYWxpbmUgPSAwOwogICAgICAgIFNZU1RFTV9JTkZPIHN5c0luZm87CiAgICAgICAgdm9pZCAqb2xkbWVtID0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5OwoKICAgICAgICBzd2l0Y2ggKFRoaXMtPmJ5dGVzUGVyUGl4ZWwpIHsKICAgICAgICAgICAgY2FzZSAyOgogICAgICAgICAgICBjYXNlIDQ6CiAgICAgICAgICAgICAgICAvKiBBbGxvY2F0ZSBleHRyYSBzcGFjZSB0byBzdG9yZSB0aGUgUkdCIGJpdCBtYXNrcy4gKi8KICAgICAgICAgICAgICAgIGJfaW5mbyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoQklUTUFQSU5GT0hFQURFUikgKyAzICogc2l6ZW9mKERXT1JEKSk7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgICAgIGJfaW5mbyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoQklUTUFQSU5GT0hFQURFUikpOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgLyogQWxsb2NhdGUgZXh0cmEgc3BhY2UgZm9yIGEgcGFsZXR0ZS4gKi8KICAgICAgICAgICAgICAgIGJfaW5mbyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKEJJVE1BUElORk9IRUFERVIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIHNpemVvZihSR0JRVUFEKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiAoMSA8PCAoVGhpcy0+Ynl0ZXNQZXJQaXhlbCAqIDgpKSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGlmICghYl9pbmZvKQogICAgICAgICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKCiAgICAgICAgLyogU29tZSBhcHBzIGFjY2VzcyB0aGUgc3VyZmFjZSBpbiB2aWEgRFdPUkRzLCBhbmQgZG8gbm90IHRha2UgdGhlIG5lY2Vzc2FyeSBjYXJlIGF0IHRoZSBlbmQgb2YgdGhlCiAgICAgICAgICogc3VyZmFjZS4gU28gd2UgbmVlZCBhdCBsZWFzdCBleHRyYSA0IGJ5dGVzIGF0IHRoZSBlbmQgb2YgdGhlIHN1cmZhY2UuIENoZWNrIGFnYWluc3QgdGhlIHBhZ2Ugc2l6ZSwKICAgICAgICAgKiBpZiB0aGUgbGFzdCBwYWdlIHVzZWQgZm9yIHRoZSBzdXJmYWNlIGhhcyBhdCBsZWFzdCA0IHNwYXJlIGJ5dGVzIHdlJ3JlIHNhZmUsIG90aGVyd2lzZQogICAgICAgICAqIGFkZCBhbiBleHRyYSBsaW5lIHRvIHRoZSBkaWIgc2VjdGlvbgogICAgICAgICAqLwogICAgICAgIEdldFN5c3RlbUluZm8oJnN5c0luZm8pOwogICAgICAgIGlmKCAoKFRoaXMtPnJlc291cmNlLnNpemUgKyAzKSAlIHN5c0luZm8uZHdQYWdlU2l6ZSkgPCA0KSB7CiAgICAgICAgICAgIGV4dHJhbGluZSA9IDE7CiAgICAgICAgICAgIFRSQUNFKCJBZGRpbmcgYW4gZXh0cmEgbGluZSB0byB0aGUgZGliIHNlY3Rpb25cbiIpOwogICAgICAgIH0KCiAgICAgICAgYl9pbmZvLT5ibWlIZWFkZXIuYmlTaXplID0gc2l6ZW9mKEJJVE1BUElORk9IRUFERVIpOwogICAgICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpV2lkdGggPSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICBiX2luZm8tPmJtaUhlYWRlci5iaUhlaWdodCA9IC1UaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQgLWV4dHJhbGluZTsKICAgICAgICBiX2luZm8tPmJtaUhlYWRlci5iaVNpemVJbWFnZSA9ICggVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0ICsgZXh0cmFsaW5lKSAqIElXaW5lRDNEU3VyZmFjZV9HZXRQaXRjaChpZmFjZSk7CiAgICAgICAgYl9pbmZvLT5ibWlIZWFkZXIuYmlQbGFuZXMgPSAxOwogICAgICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpQml0Q291bnQgPSBUaGlzLT5ieXRlc1BlclBpeGVsICogODsKCiAgICAgICAgYl9pbmZvLT5ibWlIZWFkZXIuYmlYUGVsc1Blck1ldGVyID0gMDsKICAgICAgICBiX2luZm8tPmJtaUhlYWRlci5iaVlQZWxzUGVyTWV0ZXIgPSAwOwogICAgICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpQ2xyVXNlZCA9IDA7CiAgICAgICAgYl9pbmZvLT5ibWlIZWFkZXIuYmlDbHJJbXBvcnRhbnQgPSAwOwoKICAgICAgICAvKiBHZXQgdGhlIGJpdCBtYXNrcyAqLwogICAgICAgIG1hc2tzID0gKERXT1JEICopICYoYl9pbmZvLT5ibWlDb2xvcnMpOwogICAgICAgIHN3aXRjaCAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0KSB7CiAgICAgICAgICAgIGNhc2UgV0lORUQzREZNVF9SOEc4Qjg6CiAgICAgICAgICAgICAgICB1c2FnZSA9IERJQl9SR0JfQ09MT1JTOwogICAgICAgICAgICAgICAgYl9pbmZvLT5ibWlIZWFkZXIuYmlDb21wcmVzc2lvbiA9IEJJX1JHQjsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBXSU5FRDNERk1UX1gxUjVHNUI1OgogICAgICAgICAgICBjYXNlIFdJTkVEM0RGTVRfQTFSNUc1QjU6CiAgICAgICAgICAgIGNhc2UgV0lORUQzREZNVF9BNFI0RzRCNDoKICAgICAgICAgICAgY2FzZSBXSU5FRDNERk1UX1g0UjRHNEI0OgogICAgICAgICAgICBjYXNlIFdJTkVEM0RGTVRfUjNHM0IyOgogICAgICAgICAgICBjYXNlIFdJTkVEM0RGTVRfQThSM0czQjI6CiAgICAgICAgICAgIGNhc2UgV0lORUQzREZNVF9BMkIxMEcxMFIxMDoKICAgICAgICAgICAgY2FzZSBXSU5FRDNERk1UX0E4QjhHOFI4OgogICAgICAgICAgICBjYXNlIFdJTkVEM0RGTVRfWDhCOEc4Ujg6CiAgICAgICAgICAgIGNhc2UgV0lORUQzREZNVF9BMlIxMEcxMEIxMDoKICAgICAgICAgICAgY2FzZSBXSU5FRDNERk1UX1I1RzZCNToKICAgICAgICAgICAgY2FzZSBXSU5FRDNERk1UX0ExNkIxNkcxNlIxNjoKICAgICAgICAgICAgICAgIHVzYWdlID0gMDsKICAgICAgICAgICAgICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpQ29tcHJlc3Npb24gPSBCSV9CSVRGSUVMRFM7CiAgICAgICAgICAgICAgICBtYXNrc1swXSA9IGZvcm1hdEVudHJ5LT5yZWRNYXNrOwogICAgICAgICAgICAgICAgbWFza3NbMV0gPSBmb3JtYXRFbnRyeS0+Z3JlZW5NYXNrOwogICAgICAgICAgICAgICAgbWFza3NbMl0gPSBmb3JtYXRFbnRyeS0+Ymx1ZU1hc2s7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAvKiBEb24ndCBrbm93IHBhbGV0dGUgKi8KICAgICAgICAgICAgICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpQ29tcHJlc3Npb24gPSBCSV9SR0I7CiAgICAgICAgICAgICAgICB1c2FnZSA9IDA7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGRkYyA9IEdldERDKDApOwogICAgICAgIGlmIChkZGMgPT0gMCkgewogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBiX2luZm8pOwogICAgICAgICAgICByZXR1cm4gSFJFU1VMVF9GUk9NX1dJTjMyKEdldExhc3RFcnJvcigpKTsKICAgICAgICB9CgogICAgICAgIFRSQUNFKCJDcmVhdGluZyBhIERJQiBzZWN0aW9uIHdpdGggc2l6ZSAlZHglZHglZCwgc2l6ZT0lZFxuIiwgYl9pbmZvLT5ibWlIZWFkZXIuYmlXaWR0aCwgYl9pbmZvLT5ibWlIZWFkZXIuYmlIZWlnaHQsIGJfaW5mby0+Ym1pSGVhZGVyLmJpQml0Q291bnQsIGJfaW5mby0+Ym1pSGVhZGVyLmJpU2l6ZUltYWdlKTsKICAgICAgICBUaGlzLT5kaWIuRElCc2VjdGlvbiA9IENyZWF0ZURJQlNlY3Rpb24oZGRjLCBiX2luZm8sIHVzYWdlLCAmVGhpcy0+ZGliLmJpdG1hcF9kYXRhLCAwIC8qIEhhbmRsZSAqLywgMCAvKiBPZmZzZXQgKi8pOwogICAgICAgIFJlbGVhc2VEQygwLCBkZGMpOwoKICAgICAgICBpZiAoIVRoaXMtPmRpYi5ESUJzZWN0aW9uKSB7CiAgICAgICAgICAgIEVSUigiQ3JlYXRlRElCU2VjdGlvbiBmYWlsZWQhXG4iKTsKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgYl9pbmZvKTsKICAgICAgICAgICAgcmV0dXJuIEhSRVNVTFRfRlJPTV9XSU4zMihHZXRMYXN0RXJyb3IoKSk7CiAgICAgICAgfQoKICAgICAgICBUUkFDRSgiRElCU2VjdGlvbiBhdCA6ICVwXG4iLCBUaGlzLT5kaWIuYml0bWFwX2RhdGEpOwoKICAgICAgICAvKiBjb3B5IHRoZSBleGlzdGluZyBzdXJmYWNlIHRvIHRoZSBkaWIgc2VjdGlvbiAqLwogICAgICAgIGlmKFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSkgewogICAgICAgICAgICBtZW1jcHkoVGhpcy0+ZGliLmJpdG1hcF9kYXRhLCBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnksIGJfaW5mby0+Ym1pSGVhZGVyLmJpU2l6ZUltYWdlKTsKICAgICAgICAgICAgLyogV2Ugd29uJ3QgbmVlZCB0aGF0IGFueSBtb3JlICovCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLyogVGhpcyBpcyB0byBtYWtlIExvY2tSZWN0IHJlYWQgdGhlIGdsIFRleHR1cmUgYWx0aG91Z2ggbWVtb3J5IGlzIGFsbG9jYXRlZCAqLwogICAgICAgICAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfSU5TWVNNRU07CiAgICAgICAgfQoKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBiX2luZm8pOwoKICAgICAgICAvKiBVc2UgdGhlIGRpYiBzZWN0aW9uIGZyb20gbm93IG9uICovCiAgICAgICAgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gVGhpcy0+ZGliLmJpdG1hcF9kYXRhOwoKICAgICAgICAvKiBOb3cgYWxsb2NhdGUgYSBIREMgKi8KICAgICAgICBUaGlzLT5oREMgPSBDcmVhdGVDb21wYXRpYmxlREMoMCk7CiAgICAgICAgVGhpcy0+ZGliLmhvbGRiaXRtYXAgPSBTZWxlY3RPYmplY3QoVGhpcy0+aERDLCBUaGlzLT5kaWIuRElCc2VjdGlvbik7CiAgICAgICAgVFJBQ0UoInVzaW5nIHdpbmVkM2QgcGFsZXR0ZSAlcFxuIiwgVGhpcy0+cGFsZXR0ZSk7CiAgICAgICAgU2VsZWN0UGFsZXR0ZShUaGlzLT5oREMsCiAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5wYWxldHRlID8gVGhpcy0+cGFsZXR0ZS0+aHBhbCA6IDAsCiAgICAgICAgICAgICAgICAgICAgICBGQUxTRSk7CgogICAgICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX0RJQlNFQ1RJT047CgogICAgICAgIGlmKFRoaXMtPkZsYWdzICYgU0ZMQUdfQ0xJRU5UKSB7CiAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9QcmVMb2FkKGlmYWNlKTsKICAgICAgICB9CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb2xkbWVtKTsKICAgIH0KCiAgICAvKiBMb2NrIHRoZSBzdXJmYWNlICovCiAgICBociA9IElXaW5lRDNEU3VyZmFjZV9Mb2NrUmVjdChpZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZsb2NrLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDApOwogICAgaWYoRkFJTEVEKGhyKSkgewogICAgICAgIEVSUigiSVdpbmVEM0RTdXJmYWNlX0xvY2tSZWN0IGZhaWxlZCB3aXRoIGhyID0gJTA4eFxuIiwgaHIpOwogICAgICAgIC8qIGtlZXAgdGhlIGRpYiBzZWN0aW9uICovCiAgICAgICAgcmV0dXJuIGhyOwogICAgfQoKICAgIGlmKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX1A4IHx8CiAgICAgICAgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfQThQOCkgewogICAgICAgIHVuc2lnbmVkIGludCBuOwogICAgICAgIGlmKFRoaXMtPnBhbGV0dGUpIHsKICAgICAgICAgICAgUEFMRVRURUVOVFJZIGVudFsyNTZdOwoKICAgICAgICAgICAgR2V0UGFsZXR0ZUVudHJpZXMoVGhpcy0+cGFsZXR0ZS0+aHBhbCwgMCwgMjU2LCBlbnQpOwogICAgICAgICAgICBmb3IgKG49MDsgbjwyNTY7IG4rKykgewogICAgICAgICAgICAgICAgY29sW25dLnJnYlJlZCAgID0gZW50W25dLnBlUmVkOwogICAgICAgICAgICAgICAgY29sW25dLnJnYkdyZWVuID0gZW50W25dLnBlR3JlZW47CiAgICAgICAgICAgICAgICBjb2xbbl0ucmdiQmx1ZSAgPSBlbnRbbl0ucGVCbHVlOwogICAgICAgICAgICAgICAgY29sW25dLnJnYlJlc2VydmVkID0gMDsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlSW1wbCAqZGV2aWNlID0gVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZTsKCiAgICAgICAgICAgIGZvciAobj0wOyBuPDI1NjsgbisrKSB7CiAgICAgICAgICAgICAgICBjb2xbbl0ucmdiUmVkICAgPSBkZXZpY2UtPnBhbGV0dGVzW2RldmljZS0+Y3VycmVudFBhbGV0dGVdW25dLnBlUmVkOwogICAgICAgICAgICAgICAgY29sW25dLnJnYkdyZWVuID0gZGV2aWNlLT5wYWxldHRlc1tkZXZpY2UtPmN1cnJlbnRQYWxldHRlXVtuXS5wZUdyZWVuOwogICAgICAgICAgICAgICAgY29sW25dLnJnYkJsdWUgID0gZGV2aWNlLT5wYWxldHRlc1tkZXZpY2UtPmN1cnJlbnRQYWxldHRlXVtuXS5wZUJsdWU7CiAgICAgICAgICAgICAgICBjb2xbbl0ucmdiUmVzZXJ2ZWQgPSAwOwogICAgICAgICAgICB9CgogICAgICAgIH0KICAgICAgICBTZXRESUJDb2xvclRhYmxlKFRoaXMtPmhEQywgMCwgMjU2LCBjb2wpOwogICAgfQoKICAgICpwSERDID0gVGhpcy0+aERDOwogICAgVFJBQ0UoInJldHVybmluZyAlcFxuIiwqcEhEQyk7CiAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19EQ0lOVVNFOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1JlbGVhc2VEQyhJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBIREMgaERDKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKCiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIixUaGlzLGhEQyk7CgogICAgaWYgKCEoVGhpcy0+RmxhZ3MgJiBTRkxBR19EQ0lOVVNFKSkKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKCiAgICAvKiB3ZSBsb2NrZWQgZmlyc3QsIHNvIHVubG9jayBub3cgKi8KICAgIElXaW5lRDNEU3VyZmFjZV9VbmxvY2tSZWN0KGlmYWNlKTsKCiAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfRENJTlVTRTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgIElXaW5lRDNEU3VyZmFjZSBJbnRlcm5hbCAoTm8gbWFwcGluZyB0byBkaXJlY3R4IGFwaSkgcGFydHMgZm9sbG93CiAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqLwoKc3RhdGljIEhSRVNVTFQgZDNkZm10X2dldF9jb252KElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMsIEJPT0wgbmVlZF9hbHBoYV9jaywgQk9PTCB1c2VfdGV4dHVyaW5nLCBHTGVudW0gKmZvcm1hdCwgR0xlbnVtICppbnRlcm5hbCwgR0xlbnVtICp0eXBlLCBDT05WRVJUX1RZUEVTICpjb252ZXJ0LCBpbnQgKnRhcmdldF9icHApIHsKICAgIEJPT0wgY29sb3JrZXlfYWN0aXZlID0gbmVlZF9hbHBoYV9jayAmJiAoVGhpcy0+Q0tleUZsYWdzICYgV0lORUREU0RfQ0tTUkNCTFQpOwogICAgY29uc3QgUGl4ZWxGb3JtYXREZXNjICpmb3JtYXRFbnRyeSA9IGdldEZvcm1hdERlc2NFbnRyeShUaGlzLT5yZXNvdXJjZS5mb3JtYXQpOwoKICAgIC8qIERlZmF1bHQgdmFsdWVzOiBGcm9tIHRoZSBzdXJmYWNlICovCiAgICAqZm9ybWF0ID0gZm9ybWF0RW50cnktPmdsRm9ybWF0OwogICAgKmludGVybmFsID0gZm9ybWF0RW50cnktPmdsSW50ZXJuYWw7CiAgICAqdHlwZSA9IGZvcm1hdEVudHJ5LT5nbFR5cGU7CiAgICAqY29udmVydCA9IE5PX0NPTlZFUlNJT047CiAgICAqdGFyZ2V0X2JwcCA9IFRoaXMtPmJ5dGVzUGVyUGl4ZWw7CgogICAgLyogT2ssIG5vdyBsb29rIGlmIHdlIGhhdmUgdG8gZG8gYW55IGNvbnZlcnNpb24gKi8KICAgIHN3aXRjaChUaGlzLT5yZXNvdXJjZS5mb3JtYXQpIHsKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfUDg6CiAgICAgICAgICAgIC8qICoqKioqKioqKioqKioqKioKICAgICAgICAgICAgICAgIFBhbGV0dGVkIFRleHR1cmUKICAgICAgICAgICAgICAgICoqKioqKioqKioqKioqKiogKi8KICAgICAgICAgICAgLyogVXNlIGNvbnZlcnNpb24gd2hlbiB0aGUgcGFsZXR0ZWQgdGV4dHVyZSBleHRlbnNpb24gaXMgbm90IGF2YWlsYWJsZSwgb3Igd2hlbiBpdCBpcyBhdmFpbGFibGUgbWFrZSBzdXJlIGl0IGlzIHVzZWQKICAgICAgICAgICAgICogZm9yIHRleHR1cmluZyBhcyBpdCB3b24ndCB3b3JrIGZvciBjYWxscyBsaWtlIGdsRHJhdy0vZ2xSZWFkUGl4ZWxzIGFuZCBmdXJ0aGVyIGFsc28gdXNlIGNvbnZlcnNpb24gaW4gY2FzZSBvZiBjb2xvciBrZXlpbmcuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZighR0xfU1VQUE9SVChFWFRfUEFMRVRURURfVEVYVFVSRSkgfHwgY29sb3JrZXlfYWN0aXZlIHx8ICghdXNlX3RleHR1cmluZyAmJiBHTF9TVVBQT1JUKEVYVF9QQUxFVFRFRF9URVhUVVJFKSkgKSB7CiAgICAgICAgICAgICAgICAqZm9ybWF0ID0gR0xfUkdCQTsKICAgICAgICAgICAgICAgICppbnRlcm5hbCA9IEdMX1JHQkE7CiAgICAgICAgICAgICAgICAqdHlwZSA9IEdMX1VOU0lHTkVEX0JZVEU7CiAgICAgICAgICAgICAgICAqdGFyZ2V0X2JwcCA9IDQ7CiAgICAgICAgICAgICAgICBpZihjb2xvcmtleV9hY3RpdmUpIHsKICAgICAgICAgICAgICAgICAgICAqY29udmVydCA9IENPTlZFUlRfUEFMRVRURURfQ0s7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICpjb252ZXJ0ID0gQ09OVkVSVF9QQUxFVFRFRDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgV0lORUQzREZNVF9SM0czQjI6CiAgICAgICAgICAgIC8qICoqKioqKioqKioqKioqKioqKioqKioKICAgICAgICAgICAgICAgIEdMX1VOU0lHTkVEX0JZVEVfM18zXzIKICAgICAgICAgICAgICAgICoqKioqKioqKioqKioqKioqKioqKiogKi8KICAgICAgICAgICAgaWYgKGNvbG9ya2V5X2FjdGl2ZSkgewogICAgICAgICAgICAgICAgLyogVGhpcyB0ZXh0dXJlIGZvcm1hdCB3aWxsIG5ldmVyIGJlIHVzZWQuLiBTbyBkbyBub3QgY2FyZSBhYm91dCBjb2xvciBrZXlpbmcKICAgICAgICAgICAgICAgICAgICB1cCB1bnRpbCB0aGUgcG9pbnQgaW4gdGltZSBpdCB3aWxsIGJlIG5lZWRlZCA6LSkgKi8KICAgICAgICAgICAgICAgIEZJWE1FKCIgQ29sb3JLZXlpbmcgbm90IHN1cHBvcnRlZCBpbiB0aGUgUkdCIDMzMiBmb3JtYXQgIVxuIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgV0lORUQzREZNVF9SNUc2QjU6CiAgICAgICAgICAgIGlmIChjb2xvcmtleV9hY3RpdmUpIHsKICAgICAgICAgICAgICAgICpjb252ZXJ0ID0gQ09OVkVSVF9DS181NjU7CiAgICAgICAgICAgICAgICAqZm9ybWF0ID0gR0xfUkdCQTsKICAgICAgICAgICAgICAgICppbnRlcm5hbCA9IEdMX1JHQkE7CiAgICAgICAgICAgICAgICAqdHlwZSA9IEdMX1VOU0lHTkVEX1NIT1JUXzVfNV81XzE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgV0lORUQzREZNVF9YMVI1RzVCNToKICAgICAgICAgICAgaWYgKGNvbG9ya2V5X2FjdGl2ZSkgewogICAgICAgICAgICAgICAgKmNvbnZlcnQgPSBDT05WRVJUX0NLXzU1NTE7CiAgICAgICAgICAgICAgICAqZm9ybWF0ID0gR0xfQkdSQTsKICAgICAgICAgICAgICAgICppbnRlcm5hbCA9IEdMX1JHQkE7CiAgICAgICAgICAgICAgICAqdHlwZSA9IEdMX1VOU0lHTkVEX1NIT1JUXzFfNV81XzVfUkVWOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfUjhHOEI4OgogICAgICAgICAgICBpZiAoY29sb3JrZXlfYWN0aXZlKSB7CiAgICAgICAgICAgICAgICAqY29udmVydCA9IENPTlZFUlRfQ0tfUkdCMjQ7CiAgICAgICAgICAgICAgICAqZm9ybWF0ID0gR0xfUkdCQTsKICAgICAgICAgICAgICAgICppbnRlcm5hbCA9IEdMX1JHQkE7CiAgICAgICAgICAgICAgICAqdHlwZSA9IEdMX1VOU0lHTkVEX0lOVF84XzhfOF84OwogICAgICAgICAgICAgICAgKnRhcmdldF9icHAgPSA0OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfWDhSOEc4Qjg6CiAgICAgICAgICAgIGlmIChjb2xvcmtleV9hY3RpdmUpIHsKICAgICAgICAgICAgICAgICpjb252ZXJ0ID0gQ09OVkVSVF9SR0IzMl84ODg7CiAgICAgICAgICAgICAgICAqZm9ybWF0ID0gR0xfUkdCQTsKICAgICAgICAgICAgICAgICppbnRlcm5hbCA9IEdMX1JHQkE7CiAgICAgICAgICAgICAgICAqdHlwZSA9IEdMX1VOU0lHTkVEX0lOVF84XzhfOF84OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfVjhVODoKICAgICAgICAgICAgaWYoR0xfU1VQUE9SVChOVl9URVhUVVJFX1NIQURFUjMpKSBicmVhazsKICAgICAgICAgICAgZWxzZSBpZihHTF9TVVBQT1JUKEFUSV9FTlZNQVBfQlVNUE1BUCkpIHsKICAgICAgICAgICAgICAgICpmb3JtYXQgPSBHTF9EVURWX0FUSTsKICAgICAgICAgICAgICAgICppbnRlcm5hbCA9IEdMX0RVOERWOF9BVEk7CiAgICAgICAgICAgICAgICAqdHlwZSA9IEdMX0JZVEU7CiAgICAgICAgICAgICAgICAvKiBObyBjb252ZXJzaW9uIC0gSnVzdCBjaGFuZ2UgdGhlIGdsIHR5cGUgKi8KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgICpjb252ZXJ0ID0gQ09OVkVSVF9WOFU4OwogICAgICAgICAgICAqZm9ybWF0ID0gR0xfQkdSOwogICAgICAgICAgICAqaW50ZXJuYWwgPSBHTF9SR0I4OwogICAgICAgICAgICAqdHlwZSA9IEdMX1VOU0lHTkVEX0JZVEU7CiAgICAgICAgICAgICp0YXJnZXRfYnBwID0gMzsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgV0lORUQzREZNVF9YOEw4VjhVODoKICAgICAgICAgICAgaWYoR0xfU1VQUE9SVChOVl9URVhUVVJFX1NIQURFUjMpKSBicmVhazsKICAgICAgICAgICAgKmNvbnZlcnQgPSBDT05WRVJUX1g4TDhWOFU4OwogICAgICAgICAgICAqZm9ybWF0ID0gR0xfQkdSQTsKICAgICAgICAgICAgKmludGVybmFsID0gR0xfUkdCQTg7CiAgICAgICAgICAgICp0eXBlID0gR0xfVU5TSUdORURfQllURTsKICAgICAgICAgICAgKnRhcmdldF9icHAgPSA0OwogICAgICAgICAgICAvKiBOb3Qgc3VwcG9ydGVkIGJ5IEdMX0FUSV9lbnZtYXBfYnVtcG1hcCAqLwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1E4VzhWOFU4OgogICAgICAgICAgICBpZihHTF9TVVBQT1JUKE5WX1RFWFRVUkVfU0hBREVSMykpIGJyZWFrOwogICAgICAgICAgICAqY29udmVydCA9IENPTlZFUlRfUThXOFY4VTg7CiAgICAgICAgICAgICpmb3JtYXQgPSBHTF9CR1JBOwogICAgICAgICAgICAqaW50ZXJuYWwgPSBHTF9SR0JBODsKICAgICAgICAgICAgKnR5cGUgPSBHTF9VTlNJR05FRF9CWVRFOwogICAgICAgICAgICAqdGFyZ2V0X2JwcCA9IDQ7CiAgICAgICAgICAgIC8qIE5vdCBzdXBwb3J0ZWQgYnkgR0xfQVRJX2Vudm1hcF9idW1wbWFwICovCiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfVjE2VTE2OgogICAgICAgICAgICBpZihHTF9TVVBQT1JUKE5WX1RFWFRVUkVfU0hBREVSMykpIGJyZWFrOwogICAgICAgICAgICAqY29udmVydCA9IENPTlZFUlRfVjE2VTE2OwogICAgICAgICAgICAqZm9ybWF0ID0gR0xfQkdSOwogICAgICAgICAgICAqaW50ZXJuYWwgPSBHTF9SR0IxNjsKICAgICAgICAgICAgKnR5cGUgPSBHTF9TSE9SVDsKICAgICAgICAgICAgKnRhcmdldF9icHAgPSA2OwogICAgICAgICAgICAvKiBXaGF0IHNob3VsZCBJIGRvIGhlcmUgYWJvdXQgR0xfQVRJX2Vudm1hcF9idW1wbWFwPwogICAgICAgICAgICAgKiBDb252ZXJ0IGl0IG9yIGFsbG93IGRhdGEgbG9zcyBieSBsb2FkaW5nIGl0IGludG8gYSA4IGJpdCAvIGNoYW5uZWwgdGV4dHVyZT8KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBicmVhazsKICAgIH0KCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBkM2RmbXRfY29udmVydF9zdXJmYWNlKEJZVEUgKnNyYywgQllURSAqZHN0LCBVSU5UIHBpdGNoLCBVSU5UIHdpZHRoLCBVSU5UIGhlaWdodCwgVUlOVCBvdXRwaXRjaCwgQ09OVkVSVF9UWVBFUyBjb252ZXJ0LCBJV2luZUQzRFN1cmZhY2VJbXBsICpzdXJmKSB7CiAgICBCWVRFICpzb3VyY2UsICpkZXN0OwogICAgVFJBQ0UoIiglcCktPiglcCksKCVkLCVkLCVkLCVkLCVwKVxuIiwgc3JjLCBkc3QsIHBpdGNoLCBoZWlnaHQsIG91dHBpdGNoLCBjb252ZXJ0LCBzdXJmKTsKCiAgICBzd2l0Y2ggKGNvbnZlcnQpIHsKICAgICAgICBjYXNlIE5PX0NPTlZFUlNJT046CiAgICAgICAgewogICAgICAgICAgICBtZW1jcHkoZHN0LCBzcmMsIHBpdGNoICogaGVpZ2h0KTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGNhc2UgQ09OVkVSVF9QQUxFVFRFRDoKICAgICAgICBjYXNlIENPTlZFUlRfUEFMRVRURURfQ0s6CiAgICAgICAgewogICAgICAgICAgICBJV2luZUQzRFBhbGV0dGVJbXBsKiBwYWwgPSBzdXJmLT5wYWxldHRlOwogICAgICAgICAgICBCWVRFIHRhYmxlWzI1Nl1bNF07CiAgICAgICAgICAgIHVuc2lnbmVkIGludCBpOwogICAgICAgICAgICB1bnNpZ25lZCBpbnQgeCwgeTsKCiAgICAgICAgICAgIGlmKCBwYWwgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgLyogVE9ETzogSWYgd2UgYXJlIGEgc3VibGV2ZWwsIHRyeSB0byBnZXQgdGhlIHBhbGV0dGUgZnJvbSBsZXZlbCAwICovCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChwYWwgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgLyogU3RpbGwgbm8gcGFsZXR0ZT8gVXNlIHRoZSBkZXZpY2UncyBwYWxldHRlICovCiAgICAgICAgICAgICAgICAvKiBHZXQgdGhlIHN1cmZhY2UncyBwYWxldHRlICovCiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgMjU2OyBpKyspIHsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZUltcGwgKmRldmljZSA9IHN1cmYtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CgogICAgICAgICAgICAgICAgICAgIHRhYmxlW2ldWzBdID0gZGV2aWNlLT5wYWxldHRlc1tkZXZpY2UtPmN1cnJlbnRQYWxldHRlXVtpXS5wZVJlZDsKICAgICAgICAgICAgICAgICAgICB0YWJsZVtpXVsxXSA9IGRldmljZS0+cGFsZXR0ZXNbZGV2aWNlLT5jdXJyZW50UGFsZXR0ZV1baV0ucGVHcmVlbjsKICAgICAgICAgICAgICAgICAgICB0YWJsZVtpXVsyXSA9IGRldmljZS0+cGFsZXR0ZXNbZGV2aWNlLT5jdXJyZW50UGFsZXR0ZV1baV0ucGVCbHVlOwogICAgICAgICAgICAgICAgICAgIGlmICgoY29udmVydCA9PSBDT05WRVJUX1BBTEVUVEVEX0NLKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAoaSA+PSBzdXJmLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUxvd1ZhbHVlKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAoaSA8PSBzdXJmLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUhpZ2hWYWx1ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogV2Ugc2hvdWxkIG1heWJlIGhlcmUgcHV0IGEgbW9yZSAnbmV1dHJhbCcgY29sb3IgdGhhbiB0aGUgc3RhbmRhcmQgYnJpZ2h0IHB1cnBsZQogICAgICAgICAgICAgICAgICAgICAgICAgIG9uZSBvZnRlbiB1c2VkIGJ5IGFwcGxpY2F0aW9uIHRvIHByZXZlbnQgdGhlIG5pY2UgcHVycGxlIGJvcmRlcnMgd2hlbiBiaS1saW5lYXIKICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXJpbmcgaXMgb24gKi8KICAgICAgICAgICAgICAgICAgICAgICAgdGFibGVbaV1bM10gPSAweDAwOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRhYmxlW2ldWzNdID0gMHhGRjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBUUkFDRSgiVXNpbmcgc3VyZmFjZSBwYWxldHRlICVwXG4iLCBwYWwpOwogICAgICAgICAgICAgICAgLyogR2V0IHRoZSBzdXJmYWNlJ3MgcGFsZXR0ZSAqLwogICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IDI1NjsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgdGFibGVbaV1bMF0gPSBwYWwtPnBhbGVudHNbaV0ucGVSZWQ7CiAgICAgICAgICAgICAgICAgICAgdGFibGVbaV1bMV0gPSBwYWwtPnBhbGVudHNbaV0ucGVHcmVlbjsKICAgICAgICAgICAgICAgICAgICB0YWJsZVtpXVsyXSA9IHBhbC0+cGFsZW50c1tpXS5wZUJsdWU7CiAgICAgICAgICAgICAgICAgICAgaWYgKChjb252ZXJ0ID09IENPTlZFUlRfUEFMRVRURURfQ0spICYmCiAgICAgICAgICAgICAgICAgICAgICAgIChpID49IHN1cmYtPlNyY0JsdENLZXkuZHdDb2xvclNwYWNlTG93VmFsdWUpICYmCiAgICAgICAgICAgICAgICAgICAgICAgIChpIDw9IHN1cmYtPlNyY0JsdENLZXkuZHdDb2xvclNwYWNlSGlnaFZhbHVlKSkgewogICAgICAgICAgICAgICAgICAgICAgICAvKiBXZSBzaG91bGQgbWF5YmUgaGVyZSBwdXQgYSBtb3JlICduZXV0cmFsJyBjb2xvciB0aGFuIHRoZSBzdGFuZGFyZCBicmlnaHQgcHVycGxlCiAgICAgICAgICAgICAgICAgICAgICAgICAgb25lIG9mdGVuIHVzZWQgYnkgYXBwbGljYXRpb24gdG8gcHJldmVudCB0aGUgbmljZSBwdXJwbGUgYm9yZGVycyB3aGVuIGJpLWxpbmVhcgogICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcmluZyBpcyBvbiAqLwogICAgICAgICAgICAgICAgICAgICAgICB0YWJsZVtpXVszXSA9IDB4MDA7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmKHBhbC0+RmxhZ3MgJiBXSU5FRERQQ0FQU19BTFBIQSkgewogICAgICAgICAgICAgICAgICAgICAgICB0YWJsZVtpXVszXSA9IHBhbC0+cGFsZW50c1tpXS5wZUZsYWdzOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRhYmxlW2ldWzNdID0gMHhGRjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZvciAoeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc291cmNlID0gc3JjICsgcGl0Y2ggKiB5OwogICAgICAgICAgICAgICAgZGVzdCA9IGRzdCArIG91dHBpdGNoICogeTsKICAgICAgICAgICAgICAgIC8qIFRoaXMgaXMgYW4gMSBicHAgZm9ybWF0LCB1c2luZyB0aGUgd2lkdGggaGVyZSBpcyBmaW5lICovCiAgICAgICAgICAgICAgICBmb3IgKHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewogICAgICAgICAgICAgICAgICAgIEJZVEUgY29sb3IgPSAqc291cmNlKys7CiAgICAgICAgICAgICAgICAgICAgKmRlc3QrKyA9IHRhYmxlW2NvbG9yXVswXTsKICAgICAgICAgICAgICAgICAgICAqZGVzdCsrID0gdGFibGVbY29sb3JdWzFdOwogICAgICAgICAgICAgICAgICAgICpkZXN0KysgPSB0YWJsZVtjb2xvcl1bMl07CiAgICAgICAgICAgICAgICAgICAgKmRlc3QrKyA9IHRhYmxlW2NvbG9yXVszXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBDT05WRVJUX0NLXzU2NToKICAgICAgICB7CiAgICAgICAgICAgIC8qIENvbnZlcnRpbmcgdGhlIDU2NSBmb3JtYXQgaW4gNTU1MSBwYWNrZWQgdG8gZW11bGF0ZSBjb2xvci1rZXlpbmcuCgogICAgICAgICAgICAgIE5vdGUgOiBpbiBhbGwgdGhlc2UgY29udmVyc2lvbiwgaXQgd291bGQgYmUgYmVzdCB0byBhdmVyYWdlIHRoZSBhdmVyYWdpbmcKICAgICAgICAgICAgICAgICAgICAgIHBpeGVscyB0byBnZXQgdGhlIGNvbG9yIG9mIHRoZSBwaXhlbCB0aGF0IHdpbGwgYmUgY29sb3Ita2V5ZWQgdG8KICAgICAgICAgICAgICAgICAgICAgIHByZXZlbnQgJ2NvbG9yIGJsZWVkaW5nJy4gVGhpcyB3aWxsIGJlIGRvbmUgbGF0ZXIgb24gaWYgZXZlciBpdCBpcwogICAgICAgICAgICAgICAgICAgICAgdG9vIHZpc2libGUuCgogICAgICAgICAgICAgIE5vdGUyOiBOdmlkaWEgZG9jdW1lbnRzIHNheSB0aGF0IHRoZWlyIGRyaXZlciBkb2VzIG5vdCBzdXBwb3J0IGFscGhhICsgY29sb3Iga2V5aW5nCiAgICAgICAgICAgICAgICAgICAgIG9uIHRoZSBzYW1lIHN1cmZhY2UgYW5kIGRpc2FibGVzIGNvbG9yIGtleWluZyBpbiBzdWNoIGEgY2FzZQogICAgICAgICAgICAqLwogICAgICAgICAgICB1bnNpZ25lZCBpbnQgeCwgeTsKICAgICAgICAgICAgV09SRCAqU291cmNlOwogICAgICAgICAgICBXT1JEICpEZXN0OwoKICAgICAgICAgICAgVFJBQ0UoIkNvbG9yIGtleWVkIDU2NVxuIik7CgogICAgICAgICAgICBmb3IgKHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKICAgICAgICAgICAgICAgIFNvdXJjZSA9IChXT1JEICopIChzcmMgKyB5ICogcGl0Y2gpOwogICAgICAgICAgICAgICAgRGVzdCA9IChXT1JEICopIChkc3QgKyB5ICogb3V0cGl0Y2gpOwogICAgICAgICAgICAgICAgZm9yICh4ID0gMDsgeCA8IHdpZHRoOyB4KysgKSB7CiAgICAgICAgICAgICAgICAgICAgV09SRCBjb2xvciA9ICpTb3VyY2UrKzsKICAgICAgICAgICAgICAgICAgICAqRGVzdCA9ICgoY29sb3IgJiAweEZGQzApIHwgKChjb2xvciAmIDB4MUYpIDw8IDEpKTsKICAgICAgICAgICAgICAgICAgICBpZiAoKGNvbG9yIDwgc3VyZi0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VMb3dWYWx1ZSkgfHwKICAgICAgICAgICAgICAgICAgICAgICAgKGNvbG9yID4gc3VyZi0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VIaWdoVmFsdWUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICpEZXN0IHw9IDB4MDAwMTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgRGVzdCsrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIENPTlZFUlRfQ0tfNTU1MToKICAgICAgICB7CiAgICAgICAgICAgIC8qIENvbnZlcnRpbmcgWDFSNUc1QjUgZm9ybWF0IHRvIFI1RzVCNUExIHRvIGVtdWxhdGUgY29sb3Ita2V5aW5nLiAqLwogICAgICAgICAgICB1bnNpZ25lZCBpbnQgeCwgeTsKICAgICAgICAgICAgV09SRCAqU291cmNlOwogICAgICAgICAgICBXT1JEICpEZXN0OwogICAgICAgICAgICBUUkFDRSgiQ29sb3Iga2V5ZWQgNTU1MVxuIik7CiAgICAgICAgICAgIGZvciAoeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewogICAgICAgICAgICAgICAgU291cmNlID0gKFdPUkQgKikgKHNyYyArIHkgKiBwaXRjaCk7CiAgICAgICAgICAgICAgICBEZXN0ID0gKFdPUkQgKikgKGRzdCArIHkgKiBvdXRwaXRjaCk7CiAgICAgICAgICAgICAgICBmb3IgKHggPSAwOyB4IDwgd2lkdGg7IHgrKyApIHsKICAgICAgICAgICAgICAgICAgICBXT1JEIGNvbG9yID0gKlNvdXJjZSsrOwoJCSAgICAqRGVzdCA9IGNvbG9yOwogICAgICAgICAgICAgICAgICAgIGlmICgoY29sb3IgPCBzdXJmLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUxvd1ZhbHVlKSB8fAogICAgICAgICAgICAgICAgICAgICAgICAoY29sb3IgPiBzdXJmLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUhpZ2hWYWx1ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgKkRlc3QgfD0gKDEgPDwgMTUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgKkRlc3QgJj0gfigxIDw8IDE1KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgRGVzdCsrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIENPTlZFUlRfVjhVODoKICAgICAgICB7CiAgICAgICAgICAgIHVuc2lnbmVkIGludCB4LCB5OwogICAgICAgICAgICBzaG9ydCAqU291cmNlOwogICAgICAgICAgICB1bnNpZ25lZCBjaGFyICpEZXN0OwogICAgICAgICAgICBmb3IoeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewogICAgICAgICAgICAgICAgU291cmNlID0gKHNob3J0ICopIChzcmMgKyB5ICogcGl0Y2gpOwogICAgICAgICAgICAgICAgRGVzdCA9ICh1bnNpZ25lZCBjaGFyICopIChkc3QgKyB5ICogb3V0cGl0Y2gpOwogICAgICAgICAgICAgICAgZm9yICh4ID0gMDsgeCA8IHdpZHRoOyB4KysgKSB7CiAgICAgICAgICAgICAgICAgICAgbG9uZyBjb2xvciA9ICgqU291cmNlKyspOwogICAgICAgICAgICAgICAgICAgIC8qIEIgKi8gRGVzdFswXSA9IDB4ZmY7CiAgICAgICAgICAgICAgICAgICAgLyogRyAqLyBEZXN0WzFdID0gKGNvbG9yID4+IDgpICsgMTI4OyAvKiBWICovCiAgICAgICAgICAgICAgICAgICAgLyogUiAqLyBEZXN0WzJdID0gKGNvbG9yKSArIDEyODsgICAgICAvKiBVICovCiAgICAgICAgICAgICAgICAgICAgRGVzdCArPSAzOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgY2FzZSBDT05WRVJUX1E4VzhWOFU4OgogICAgICAgIHsKICAgICAgICAgICAgdW5zaWduZWQgaW50IHgsIHk7CiAgICAgICAgICAgIERXT1JEICpTb3VyY2U7CiAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgKkRlc3Q7CiAgICAgICAgICAgIGZvcih5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CiAgICAgICAgICAgICAgICBTb3VyY2UgPSAoRFdPUkQgKikgKHNyYyArIHkgKiBwaXRjaCk7CiAgICAgICAgICAgICAgICBEZXN0ID0gKHVuc2lnbmVkIGNoYXIgKikgKGRzdCArIHkgKiBvdXRwaXRjaCk7CiAgICAgICAgICAgICAgICBmb3IgKHggPSAwOyB4IDwgd2lkdGg7IHgrKyApIHsKICAgICAgICAgICAgICAgICAgICBsb25nIGNvbG9yID0gKCpTb3VyY2UrKyk7CiAgICAgICAgICAgICAgICAgICAgLyogQiAqLyBEZXN0WzBdID0gKChjb2xvciA+PiAxNikgJiAweGZmKSArIDEyODsgLyogVyAqLwogICAgICAgICAgICAgICAgICAgIC8qIEcgKi8gRGVzdFsxXSA9ICgoY29sb3IgPj4gOCApICYgMHhmZikgKyAxMjg7IC8qIFYgKi8KICAgICAgICAgICAgICAgICAgICAvKiBSICovIERlc3RbMl0gPSAoY29sb3IgICAgICAgICAmIDB4ZmYpICsgMTI4OyAvKiBVICovCiAgICAgICAgICAgICAgICAgICAgLyogQSAqLyBEZXN0WzNdID0gKChjb2xvciA+PiAyNCkgJiAweGZmKSArIDEyODsgLyogUSAqLwogICAgICAgICAgICAgICAgICAgIERlc3QgKz0gNDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIEVSUigiVW5zdXBwb3J0ZWQgY29udmVyc2F0aW9uIHR5cGUgJWRcbiIsIGNvbnZlcnQpOwogICAgfQogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCBpbiBjYXNlIG9mIDhiaXQgcGFsZXR0ZWQgdGV4dHVyZXMgdG8gdXBsb2FkIHRoZSBwYWxldHRlLgogICBGb3Igbm93IGl0IG9ubHkgc3VwcG9ydHMgR0xfRVhUX3BhbGV0dGVkX3RleHR1cmUgZXh0ZW5zaW9uIGJ1dCBzdXBwb3J0IGZvciBvdGhlcgogICBleHRlbnNpb25zIGxpa2UgQVJCX2ZyYWdtZW50X3Byb2dyYW0gYW5kIEFUSV9mcmFnbWVudF9zaGFkZXJzIHdpbGwgYmUgYWRkZWQgYXMgd2VsbC4KKi8Kc3RhdGljIHZvaWQgZDNkZm10X3A4X3VwbG9hZF9wYWxldHRlKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIENPTlZFUlRfVFlQRVMgY29udmVydCkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFBhbGV0dGVJbXBsKiBwYWwgPSBUaGlzLT5wYWxldHRlOwogICAgQllURSB0YWJsZVsyNTZdWzRdOwogICAgaW50IGk7CgogICAgaWYgKHBhbCA9PSBOVUxMKSB7CiAgICAgICAgLyogU3RpbGwgbm8gcGFsZXR0ZT8gVXNlIHRoZSBkZXZpY2UncyBwYWxldHRlICovCiAgICAgICAgLyogR2V0IHRoZSBzdXJmYWNlJ3MgcGFsZXR0ZSAqLwogICAgICAgIGZvciAoaSA9IDA7IGkgPCAyNTY7IGkrKykgewogICAgICAgICAgICBJV2luZUQzRERldmljZUltcGwgKmRldmljZSA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CgogICAgICAgICAgICB0YWJsZVtpXVswXSA9IGRldmljZS0+cGFsZXR0ZXNbZGV2aWNlLT5jdXJyZW50UGFsZXR0ZV1baV0ucGVSZWQ7CiAgICAgICAgICAgIHRhYmxlW2ldWzFdID0gZGV2aWNlLT5wYWxldHRlc1tkZXZpY2UtPmN1cnJlbnRQYWxldHRlXVtpXS5wZUdyZWVuOwogICAgICAgICAgICB0YWJsZVtpXVsyXSA9IGRldmljZS0+cGFsZXR0ZXNbZGV2aWNlLT5jdXJyZW50UGFsZXR0ZV1baV0ucGVCbHVlOwogICAgICAgICAgICBpZiAoKGNvbnZlcnQgPT0gQ09OVkVSVF9QQUxFVFRFRF9DSykgJiYKICAgICAgICAgICAgICAgIChpID49IFRoaXMtPlNyY0JsdENLZXkuZHdDb2xvclNwYWNlTG93VmFsdWUpICYmCiAgICAgICAgICAgICAgICAoaSA8PSBUaGlzLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUhpZ2hWYWx1ZSkpIHsKICAgICAgICAgICAgICAgIC8qIFdlIHNob3VsZCBtYXliZSBoZXJlIHB1dCBhIG1vcmUgJ25ldXRyYWwnIGNvbG9yIHRoYW4gdGhlIHN0YW5kYXJkIGJyaWdodCBwdXJwbGUKICAgICAgICAgICAgICAgICAgIG9uZSBvZnRlbiB1c2VkIGJ5IGFwcGxpY2F0aW9uIHRvIHByZXZlbnQgdGhlIG5pY2UgcHVycGxlIGJvcmRlcnMgd2hlbiBiaS1saW5lYXIKICAgICAgICAgICAgICAgICAgIGZpbHRlcmluZyBpcyBvbiAqLwogICAgICAgICAgICAgICAgdGFibGVbaV1bM10gPSAweDAwOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdGFibGVbaV1bM10gPSAweEZGOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICBUUkFDRSgiVXNpbmcgc3VyZmFjZSBwYWxldHRlICVwXG4iLCBwYWwpOwogICAgICAgIC8qIEdldCB0aGUgc3VyZmFjZSdzIHBhbGV0dGUgKi8KICAgICAgICBmb3IgKGkgPSAwOyBpIDwgMjU2OyBpKyspIHsKICAgICAgICAgICAgdGFibGVbaV1bMF0gPSBwYWwtPnBhbGVudHNbaV0ucGVSZWQ7CiAgICAgICAgICAgIHRhYmxlW2ldWzFdID0gcGFsLT5wYWxlbnRzW2ldLnBlR3JlZW47CiAgICAgICAgICAgIHRhYmxlW2ldWzJdID0gcGFsLT5wYWxlbnRzW2ldLnBlQmx1ZTsKICAgICAgICAgICAgaWYgKChjb252ZXJ0ID09IENPTlZFUlRfUEFMRVRURURfQ0spICYmCiAgICAgICAgICAgICAgICAoaSA+PSBUaGlzLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUxvd1ZhbHVlKSAmJgogICAgICAgICAgICAgICAgKGkgPD0gVGhpcy0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VIaWdoVmFsdWUpKSB7CiAgICAgICAgICAgICAgICAvKiBXZSBzaG91bGQgbWF5YmUgaGVyZSBwdXQgYSBtb3JlICduZXV0cmFsJyBjb2xvciB0aGFuIHRoZSBzdGFuZGFyZCBicmlnaHQgcHVycGxlCiAgICAgICAgICAgICAgICAgICBvbmUgb2Z0ZW4gdXNlZCBieSBhcHBsaWNhdGlvbiB0byBwcmV2ZW50IHRoZSBuaWNlIHB1cnBsZSBib3JkZXJzIHdoZW4gYmktbGluZWFyCiAgICAgICAgICAgICAgICAgICBmaWx0ZXJpbmcgaXMgb24gKi8KICAgICAgICAgICAgICAgIHRhYmxlW2ldWzNdID0gMHgwMDsKICAgICAgICAgICAgfSBlbHNlIGlmKHBhbC0+RmxhZ3MgJiBXSU5FRERQQ0FQU19BTFBIQSkgewogICAgICAgICAgICAgICAgdGFibGVbaV1bM10gPSBwYWwtPnBhbGVudHNbaV0ucGVGbGFnczsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHRhYmxlW2ldWzNdID0gMHhGRjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIEdMX0VYVENBTEwoZ2xDb2xvclRhYmxlRVhUKEdMX1RFWFRVUkVfMkQsR0xfUkdCQSwyNTYsR0xfUkdCQSxHTF9VTlNJR05FRF9CWVRFLCB0YWJsZSkpOwp9CgpzdGF0aWMgQk9PTCBwYWxldHRlOV9jaGFuZ2VkKElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqZGV2aWNlID0gVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZTsKCiAgICBpZihUaGlzLT5wYWxldHRlIHx8IChUaGlzLT5yZXNvdXJjZS5mb3JtYXQgIT0gV0lORUQzREZNVF9QOCAmJiBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgIT0gV0lORUQzREZNVF9BOFA4KSkgewogICAgICAgIC8qIElmIGEgZGRyYXctc3R5bGUgcGFsZXR0ZSBpcyBhdHRhY2hlZCBhc3N1bWUgbm8gZDNkOSBwYWxldHRlIGNoYW5nZS4KICAgICAgICAgKiBBbHNvIHRoZSBwYWxldHRlIGlzbid0IGludGVyZXN0aW5nIGlmIHRoZSBzdXJmYWNlIGZvcm1hdCBpc24ndCBQOCBvciBBOFA4CiAgICAgICAgICovCiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGlmKFRoaXMtPnBhbGV0dGU5KSB7CiAgICAgICAgaWYobWVtY21wKFRoaXMtPnBhbGV0dGU5LCAmZGV2aWNlLT5wYWxldHRlc1tkZXZpY2UtPmN1cnJlbnRQYWxldHRlXSwgc2l6ZW9mKFBBTEVUVEVFTlRSWSkgKiAyNTYpID09IDApIHsKICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgVGhpcy0+cGFsZXR0ZTkgPSAoUEFMRVRURUVOVFJZICopIEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoUEFMRVRURUVOVFJZKSAqIDI1Nik7CiAgICB9CiAgICBtZW1jcHkoVGhpcy0+cGFsZXR0ZTksICZkZXZpY2UtPnBhbGV0dGVzW2RldmljZS0+Y3VycmVudFBhbGV0dGVdLCBzaXplb2YoUEFMRVRURUVOVFJZKSAqIDI1Nik7CiAgICByZXR1cm4gVFJVRTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfTG9hZFRleHR1cmUoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRERldmljZUltcGwgKmRldmljZSA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CiAgICBHTGVudW0gZm9ybWF0LCBpbnRlcm5hbCwgdHlwZTsKICAgIENPTlZFUlRfVFlQRVMgY29udmVydDsKICAgIGludCBicHA7CiAgICBpbnQgd2lkdGgsIHBpdGNoLCBvdXRwaXRjaDsKICAgIEJZVEUgKm1lbTsKCiAgICBpZiAoIShUaGlzLT5GbGFncyAmIFNGTEFHX0lOVEVYVFVSRSkpIHsKICAgICAgICBUUkFDRSgiUmVsb2FkaW5nIGJlY2F1c2Ugc3VyZmFjZSBpcyBkaXJ0eVxuIik7CiAgICB9IGVsc2UgaWYoLyogUmVsb2FkOiBnbCB0ZXh0dXJlIGhhcyBjaywgbm93IG5vIGNrZXkgaXMgc2V0IE9SICovCiAgICAgICAgICAgICAgKChUaGlzLT5GbGFncyAmIFNGTEFHX0dMQ0tFWSkgJiYgKCEoVGhpcy0+Q0tleUZsYWdzICYgV0lORUREU0RfQ0tTUkNCTFQpKSkgfHwKICAgICAgICAgICAgICAvKiBSZWxvYWQ6IHZpY2UgdmVyc2EgIE9SICovCiAgICAgICAgICAgICAgKCghKFRoaXMtPkZsYWdzICYgU0ZMQUdfR0xDS0VZKSkgJiYgKFRoaXMtPkNLZXlGbGFncyAmIFdJTkVERFNEX0NLU1JDQkxUKSkgfHwKICAgICAgICAgICAgICAvKiBBbHNvIHJlbG9hZDogQ29sb3Iga2V5IGlzIGFjdGl2ZSBBTkQgdGhlIGNvbG9yIGtleSBoYXMgY2hhbmdlZCAqLwogICAgICAgICAgICAgICgoVGhpcy0+Q0tleUZsYWdzICYgV0lORUREU0RfQ0tTUkNCTFQpICYmICgKICAgICAgICAgICAgICAgIChUaGlzLT5nbENLZXkuZHdDb2xvclNwYWNlTG93VmFsdWUgIT0gVGhpcy0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VMb3dWYWx1ZSkgfHwKICAgICAgICAgICAgICAgIChUaGlzLT5nbENLZXkuZHdDb2xvclNwYWNlSGlnaFZhbHVlICE9IFRoaXMtPlNyY0JsdENLZXkuZHdDb2xvclNwYWNlSGlnaFZhbHVlKSkpKSB7CiAgICAgICAgVFJBQ0UoIlJlbG9hZGluZyBiZWNhdXNlIG9mIGNvbG9yIGtleWluZ1xuIik7CiAgICB9IGVsc2UgaWYocGFsZXR0ZTlfY2hhbmdlZChUaGlzKSkgewogICAgICAgIFRSQUNFKCJSZWxvYWRpbmcgc3VyZmFjZSBiZWNhdXNlIHRoZSBkM2Q4LzkgcGFsZXR0ZSB3YXMgY2hhbmdlZFxuIik7CiAgICB9IGVsc2UgewogICAgICAgIFRSQUNFKCJzdXJmYWNlIGlzIGFscmVhZHkgaW4gdGV4dHVyZVxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfSU5URVhUVVJFOwoKICAgIC8qIFJlc291cmNlcyBhcmUgcGxhY2VkIGluIHN5c3RlbSBSQU0gYW5kIGRvIG5vdCBuZWVkIHRvIGJlIHJlY3JlYXRlZCB3aGVuIGEgZGV2aWNlIGlzIGxvc3QuCiAgICAqICBUaGVzZSByZXNvdXJjZXMgYXJlIG5vdCBib3VuZCBieSBkZXZpY2Ugc2l6ZSBvciBmb3JtYXQgcmVzdHJpY3Rpb25zLiBCZWNhdXNlIG9mIHRoaXMsCiAgICAqICB0aGVzZSByZXNvdXJjZXMgY2Fubm90IGJlIGFjY2Vzc2VkIGJ5IHRoZSBEaXJlY3QzRCBkZXZpY2Ugbm9yIHNldCBhcyB0ZXh0dXJlcyBvciByZW5kZXIgdGFyZ2V0cy4KICAgICogIEhvd2V2ZXIsIHRoZXNlIHJlc291cmNlcyBjYW4gYWx3YXlzIGJlIGNyZWF0ZWQsIGxvY2tlZCwgYW5kIGNvcGllZC4KICAgICovCiAgICBpZiAoVGhpcy0+cmVzb3VyY2UucG9vbCA9PSBXSU5FRDNEUE9PTF9TQ1JBVENIICkKICAgIHsKICAgICAgICBGSVhNRSgiKCVwKSBPcGVyYXRpb24gbm90IHN1cHBvcnRlZCBmb3Igc2NyYXRjaCB0ZXh0dXJlc1xuIixUaGlzKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBkM2RmbXRfZ2V0X2NvbnYoVGhpcywgVFJVRSAvKiBXZSBuZWVkIGNvbG9yIGtleWluZyAqLywgVFJVRSAvKiBXZSB3aWxsIHVzZSB0ZXh0dXJlcyAqLywgJmZvcm1hdCwgJmludGVybmFsLCAmdHlwZSwgJmNvbnZlcnQsICZicHApOwoKICAgIGlmIChUaGlzLT5GbGFncyAmIFNGTEFHX0lORFJBV0FCTEUpIHsKICAgICAgICBpZiAoVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCAhPSAwKQogICAgICAgICAgICBGSVhNRSgiU3VyZmFjZSBpbiB0ZXh0dXJlIGlzIG9ubHkgc3VwcG9ydGVkIGZvciBsZXZlbCAwXG4iKTsKICAgICAgICBlbHNlIGlmIChUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9QOCB8fCBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9BOFA4IHx8CiAgICAgICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMSB8fCBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQyIHx8CiAgICAgICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMyB8fCBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQ0IHx8CiAgICAgICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNSkKICAgICAgICAgICAgRklYTUUoIkZvcm1hdCAlZCBub3Qgc3VwcG9ydGVkXG4iLCBUaGlzLT5yZXNvdXJjZS5mb3JtYXQpOwogICAgICAgIGVsc2UgewogICAgICAgICAgICBHTGludCBwcmV2UmVhZDsKCiAgICAgICAgICAgIEVOVEVSX0dMKCk7CiAgICAgICAgICAgIGdsR2V0SW50ZWdlcnYoR0xfUkVBRF9CVUZGRVIsICZwcmV2UmVhZCk7CiAgICAgICAgICAgIHZjaGVja0dMY2FsbCgiZ2xHZXRJbnRlZ2VydiIpOwogICAgICAgICAgICBnbFJlYWRCdWZmZXIoVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZS0+b2Zmc2NyZWVuQnVmZmVyKTsKICAgICAgICAgICAgdmNoZWNrR0xjYWxsKCJnbFJlYWRCdWZmZXIiKTsKCiAgICAgICAgICAgIGlmKCEoVGhpcy0+RmxhZ3MgJiBTRkxBR19BTExPQ0FURUQpKSB7CiAgICAgICAgICAgICAgICBzdXJmYWNlX2FsbG9jYXRlX3N1cmZhY2UoVGhpcywgaW50ZXJuYWwsIFRoaXMtPnBvdzJXaWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5wb3cySGVpZ2h0LCBmb3JtYXQsIHR5cGUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBnbENvcHlUZXhTdWJJbWFnZTJEKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xDb3B5VGV4U3ViSW1hZ2UyRCIpOwoKICAgICAgICAgICAgZ2xSZWFkQnVmZmVyKHByZXZSZWFkKTsKICAgICAgICAgICAgdmNoZWNrR0xjYWxsKCJnbFJlYWRCdWZmZXIiKTsKCiAgICAgICAgICAgIExFQVZFX0dMKCk7CgogICAgICAgICAgICBUUkFDRSgiVXBkYXRlZCB0YXJnZXQgJWRcbiIsIFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0KTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9IGVsc2UKICAgICAgICAvKiBUaGUgb25seSBwbGFjZSB3aGVyZSBMb2FkVGV4dHVyZSgpIG1pZ2h0IGdldCBjYWxsZWQgd2hlbiBpc0luRHJhdz0xCiAgICAgICAgICogaXMgQWN0aXZhdGVDb250ZXh0IHdoZXJlIGxhc3RBY3RpdmVSZW5kZXJUYXJnZXQgaXMgcHJlbG9hZGVkLgogICAgICAgICAqLwogICAgICAgIGlmKGlmYWNlID09IGRldmljZS0+bGFzdEFjdGl2ZVJlbmRlclRhcmdldCAmJiBkZXZpY2UtPmlzSW5EcmF3KQogICAgICAgICAgICBFUlIoIlJlYWRpbmcgYmFjayByZW5kZXIgdGFyZ2V0IGJ1dCBTRkxBR19JTkRSQVdBQkxFIG5vdCBzZXRcbiIpOwoKICAgIC8qIE90aGVyd2lzZTogU3lzdGVtIG1lbW9yeSBjb3B5IG11c3QgYmUgbW9zdCB1cCB0byBkYXRlICovCgogICAgaWYoVGhpcy0+Q0tleUZsYWdzICYgV0lORUREU0RfQ0tTUkNCTFQpIHsKICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19HTENLRVk7CiAgICAgICAgVGhpcy0+Z2xDS2V5ID0gVGhpcy0+U3JjQmx0Q0tleTsKICAgIH0KICAgIGVsc2UgVGhpcy0+RmxhZ3MgJj0gflNGTEFHX0dMQ0tFWTsKCiAgICAvKiBUaGUgd2lkdGggaXMgaW4gJ2xlbmd0aCcgbm90IGluIGJ5dGVzICovCiAgICB3aWR0aCA9IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoOwogICAgcGl0Y2ggPSBJV2luZUQzRFN1cmZhY2VfR2V0UGl0Y2goaWZhY2UpOwoKICAgIGlmKChjb252ZXJ0ICE9IE5PX0NPTlZFUlNJT04pICYmIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSkgewogICAgICAgIGludCBoZWlnaHQgPSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQ7CgogICAgICAgIC8qIFN0aWNrIHRvIHRoZSBhbGlnbm1lbnQgZm9yIHRoZSBjb252ZXJ0ZWQgc3VyZmFjZSB0b28sIG1ha2VzIGl0IGVhc2llciB0byBsb2FkIHRoZSBzdXJmYWNlICovCiAgICAgICAgb3V0cGl0Y2ggPSB3aWR0aCAqIGJwcDsKICAgICAgICBvdXRwaXRjaCA9IChvdXRwaXRjaCArIFNVUkZBQ0VfQUxJR05NRU5UIC0gMSkgJiB+KFNVUkZBQ0VfQUxJR05NRU5UIC0gMSk7CgogICAgICAgIG1lbSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBvdXRwaXRjaCAqIGhlaWdodCk7CiAgICAgICAgaWYoIW1lbSkgewogICAgICAgICAgICBFUlIoIk91dCBvZiBtZW1vcnkgJWQsICVkIVxuIiwgb3V0cGl0Y2gsIGhlaWdodCk7CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX09VVE9GVklERU9NRU1PUlk7CiAgICAgICAgfQogICAgICAgIGQzZGZtdF9jb252ZXJ0X3N1cmZhY2UoVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5LCBtZW0sIHBpdGNoLCB3aWR0aCwgaGVpZ2h0LCBvdXRwaXRjaCwgY29udmVydCwgVGhpcyk7CgogICAgICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX0NPTlZFUlRFRDsKICAgIH0gZWxzZSBpZiAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfUDggJiYgR0xfU1VQUE9SVChFWFRfUEFMRVRURURfVEVYVFVSRSkpIHsKICAgICAgICBkM2RmbXRfcDhfdXBsb2FkX3BhbGV0dGUoaWZhY2UsIGNvbnZlcnQpOwogICAgICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19DT05WRVJURUQ7CiAgICAgICAgbWVtID0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5OwogICAgfSBlbHNlIHsKICAgICAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfQ09OVkVSVEVEOwogICAgICAgIG1lbSA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeTsKICAgIH0KCiAgICAvKiBNYWtlIHN1cmUgdGhlIGNvcnJlY3QgcGl0Y2ggaXMgdXNlZCAqLwogICAgZ2xQaXhlbFN0b3JlaShHTF9VTlBBQ0tfUk9XX0xFTkdUSCwgd2lkdGgpOwoKICAgIGlmICgoVGhpcy0+RmxhZ3MgJiBTRkxBR19OT05QT1cyKSAmJiAhKFRoaXMtPkZsYWdzICYgU0ZMQUdfT1ZFUlNJWkUpKSB7CiAgICAgICAgVFJBQ0UoIm5vbiBwb3dlciBvZiB0d28gc3VwcG9ydFxuIik7CiAgICAgICAgaWYoIShUaGlzLT5GbGFncyAmIFNGTEFHX0FMTE9DQVRFRCkpIHsKICAgICAgICAgICAgc3VyZmFjZV9hbGxvY2F0ZV9zdXJmYWNlKFRoaXMsIGludGVybmFsLCBUaGlzLT5wb3cyV2lkdGgsIFRoaXMtPnBvdzJIZWlnaHQsIGZvcm1hdCwgdHlwZSk7CiAgICAgICAgfQogICAgICAgIGlmIChtZW0pIHsKICAgICAgICAgICAgc3VyZmFjZV91cGxvYWRfZGF0YShUaGlzLCBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCwgVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0LCBmb3JtYXQsIHR5cGUsIG1lbSk7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICAvKiBXaGVuIG1ha2luZyB0aGUgcmVhbGxvYyBjb25kaXRpb25hbCwga2VlcCBpbiBtaW5kIHRoYXQgR0xfQVBQTEVfY2xpZW50X3N0b3JhZ2UgbWF5IGJlIGluIHVzZSwgYW5kIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeQogICAgICAgICAqIGNoYW5nZWQuIFNvIGFsc28ga2VlcCB0cmFjayBvZiBtZW1vcnkgY2hhbmdlcy4gSW4gdGhpcyBjYXNlIHRoZSB0ZXh0dXJlIGhhcyB0byBiZSByZWFsbG9jYXRlZAogICAgICAgICAqLwogICAgICAgIGlmKCEoVGhpcy0+RmxhZ3MgJiBTRkxBR19BTExPQ0FURUQpKSB7CiAgICAgICAgICAgIHN1cmZhY2VfYWxsb2NhdGVfc3VyZmFjZShUaGlzLCBpbnRlcm5hbCwgVGhpcy0+Z2xSZWN0LnJpZ2h0IC0gVGhpcy0+Z2xSZWN0LmxlZnQsIFRoaXMtPmdsUmVjdC5ib3R0b20gLSBUaGlzLT5nbFJlY3QudG9wLCBmb3JtYXQsIHR5cGUpOwogICAgICAgIH0KICAgICAgICBpZiAobWVtKSB7CiAgICAgICAgICAgIHN1cmZhY2VfdXBsb2FkX2RhdGEoVGhpcywgVGhpcy0+Z2xSZWN0LnJpZ2h0IC0gVGhpcy0+Z2xSZWN0LmxlZnQsIFRoaXMtPmdsUmVjdC5ib3R0b20gLSBUaGlzLT5nbFJlY3QudG9wLCBmb3JtYXQsIHR5cGUsIG1lbSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qIFJlc3RvcmUgdGhlIGRlZmF1bHQgcGl0Y2ggKi8KICAgIGdsUGl4ZWxTdG9yZWkoR0xfVU5QQUNLX1JPV19MRU5HVEgsIDApOwoKICAgIGlmIChtZW0gIT0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KQogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG1lbSk7CgojaWYgMAogICAgewogICAgICAgIHN0YXRpYyB1bnNpZ25lZCBpbnQgZ2VuID0gMDsKICAgICAgICBjaGFyIGJ1ZmZlcls0MDk2XTsKICAgICAgICArK2dlbjsKICAgICAgICBpZiAoKGdlbiAlIDEwKSA9PSAwKSB7CiAgICAgICAgICAgIHNucHJpbnRmKGJ1ZmZlciwgc2l6ZW9mKGJ1ZmZlciksICIvdG1wL3N1cmZhY2UlcF90eXBlJXVfbGV2ZWwldV8ldS5wcG0iLCBUaGlzLCBUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCwgVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCwgZ2VuKTsKICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TYXZlU25hcHNob3QoaWZhY2UsIGJ1ZmZlcik7CiAgICAgICAgfQogICAgICAgIC8qCiAgICAgICAgICogZGVidWdnaW5nIGNyYXNoIGNvZGUKICAgICAgICAgaWYgKGdlbiA9PSAyNTApIHsKICAgICAgICAgdm9pZCoqIHRlc3QgPSBOVUxMOwogICAgICAgICAqdGVzdCA9IDA7CiAgICAgICAgIH0KICAgICAgICAgKi8KICAgIH0KI2VuZGlmCgogICAgaWYgKCEoVGhpcy0+RmxhZ3MgJiBTRkxBR19ET05PVEZSRUUpKSB7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKICAgICAgICBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgPSBOVUxMOwogICAgICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19JTlNZU01FTTsKICAgIH0KCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKI2luY2x1ZGUgPGVycm5vLmg+CiNpbmNsdWRlIDxzdGRpby5oPgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1NhdmVTbmFwc2hvdChJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBjb25zdCBjaGFyKiBmaWxlbmFtZSkgewogICAgRklMRSogZiA9IE5VTEw7CiAgICBVSU5UIGksIHk7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIGNoYXIgKmFsbG9jYXRlZE1lbW9yeTsKICAgIGNoYXIgKnRleHR1cmVSb3c7CiAgICBJV2luZUQzRFN3YXBDaGFpbiAqc3dhcENoYWluID0gTlVMTDsKICAgIGludCB3aWR0aCwgaGVpZ2h0OwogICAgR0x1aW50IHRtcFRleHR1cmUgPSAwOwogICAgRFdPUkQgY29sb3I7CiAgICAvKkZJWE1FOgogICAgVGV4dHVyZXMgbXkgbm90IGJlIHN0b3JlZCBpbiAtPmFsbG9jYXRlZGdNZW1vcnkgYW5kIGEgR2xUZXh0dXJlCiAgICBzbyB3ZSBzaG91bGQgbG9jayB0aGUgc3VyZmFjZSBiZWZvcmUgc2F2aW5nIGEgc25hcHNob3QsIG9yIGF0IGxlYXN0IGNoZWNrIHRoYXQKICAgICovCiAgICAvKiBUT0RPOiBDb21wcmVzc2VkIHRleHR1cmUgaW1hZ2VzIGNhbiBiZSBvYnRhaW5lZCBmcm9tIHRoZSBHTCBpbiB1bmNvbXByZXNzZWQgZm9ybQogICAgYnkgY2FsbGluZyBHZXRUZXhJbWFnZSBhbmQgaW4gY29tcHJlc3NlZCBmb3JtIGJ5IGNhbGxpbmcKICAgIEdldENvbXByZXNzZWRUZXhJbWFnZUFSQi4gIFF1ZXJpZWQgY29tcHJlc3NlZCBpbWFnZXMgY2FuIGJlIHNhdmVkIGFuZAogICAgbGF0ZXIgcmV1c2VkIGJ5IGNhbGxpbmcgQ29tcHJlc3NlZFRleEltYWdlWzEyM11EQVJCLiAgUHJlLWNvbXByZXNzZWQKICAgIHRleHR1cmUgaW1hZ2VzIGRvIG5vdCBuZWVkIHRvIGJlIHByb2Nlc3NlZCBieSB0aGUgR0wgYW5kIHNob3VsZAogICAgc2lnbmlmaWNhbnRseSBpbXByb3ZlIHRleHR1cmUgbG9hZGluZyBwZXJmb3JtYW5jZSByZWxhdGl2ZSB0byB1bmNvbXByZXNzZWQKICAgIGltYWdlcy4gKi8KCi8qIFNldHVwIHRoZSB3aWR0aCBhbmQgaGVpZ2h0IHRvIGJlIHRoZSBpbnRlcm5hbCB0ZXh0dXJlIHdpZHRoIGFuZCBoZWlnaHQuICovCiAgICB3aWR0aCAgPSBUaGlzLT5wb3cyV2lkdGg7CiAgICBoZWlnaHQgPSBUaGlzLT5wb3cySGVpZ2h0OwovKiBjaGVjayB0byBzZWUgaWYgd2VyZSBhICd2aXJ0dWFsJyB0ZXh0dXJlIGUuZy4gd2VyZSBub3QgYSBwYnVmZmVyIG9mIHRleHR1cmUgd2VyZSBhIGJhY2sgYnVmZmVyKi8KICAgIElXaW5lRDNEU3VyZmFjZV9HZXRDb250YWluZXIoaWZhY2UsICZJSURfSVdpbmVEM0RTd2FwQ2hhaW4sICh2b2lkICoqKSZzd2FwQ2hhaW4pOwoKICAgIGlmIChUaGlzLT5GbGFncyAmIFNGTEFHX0lORFJBV0FCTEUgJiYgIShUaGlzLT5GbGFncyAmIFNGTEFHX0lOVEVYVFVSRSkpIHsKICAgICAgICAvKiBpZiB3ZXJlIG5vdCBhIHJlYWwgdGV4dHVyZSB0aGVuIHJlYWQgdGhlIGJhY2sgYnVmZmVyIGludG8gYSByZWFsIHRleHR1cmUgKi8KICAgICAgICAvKiB3ZSBkb24ndCB3YW50IHRvIGludGVyZmVyZSB3aXRoIHRoZSBiYWNrIGJ1ZmZlciBzbyByZWFkIHRoZSBkYXRhIGludG8gYSB0ZW1wb3JhcnkKICAgICAgICAgKiB0ZXh0dXJlIGFuZCB0aGVuIHNhdmUgdGhlIGRhdGEgb3V0IG9mIHRoZSB0ZW1wb3JhcnkgdGV4dHVyZQogICAgICAgICAqLwogICAgICAgIEdMaW50IHByZXZSZWFkOwogICAgICAgIEVOVEVSX0dMKCk7CiAgICAgICAgVFJBQ0UoIiglcCkgUmVhZGluZyByZW5kZXIgdGFyZ2V0IGludG8gdGV4dHVyZVxuIiwgVGhpcyk7CiAgICAgICAgZ2xFbmFibGUoR0xfVEVYVFVSRV8yRCk7CgogICAgICAgIGdsR2VuVGV4dHVyZXMoMSwgJnRtcFRleHR1cmUpOwogICAgICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgdG1wVGV4dHVyZSk7CgogICAgICAgIGdsVGV4SW1hZ2UyRChHTF9URVhUVVJFXzJELAogICAgICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgICAgICBHTF9SR0JBLAogICAgICAgICAgICAgICAgICAgICAgICB3aWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0LAogICAgICAgICAgICAgICAgICAgICAgICAwLypib3JkZXIqLywKICAgICAgICAgICAgICAgICAgICAgICAgR0xfUkdCQSwKICAgICAgICAgICAgICAgICAgICAgICAgR0xfVU5TSUdORURfSU5UXzhfOF84XzhfUkVWLAogICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKCiAgICAgICAgZ2xHZXRJbnRlZ2VydihHTF9SRUFEX0JVRkZFUiwgJnByZXZSZWFkKTsKICAgICAgICB2Y2hlY2tHTGNhbGwoImdsR2V0SW50ZWdlcnYiKTsKICAgICAgICBnbFJlYWRCdWZmZXIoc3dhcENoYWluID8gR0xfQkFDSyA6IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2UtPm9mZnNjcmVlbkJ1ZmZlcik7CiAgICAgICAgdmNoZWNrR0xjYWxsKCJnbFJlYWRCdWZmZXIiKTsKICAgICAgICBnbENvcHlUZXhJbWFnZTJEKEdMX1RFWFRVUkVfMkQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgR0xfUkdCQSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAwKTsKCiAgICAgICAgY2hlY2tHTGNhbGwoImdsQ29weVRleEltYWdlMkQiKTsKICAgICAgICBnbFJlYWRCdWZmZXIocHJldlJlYWQpOwogICAgICAgIExFQVZFX0dMKCk7CgogICAgfSBlbHNlIHsgLyogYmluZCB0aGUgcmVhbCB0ZXh0dXJlLCBhbmQgbWFrZSBzdXJlIGl0IHVwIHRvIGRhdGUgKi8KICAgICAgICBJV2luZUQzRFN1cmZhY2VfUHJlTG9hZChpZmFjZSk7CiAgICB9CiAgICBhbGxvY2F0ZWRNZW1vcnkgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgd2lkdGggICogaGVpZ2h0ICogNCk7CiAgICBFTlRFUl9HTCgpOwogICAgRklYTUUoIlNhdmluZyB0ZXh0dXJlIGxldmVsICVkIHdpZHRoICVkIGhlaWdodCAlZFxuIiwgVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCwgd2lkdGgsIGhlaWdodCk7CiAgICBnbEdldFRleEltYWdlKEdMX1RFWFRVUkVfMkQsCiAgICAgICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLAogICAgICAgICAgICAgICAgR0xfUkdCQSwKICAgICAgICAgICAgICAgIEdMX1VOU0lHTkVEX0lOVF84XzhfOF84X1JFViwKICAgICAgICAgICAgICAgIGFsbG9jYXRlZE1lbW9yeSk7CiAgICBjaGVja0dMY2FsbCgiZ2xUZXhJbWFnZTJEIik7CiAgICBpZiAodG1wVGV4dHVyZSkgewogICAgICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgMCk7CiAgICAgICAgZ2xEZWxldGVUZXh0dXJlcygxLCAmdG1wVGV4dHVyZSk7CiAgICB9CiAgICBMRUFWRV9HTCgpOwoKICAgIGYgPSBmb3BlbihmaWxlbmFtZSwgIncrIik7CiAgICBpZiAoTlVMTCA9PSBmKSB7CiAgICAgICAgRVJSKCJvcGVuaW5nIG9mICVzIGZhaWxlZCB3aXRoOiAlc1xuIiwgZmlsZW5hbWUsIHN0cmVycm9yKGVycm5vKSk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9Ci8qIFNhdmUgdGhlIGRhdCBvdXQgdG8gYSBUR0EgZmlsZSBiZWNhdXNlIDE6IGl0J3MgYW4gZWFzeSByYXcgZm9ybWF0LCAyOiBpdCBzdXBwb3J0cyBhbiBhbHBoYSBjaGFuZWwqLwogICAgVFJBQ0UoIiglcCkgb3BlbmVkICVzIHdpdGggZm9ybWF0ICVzXG4iLCBUaGlzLCBmaWxlbmFtZSwgZGVidWdfZDNkZm9ybWF0KFRoaXMtPnJlc291cmNlLmZvcm1hdCkpOwovKiBUR0EgaGVhZGVyICovCiAgICBmcHV0YygwLGYpOwogICAgZnB1dGMoMCxmKTsKICAgIGZwdXRjKDIsZik7CiAgICBmcHV0YygwLGYpOwogICAgZnB1dGMoMCxmKTsKICAgIGZwdXRjKDAsZik7CiAgICBmcHV0YygwLGYpOwogICAgZnB1dGMoMCxmKTsKICAgIGZwdXRjKDAsZik7CiAgICBmcHV0YygwLGYpOwogICAgZnB1dGMoMCxmKTsKICAgIGZwdXRjKDAsZik7Ci8qIHNob3J0IHdpZHRoKi8KICAgIGZ3cml0ZSgmd2lkdGgsMiwxLGYpOwovKiBzaG9ydCBoZWlnaHQgKi8KICAgIGZ3cml0ZSgmaGVpZ2h0LDIsMSxmKTsKLyogZm9ybWF0IHJnYmEgKi8KICAgIGZwdXRjKDB4MjAsZik7CiAgICBmcHV0YygweDI4LGYpOwovKiByYXcgZGF0YSAqLwogICAgLyogaWYgIHRoZSBkYXRhIGlzIHVwc2lkZSBkb3duIGlmIHdlJ3ZlIGZldGNoZWQgaXQgZnJvbSBhIGJhY2sgYnVmZmVyLCBzbyBpdCBuZWVkcyBmbGlwcGluZyBhZ2FpbiB0byBtYWtlIGl0IHRoZSBjb3JyZWN0IHdheSB1cCovCiAgICBpZihzd2FwQ2hhaW4pCiAgICAgICAgdGV4dHVyZVJvdyA9IGFsbG9jYXRlZE1lbW9yeSArICh3aWR0aCAqIChoZWlnaHQgLSAxKSAqNCk7CiAgICBlbHNlCiAgICAgICAgdGV4dHVyZVJvdyA9IGFsbG9jYXRlZE1lbW9yeTsKICAgIGZvciAoeSA9IDAgOyB5IDwgaGVpZ2h0OyB5KyspIHsKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgd2lkdGg7ICBpKyspIHsKICAgICAgICAgICAgY29sb3IgPSAqKChEV09SRCopdGV4dHVyZVJvdyk7CiAgICAgICAgICAgIGZwdXRjKChjb2xvciA+PiAxNikgJiAweEZGLCBmKTsgLyogQiAqLwogICAgICAgICAgICBmcHV0YygoY29sb3IgPj4gIDgpICYgMHhGRiwgZik7IC8qIEcgKi8KICAgICAgICAgICAgZnB1dGMoKGNvbG9yID4+ICAwKSAmIDB4RkYsIGYpOyAvKiBSICovCiAgICAgICAgICAgIGZwdXRjKChjb2xvciA+PiAyNCkgJiAweEZGLCBmKTsgLyogQSAqLwogICAgICAgICAgICB0ZXh0dXJlUm93ICs9IDQ7CiAgICAgICAgfQogICAgICAgIC8qIHRha2UgdHdvIHJvd3Mgb2YgdGhlIHBvaW50ZXIgdG8gdGhlIHRleHR1cmUgbWVtb3J5ICovCiAgICAgICAgaWYoc3dhcENoYWluKQogICAgICAgICAgICAodGV4dHVyZVJvdy09IHdpZHRoIDw8IDMpOwoKICAgIH0KICAgIFRSQUNFKCJDbG9zaW5nIGZpbGVcbiIpOwogICAgZmNsb3NlKGYpOwoKICAgIGlmKHN3YXBDaGFpbikgewogICAgICAgIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2Uoc3dhcENoYWluKTsKICAgIH0KICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGFsbG9jYXRlZE1lbW9yeSk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqCiAqICAgU2xpZ2h0bHkgaW5lZmZpY2llbnQgd2F5IHRvIGhhbmRsZSBtdWx0aXBsZSBkaXJ0eSByZWN0cyBidXQgaXQgd29ya3MgOikKICovCmV4dGVybiBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0FkZERpcnR5UmVjdChJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBDT05TVCBSRUNUKiBwRGlydHlSZWN0KSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEQmFzZVRleHR1cmUgKmJhc2VUZXh0dXJlID0gTlVMTDsKICAgIFRoaXMtPkZsYWdzICY9IH4oU0ZMQUdfSU5URVhUVVJFIHwgU0ZMQUdfSU5EUkFXQUJMRSk7CiAgICBpZiAoTlVMTCAhPSBwRGlydHlSZWN0KSB7CiAgICAgICAgVGhpcy0+ZGlydHlSZWN0LmxlZnQgICA9IG1pbihUaGlzLT5kaXJ0eVJlY3QubGVmdCwgICBwRGlydHlSZWN0LT5sZWZ0KTsKICAgICAgICBUaGlzLT5kaXJ0eVJlY3QudG9wICAgID0gbWluKFRoaXMtPmRpcnR5UmVjdC50b3AsICAgIHBEaXJ0eVJlY3QtPnRvcCk7CiAgICAgICAgVGhpcy0+ZGlydHlSZWN0LnJpZ2h0ICA9IG1heChUaGlzLT5kaXJ0eVJlY3QucmlnaHQsICBwRGlydHlSZWN0LT5yaWdodCk7CiAgICAgICAgVGhpcy0+ZGlydHlSZWN0LmJvdHRvbSA9IG1heChUaGlzLT5kaXJ0eVJlY3QuYm90dG9tLCBwRGlydHlSZWN0LT5ib3R0b20pOwogICAgfSBlbHNlIHsKICAgICAgICBUaGlzLT5kaXJ0eVJlY3QubGVmdCAgID0gMDsKICAgICAgICBUaGlzLT5kaXJ0eVJlY3QudG9wICAgID0gMDsKICAgICAgICBUaGlzLT5kaXJ0eVJlY3QucmlnaHQgID0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAgICAgVGhpcy0+ZGlydHlSZWN0LmJvdHRvbSA9IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgIH0KICAgIFRSQUNFKCIoJXApIDogRGlydHk6IHllcywgUmVjdDooJWQsJWQsJWQsJWQpXG4iLCBUaGlzLCBUaGlzLT5kaXJ0eVJlY3QubGVmdCwKICAgICAgICAgIFRoaXMtPmRpcnR5UmVjdC50b3AsIFRoaXMtPmRpcnR5UmVjdC5yaWdodCwgVGhpcy0+ZGlydHlSZWN0LmJvdHRvbSk7CiAgICAvKiBpZiB0aGUgY29udGFpbmVyIGlzIGEgYmFzZXRleHR1cmUgdGhlbiBtYXJrIGl0IGRpcnR5LiAqLwogICAgaWYgKElXaW5lRDNEU3VyZmFjZV9HZXRDb250YWluZXIoaWZhY2UsICZJSURfSVdpbmVEM0RCYXNlVGV4dHVyZSwgKHZvaWQgKiopJmJhc2VUZXh0dXJlKSA9PSBXSU5FRDNEX09LKSB7CiAgICAgICAgVFJBQ0UoIlBhc3NpbmcgdG8gY29uYXRpbmVyXG4iKTsKICAgICAgICBJV2luZUQzREJhc2VUZXh0dXJlX1NldERpcnR5KGJhc2VUZXh0dXJlLCBUUlVFKTsKICAgICAgICBJV2luZUQzREJhc2VUZXh0dXJlX1JlbGVhc2UoYmFzZVRleHR1cmUpOwogICAgfQogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0Q29udGFpbmVyKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIElXaW5lRDNEQmFzZSAqY29udGFpbmVyKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKCiAgICBUUkFDRSgiVGhpcyAlcCwgY29udGFpbmVyICVwXG4iLCBUaGlzLCBjb250YWluZXIpOwoKICAgIC8qIFdlIGNhbid0IGtlZXAgYSByZWZlcmVuY2UgdG8gdGhlIGNvbnRhaW5lciwgc2luY2UgdGhlIGNvbnRhaW5lciBhbHJlYWR5IGtlZXBzIGEgcmVmZXJlbmNlIHRvIHVzLiAqLwoKICAgIFRSQUNFKCJTZXR0aW5nIGNvbnRhaW5lciB0byAlcCBmcm9tICVwXG4iLCBjb250YWluZXIsIFRoaXMtPmNvbnRhaW5lcik7CiAgICBUaGlzLT5jb250YWluZXIgPSBjb250YWluZXI7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0Rm9ybWF0KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIFdJTkVEM0RGT1JNQVQgZm9ybWF0KSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIGNvbnN0IFBpeGVsRm9ybWF0RGVzYyAqZm9ybWF0RW50cnkgPSBnZXRGb3JtYXREZXNjRW50cnkoZm9ybWF0KTsKCiAgICBpZiAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ICE9IFdJTkVEM0RGTVRfVU5LTk9XTikgewogICAgICAgIEZJWE1FKCIoJXApIDogVGhlIGZvcmFtdCBvZiB0aGUgc3VyZmFjZSBtdXN0IGJlIFdJTkVEM0RGT1JNQVRfVU5LTk9XTlxuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgVFJBQ0UoIiglcCkgOiBTZXR0aW5nIHRleHR1cmUgZm9yYW10IHRvICglZCwlcylcbiIsIFRoaXMsIGZvcm1hdCwgZGVidWdfZDNkZm9ybWF0KGZvcm1hdCkpOwogICAgaWYgKGZvcm1hdCA9PSBXSU5FRDNERk1UX1VOS05PV04pIHsKICAgICAgICBUaGlzLT5yZXNvdXJjZS5zaXplID0gMDsKICAgIH0gZWxzZSBpZiAoZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMSkgewogICAgICAgIC8qIERYVDEgaXMgaGFsZiBieXRlIHBlciBwaXhlbCAqLwogICAgICAgIFRoaXMtPnJlc291cmNlLnNpemUgPSAoKG1heChUaGlzLT5wb3cyV2lkdGgsIDQpICogZm9ybWF0RW50cnktPmJwcCkgKiBtYXgoVGhpcy0+cG93MkhlaWdodCwgNCkpID4+IDE7CgogICAgfSBlbHNlIGlmIChmb3JtYXQgPT0gV0lORUQzREZNVF9EWFQyIHx8IGZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDMgfHwKICAgICAgICAgICAgICAgZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNCB8fCBmb3JtYXQgPT0gV0lORUQzREZNVF9EWFQ1KSB7CiAgICAgICAgVGhpcy0+cmVzb3VyY2Uuc2l6ZSA9ICgobWF4KFRoaXMtPnBvdzJXaWR0aCwgNCkgKiBmb3JtYXRFbnRyeS0+YnBwKSAqIG1heChUaGlzLT5wb3cySGVpZ2h0LCA0KSk7CiAgICB9IGVsc2UgewogICAgICAgIFRoaXMtPnJlc291cmNlLnNpemUgPSAoKFRoaXMtPnBvdzJXaWR0aCAqIGZvcm1hdEVudHJ5LT5icHApICsgU1VSRkFDRV9BTElHTk1FTlQgLSAxKSAmIH4oU1VSRkFDRV9BTElHTk1FTlQgLSAxKTsKICAgICAgICBUaGlzLT5yZXNvdXJjZS5zaXplICo9IFRoaXMtPnBvdzJIZWlnaHQ7CiAgICB9CgoKICAgIC8qIFNldHVwIHNvbWUgZ2xmb3JtYXQgZGVmYXVsdHMgKi8KICAgIFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xGb3JtYXQgICAgICAgICA9IGZvcm1hdEVudHJ5LT5nbEZvcm1hdDsKICAgIFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xGb3JtYXRJbnRlcm5hbCA9IGZvcm1hdEVudHJ5LT5nbEludGVybmFsOwogICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbFR5cGUgICAgICAgICAgID0gZm9ybWF0RW50cnktPmdsVHlwZTsKCiAgICBpZiAoZm9ybWF0ICE9IFdJTkVEM0RGTVRfVU5LTk9XTikgewogICAgICAgIFRoaXMtPmJ5dGVzUGVyUGl4ZWwgPSBmb3JtYXRFbnRyeS0+YnBwOwogICAgfSBlbHNlIHsKICAgICAgICBUaGlzLT5ieXRlc1BlclBpeGVsID0gMDsKICAgIH0KCiAgICBUaGlzLT5GbGFncyB8PSAoV0lORUQzREZNVF9EMTZfTE9DS0FCTEUgPT0gZm9ybWF0KSA/IFNGTEFHX0xPQ0tBQkxFIDogMDsKICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19BTExPQ0FURUQ7CgogICAgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID0gZm9ybWF0OwoKICAgIFRSQUNFKCIoJXApIDogU2l6ZSAlZCwgYnl0ZXNQZXJQaXhlbCAlZCwgZ2xGb3JtYXQgJWQsIGdsRm90bWF0SW50ZXJuYWwgJWQsIGdsVHlwZSAlZFxuIiwgVGhpcywgVGhpcy0+cmVzb3VyY2Uuc2l6ZSwgVGhpcy0+Ynl0ZXNQZXJQaXhlbCwgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdCwgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdEludGVybmFsLCBUaGlzLT5nbERlc2NyaXB0aW9uLmdsVHlwZSk7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0TWVtKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIHZvaWQgKk1lbSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwoKICAgIC8qIFJlbmRlciB0YXJnZXRzIGRlcGVuZCBvbiB0aGVpciBoZGMsIGFuZCB3ZSBjYW4ndCBjcmVhdGUgYSBoZGMgb24gYSB1c2VyIHBvaW50ZXIgKi8KICAgIGlmKFRoaXMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkgewogICAgICAgIEVSUigiTm90IHN1cHBvcnRlZCBvbiByZW5kZXIgdGFyZ2V0c1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgaWYoVGhpcy0+RmxhZ3MgJiAoU0ZMQUdfTE9DS0VEIHwgU0ZMQUdfRENJTlVTRSkpIHsKICAgICAgICBXQVJOKCJTdXJmYWNlIGlzIGxvY2tlZCBvciB0aGUgSERDIGlzIGluIHVzZVxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgaWYoTWVtICYmIE1lbSAhPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpIHsKICAgICAgICB2b2lkICpyZWxlYXNlID0gTlVMTDsKCiAgICAgICAgLyogRG8gSSBoYXZlIHRvIGNvcHkgdGhlIG9sZCBzdXJmYWNlIGNvbnRlbnQ/ICovCiAgICAgICAgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19ESUJTRUNUSU9OKSB7CiAgICAgICAgICAgICAgICAvKiBSZWxlYXNlIHRoZSBEQy4gTm8gbmVlZCB0byBob2xkIHRoZSBjcml0aWNhbCBzZWN0aW9uIGZvciB0aGUgdXBkYXRlCiAgICAgICAgICAgICAgICAgKiBUaHJlYWQgYmVjYXVzZSB0aGlzIHRocmVhZCBydW5zIG9ubHkgb24gZnJvbnQgYnVmZmVycywgYnV0IHRoaXMgbWV0aG9kCiAgICAgICAgICAgICAgICAgKiBmYWlscyBmb3IgcmVuZGVyIHRhcmdldHMgaW4gdGhlIGNoZWNrIGFib3ZlLgogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBTZWxlY3RPYmplY3QoVGhpcy0+aERDLCBUaGlzLT5kaWIuaG9sZGJpdG1hcCk7CiAgICAgICAgICAgICAgICBEZWxldGVEQyhUaGlzLT5oREMpOwogICAgICAgICAgICAgICAgLyogUmVsZWFzZSB0aGUgRElCIHNlY3Rpb24gKi8KICAgICAgICAgICAgICAgIERlbGV0ZU9iamVjdChUaGlzLT5kaWIuRElCc2VjdGlvbik7CiAgICAgICAgICAgICAgICBUaGlzLT5kaWIuYml0bWFwX2RhdGEgPSBOVUxMOwogICAgICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gTlVMTDsKICAgICAgICAgICAgICAgIFRoaXMtPmhEQyA9IE5VTEw7CiAgICAgICAgICAgICAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfRElCU0VDVElPTjsKICAgICAgICB9IGVsc2UgaWYoIShUaGlzLT5GbGFncyAmIFNGTEFHX1VTRVJQVFIpKSB7CiAgICAgICAgICAgIHJlbGVhc2UgPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnk7CiAgICAgICAgfQogICAgICAgIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IE1lbTsKICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19VU0VSUFRSIHwgU0ZMQUdfSU5TWVNNRU07CgogICAgICAgIC8qIE5vdyB0aGUgc3VyZmFjZSBtZW1vcnkgaXMgbW9zdCB1cCBkbyBkYXRlLiBJbnZhbGlkYXRlIGRyYXdhYmxlIGFuZCB0ZXh0dXJlICovCiAgICAgICAgVGhpcy0+RmxhZ3MgJj0gfihTRkxBR19JTkRSQVdBQkxFIHwgU0ZMQUdfSU5URVhUVVJFKTsKCiAgICAgICAgLyogRm9yIGNsaWVudCB0ZXh0dXJlcyBvcGVuZ2wgaGFzIHRvIGJlIG5vdGlmaWVkICovCiAgICAgICAgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19DTElFTlQpIHsKICAgICAgICAgICAgVGhpcy0+RmxhZ3MgJj0gflNGTEFHX0FMTE9DQVRFRDsKICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1ByZUxvYWQoaWZhY2UpOwogICAgICAgICAgICAvKiBBbmQgaG9wZSB0aGF0IHRoZSBhcHAgYmVoYXZlcyBjb3JyZWN0bHkgYW5kIGRpZCBub3QgZnJlZSB0aGUgb2xkIHN1cmZhY2UgbWVtb3J5IGJlZm9yZSBzZXR0aW5nIGEgbmV3IHBvaW50ZXIgKi8KICAgICAgICB9CgogICAgICAgIC8qIE5vdyBmcmVlIHRoZSBvbGQgbWVtb3J5IGlmIGFueSAqLwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHJlbGVhc2UpOwogICAgfSBlbHNlIGlmKFRoaXMtPkZsYWdzICYgU0ZMQUdfVVNFUlBUUikgewogICAgICAgIC8qIExvY2tyZWN0IGFuZCBHZXREQyB3aWxsIHJlLWNyZWF0ZSB0aGUgZGliIHNlY3Rpb24gYW5kIGFsbG9jYXRlZCBtZW1vcnkgKi8KICAgICAgICBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgPSBOVUxMOwogICAgICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19VU0VSUFRSOwoKICAgICAgICBpZihUaGlzLT5GbGFncyAmIFNGTEFHX0NMSUVOVCkgewogICAgICAgICAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfQUxMT0NBVEVEOwogICAgICAgICAgICAvKiBUaGlzIHJlc3BlY2lmaWVzIGFuIGVtcHR5IHRleHR1cmUgYW5kIG9wZW5nbCBrbm93cyB0aGF0IHRoZSBvbGQgbWVtb3J5IGlzIGdvbmUgKi8KICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1ByZUxvYWQoaWZhY2UpOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9GbGlwKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIElXaW5lRDNEU3VyZmFjZSAqb3ZlcnJpZGUsIERXT1JEIEZsYWdzKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNERGV2aWNlICpEM0QgPSAoSVdpbmVEM0REZXZpY2UgKikgVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZTsKICAgIFRSQUNFKCIoJXApLT4oJXAsJXgpXG4iLCBUaGlzLCBvdmVycmlkZSwgRmxhZ3MpOwoKICAgIC8qIEZsaXBwaW5nIGlzIG9ubHkgc3VwcG9ydGVkIG9uIFJlbmRlclRhcmdldHMgKi8KICAgIGlmKCAhKFRoaXMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkgKSByZXR1cm4gV0lORURERVJSX05PVEZMSVBQQUJMRTsKCiAgICBpZihvdmVycmlkZSkgewogICAgICAgIC8qIEREcmF3IHNldHMgdGhpcyBmb3IgdGhlIFgxMSBzdXJmYWNlcywgc28gZG9uJ3QgY29uZnVzZSB0aGUgdXNlciAKICAgICAgICAgKiBGSVhNRSgiKCVwKSBUYXJnZXQgb3ZlcnJpZGUgaXMgbm90IHN1cHBvcnRlZCBieSBub3dcbiIsIFRoaXMpOwogICAgICAgICAqIEFkZGl0aW9uYWxseSwgaXQgaXNuJ3QgcmVhbGx5IHBvc3NpYmxlIHRvIHN1cHBvcnQgdHJpcGxlLWJ1ZmZlcmluZwogICAgICAgICAqIHByb3Blcmx5IG9uIG9wZW5nbCBhdCBhbGwKICAgICAgICAgKi8KICAgIH0KCiAgICAvKiBGbGlwcGluZyBhIE9wZW5HTCBzdXJmYWNlIC0+IFVzZSBXaW5lRDNERGV2aWNlOjpQcmVzZW50ICovCiAgICByZXR1cm4gSVdpbmVEM0REZXZpY2VfUHJlc2VudChEM0QsIE5VTEwsIE5VTEwsIDAsIE5VTEwpOwp9CgovKiBEb2VzIGEgZGlyZWN0IGZyYW1lIGJ1ZmZlciAtPiB0ZXh0dXJlIGNvcHkuIFN0cmV0Y2hpbmcgaXMgZG9uZQogKiB3aXRoIHNpbmdsZSBwaXhlbCBjb3B5IGNhbGxzCiAqLwpzdGF0aWMgaW5saW5lIHZvaWQgZmJfY29weV90b190ZXh0dXJlX2RpcmVjdChJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzLCBJV2luZUQzRFN1cmZhY2UgKlNyY1N1cmZhY2UsIElXaW5lRDNEU3dhcENoYWluSW1wbCAqc3dhcGNoYWluLCBXSU5FRDNEUkVDVCAqc3JlY3QsIFdJTkVEM0RSRUNUICpkcmVjdCwgQk9PTCB1cHNpZGVkb3duLCBXSU5FRDNEVEVYVFVSRUZJTFRFUlRZUEUgRmlsdGVyKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKm15RGV2aWNlID0gVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZTsKICAgIGZsb2F0IHhyZWwsIHlyZWw7CiAgICBVSU5UIHJvdzsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlNyYyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIFNyY1N1cmZhY2U7CgogICAgRU5URVJfR0woKTsKCiAgICBBY3RpdmF0ZUNvbnRleHQobXlEZXZpY2UsIFNyY1N1cmZhY2UsIENUWFVTQUdFX0JMSVQpOwoKICAgIC8qIEJpbmQgdGhlIHRhcmdldCB0ZXh0dXJlICovCiAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIFRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpOwogICAgY2hlY2tHTGNhbGwoImdsQmluZFRleHR1cmUiKTsKICAgIGlmKCFzd2FwY2hhaW4pIHsKICAgICAgICBnbFJlYWRCdWZmZXIobXlEZXZpY2UtPm9mZnNjcmVlbkJ1ZmZlcik7CiAgICB9IGVsc2UgewogICAgICAgIEdMZW51bSBidWZmZXIgPSBzdXJmYWNlX2dldF9nbF9idWZmZXIoU3JjU3VyZmFjZSwgKElXaW5lRDNEU3dhcENoYWluICopc3dhcGNoYWluKTsKICAgICAgICBnbFJlYWRCdWZmZXIoYnVmZmVyKTsKICAgIH0KICAgIGNoZWNrR0xjYWxsKCJnbFJlYWRCdWZmZXIiKTsKCiAgICB4cmVsID0gKGZsb2F0KSAoc3JlY3QtPngyIC0gc3JlY3QtPngxKSAvIChmbG9hdCkgKGRyZWN0LT54MiAtIGRyZWN0LT54MSk7CiAgICB5cmVsID0gKGZsb2F0KSAoc3JlY3QtPnkyIC0gc3JlY3QtPnkxKSAvIChmbG9hdCkgKGRyZWN0LT55MiAtIGRyZWN0LT55MSk7CgogICAgaWYoICh4cmVsIC0gMS4wIDwgLWVwcykgfHwgKHhyZWwgLSAxLjAgPiBlcHMpKSB7CiAgICAgICAgRklYTUUoIkRvaW5nIGEgcGl4ZWwgYnkgcGl4ZWwgY29weSBmcm9tIHRoZSBmcmFtZWJ1ZmZlciB0byBhIHRleHR1cmUsIGV4cGVjdCBtYWpvciBwZXJmb3JtYW5jZSBpc3N1ZXNcbiIpOwoKICAgICAgICBpZihGaWx0ZXIgIT0gV0lORUQzRFRFWEZfTk9ORSAmJiBGaWx0ZXIgIT0gV0lORUQzRFRFWEZfUE9JTlQpIHsKICAgICAgICAgICAgRVJSKCJUZXh0dXJlIGZpbHRlcmluZyBub3Qgc3VwcG9ydGVkIGluIGRpcmVjdCBibGl0XG4iKTsKICAgICAgICB9CiAgICB9IGVsc2UgaWYoKEZpbHRlciAhPSBXSU5FRDNEVEVYRl9OT05FICYmIEZpbHRlciAhPSBXSU5FRDNEVEVYRl9QT0lOVCkgJiYgKCh5cmVsIC0gMS4wIDwgLWVwcykgfHwgKHlyZWwgLSAxLjAgPiBlcHMpKSkgewogICAgICAgIEVSUigiVGV4dHVyZSBmaWx0ZXJpbmcgbm90IHN1cHBvcnRlZCBpbiBkaXJlY3QgYmxpdFxuIik7CiAgICB9CgogICAgaWYodXBzaWRlZG93biAmJgogICAgICAgISgoeHJlbCAtIDEuMCA8IC1lcHMpIHx8ICh4cmVsIC0gMS4wID4gZXBzKSkgJiYKICAgICAgICEoKHlyZWwgLSAxLjAgPCAtZXBzKSB8fCAoeXJlbCAtIDEuMCA+IGVwcykpKSB7CiAgICAgICAgLyogVXBzaWRlIGRvd24gY29weSB3aXRob3V0IHN0cmV0Y2hpbmcgaXMgbmljZSwgb25lIGdsQ29weVRleFN1YkltYWdlIGNhbGwgd2lsbCBkbyAqLwoKICAgICAgICBnbENvcHlUZXhTdWJJbWFnZTJEKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRyZWN0LT54MSwgZHJlY3QtPnkxLCAvKiB4b2Zmc2V0LCB5b2Zmc2V0ICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcmVjdC0+eDEsIFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0IC0gc3JlY3QtPnkyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZHJlY3QtPngyIC0gZHJlY3QtPngxLCBkcmVjdC0+eTIgLSBkcmVjdC0+eTEpOwogICAgfSBlbHNlIHsKICAgICAgICBVSU5UIHlvZmZzZXQgPSBTcmMtPmN1cnJlbnREZXNjLkhlaWdodCAtIHNyZWN0LT55MSArIGRyZWN0LT55MSAtIDE7CiAgICAgICAgLyogSSBoYXZlIHRvIHByb2Nlc3MgdGhpcyByb3cgYnkgcm93IHRvIHN3YXAgdGhlIGltYWdlLAogICAgICAgICAqIG90aGVyd2lzZSBpdCB3b3VsZCBiZSB1cHNpZGUgZG93biwgc28gc3RyZWNoaW5nIGluIHkgZGlyZWN0aW9uCiAgICAgICAgICogZG9lc24ndCBjb3N0IGV4dHJhIHRpbWUKICAgICAgICAgKgogICAgICAgICAqIEhvd2V2ZXIsIHN0cmVjaGluZyBpbiB4IGRpcmVjdGlvbiBjYW4gYmUgYXZvaWRlZCBpZiBub3QgbmVjZXNzYXJ5CiAgICAgICAgICovCiAgICAgICAgZm9yKHJvdyA9IGRyZWN0LT55MTsgcm93IDwgZHJlY3QtPnkyOyByb3crKykgewogICAgICAgICAgICBpZiggKHhyZWwgLSAxLjAgPCAtZXBzKSB8fCAoeHJlbCAtIDEuMCA+IGVwcykpIHsKICAgICAgICAgICAgICAgIC8qIFdlbGwsIHRoYXQgc3R1ZmYgd29ya3MsIGJ1dCBpdCdzIHZlcnkgc2xvdy4KICAgICAgICAgICAgICAgICAqIGZpbmQgYSBiZXR0ZXIgd2F5IGluc3RlYWQKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgVUlOVCBjb2w7CgogICAgICAgICAgICAgICAgZm9yKGNvbCA9IGRyZWN0LT54MTsgY29sIDwgZHJlY3QtPngyOyBjb2wrKykgewogICAgICAgICAgICAgICAgICAgIGdsQ29weVRleFN1YkltYWdlMkQoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHJlY3QtPngxICsgY29sLCByb3csIC8qIHhvZmZzZXQsIHlvZmZzZXQgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNyZWN0LT54MSArIGNvbCAqIHhyZWwsIHlvZmZzZXQgLSAoaW50KSAocm93ICogeXJlbCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLCAxKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGdsQ29weVRleFN1YkltYWdlMkQoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRyZWN0LT54MSwgcm93LCAvKiB4b2Zmc2V0LCB5b2Zmc2V0ICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNyZWN0LT54MSwgeW9mZnNldCAtIChpbnQpIChyb3cgKiB5cmVsKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHJlY3QtPngyLWRyZWN0LT54MSwgMSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgdmNoZWNrR0xjYWxsKCJnbENvcHlUZXhTdWJJbWFnZTJEIik7CiAgICBMRUFWRV9HTCgpOwp9CgovKiBVc2VzIHRoZSBoYXJkd2FyZSB0byBzdHJldGNoIGFuZCBmbGlwIHRoZSBpbWFnZSAqLwpzdGF0aWMgaW5saW5lIHZvaWQgZmJfY29weV90b190ZXh0dXJlX2h3c3RyZXRjaChJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzLCBJV2luZUQzRFN1cmZhY2UgKlNyY1N1cmZhY2UsIElXaW5lRDNEU3dhcENoYWluSW1wbCAqc3dhcGNoYWluLCBXSU5FRDNEUkVDVCAqc3JlY3QsIFdJTkVEM0RSRUNUICpkcmVjdCwgQk9PTCB1cHNpZGVkb3duLCBXSU5FRDNEVEVYVFVSRUZJTFRFUlRZUEUgRmlsdGVyKSB7CiAgICBHTHVpbnQgc3JjLCBiYWNrdXAgPSAwOwogICAgSVdpbmVEM0REZXZpY2VJbXBsICpteURldmljZSA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpTcmMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBTcmNTdXJmYWNlOwogICAgZmxvYXQgbGVmdCwgcmlnaHQsIHRvcCwgYm90dG9tOyAvKiBUZXh0dXJlIGNvb3JkaW5hdGVzICovCiAgICBVSU5UIGZid2lkdGggPSBTcmMtPmN1cnJlbnREZXNjLldpZHRoOwogICAgVUlOVCBmYmhlaWdodCA9IFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0OwogICAgR0xlbnVtIGRyYXdCdWZmZXIgPSBHTF9CQUNLOwoKICAgIFRSQUNFKCJVc2luZyBod3N0cmV0Y2ggYmxpdFxuIik7CiAgICAvKiBBY3RpdmF0ZSB0aGUgUHJvcGVyIGNvbnRleHQgZm9yIHJlYWRpbmcgZnJvbSB0aGUgc291cmNlIHN1cmZhY2UsIHNldCBpdCB1cCBmb3IgYmxpdHRpbmcgKi8KICAgIEVOVEVSX0dMKCk7CiAgICBBY3RpdmF0ZUNvbnRleHQobXlEZXZpY2UsIFNyY1N1cmZhY2UsIENUWFVTQUdFX0JMSVQpOwoKICAgIC8qIFRyeSB0byB1c2UgYW4gYXV4IGJ1ZmZlciBmb3IgZHJhd2luZyB0aGUgcmVjdGFuZ2xlLiBUaGlzIHdheSBpdCBkb2Vzbid0IG5lZWQgcmVzdG9yaW5nLgogICAgICogVGhpcyB3YXkgd2UgZG9uJ3QgaGF2ZSB0byB3YWl0IGZvciB0aGUgMm5kIHJlYWRiYWNrIHRvIGZpbmlzaCB0byBsZWF2ZSB0aGlzIGZ1bmN0aW9uLgogICAgICovCiAgICBpZihHTF9MSU1JVFMoYXV4X2J1ZmZlcnMpID49IDIpIHsKICAgICAgICAvKiBHb3QgbW9yZSB0aGFuIG9uZSBhdXggYnVmZmVyPyBVc2UgdGhlIDJuZCBhdXggYnVmZmVyICovCiAgICAgICAgZHJhd0J1ZmZlciA9IEdMX0FVWDE7CiAgICB9IGVsc2UgaWYoKHN3YXBjaGFpbiB8fCBteURldmljZS0+b2Zmc2NyZWVuQnVmZmVyID09IEdMX0JBQ0spICYmIEdMX0xJTUlUUyhhdXhfYnVmZmVycykgPj0gMSkgewogICAgICAgIC8qIE9ubHkgb25lIGF1eCBidWZmZXIsIGJ1dCBpdCBpc24ndCB1c2VkIChPbnNjcmVlbiByZW5kZXJpbmcsIG9yIG5vbi1hdXggb3JtKT8gVXNlIGl0ISAqLwogICAgICAgIGRyYXdCdWZmZXIgPSBHTF9BVVgwOwogICAgfQoKICAgIGlmKCFzd2FwY2hhaW4gJiYgd2luZWQzZF9zZXR0aW5ncy5vZmZzY3JlZW5fcmVuZGVyaW5nX21vZGUgPT0gT1JNX0ZCTykgewogICAgICAgIGdsR2VuVGV4dHVyZXMoMSwgJmJhY2t1cCk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsR2VuVGV4dHVyZXNcbiIpOwogICAgICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgYmFja3VwKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xCaW5kVGV4dHVyZShTcmMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCBTcmMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpIik7CiAgICB9IGVsc2UgewogICAgICAgIC8qIEJhY2t1cCB0aGUgYmFjayBidWZmZXIgYW5kIGNvcHkgdGhlIHNvdXJjZSBidWZmZXIgaW50byBhIHRleHR1cmUgdG8gZHJhdyBhbiB1cHNpZGUgZG93biBzdHJldGNoZWQgcXVhZC4gSWYKICAgICAgICAgKiB3ZSBhcmUgcmVhZGluZyBmcm9tIHRoZSBiYWNrIGJ1ZmZlciwgdGhlIGJhY2t1cCBjYW4gYmUgdXNlZCBhcyBzb3VyY2UgdGV4dHVyZQogICAgICAgICAqLwogICAgICAgIGlmKFNyYy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSA9PSAwKSB7CiAgICAgICAgICAgIC8qIEdldCBpdCBhIGRlc2NyaXB0aW9uICovCiAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9QcmVMb2FkKFNyY1N1cmZhY2UpOwogICAgICAgIH0KICAgICAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIFNyYy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQmluZFRleHR1cmUoU3JjLT5nbERlc2NyaXB0aW9uLnRhcmdldCwgU3JjLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lKSIpOwoKICAgICAgICAvKiBGb3Igbm93IGludmFsaWRhdGUgdGhlIHRleHR1cmUgY29weSBvZiB0aGUgYmFjayBidWZmZXIuIERyYXdhYmxlIGFuZCBzeXNtZW0gY29weSBhcmUgdW50b3VjaGVkICovCiAgICAgICAgU3JjLT5GbGFncyAmPSB+U0ZMQUdfSU5URVhUVVJFOwogICAgfQoKICAgIGdsUmVhZEJ1ZmZlcihHTF9CQUNLKTsKICAgIGNoZWNrR0xjYWxsKCJnbFJlYWRCdWZmZXIoR0xfQkFDSykiKTsKCiAgICAvKiBUT0RPOiBPbmx5IGJhY2sgdXAgdGhlIHBhcnQgdGhhdCB3aWxsIGJlIG92ZXJ3cml0dGVuICovCiAgICBnbENvcHlUZXhTdWJJbWFnZTJEKEdMX1RFWFRVUkVfMkQsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAgLyogcmVhZCBvZmZzZXRzICovLAogICAgICAgICAgICAgICAgICAgICAgICAwLCAwLAogICAgICAgICAgICAgICAgICAgICAgICBmYndpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICBmYmhlaWdodCk7CgogICAgY2hlY2tHTGNhbGwoImdsQ29weVRleFN1YkltYWdlMkQiKTsKCiAgICAvKiBObyBpc3N1ZSB3aXRoIG92ZXJyaWRpbmcgdGhlc2UgLSB0aGUgc2FtcGxlciBpcyBkaXJ0eSBkdWUgdG8gYmxpdCB1c2FnZSAqLwogICAgZ2xUZXhQYXJhbWV0ZXJpKEdMX1RFWFRVUkVfMkQsIEdMX1RFWFRVUkVfTUFHX0ZJTFRFUiwKICAgICAgICAgICAgICAgICAgICBzdGF0ZUxvb2t1cFtXSU5FTE9PS1VQX01BR0ZJTFRFUl1bRmlsdGVyIC0gbWluTG9va3VwW1dJTkVMT09LVVBfTUFHRklMVEVSXV0pOwogICAgY2hlY2tHTGNhbGwoImdsVGV4UGFyYW1ldGVyaSIpOwogICAgZ2xUZXhQYXJhbWV0ZXJpKEdMX1RFWFRVUkVfMkQsIEdMX1RFWFRVUkVfTUlOX0ZJTFRFUiwKICAgICAgICAgICAgICAgICAgICBtaW5NaXBMb29rdXBbRmlsdGVyXVtXSU5FRDNEVEVYRl9OT05FXSk7CiAgICBjaGVja0dMY2FsbCgiZ2xUZXhQYXJhbWV0ZXJpIik7CgogICAgaWYoIXN3YXBjaGFpbiB8fCAoSVdpbmVEM0RTdXJmYWNlICopIFNyYyA9PSBzd2FwY2hhaW4tPmJhY2tCdWZmZXJbMF0pIHsKICAgICAgICBzcmMgPSBiYWNrdXAgPyBiYWNrdXAgOiBTcmMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWU7CiAgICB9IGVsc2UgewogICAgICAgIGdsUmVhZEJ1ZmZlcihHTF9GUk9OVCk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsUmVhZEJ1ZmZlcihHTF9GUk9OVCkiKTsKCiAgICAgICAgZ2xHZW5UZXh0dXJlcygxLCAmc3JjKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xHZW5UZXh0dXJlcygxLCAmc3JjKSIpOwogICAgICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgc3JjKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCBzcmMpIik7CgogICAgICAgIC8qIFRPRE86IE9ubHkgY29weSB0aGUgcGFydCB0aGF0IHdpbGwgYmUgcmVhZC4gVXNlIHNyZWN0LT54MSwgc3JlY3QtPnkyIGFzIG9yaWdpbiwgYnV0IHdpdGggdGhlIHdpZHRoIHdhdGNoCiAgICAgICAgICogb3V0IGZvciBwb3dlciBvZiAyIHNpemVzCiAgICAgICAgICovCiAgICAgICAgZ2xUZXhJbWFnZTJEKEdMX1RFWFRVUkVfMkQsIDAsIEdMX1JHQkEsIFNyYy0+cG93MldpZHRoLCBTcmMtPnBvdzJIZWlnaHQsIDAsCiAgICAgICAgICAgICAgICAgICAgR0xfUkdCQSwgR0xfVU5TSUdORURfQllURSwgTlVMTCk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsVGV4SW1hZ2UyRCIpOwogICAgICAgIGdsQ29weVRleFN1YkltYWdlMkQoR0xfVEVYVFVSRV8yRCwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAgLyogcmVhZCBvZmZzZXRzICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZid2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYmhlaWdodCk7CgogICAgICAgIGdsVGV4UGFyYW1ldGVyaShHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX01BR19GSUxURVIsIEdMX05FQVJFU1QpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbFRleFBhcmFtZXRlcmkiKTsKICAgICAgICBnbFRleFBhcmFtZXRlcmkoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9NSU5fRklMVEVSLCBHTF9ORUFSRVNUKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xUZXhQYXJhbWV0ZXJpIik7CgogICAgICAgIGdsUmVhZEJ1ZmZlcihHTF9CQUNLKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xSZWFkQnVmZmVyKEdMX0JBQ0spIik7CiAgICB9CiAgICBjaGVja0dMY2FsbCgiZ2xFbmQgYW5kIHByZXZpb3VzIik7CgogICAgbGVmdCA9IChmbG9hdCkgc3JlY3QtPngxIC8gKGZsb2F0KSBTcmMtPnBvdzJXaWR0aDsKICAgIHJpZ2h0ID0gKGZsb2F0KSBzcmVjdC0+eDIgLyAoZmxvYXQpIFNyYy0+cG93MldpZHRoOwoKICAgIGlmKHVwc2lkZWRvd24pIHsKICAgICAgICB0b3AgPSAoZmxvYXQpIChTcmMtPmN1cnJlbnREZXNjLkhlaWdodCAtIHNyZWN0LT55MSkgLyAoZmxvYXQpIFNyYy0+cG93MkhlaWdodDsKICAgICAgICBib3R0b20gPSAoZmxvYXQpIChTcmMtPmN1cnJlbnREZXNjLkhlaWdodCAtIHNyZWN0LT55MikgLyAoZmxvYXQpIFNyYy0+cG93MkhlaWdodDsKICAgIH0gZWxzZSB7CiAgICAgICAgdG9wID0gKGZsb2F0KSAoU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQgLSBzcmVjdC0+eTIpIC8gKGZsb2F0KSBTcmMtPnBvdzJIZWlnaHQ7CiAgICAgICAgYm90dG9tID0gKGZsb2F0KSAoU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQgLSBzcmVjdC0+eTEpIC8gKGZsb2F0KSBTcmMtPnBvdzJIZWlnaHQ7CiAgICB9CgogICAgLyogZHJhdyB0aGUgc291cmNlIHRleHR1cmUgc3RyZXRjaGVkIGFuZCB1cHNpZGUgZG93bi4gVGhlIGNvcnJlY3Qgc3VyZmFjZSBpcyBib3VuZCBhbHJlYWR5ICovCiAgICBnbFRleFBhcmFtZXRlcmkoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9XUkFQX1MsIEdMX0NMQU1QKTsKICAgIGdsVGV4UGFyYW1ldGVyaShHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX1dSQVBfVCwgR0xfQ0xBTVApOwoKICAgIGdsRHJhd0J1ZmZlcihkcmF3QnVmZmVyKTsKICAgIGdsUmVhZEJ1ZmZlcihkcmF3QnVmZmVyKTsKCiAgICBnbEJlZ2luKEdMX1FVQURTKTsKICAgICAgICAvKiBib3R0b20gbGVmdCAqLwogICAgICAgIGdsVGV4Q29vcmQyZihsZWZ0LCBib3R0b20pOwogICAgICAgIGdsVmVydGV4MmkoMCwgZmJoZWlnaHQpOwoKICAgICAgICAvKiB0b3AgbGVmdCAqLwogICAgICAgIGdsVGV4Q29vcmQyZihsZWZ0LCB0b3ApOwogICAgICAgIGdsVmVydGV4MmkoMCwgZmJoZWlnaHQgLSBkcmVjdC0+eTIgLSBkcmVjdC0+eTEpOwoKICAgICAgICAvKiB0b3AgcmlnaHQgKi8KICAgICAgICBnbFRleENvb3JkMmYocmlnaHQsIHRvcCk7CiAgICAgICAgZ2xWZXJ0ZXgyaShkcmVjdC0+eDIgLSBkcmVjdC0+eDEsIGZiaGVpZ2h0IC0gZHJlY3QtPnkyIC0gZHJlY3QtPnkxKTsKCiAgICAgICAgLyogYm90dG9tIHJpZ2h0ICovCiAgICAgICAgZ2xUZXhDb29yZDJmKHJpZ2h0LCBib3R0b20pOwogICAgICAgIGdsVmVydGV4MmkoZHJlY3QtPngyIC0gZHJlY3QtPngxLCBmYmhlaWdodCk7CiAgICBnbEVuZCgpOwogICAgY2hlY2tHTGNhbGwoImdsRW5kIGFuZCBwcmV2aW91cyIpOwoKICAgIC8qIE5vdyByZWFkIHRoZSBzdHJldGNoZWQgYW5kIHVwc2lkZSBkb3duIGltYWdlIGludG8gdGhlIGRlc3RpbmF0aW9uIHRleHR1cmUgKi8KICAgIGdsQmluZFRleHR1cmUoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsIFRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpOwogICAgY2hlY2tHTGNhbGwoImdsQmluZFRleHR1cmUiKTsKICAgIGdsQ29weVRleFN1YkltYWdlMkQoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgICAgICAgIGRyZWN0LT54MSwgZHJlY3QtPnkxLCAvKiB4b2Zmc2V0LCB5b2Zmc2V0ICovCiAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsIC8qIFdlIGJsaXR0ZWQgdGhlIGltYWdlIHRvIHRoZSBvcmlnaW4gKi8KICAgICAgICAgICAgICAgICAgICAgICAgZHJlY3QtPngyIC0gZHJlY3QtPngxLCBkcmVjdC0+eTIgLSBkcmVjdC0+eTEpOwogICAgY2hlY2tHTGNhbGwoImdsQ29weVRleFN1YkltYWdlMkQiKTsKCiAgICAvKiBXcml0ZSB0aGUgYmFjayBidWZmZXIgYmFja3VwIGJhY2sgKi8KICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgYmFja3VwID8gYmFja3VwIDogU3JjLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lKTsKICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIFNyYy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSkiKTsKCiAgICBpZihkcmF3QnVmZmVyID09IEdMX0JBQ0spIHsKICAgICAgICBnbEJlZ2luKEdMX1FVQURTKTsKICAgICAgICAgICAgLyogdG9wIGxlZnQgKi8KICAgICAgICAgICAgZ2xUZXhDb29yZDJmKDAuMCwgKGZsb2F0KSBmYmhlaWdodCAvIChmbG9hdCkgU3JjLT5wb3cySGVpZ2h0KTsKICAgICAgICAgICAgZ2xWZXJ0ZXgyaSgwLCAwKTsKCiAgICAgICAgICAgIC8qIGJvdHRvbSBsZWZ0ICovCiAgICAgICAgICAgIGdsVGV4Q29vcmQyZigwLjAsIDAuMCk7CiAgICAgICAgICAgIGdsVmVydGV4MmkoMCwgZmJoZWlnaHQpOwoKICAgICAgICAgICAgLyogYm90dG9tIHJpZ2h0ICovCiAgICAgICAgICAgIGdsVGV4Q29vcmQyZigoZmxvYXQpIGZid2lkdGggLyAoZmxvYXQpIFNyYy0+cG93MldpZHRoLCAwLjApOwogICAgICAgICAgICBnbFZlcnRleDJpKGZid2lkdGgsIFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0KTsKCiAgICAgICAgICAgIC8qIHRvcCByaWdodCAqLwogICAgICAgICAgICBnbFRleENvb3JkMmYoKGZsb2F0KSBmYndpZHRoIC8gKGZsb2F0KSBTcmMtPnBvdzJXaWR0aCwgKGZsb2F0KSBmYmhlaWdodCAvIChmbG9hdCkgU3JjLT5wb3cySGVpZ2h0KTsKICAgICAgICAgICAgZ2xWZXJ0ZXgyaShmYndpZHRoLCAwKTsKICAgICAgICBnbEVuZCgpOwogICAgfSBlbHNlIHsKICAgICAgICAvKiBSZXN0b3JlIHRoZSBvbGQgZHJhdyBidWZmZXIgKi8KICAgICAgICBnbERyYXdCdWZmZXIoR0xfQkFDSyk7CiAgICB9CgogICAgLyogQ2xlYW51cCAqLwogICAgaWYoc3JjICE9IFNyYy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSAmJiBzcmMgIT0gYmFja3VwKSB7CiAgICAgICAgZ2xEZWxldGVUZXh0dXJlcygxLCAmc3JjKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xEZWxldGVUZXh0dXJlcygxLCAmc3JjKSIpOwogICAgfQogICAgaWYoYmFja3VwKSB7CiAgICAgICAgZ2xEZWxldGVUZXh0dXJlcygxLCAmYmFja3VwKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xEZWxldGVUZXh0dXJlcygxLCAmYmFja3VwKSIpOwogICAgfQogICAgTEVBVkVfR0woKTsKfQoKLyogTm90IGNhbGxlZCBmcm9tIHRoZSBWVGFibGUgKi8Kc3RhdGljIEhSRVNVTFQgSVdpbmVEM0RTdXJmYWNlSW1wbF9CbHRPdmVycmlkZShJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzLCBSRUNUICpEZXN0UmVjdCwgSVdpbmVEM0RTdXJmYWNlICpTcmNTdXJmYWNlLCBSRUNUICpTcmNSZWN0LCBEV09SRCBGbGFncywgV0lORUREQkxURlggKkREQmx0RngsIFdJTkVEM0RURVhUVVJFRklMVEVSVFlQRSBGaWx0ZXIpIHsKICAgIFdJTkVEM0RSRUNUIHJlY3Q7CiAgICBJV2luZUQzRERldmljZUltcGwgKm15RGV2aWNlID0gVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZTsKICAgIElXaW5lRDNEU3dhcENoYWluSW1wbCAqc3JjU3dhcGNoYWluID0gTlVMTCwgKmRzdFN3YXBjaGFpbiA9IE5VTEw7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpTcmMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBTcmNTdXJmYWNlOwoKICAgIFRSQUNFKCIoJXApLT4oJXAsJXAsJXAsJTA4eCwlcClcbiIsIFRoaXMsIERlc3RSZWN0LCBTcmNTdXJmYWNlLCBTcmNSZWN0LCBGbGFncywgRERCbHRGeCk7CgogICAgLyogR2V0IHRoZSBzd2FwY2hhaW4uIE9uZSBvZiB0aGUgc3VyZmFjZXMgaGFzIHRvIGJlIGEgcHJpbWFyeSBzdXJmYWNlICovCiAgICBJV2luZUQzRFN1cmZhY2VfR2V0Q29udGFpbmVyKCAoSVdpbmVEM0RTdXJmYWNlICopIFRoaXMsICZJSURfSVdpbmVEM0RTd2FwQ2hhaW4sICh2b2lkICoqKSZkc3RTd2FwY2hhaW4pOwogICAgaWYoZHN0U3dhcGNoYWluKSBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKChJV2luZUQzRFN3YXBDaGFpbiAqKSBkc3RTd2FwY2hhaW4pOwogICAgaWYoU3JjKSB7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lciggKElXaW5lRDNEU3VyZmFjZSAqKSBTcmMsICZJSURfSVdpbmVEM0RTd2FwQ2hhaW4sICh2b2lkICoqKSZzcmNTd2FwY2hhaW4pOwogICAgICAgIGlmKHNyY1N3YXBjaGFpbikgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZSgoSVdpbmVEM0RTd2FwQ2hhaW4gKikgc3JjU3dhcGNoYWluKTsKICAgIH0KCiAgICAvKiBFYXJseSBzb3J0IG91dCBvZiBjYXNlcyB3aGVyZSBubyByZW5kZXIgdGFyZ2V0IGlzIHVzZWQgKi8KICAgIGlmKCFkc3RTd2FwY2hhaW4gJiYgIXNyY1N3YXBjaGFpbiAmJgogICAgICAgIFNyY1N1cmZhY2UgIT0gbXlEZXZpY2UtPnJlbmRlcl90YXJnZXRzWzBdICYmIFRoaXMgIT0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgbXlEZXZpY2UtPnJlbmRlcl90YXJnZXRzWzBdKSB7CiAgICAgICAgVFJBQ0UoIk5vIHN1cmZhY2UgaXMgcmVuZGVyIHRhcmdldCwgbm90IHVzaW5nIGhhcmR3YXJlIGJsaXQuIFNyYyA9ICVwLCBkc3QgPSAlcFxuIiwgU3JjLCBUaGlzKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICAvKiBObyBkZXN0aW5hdGlvbiBjb2xvciBrZXlpbmcgc3VwcG9ydGVkICovCiAgICBpZihGbGFncyAmIChXSU5FRERCTFRfS0VZREVTVCB8IFdJTkVEREJMVF9LRVlERVNUT1ZFUlJJREUpKSB7CiAgICAgICAgLyogQ2FuIHdlIHN1cHBvcnQgdGhhdCB3aXRoIGdsQmxlbmRGdW5jIGlmIGJsaXR0aW5nIHRvIHRoZSBmcmFtZSBidWZmZXI/ICovCiAgICAgICAgVFJBQ0UoIkRlc3RpbmF0aW9uIGNvbG9yIGtleSBub3Qgc3VwcG9ydGVkIGluIGFjY2VsZXJhdGVkIEJsaXQsIGZhbGxpbmcgYmFjayB0byBzb2Z0d2FyZVxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgaWYgKERlc3RSZWN0KSB7CiAgICAgICAgcmVjdC54MSA9IERlc3RSZWN0LT5sZWZ0OwogICAgICAgIHJlY3QueTEgPSBEZXN0UmVjdC0+dG9wOwogICAgICAgIHJlY3QueDIgPSBEZXN0UmVjdC0+cmlnaHQ7CiAgICAgICAgcmVjdC55MiA9IERlc3RSZWN0LT5ib3R0b207CiAgICB9IGVsc2UgewogICAgICAgIHJlY3QueDEgPSAwOwogICAgICAgIHJlY3QueTEgPSAwOwogICAgICAgIHJlY3QueDIgPSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICByZWN0LnkyID0gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0OwogICAgfQoKICAgIC8qIFRoZSBvbmx5IGNhc2Ugd2hlcmUgYm90aCBzdXJmYWNlcyBvbiBhIHN3YXBjaGFpbiBhcmUgc3VwcG9ydGVkIGlzIGEgYmFjayBidWZmZXIgLT4gZnJvbnQgYnVmZmVyIGJsaXQgb24gdGhlIHNhbWUgc3dhcGNoYWluICovCiAgICBpZihkc3RTd2FwY2hhaW4gJiYgZHN0U3dhcGNoYWluID09IHNyY1N3YXBjaGFpbiAmJiBkc3RTd2FwY2hhaW4tPmJhY2tCdWZmZXIgJiYKICAgICAgICgoSVdpbmVEM0RTdXJmYWNlICopIFRoaXMgPT0gZHN0U3dhcGNoYWluLT5mcm9udEJ1ZmZlcikgJiYgU3JjU3VyZmFjZSA9PSBkc3RTd2FwY2hhaW4tPmJhY2tCdWZmZXJbMF0pIHsKICAgICAgICAvKiBIYWxmLWxpZmUgZG9lcyBhIEJsdCBmcm9tIHRoZSBiYWNrIGJ1ZmZlciB0byB0aGUgZnJvbnQgYnVmZmVyLAogICAgICAgICAqIEZ1bGwgc3VyZmFjZSBzaXplLCBubyBmbGFncy4uLiBVc2UgcHJlc2VudCBpbnN0ZWFkCiAgICAgICAgICoKICAgICAgICAgKiBUaGlzIHBhdGggd2lsbCBvbmx5IGJlIGVudGVyZWQgZm9yIGQzZDcgYW5kIGRkcmF3IGFwcHMsIGJlY2F1c2UgZDNkOC85IG9mZmVyIG5vIHdheSB0byBibGl0IFRPIHRoZSBmcm9udCBidWZmZXIKICAgICAgICAgKi8KCiAgICAgICAgLyogQ2hlY2sgcmVjdHMgLSBJV2luZUQzRERldmljZV9QcmVzZW50IGRvZXNuJ3QgaGFuZGxlIHRoZW0gKi8KICAgICAgICB3aGlsZSgxKQogICAgICAgIHsKICAgICAgICAgICAgUkVDVCBteVNyY1JlY3Q7CiAgICAgICAgICAgIFRSQUNFKCJMb29raW5nIGlmIGEgUHJlc2VudCBjYW4gYmUgZG9uZS4uLlxuIik7CiAgICAgICAgICAgIC8qIFNvdXJjZSBSZWN0YW5nbGUgbXVzdCBiZSBmdWxsIHN1cmZhY2UgKi8KICAgICAgICAgICAgaWYoIFNyY1JlY3QgKSB7CiAgICAgICAgICAgICAgICBpZihTcmNSZWN0LT5sZWZ0ICE9IDAgfHwgU3JjUmVjdC0+dG9wICE9IDAgfHwKICAgICAgICAgICAgICAgICAgIFNyY1JlY3QtPnJpZ2h0ICE9IFNyYy0+Y3VycmVudERlc2MuV2lkdGggfHwgU3JjUmVjdC0+Ym90dG9tICE9IFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0KSB7CiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIk5vLCBTb3VyY2UgcmVjdGFuZ2xlIGRvZXNuJ3QgbWF0Y2hcbiIpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIG15U3JjUmVjdC5sZWZ0ID0gMDsKICAgICAgICAgICAgbXlTcmNSZWN0LnRvcCA9IDA7CiAgICAgICAgICAgIG15U3JjUmVjdC5yaWdodCA9IFNyYy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAgICAgICAgIG15U3JjUmVjdC5ib3R0b20gPSBTcmMtPmN1cnJlbnREZXNjLkhlaWdodDsKCiAgICAgICAgICAgIC8qIE5vIHN0cmV0Y2hpbmcgbWF5IG9jY3VyICovCiAgICAgICAgICAgIGlmKG15U3JjUmVjdC5yaWdodCAhPSByZWN0LngyIC0gcmVjdC54MSB8fAogICAgICAgICAgICAgICBteVNyY1JlY3QuYm90dG9tICE9IHJlY3QueTIgLSByZWN0LnkxKSB7CiAgICAgICAgICAgICAgICBUUkFDRSgiTm8sIHN0cmV0Y2hpbmcgaXMgZG9uZVxuIik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyogRGVzdGluYXRpb24gbXVzdCBiZSBmdWxsIHN1cmZhY2Ugb3IgbWF0Y2ggdGhlIGNsaXBwaW5nIHJlY3RhbmdsZSAqLwogICAgICAgICAgICBpZihUaGlzLT5jbGlwcGVyICYmICgoSVdpbmVEM0RDbGlwcGVySW1wbCAqKSBUaGlzLT5jbGlwcGVyKS0+aFduZCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgUkVDVCBjbGlwcmVjdDsKICAgICAgICAgICAgICAgIFBPSU5UIHBvc1syXTsKICAgICAgICAgICAgICAgIEdldENsaWVudFJlY3QoKChJV2luZUQzRENsaXBwZXJJbXBsICopIFRoaXMtPmNsaXBwZXIpLT5oV25kLCAmY2xpcHJlY3QpOwogICAgICAgICAgICAgICAgcG9zWzBdLnggPSByZWN0LngxOwogICAgICAgICAgICAgICAgcG9zWzBdLnkgPSByZWN0LnkxOwogICAgICAgICAgICAgICAgcG9zWzFdLnggPSByZWN0LngyOwogICAgICAgICAgICAgICAgcG9zWzFdLnkgPSByZWN0LnkyOwogICAgICAgICAgICAgICAgTWFwV2luZG93UG9pbnRzKEdldERlc2t0b3BXaW5kb3coKSwgKChJV2luZUQzRENsaXBwZXJJbXBsICopIFRoaXMtPmNsaXBwZXIpLT5oV25kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvcywgMik7CgogICAgICAgICAgICAgICAgaWYocG9zWzBdLnggIT0gY2xpcHJlY3QubGVmdCAgfHwgcG9zWzBdLnkgIT0gY2xpcHJlY3QudG9wICAgfHwKICAgICAgICAgICAgICAgICAgIHBvc1sxXS54ICE9IGNsaXByZWN0LnJpZ2h0IHx8IHBvc1sxXS55ICE9IGNsaXByZWN0LmJvdHRvbSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBUUkFDRSgiTm8sIGRlc3QgcmVjdGFuZ2xlIGRvZXNuJ3QgbWF0Y2goY2xpcHBlcilcbiIpOwogICAgICAgICAgICAgICAgICAgIFRSQUNFKCJDbGlwIHJlY3QgYXQgKCVkLCVkKS0oJWQsJWQpXG4iLCBjbGlwcmVjdC5sZWZ0LCBjbGlwcmVjdC50b3AsIGNsaXByZWN0LnJpZ2h0LCBjbGlwcmVjdC5ib3R0b20pOwogICAgICAgICAgICAgICAgICAgIFRSQUNFKCJCbHQgZGVzdDogKCVkLCVkKS0oJWQsJWQpXG4iLCByZWN0LngxLCByZWN0LnkxLCByZWN0LngyLCByZWN0LnkyKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmKHJlY3QueDEgIT0gMCB8fCByZWN0LnkxICE9IDAgfHwKICAgICAgICAgICAgICAgICAgIHJlY3QueDIgIT0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGggfHwgcmVjdC55MiAhPSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQpIHsKICAgICAgICAgICAgICAgICAgICBUUkFDRSgiTm8sIGRlc3QgcmVjdGFuZ2xlIGRvZXNuJ3QgbWF0Y2goc3VyZmFjZSBzaXplKVxuIik7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIFRSQUNFKCJZZXNcbiIpOwoKICAgICAgICAgICAgLyogVGhlc2UgZmxhZ3MgYXJlIHVuaW1wb3J0YW50IGZvciB0aGUgZmxhZyBjaGVjaywgcmVtb3ZlIHRoZW0gKi8KICAgICAgICAgICAgaWYoKEZsYWdzICYgfihXSU5FRERCTFRfRE9OT1RXQUlUIHwgV0lORUREQkxUX1dBSVQpKSA9PSAwKSB7CiAgICAgICAgICAgICAgICBXSU5FRDNEU1dBUEVGRkVDVCBvcmlnX3N3YXAgPSBkc3RTd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5Td2FwRWZmZWN0OwoKICAgICAgICAgICAgICAgIC8qIFRoZSBpZGVhIGJlaGluZCB0aGlzIGlzIHRoYXQgYSBnbFJlYWRQaXhlbHMgYW5kIGEgZ2xEcmF3UGl4ZWxzIGNhbGwKICAgICAgICAgICAgICAgICAgICAqIHRha2UgdmVyeSBsb25nLCB3aGlsZSBhIGZsaXAgaXMgZmFzdC4KICAgICAgICAgICAgICAgICAgICAqIFRoaXMgYXBwbGllcyB0byBIYWxmLUxpZmUsIHdoaWNoIGRvZXMgc3VjaCBCbHRzIGV2ZXJ5IHRpbWUgaXQgZmluaXNoZWQKICAgICAgICAgICAgICAgICAgICAqIGEgZnJhbWUsIGFuZCB0byBQcmluY2Ugb2YgUGVyc2lhIDNELCB3aGljaCB1c2VzIHRoaXMgdG8gZHJhdyBhdCBsZWFzdCB0aGUgbWFpbgogICAgICAgICAgICAgICAgICAgICogbWVudS4gVGhpcyBpcyBhbHNvIHVzZWQgYnkgYWxsIGFwcHMgd2hlbiB0aGV5IGRvIHdpbmRvd2VkIHJlbmRlcmluZwogICAgICAgICAgICAgICAgICAgICoKICAgICAgICAgICAgICAgICAgICAqIFRoZSBwcm9ibGVtIGlzIHRoYXQgZmxpcHBpbmcgaXMgbm90IHJlYWxseSB0aGUgc2FtZSBhcyBjb3B5aW5nLiBBZnRlciBhCiAgICAgICAgICAgICAgICAgICAgKiBCbHQgdGhlIGZyb250IGJ1ZmZlciBpcyBhIGNvcHkgb2YgdGhlIGJhY2sgYnVmZmVyLCBhbmQgdGhlIGJhY2sgYnVmZmVyIGlzCiAgICAgICAgICAgICAgICAgICAgKiB1bnRvdWNoZWQuIFRoZXJlZm9yZSBpdCdzIG5lY2Vzc2FyeSB0byBvdmVycmlkZSB0aGUgc3dhcCBlZmZlY3QKICAgICAgICAgICAgICAgICAgICAqIGFuZCB0byBzZXQgaXQgYmFjayBhZnRlciB0aGUgZmxpcC4KICAgICAgICAgICAgICAgICAgICAqCiAgICAgICAgICAgICAgICAgICAgKiBXaW5kb3dlZCBEaXJlY3QzRCA8IDcgYXBwcyBkbyB0aGUgc2FtZS4gVGhlIEQzRDcgc2RrIGRlbXNvIGFyZSBuaWNlCiAgICAgICAgICAgICAgICAgICAgKiB0ZXN0Y2FzZXMuCiAgICAgICAgICAgICAgICAgICAgKi8KCiAgICAgICAgICAgICAgICBkc3RTd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5Td2FwRWZmZWN0ID0gV0lORUQzRFNXQVBFRkZFQ1RfQ09QWTsKCiAgICAgICAgICAgICAgICBUUkFDRSgiRnVsbCBzY3JlZW4gYmFjayBidWZmZXIgLT4gZnJvbnQgYnVmZmVyIGJsdCwgcGVyZm9ybWluZyBhIGZsaXAgaW5zdGVhZFxuIik7CiAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZV9QcmVzZW50KChJV2luZUQzRERldmljZSAqKSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgTlVMTCwgMCwgTlVMTCk7CgogICAgICAgICAgICAgICAgZHN0U3dhcGNoYWluLT5wcmVzZW50UGFybXMuU3dhcEVmZmVjdCA9IG9yaWdfc3dhcDsKCiAgICAgICAgICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIFRSQUNFKCJVbnN1cHBvcnRlZCBibGl0IGJldHdlZW4gYnVmZmVycyBvbiB0aGUgc2FtZSBzd2FwY2hhaW5cbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfSBlbHNlIGlmKChkc3RTd2FwY2hhaW4gfHwgVGhpcyA9PSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBteURldmljZS0+cmVuZGVyX3RhcmdldHNbMF0pICYmCiAgICAgICAgICAgICAgKHNyY1N3YXBjaGFpbiB8fCBTcmNTdXJmYWNlID09IG15RGV2aWNlLT5yZW5kZXJfdGFyZ2V0c1swXSkgKSB7CiAgICAgICAgRVJSKCJDYW4ndCBwZXJmb3JtIGhhcmR3YXJlIGJsaXQgYmV0d2VlbiAyIGRpZmZlcmVudCBzd2FwY2hhaW5zLCBmYWxsaW5nIGJhY2sgdG8gc29mdHdhcmVcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIGlmKHNyY1N3YXBjaGFpbiB8fCBTcmNTdXJmYWNlID09IG15RGV2aWNlLT5yZW5kZXJfdGFyZ2V0c1swXSkgewogICAgICAgIC8qIEJsaXQgZnJvbSByZW5kZXIgdGFyZ2V0IHRvIHRleHR1cmUgKi8KICAgICAgICBXSU5FRDNEUkVDVCBzcmVjdDsKICAgICAgICBCT09MIHVwc2lkZURvd24sIHN0cmV0Y2h4OwoKICAgICAgICBpZihGbGFncyAmIChXSU5FRERCTFRfS0VZU1JDIHwgV0lORUREQkxUX0tFWVNSQ09WRVJSSURFKSkgewogICAgICAgICAgICBUUkFDRSgiQ29sb3Iga2V5aW5nIG5vdCBzdXBwb3J0ZWQgYnkgZnJhbWUgYnVmZmVyIHRvIHRleHR1cmUgYmxpdFxuIik7CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgICAgICAgICAvKiBEZXN0aW5hdGlvbiBjb2xvciBrZXkgaXMgY2hlY2tlZCBhYm92ZSAqLwogICAgICAgIH0KCiAgICAgICAgLyogQ2FsbCBwcmVsb2FkIGZvciB0aGUgc3VyZmFjZSB0byBtYWtlIHN1cmUgaXQgaXNuJ3QgZGlydHkgKi8KICAgICAgICBpZiAoR0xfU1VQUE9SVChBUkJfTVVMVElURVhUVVJFKSkgewogICAgICAgICAgICBHTF9FWFRDQUxMKGdsQWN0aXZlVGV4dHVyZUFSQihHTF9URVhUVVJFMF9BUkIpKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsQWN0aXZlVGV4dHVyZUFSQiIpOwogICAgICAgIH0KICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZSwgU1RBVEVfU0FNUExFUigwKSk7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1ByZUxvYWQoKElXaW5lRDNEU3VyZmFjZSAqKSBUaGlzKTsKCiAgICAgICAgLyogTWFrZSBzdXJlIHRoYXQgdGhlIHRvcCBwaXhlbCBpcyBhbHdheXMgYWJvdmUgdGhlIGJvdHRvbSBwaXhlbCwgYW5kIGtlZXAgYSBzZXBlcmF0ZSB1cHNpZGUgZG93biBmbGFnCiAgICAgICAgICAgICogZ2xDb3B5VGV4U3ViSW1hZ2UgaXMgYSBiaXQgcGlja3kgYWJvdXQgdGhlIHBhcmFtZXRlcnMgd2UgcGFzcyB0byBpdAogICAgICAgICAgICAqLwogICAgICAgIGlmKFNyY1JlY3QpIHsKICAgICAgICAgICAgaWYoU3JjUmVjdC0+dG9wIDwgU3JjUmVjdC0+Ym90dG9tKSB7CiAgICAgICAgICAgICAgICBzcmVjdC55MSA9IFNyY1JlY3QtPnRvcDsKICAgICAgICAgICAgICAgIHNyZWN0LnkyID0gU3JjUmVjdC0+Ym90dG9tOwogICAgICAgICAgICAgICAgdXBzaWRlRG93biA9IEZBTFNFOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgc3JlY3QueTEgPSBTcmNSZWN0LT5ib3R0b207CiAgICAgICAgICAgICAgICBzcmVjdC55MiA9IFNyY1JlY3QtPnRvcDsKICAgICAgICAgICAgICAgIHVwc2lkZURvd24gPSBUUlVFOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHNyZWN0LngxID0gU3JjUmVjdC0+bGVmdDsKICAgICAgICAgICAgc3JlY3QueDIgPSBTcmNSZWN0LT5yaWdodDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzcmVjdC54MSA9IDA7CiAgICAgICAgICAgIHNyZWN0LnkxID0gMDsKICAgICAgICAgICAgc3JlY3QueDIgPSBTcmMtPmN1cnJlbnREZXNjLldpZHRoOwogICAgICAgICAgICBzcmVjdC55MiA9IFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0OwogICAgICAgICAgICB1cHNpZGVEb3duID0gRkFMU0U7CiAgICAgICAgfQogICAgICAgIGlmKHJlY3QueDEgPiByZWN0LngyKSB7CiAgICAgICAgICAgIFVJTlQgdG1wID0gcmVjdC54MjsKICAgICAgICAgICAgcmVjdC54MiA9IHJlY3QueDE7CiAgICAgICAgICAgIHJlY3QueDEgPSB0bXA7CiAgICAgICAgICAgIHVwc2lkZURvd24gPSAhdXBzaWRlRG93bjsKICAgICAgICB9CiAgICAgICAgaWYoIXNyY1N3YXBjaGFpbikgewogICAgICAgICAgICBUUkFDRSgiUmVhZGluZyBmcm9tIGFuIG9mZnNjcmVlbiB0YXJnZXRcbiIpOwogICAgICAgICAgICB1cHNpZGVEb3duID0gIXVwc2lkZURvd247CiAgICAgICAgfQoKICAgICAgICBpZihyZWN0LngyIC0gcmVjdC54MSAhPSBzcmVjdC54MiAtIHNyZWN0LngxKSB7CiAgICAgICAgICAgIHN0cmV0Y2h4ID0gVFJVRTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzdHJldGNoeCA9IEZBTFNFOwogICAgICAgIH0KCiAgICAgICAgLyogQmx0IGlzIGEgcHJldHR5IHBvd2VyZnVsIGNhbGwsIHdoaWxlIGdsQ29weVRleFN1YkltYWdlMkQgaXMgbm90LiBnbENvcHlUZXhTdWJJbWFnZSBjYW5ub3QKICAgICAgICAgKiBmbGlwIHRoZSBpbWFnZSBub3Igc2NhbGUgaXQuCiAgICAgICAgICoKICAgICAgICAgKiAtPiBJZiB0aGUgYXBwIGFza3MgZm9yIGEgdW5zY2FsZWQsIHVwc2lkZSBkb3duIGNvcHksIGp1c3QgcGVyZm9ybSBvbmUgZ2xDb3B5VGV4U3ViSW1hZ2UyRCBjYWxsCiAgICAgICAgICogLT4gSWYgdGhlIGFwcCB3YW50cyBhIGltYWdlIHdpZHRoIGFuIHVuc2NhbGVkIHdpZHRoLCBjb3B5IGl0IGxpbmUgcGVyIGxpbmUKICAgICAgICAgKiAtPiBJZiB0aGUgYXBwIHdhbnRzIGEgaW1hZ2UgdGhhdCBpcyBzY2FsZWQgb24gdGhlIHggYXhpcywgYW5kIHRoZSBkZXN0aW5hdGlvbiByZWN0YW5nbGUgaXMgc21hbGxlcgogICAgICAgICAqICAgIHRoYW4gdGhlIGZyYW1lIGJ1ZmZlciwgZHJhdyBhbiB1cHNpZGUgZG93biBzY2FsZWQgaW1hZ2Ugb250byB0aGUgZmIsIHJlYWQgaXQgYmFjayBhbmQgcmVzdG9yZSB0aGUKICAgICAgICAgKiAgICBiYWNrIGJ1ZmZlci4gVGhpcyBpcyBzbG93ZXIgdGhhbiByZWFkaW5nIGxpbmUgcGVyIGxpbmUsIHRodXMgbm90IHVzZWQgZm9yIGZsaXBwaW5nCiAgICAgICAgICogLT4gSWYgdGhlIGFwcCB3YW50cyBhIHNjYWxlZCBpbWFnZSB3aXRoIGEgZGVzdCByZWN0IHRoYXQgaXMgYmlnZ2VyIHRoYW4gdGhlIGZiLCBpdCBoYXMgdG8gYmUgY29waWVkCiAgICAgICAgICogICAgcGl4ZWwgYnkgcGl4ZWwKICAgICAgICAgKgogICAgICAgICAqIElmIEVYVF9mcmFtZWJ1ZmZlcl9ibGl0IGlzIHN1cHBvcnRlZCB0aGF0IGNhbiBiZSB1c2VkIGluc3RlYWQuIE5vdGUgdGhhdCBFWFRfZnJhbWVidWZmZXJfYmxpdCBpbXBsaWVzCiAgICAgICAgICogRkJPIHN1cHBvcnQsIHNvIGl0IGRvZXNuJ3QgcmVhbGx5IG1ha2Ugc2Vuc2UgdG8gdHJ5IGFuZCBtYWtlIGl0IHdvcmsgd2l0aCBkaWZmZXJlbnQgb2Zmc2NyZWVuIHJlbmRlcmluZwogICAgICAgICAqIGJhY2tlbmRzLgogICAgICAgICAqLwogICAgICAgIGlmICh3aW5lZDNkX3NldHRpbmdzLm9mZnNjcmVlbl9yZW5kZXJpbmdfbW9kZSA9PSBPUk1fRkJPICYmIEdMX1NVUFBPUlQoRVhUX0ZSQU1FQlVGRkVSX0JMSVQpKSB7CiAgICAgICAgICAgIHN0cmV0Y2hfcmVjdF9mYm8oKElXaW5lRDNERGV2aWNlICopbXlEZXZpY2UsIFNyY1N1cmZhY2UsICZzcmVjdCwKICAgICAgICAgICAgICAgICAgICAoSVdpbmVEM0RTdXJmYWNlICopVGhpcywgJnJlY3QsIEZpbHRlciwgdXBzaWRlRG93bik7CiAgICAgICAgfSBlbHNlIGlmKCghc3RyZXRjaHgpIHx8IHJlY3QueDIgLSByZWN0LngxID4gU3JjLT5jdXJyZW50RGVzYy5XaWR0aCB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWN0LnkyIC0gcmVjdC55MSA+IFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0KSB7CiAgICAgICAgICAgIFRSQUNFKCJObyBzdHJldGNoaW5nIGluIHggZGlyZWN0aW9uLCB1c2luZyBkaXJlY3QgZnJhbWVidWZmZXIgLT4gdGV4dHVyZSBjb3B5XG4iKTsKICAgICAgICAgICAgZmJfY29weV90b190ZXh0dXJlX2RpcmVjdChUaGlzLCBTcmNTdXJmYWNlLCBzcmNTd2FwY2hhaW4sICZzcmVjdCwgJnJlY3QsIHVwc2lkZURvd24sIEZpbHRlcik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgVFJBQ0UoIlVzaW5nIGhhcmR3YXJlIHN0cmV0Y2hpbmcgdG8gZmxpcCAvIHN0cmV0Y2ggdGhlIHRleHR1cmVcbiIpOwogICAgICAgICAgICBmYl9jb3B5X3RvX3RleHR1cmVfaHdzdHJldGNoKFRoaXMsIFNyY1N1cmZhY2UsIHNyY1N3YXBjaGFpbiwgJnNyZWN0LCAmcmVjdCwgdXBzaWRlRG93biwgRmlsdGVyKTsKICAgICAgICB9CgogICAgICAgIGlmKCEoVGhpcy0+RmxhZ3MgJiBTRkxBR19ET05PVEZSRUUpKSB7CiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSk7CiAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IE5VTEw7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgVGhpcy0+RmxhZ3MgJj0gflNGTEFHX0lOU1lTTUVNOwogICAgICAgIH0KICAgICAgICAvKiBUaGUgdGV4dHVyZSBpcyBub3cgbW9zdCB1cCB0byBkYXRlIC0gSWYgdGhlIHN1cmZhY2UgaXMgYSByZW5kZXIgdGFyZ2V0IGFuZCBoYXMgYSBkcmF3YWJsZSwgdGhpcwogICAgICAgICAqIHBhdGggaXMgbmV2ZXIgZW50ZXJlZAogICAgICAgICAqLwogICAgICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX0lOVEVYVFVSRTsKCiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9IGVsc2UgaWYoU3JjKSB7CiAgICAgICAgLyogQmxpdCBmcm9tIG9mZnNjcmVlbiBzdXJmYWNlIHRvIHJlbmRlciB0YXJnZXQgKi8KICAgICAgICBmbG9hdCBnbFRleENvb3JkWzRdOwogICAgICAgIERXT1JEIG9sZENLZXlGbGFncyA9IFNyYy0+Q0tleUZsYWdzOwogICAgICAgIFdJTkVERENPTE9SS0VZIG9sZEJsdENLZXkgPSBUaGlzLT5TcmNCbHRDS2V5OwogICAgICAgIFJFQ1QgU291cmNlUmVjdGFuZ2xlOwoKICAgICAgICBUUkFDRSgiQmx0IGZyb20gc3VyZmFjZSAlcCB0byByZW5kZXJ0YXJnZXQgJXBcbiIsIFNyYywgVGhpcyk7CgogICAgICAgIGlmKFNyY1JlY3QpIHsKICAgICAgICAgICAgU291cmNlUmVjdGFuZ2xlLmxlZnQgPSBTcmNSZWN0LT5sZWZ0OwogICAgICAgICAgICBTb3VyY2VSZWN0YW5nbGUucmlnaHQgPSBTcmNSZWN0LT5yaWdodDsKICAgICAgICAgICAgU291cmNlUmVjdGFuZ2xlLnRvcCA9IFNyY1JlY3QtPnRvcDsKICAgICAgICAgICAgU291cmNlUmVjdGFuZ2xlLmJvdHRvbSA9IFNyY1JlY3QtPmJvdHRvbTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBTb3VyY2VSZWN0YW5nbGUubGVmdCA9IDA7CiAgICAgICAgICAgIFNvdXJjZVJlY3RhbmdsZS5yaWdodCA9IFNyYy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAgICAgICAgIFNvdXJjZVJlY3RhbmdsZS50b3AgPSAwOwogICAgICAgICAgICBTb3VyY2VSZWN0YW5nbGUuYm90dG9tID0gU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICAgICAgfQoKICAgICAgICBpZighQ2FsY3VsYXRlVGV4UmVjdChTcmMsICZTb3VyY2VSZWN0YW5nbGUsIGdsVGV4Q29vcmQpKSB7CiAgICAgICAgICAgIC8qIEZhbGwgYmFjayB0byBzb2Z0d2FyZSAqLwogICAgICAgICAgICBXQVJOKCIoJXApIFNvdXJjZSB0ZXh0dXJlIGFyZWEgKCVkLCVkKS0oJWQsJWQpIGlzIHRvbyBiaWdcbiIsIFNyYywKICAgICAgICAgICAgICAgICAgICBTb3VyY2VSZWN0YW5nbGUubGVmdCwgU291cmNlUmVjdGFuZ2xlLnRvcCwKICAgICAgICAgICAgICAgICAgICBTb3VyY2VSZWN0YW5nbGUucmlnaHQsIFNvdXJjZVJlY3RhbmdsZS5ib3R0b20pOwogICAgICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgICAgICB9CgogICAgICAgIC8qIENvbG9yIGtleWluZzogQ2hlY2sgaWYgd2UgaGF2ZSB0byBkbyBhIGNvbG9yIGtleWVkIGJsdCwKICAgICAgICAgKiBhbmQgaWYgbm90IGNoZWNrIGlmIGEgY29sb3Iga2V5IGlzIGFjdGl2YXRlZC4KICAgICAgICAgKgogICAgICAgICAqIEp1c3QgbW9kaWZ5IHRoZSBjb2xvciBrZXlpbmcgcGFyYW1ldGVycyBpbiB0aGUgc3VyZmFjZSBhbmQgcmVzdG9yZSB0aGVtIGFmdGVyd2FyZHMKICAgICAgICAgKiBUaGUgc3VyZmFjZSBrZWVwcyB0cmFjayBvZiB0aGUgY29sb3Iga2V5IGxhc3QgdXNlZCB0byBsb2FkIHRoZSBvcGVuZ2wgc3VyZmFjZS4KICAgICAgICAgKiBQcmVMb2FkIHdpbGwgY2F0Y2ggdGhlIGNoYW5nZSB0byB0aGUgZmxhZ3MgYW5kIGNvbG9yIGtleSBhbmQgcmVsb2FkIGlmIG5lY2Nlc3NhcnkuCiAgICAgICAgICovCiAgICAgICAgaWYoRmxhZ3MgJiBXSU5FRERCTFRfS0VZU1JDKSB7CiAgICAgICAgICAgIC8qIFVzZSBjb2xvciBrZXkgZnJvbSBzdXJmYWNlICovCiAgICAgICAgfSBlbHNlIGlmKEZsYWdzICYgV0lORUREQkxUX0tFWVNSQ09WRVJSSURFKSB7CiAgICAgICAgICAgIC8qIFVzZSBjb2xvciBrZXkgZnJvbSBEREJsdEZ4ICovCiAgICAgICAgICAgIFNyYy0+Q0tleUZsYWdzIHw9IFdJTkVERFNEX0NLU1JDQkxUOwogICAgICAgICAgICBUaGlzLT5TcmNCbHRDS2V5ID0gRERCbHRGeC0+ZGRja1NyY0NvbG9ya2V5OwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8qIERvIG5vdCB1c2UgY29sb3Iga2V5ICovCiAgICAgICAgICAgIFNyYy0+Q0tleUZsYWdzICY9IH5XSU5FRERTRF9DS1NSQ0JMVDsKICAgICAgICB9CgogICAgICAgIC8qIE5vdyBsb2FkIHRoZSBzdXJmYWNlICovCiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1ByZUxvYWQoKElXaW5lRDNEU3VyZmFjZSAqKSBTcmMpOwoKICAgICAgICBFTlRFUl9HTCgpOwoKICAgICAgICAvKiBBY3RpdmF0ZSB0aGUgZGVzdGluYXRpb24gY29udGV4dCwgc2V0IGl0IHVwIGZvciBibGl0dGluZyAqLwogICAgICAgIEFjdGl2YXRlQ29udGV4dChteURldmljZSwgKElXaW5lRDNEU3VyZmFjZSAqKSBUaGlzLCBDVFhVU0FHRV9CTElUKTsKCiAgICAgICAgaWYoIWRzdFN3YXBjaGFpbikgewogICAgICAgICAgICBUUkFDRSgiRHJhd2luZyB0byBvZmZzY3JlZW4gYnVmZmVyXG4iKTsKICAgICAgICAgICAgZ2xEcmF3QnVmZmVyKG15RGV2aWNlLT5vZmZzY3JlZW5CdWZmZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIEdMZW51bSBidWZmZXIgPSBzdXJmYWNlX2dldF9nbF9idWZmZXIoKElXaW5lRDNEU3VyZmFjZSAqKVRoaXMsIChJV2luZUQzRFN3YXBDaGFpbiAqKWRzdFN3YXBjaGFpbik7CiAgICAgICAgICAgIFRSQUNFKCJEcmF3aW5nIHRvICUjeCBidWZmZXJcbiIsIGJ1ZmZlcik7CiAgICAgICAgICAgIGdsRHJhd0J1ZmZlcihidWZmZXIpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEcmF3QnVmZmVyIik7CiAgICAgICAgfQoKICAgICAgICAvKiBCaW5kIHRoZSB0ZXh0dXJlICovCiAgICAgICAgZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCBTcmMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRUZXh0dXJlIik7CgogICAgICAgIC8qIEZpbHRlcmluZyBmb3IgU3RyZXRjaFJlY3QgKi8KICAgICAgICBnbFRleFBhcmFtZXRlcmkoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9NQUdfRklMVEVSLAogICAgICAgICAgICAgICAgICAgICAgICBzdGF0ZUxvb2t1cFtXSU5FTE9PS1VQX01BR0ZJTFRFUl1bRmlsdGVyIC0gbWluTG9va3VwW1dJTkVMT09LVVBfTUFHRklMVEVSXV0pOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbFRleFBhcmFtZXRlcmkiKTsKICAgICAgICBnbFRleFBhcmFtZXRlcmkoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9NSU5fRklMVEVSLAogICAgICAgICAgICAgICAgICAgICAgICBtaW5NaXBMb29rdXBbRmlsdGVyXVtXSU5FRDNEVEVYRl9OT05FXSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsVGV4UGFyYW1ldGVyaSIpOwogICAgICAgIGdsVGV4UGFyYW1ldGVyaShHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX1dSQVBfUywgR0xfQ0xBTVApOwogICAgICAgIGdsVGV4UGFyYW1ldGVyaShHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX1dSQVBfVCwgR0xfQ0xBTVApOwogICAgICAgIGdsVGV4RW52aShHTF9URVhUVVJFX0VOViwgR0xfVEVYVFVSRV9FTlZfTU9ERSwgR0xfUkVQTEFDRSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsVGV4RW52aSIpOwoKICAgICAgICAvKiBUaGlzIGlzIGZvciBjb2xvciBrZXlpbmcgKi8KICAgICAgICBpZihGbGFncyAmIChXSU5FRERCTFRfS0VZU1JDIHwgV0lORUREQkxUX0tFWVNSQ09WRVJSSURFKSkgewogICAgICAgICAgICBnbEVuYWJsZShHTF9BTFBIQV9URVNUKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlIEdMX0FMUEhBX1RFU1QiKTsKICAgICAgICAgICAgZ2xBbHBoYUZ1bmMoR0xfTk9URVFVQUwsIDAuMCk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEFscGhhRnVuY1xuIik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX0FMUEhBX1RFU1QpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlIEdMX0FMUEhBX1RFU1QiKTsKICAgICAgICB9CgogICAgICAgIC8qIERyYXcgYSB0ZXh0dXJlZCBxdWFkCiAgICAgICAgICovCiAgICAgICAgZ2xCZWdpbihHTF9RVUFEUyk7CgogICAgICAgIGdsQ29sb3IzZCgxLjBmLCAxLjBmLCAxLjBmKTsKICAgICAgICBnbFRleENvb3JkMmYoZ2xUZXhDb29yZFswXSwgZ2xUZXhDb29yZFsyXSk7CiAgICAgICAgZ2xWZXJ0ZXgzZihyZWN0LngxLAogICAgICAgICAgICAgICAgICAgIHJlY3QueTEsCiAgICAgICAgICAgICAgICAgICAgMC4wKTsKCiAgICAgICAgZ2xUZXhDb29yZDJmKGdsVGV4Q29vcmRbMF0sIGdsVGV4Q29vcmRbM10pOwogICAgICAgIGdsVmVydGV4M2YocmVjdC54MSwgcmVjdC55MiwgMC4wKTsKCiAgICAgICAgZ2xUZXhDb29yZDJmKGdsVGV4Q29vcmRbMV0sIGdsVGV4Q29vcmRbM10pOwogICAgICAgIGdsVmVydGV4M2YocmVjdC54MiwKICAgICAgICAgICAgICAgICAgICByZWN0LnkyLAogICAgICAgICAgICAgICAgICAgIDAuMCk7CgogICAgICAgIGdsVGV4Q29vcmQyZihnbFRleENvb3JkWzFdLCBnbFRleENvb3JkWzJdKTsKICAgICAgICBnbFZlcnRleDNmKHJlY3QueDIsCiAgICAgICAgICAgICAgICAgICAgcmVjdC55MSwKICAgICAgICAgICAgICAgICAgICAwLjApOwogICAgICAgIGdsRW5kKCk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRW5kIik7CgogICAgICAgIGlmKEZsYWdzICYgKFdJTkVEREJMVF9LRVlTUkMgfCBXSU5FRERCTFRfS0VZU1JDT1ZFUlJJREUpKSB7CiAgICAgICAgICAgIGdsRGlzYWJsZShHTF9BTFBIQV9URVNUKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZShHTF9BTFBIQV9URVNUKSIpOwogICAgICAgIH0KCiAgICAgICAgLyogVW5iaW5kIHRoZSB0ZXh0dXJlICovCiAgICAgICAgZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCAwKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUgZ2xCaW5kVGV4dHVyZSIpOwoKICAgICAgICAvKiBUaGUgZHJhdyBidWZmZXIgc2hvdWxkIG9ubHkgbmVlZCB0byBiZSByZXN0b3JlZCBpZiB3ZSB3ZXJlIGRyYXdpbmcgdG8gdGhlIGZyb250IGJ1ZmZlciwgYW5kIHRoZXJlIGlzIGEgYmFjayBidWZmZXIuCiAgICAgICAgICogb3RoZXJ3aXNlIHRoZSBjb250ZXh0IG1hbmFnZXIgc2hvdWxkIGNob29zZSBiZXR3ZWVuIEdMX0JBQ0sgLyBvZmZzY3JlZW5EcmF3QnVmZmVyCiAgICAgICAgICovCiAgICAgICAgaWYoZHN0U3dhcGNoYWluICYmIFRoaXMgPT0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgZHN0U3dhcGNoYWluLT5mcm9udEJ1ZmZlciAmJiBkc3RTd2FwY2hhaW4tPmJhY2tCdWZmZXIpIHsKICAgICAgICAgICAgZ2xEcmF3QnVmZmVyKEdMX0JBQ0spOwogICAgICAgIH0KICAgICAgICAvKiBSZXN0b3JlIHRoZSBjb2xvciBrZXkgcGFyYW1ldGVycyAqLwogICAgICAgIFNyYy0+Q0tleUZsYWdzID0gb2xkQ0tleUZsYWdzOwogICAgICAgIFRoaXMtPlNyY0JsdENLZXkgPSBvbGRCbHRDS2V5OwoKICAgICAgICBMRUFWRV9HTCgpOwoKICAgICAgICAvKiBUT0RPOiBJZiB0aGUgc3VyZmFjZSBpcyBsb2NrZWQgb2Z0ZW4sIHBlcmZvcm0gdGhlIEJsdCBpbiBzb2Z0d2FyZSBvbiB0aGUgbWVtb3J5IGluc3RlYWQgKi8KICAgICAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfSU5TWVNNRU07CiAgICAgICAgLyogVGhlIHN1cmZhY2UgaXMgbm93IGluIHRoZSBkcmF3YWJsZS4gT24gb25zY3JlZW4gc3VyZmFjZXMgb3Igd2l0aG91dCBmYm9zIHRoZSB0ZXh0dXJlCiAgICAgICAgICogaXMgb3V0ZGF0ZWQgbm93CiAgICAgICAgICovCiAgICAgICAgaWYoZHN0U3dhcGNoYWluIHx8IHdpbmVkM2Rfc2V0dGluZ3Mub2Zmc2NyZWVuX3JlbmRlcmluZ19tb2RlICE9IE9STV9GQk8pIHsKICAgICAgICAgICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfSU5EUkFXQUJMRTsKICAgICAgICAgICAgVGhpcy0+RmxhZ3MgJj0gflNGTEFHX0lOVEVYVFVSRTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19JTlRFWFRVUkU7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0gZWxzZSB7CiAgICAgICAgLyogU291cmNlLUxlc3MgQmxpdCB0byByZW5kZXIgdGFyZ2V0ICovCiAgICAgICAgaWYgKEZsYWdzICYgV0lORUREQkxUX0NPTE9SRklMTCkgewogICAgICAgICAgICAvKiBUaGlzIGlzIGVhc3kgdG8gaGFuZGxlIGZvciB0aGUgRDNEIERldmljZS4uLiAqLwogICAgICAgICAgICBEV09SRCBjb2xvcjsKCiAgICAgICAgICAgIFRSQUNFKCJDb2xvcmZpbGxcbiIpOwoKICAgICAgICAgICAgLyogVGhlIGNvbG9yIGFzIGdpdmVuIGluIHRoZSBCbHQgZnVuY3Rpb24gaXMgaW4gdGhlIGZvcm1hdCBvZiB0aGUgZnJhbWUtYnVmZmVyLi4uCiAgICAgICAgICAgICAqICdjbGVhcicgZXhwZWN0IGl0IGluIEFSR0IgZm9ybWF0ID0+IHdlIG5lZWQgdG8gZG8gc29tZSBjb252ZXJzaW9uIDotKQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX1A4KSB7CiAgICAgICAgICAgICAgICBpZiAoVGhpcy0+cGFsZXR0ZSkgewogICAgICAgICAgICAgICAgICAgIGNvbG9yID0gKCgweEZGMDAwMDAwKSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoVGhpcy0+cGFsZXR0ZS0+cGFsZW50c1tEREJsdEZ4LT51NS5kd0ZpbGxDb2xvcl0ucGVSZWQgPDwgMTYpIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIChUaGlzLT5wYWxldHRlLT5wYWxlbnRzW0REQmx0RngtPnU1LmR3RmlsbENvbG9yXS5wZUdyZWVuIDw8IDgpIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIChUaGlzLT5wYWxldHRlLT5wYWxlbnRzW0REQmx0RngtPnU1LmR3RmlsbENvbG9yXS5wZUJsdWUpKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAweEZGMDAwMDAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX1I1RzZCNSkgewogICAgICAgICAgICAgICAgaWYgKEREQmx0RngtPnU1LmR3RmlsbENvbG9yID09IDB4RkZGRikgewogICAgICAgICAgICAgICAgICAgIGNvbG9yID0gMHhGRkZGRkZGRjsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAoKDB4RkYwMDAwMDApIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoRERCbHRGeC0+dTUuZHdGaWxsQ29sb3IgJiAweEY4MDApIDw8IDgpIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoRERCbHRGeC0+dTUuZHdGaWxsQ29sb3IgJiAweDA3RTApIDw8IDUpIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoRERCbHRGeC0+dTUuZHdGaWxsQ29sb3IgJiAweDAwMUYpIDw8IDMpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmICgoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfUjhHOEI4KSB8fAogICAgICAgICAgICAgICAgICAgIChUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9YOFI4RzhCOCkgKSB7CiAgICAgICAgICAgICAgICBjb2xvciA9IDB4RkYwMDAwMDAgfCBEREJsdEZ4LT51NS5kd0ZpbGxDb2xvcjsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmIChUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9BOFI4RzhCOCkgewogICAgICAgICAgICAgICAgY29sb3IgPSBEREJsdEZ4LT51NS5kd0ZpbGxDb2xvcjsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIEVSUigiV3Jvbmcgc3VyZmFjZSB0eXBlIGZvciBCTFQgb3ZlcnJpZGUoRm9ybWF0IGRvZXNuJ3QgbWF0Y2gpICFcbiIpOwogICAgICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIFRSQUNFKCJDYWxsaW5nIEdldFN3YXBDaGFpbiB3aXRoIG15ZGV2aWNlID0gJXBcbiIsIG15RGV2aWNlKTsKICAgICAgICAgICAgaWYoZHN0U3dhcGNoYWluICYmIGRzdFN3YXBjaGFpbi0+YmFja0J1ZmZlciAmJiBUaGlzID09IChJV2luZUQzRFN1cmZhY2VJbXBsKikgZHN0U3dhcGNoYWluLT5iYWNrQnVmZmVyWzBdKSB7CiAgICAgICAgICAgICAgICBnbERyYXdCdWZmZXIoR0xfQkFDSyk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEcmF3QnVmZmVyKEdMX0JBQ0spIik7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoZHN0U3dhcGNoYWluICYmIFRoaXMgPT0gKElXaW5lRDNEU3VyZmFjZUltcGwqKSBkc3RTd2FwY2hhaW4tPmZyb250QnVmZmVyKSB7CiAgICAgICAgICAgICAgICBnbERyYXdCdWZmZXIoR0xfRlJPTlQpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlcihHTF9GUk9OVCkiKTsKICAgICAgICAgICAgfSBlbHNlIGlmKFRoaXMgPT0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgbXlEZXZpY2UtPnJlbmRlcl90YXJnZXRzWzBdKSB7CiAgICAgICAgICAgICAgICBnbERyYXdCdWZmZXIobXlEZXZpY2UtPm9mZnNjcmVlbkJ1ZmZlcik7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEcmF3QnVmZmVyKG15RGV2aWNlLT5vZmZzY3JlZW5CdWZmZXIzKSIpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgVFJBQ0UoIlN1cmZhY2UgaXMgaGlnaGVyIGJhY2sgYnVmZmVyLCBmYWxsaW5nIGJhY2sgdG8gc29mdHdhcmVcbiIpOwogICAgICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIFRSQUNFKCIoJXApIGV4ZWN1dGluZyBSZW5kZXIgVGFyZ2V0IG92ZXJyaWRlLCBjb2xvciA9ICV4XG4iLCBUaGlzLCBjb2xvcik7CgogICAgICAgICAgICBJV2luZUQzRERldmljZV9DbGVhciggKElXaW5lRDNERGV2aWNlICopIG15RGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEgLyogTnVtYmVyIG9mIHJlY3RhbmdsZXMgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnJlY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRENMRUFSX1RBUkdFVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLjAgLyogWiAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwIC8qIFN0ZW5jaWwgKi8pOwoKICAgICAgICAgICAgLyogUmVzdG9yZSB0aGUgb3JpZ2luYWwgZHJhdyBidWZmZXIgKi8KICAgICAgICAgICAgaWYoIWRzdFN3YXBjaGFpbikgewogICAgICAgICAgICAgICAgZ2xEcmF3QnVmZmVyKG15RGV2aWNlLT5vZmZzY3JlZW5CdWZmZXIpOwogICAgICAgICAgICB9IGVsc2UgaWYoZHN0U3dhcGNoYWluLT5iYWNrQnVmZmVyICYmIGRzdFN3YXBjaGFpbi0+YmFja0J1ZmZlclswXSkgewogICAgICAgICAgICAgICAgZ2xEcmF3QnVmZmVyKEdMX0JBQ0spOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZjaGVja0dMY2FsbCgiZ2xEcmF3QnVmZmVyIik7CgogICAgICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgICAgICB9CiAgICB9CgogICAgLyogRGVmYXVsdDogRmFsbCBiYWNrIHRvIHRoZSBnZW5lcmljIGJsdC4gTm90IGFuIGVycm9yLCBhIFRSQUNFIGlzIGVub3VnaCAqLwogICAgVFJBQ0UoIkRpZG4ndCBmaW5kIGFueSB1c2FibGUgcmVuZGVyIHRhcmdldCBzZXR1cCBmb3IgaHcgYmxpdCwgZmFsbGluZyBiYWNrIHRvIHNvZnR3YXJlXG4iKTsKICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9CbHRaKElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMsIFJFQ1QgKkRlc3RSZWN0LCBJV2luZUQzRFN1cmZhY2UgKlNyY1N1cmZhY2UsIFJFQ1QgKlNyY1JlY3QsIERXT1JEIEZsYWdzLCBXSU5FRERCTFRGWCAqRERCbHRGeCkKewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpteURldmljZSA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CgogICAgaWYgKEZsYWdzICYgV0lORUREQkxUX0RFUFRIRklMTCkgewogICAgICAgIHJldHVybiBJV2luZUQzRERldmljZV9DbGVhcigoSVdpbmVEM0REZXZpY2UgKikgbXlEZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlc3RSZWN0ID09IE5VTEwgPyAwIDogMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFdJTkVEM0RSRUNUICopIERlc3RSZWN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNEQ0xFQVJfWkJVRkZFUiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgwMDAwMDAwMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZsb2F0KSBEREJsdEZ4LT51NS5kd0ZpbGxEZXB0aCAvIChmbG9hdCkgTUFYRFdPUkQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MDAwMDAwMDApOwoKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICBGSVhNRSgiKCVwKTogVW5zdXBwIGRlcHRoc3RlbmNpbCBibGl0XG4iLCBUaGlzKTsKICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9CbHQoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgUkVDVCAqRGVzdFJlY3QsIElXaW5lRDNEU3VyZmFjZSAqU3JjU3VyZmFjZSwgUkVDVCAqU3JjUmVjdCwgRFdPUkQgRmxhZ3MsIFdJTkVEREJMVEZYICpEREJsdEZ4LCBXSU5FRDNEVEVYVFVSRUZJTFRFUlRZUEUgRmlsdGVyKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlNyYyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIFNyY1N1cmZhY2U7CiAgICBJV2luZUQzRERldmljZUltcGwgKm15RGV2aWNlID0gVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZTsKICAgIFRSQUNFKCIoJXApLT4oJXAsJXAsJXAsJXgsJXApXG4iLCBUaGlzLCBEZXN0UmVjdCwgU3JjU3VyZmFjZSwgU3JjUmVjdCwgRmxhZ3MsIEREQmx0RngpOwogICAgVFJBQ0UoIiglcCk6IFVzYWdlIGlzICVzXG4iLCBUaGlzLCBkZWJ1Z19kM2R1c2FnZShUaGlzLT5yZXNvdXJjZS51c2FnZSkpOwoKICAgIC8qIEFjY2Vzc2luZyB0aGUgZGVwdGggc3RlbmNpbCBpcyBzdXBwb3NlZCB0byBmYWlsIGJldHdlZW4gYSBCZWdpblNjZW5lIGFuZCBFbmRTY2VuZSBwYWlyICovCiAgICBpZihpZmFjZSA9PSBteURldmljZS0+c3RlbmNpbEJ1ZmZlclRhcmdldCB8fCAoU3JjU3VyZmFjZSAmJiBTcmNTdXJmYWNlID09IG15RGV2aWNlLT5zdGVuY2lsQnVmZmVyVGFyZ2V0KSkgewogICAgICAgIGlmKG15RGV2aWNlLT5pblNjZW5lKSB7CiAgICAgICAgICAgIFRSQUNFKCJBdHRlbXB0IHRvIGFjY2VzcyB0aGUgZGVwdGggc3RlbmNpbCBzdXJmYWNlIGluIGEgQmVnaW5TY2VuZSAvIEVuZFNjZW5lIHBhaXIsIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMXG4iKTsKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICAgICAgfSBlbHNlIGlmKElXaW5lRDNEU3VyZmFjZUltcGxfQmx0WihUaGlzLCBEZXN0UmVjdCwgU3JjU3VyZmFjZSwgU3JjUmVjdCwgRmxhZ3MsIEREQmx0RngpID09IFdJTkVEM0RfT0spIHsKICAgICAgICAgICAgVFJBQ0UoIlogQmxpdCBvdmVycmlkZSBoYW5kbGVkIHRoZSBibGl0XG4iKTsKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICAgICAgfQogICAgfQoKICAgIC8qIFNwZWNpYWwgY2FzZXMgZm9yIFJlbmRlclRhcmdldHMgKi8KICAgIGlmKCAoVGhpcy0+cmVzb3VyY2UudXNhZ2UgJiBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUKSB8fAogICAgICAgICggU3JjICYmIChTcmMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkgKSkgewogICAgICAgIGlmKElXaW5lRDNEU3VyZmFjZUltcGxfQmx0T3ZlcnJpZGUoVGhpcywgRGVzdFJlY3QsIFNyY1N1cmZhY2UsIFNyY1JlY3QsIEZsYWdzLCBEREJsdEZ4LCBGaWx0ZXIpID09IFdJTkVEM0RfT0spIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIC8qIEZvciB0aGUgcmVzdCBjYWxsIHRoZSBYMTEgc3VyZmFjZSBpbXBsZW1lbnRhdGlvbi4KICAgICAqIEZvciBSZW5kZXJUYXJnZXRzIHRoaXMgc2hvdWxkIGJlIGltcGxlbWVudGVkIE9wZW5HTCBhY2NlbGVyYXRlZCBpbiBCbHRPdmVycmlkZSwKICAgICAqIG90aGVyIEJsdHMgYXJlIHJhdGhlciByYXJlCiAgICAgKi8KICAgIHJldHVybiBJV2luZUdESVN1cmZhY2VJbXBsX0JsdChpZmFjZSwgRGVzdFJlY3QsIFNyY1N1cmZhY2UsIFNyY1JlY3QsIEZsYWdzLCBEREJsdEZ4LCBGaWx0ZXIpOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0dldEJsdFN0YXR1cyhJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBEV09SRCBGbGFncykgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKS0+KCV4KVxuIiwgVGhpcywgRmxhZ3MpOwoKICAgIHN3aXRjaCAoRmxhZ3MpCiAgICB7CiAgICBjYXNlIFdJTkVEREdCU19DQU5CTFQ6CiAgICBjYXNlIFdJTkVEREdCU19JU0JMVERPTkU6CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CgogICAgZGVmYXVsdDoKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRGbGlwU3RhdHVzKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIERXT1JEIEZsYWdzKSB7CiAgICAvKiBYWFg6IERERVJSX0lOVkFMSURTVVJGQUNFVFlQRSAqLwoKICAgIFRSQUNFKCIoJXApLT4oJTA4eClcbiIsaWZhY2UsRmxhZ3MpOwogICAgc3dpdGNoIChGbGFncykgewogICAgY2FzZSBXSU5FRERHRlNfQ0FORkxJUDoKICAgIGNhc2UgV0lORURER0ZTX0lTRkxJUERPTkU6CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CgogICAgZGVmYXVsdDoKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9Jc0xvc3QoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwoKICAgIC8qIEQzRDggYW5kIDkgbG9vc2UgZnVsbCBkZXZpY2VzLCBkZHJhdyBvbmx5IHN1cmZhY2VzICovCiAgICByZXR1cm4gVGhpcy0+RmxhZ3MgJiBTRkxBR19MT1NUID8gV0lORUQzREVSUl9ERVZJQ0VMT1NUIDogV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9SZXN0b3JlKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBpZmFjZTsKICAgIFRSQUNFKCIoJXApXG4iLCBUaGlzKTsKCiAgICAvKiBTbyBmYXIgd2UgZG9uJ3QgbG9zZSBhbnl0aGluZyA6KSAqLwogICAgVGhpcy0+RmxhZ3MgJj0gflNGTEFHX0xPU1Q7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9CbHRGYXN0KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIERXT1JEIGRzdHgsIERXT1JEIGRzdHksIElXaW5lRDNEU3VyZmFjZSAqU291cmNlLCBSRUNUICpyc3JjLCBEV09SRCB0cmFucykgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqc3JjSW1wbCA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIFNvdXJjZTsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqbXlEZXZpY2UgPSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOwogICAgVFJBQ0UoIiglcCktPiglZCwgJWQsICVwLCAlcCwgJTA4eFxuIiwgaWZhY2UsIGRzdHgsIGRzdHksIFNvdXJjZSwgcnNyYywgdHJhbnMpOwoKICAgIGlmKG15RGV2aWNlLT5pblNjZW5lICYmCiAgICAgICAoaWZhY2UgPT0gbXlEZXZpY2UtPnN0ZW5jaWxCdWZmZXJUYXJnZXQgfHwKICAgICAgIChTb3VyY2UgJiYgU291cmNlID09IG15RGV2aWNlLT5zdGVuY2lsQnVmZmVyVGFyZ2V0KSkpIHsKICAgICAgICBUUkFDRSgiQXR0ZW1wdCB0byBhY2Nlc3MgdGhlIGRlcHRoIHN0ZW5jaWwgc3VyZmFjZSBpbiBhIEJlZ2luU2NlbmUgLyBFbmRTY2VuZSBwYWlyLCByZXR1cm5pbmcgV0lORUQzREVSUl9JTlZBTElEQ0FMTFxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgLyogU3BlY2lhbCBjYXNlcyBmb3IgUmVuZGVyVGFyZ2V0cyAqLwogICAgaWYoIChUaGlzLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQpIHx8CiAgICAgICAgKCBzcmNJbXBsICYmIChzcmNJbXBsLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQpICkpIHsKCiAgICAgICAgUkVDVCBTcmNSZWN0LCBEc3RSZWN0OwogICAgICAgIERXT1JEIEZsYWdzPTA7CgogICAgICAgIGlmKHJzcmMpIHsKICAgICAgICAgICAgU3JjUmVjdC5sZWZ0ID0gcnNyYy0+bGVmdDsKICAgICAgICAgICAgU3JjUmVjdC50b3A9IHJzcmMtPnRvcDsKICAgICAgICAgICAgU3JjUmVjdC5ib3R0b20gPSByc3JjLT5ib3R0b207CiAgICAgICAgICAgIFNyY1JlY3QucmlnaHQgPSByc3JjLT5yaWdodDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBTcmNSZWN0LmxlZnQgPSAwOwogICAgICAgICAgICBTcmNSZWN0LnRvcCA9IDA7CiAgICAgICAgICAgIFNyY1JlY3QucmlnaHQgPSBzcmNJbXBsLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICAgICAgU3JjUmVjdC5ib3R0b20gPSBzcmNJbXBsLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICAgICAgfQoKICAgICAgICBEc3RSZWN0LmxlZnQgPSBkc3R4OwogICAgICAgIERzdFJlY3QudG9wPWRzdHk7CiAgICAgICAgRHN0UmVjdC5yaWdodCA9IGRzdHggKyBTcmNSZWN0LnJpZ2h0IC0gU3JjUmVjdC5sZWZ0OwogICAgICAgIERzdFJlY3QuYm90dG9tID0gZHN0eSArIFNyY1JlY3QuYm90dG9tIC0gU3JjUmVjdC50b3A7CgogICAgICAgIC8qIENvbnZlcnQgQmx0RmFzdCBmbGFncyBpbnRvIEJ0bCBvbmVzIGJlY2F1c2UgaXQgaXMgY2FsbGVkIGZyb20gU3VyZmFjZUltcGxfQmx0IGFzIHdlbGwgKi8KICAgICAgICBpZih0cmFucyAmIFdJTkVEREJMVEZBU1RfU1JDQ09MT1JLRVkpCiAgICAgICAgICAgIEZsYWdzIHw9IFdJTkVEREJMVF9LRVlTUkM7CiAgICAgICAgaWYodHJhbnMgJiBXSU5FRERCTFRGQVNUX0RFU1RDT0xPUktFWSkKICAgICAgICAgICAgRmxhZ3MgfD0gV0lORUREQkxUX0tFWURFU1Q7CiAgICAgICAgaWYodHJhbnMgJiBXSU5FRERCTFRGQVNUX1dBSVQpCiAgICAgICAgICAgIEZsYWdzIHw9IFdJTkVEREJMVF9XQUlUOwogICAgICAgIGlmKHRyYW5zICYgV0lORUREQkxURkFTVF9ET05PVFdBSVQpCiAgICAgICAgICAgIEZsYWdzIHw9IFdJTkVEREJMVF9ET05PVFdBSVQ7CgogICAgICAgIGlmKElXaW5lRDNEU3VyZmFjZUltcGxfQmx0T3ZlcnJpZGUoVGhpcywgJkRzdFJlY3QsIFNvdXJjZSwgJlNyY1JlY3QsIEZsYWdzLCBOVUxMLCBXSU5FRDNEVEVYRl9QT0lOVCkgPT0gV0lORUQzRF9PSykgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgoKICAgIHJldHVybiBJV2luZUdESVN1cmZhY2VJbXBsX0JsdEZhc3QoaWZhY2UsIGRzdHgsIGRzdHksIFNvdXJjZSwgcnNyYywgdHJhbnMpOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0dldFBhbGV0dGUoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgSVdpbmVEM0RQYWxldHRlICoqUGFsKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIiwgVGhpcywgUGFsKTsKCiAgICAqUGFsID0gKElXaW5lRDNEUGFsZXR0ZSAqKSBUaGlzLT5wYWxldHRlOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfUmVhbGl6ZVBhbGV0dGUoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwogICAgUkdCUVVBRCBjb2xbMjU2XTsKICAgIElXaW5lRDNEUGFsZXR0ZUltcGwgKnBhbCA9IFRoaXMtPnBhbGV0dGU7CiAgICB1bnNpZ25lZCBpbnQgbjsKICAgIFRSQUNFKCIoJXApXG4iLCBUaGlzKTsKCiAgICBpZihUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9QOCB8fAogICAgICAgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfQThQOCkKICAgIHsKICAgICAgICBpZighVGhpcy0+RmxhZ3MgJiBTRkxBR19JTlNZU01FTSkgewogICAgICAgICAgICBGSVhNRSgiUGFsZXR0ZSBjaGFuZ2VkIHdpdGggc3VyZmFjZSB0aGF0IGRvZXMgbm90IGhhdmUgYW4gdXAgdG8gZGF0ZSBzeXN0ZW0gbWVtb3J5IGNvcHlcbiIpOwogICAgICAgIH0KICAgICAgICBUUkFDRSgiRGlydGlmeWluZyBzdXJmYWNlXG4iKTsKICAgICAgICBUaGlzLT5GbGFncyAmPSB+KFNGTEFHX0lOVEVYVFVSRSB8IFNGTEFHX0lORFJBV0FCTEUpOwogICAgfQoKICAgIGlmKFRoaXMtPkZsYWdzICYgU0ZMQUdfRElCU0VDVElPTikgewogICAgICAgIFRSQUNFKCIoJXApOiBVcGRhdGluZyB0aGUgaGRjJ3MgcGFsZXR0ZVxuIiwgVGhpcyk7CiAgICAgICAgZm9yIChuPTA7IG48MjU2OyBuKyspIHsKICAgICAgICAgICAgaWYocGFsKSB7CiAgICAgICAgICAgICAgICBjb2xbbl0ucmdiUmVkICAgPSBwYWwtPnBhbGVudHNbbl0ucGVSZWQ7CiAgICAgICAgICAgICAgICBjb2xbbl0ucmdiR3JlZW4gPSBwYWwtPnBhbGVudHNbbl0ucGVHcmVlbjsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JCbHVlICA9IHBhbC0+cGFsZW50c1tuXS5wZUJsdWU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZUltcGwgKmRldmljZSA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CiAgICAgICAgICAgICAgICAvKiBVc2UgdGhlIGRlZmF1bHQgZGV2aWNlIHBhbGV0dGUgKi8KICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JSZWQgICA9IGRldmljZS0+cGFsZXR0ZXNbZGV2aWNlLT5jdXJyZW50UGFsZXR0ZV1bbl0ucGVSZWQ7CiAgICAgICAgICAgICAgICBjb2xbbl0ucmdiR3JlZW4gPSBkZXZpY2UtPnBhbGV0dGVzW2RldmljZS0+Y3VycmVudFBhbGV0dGVdW25dLnBlR3JlZW47CiAgICAgICAgICAgICAgICBjb2xbbl0ucmdiQmx1ZSAgPSBkZXZpY2UtPnBhbGV0dGVzW2RldmljZS0+Y3VycmVudFBhbGV0dGVdW25dLnBlQmx1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjb2xbbl0ucmdiUmVzZXJ2ZWQgPSAwOwogICAgICAgIH0KICAgICAgICBTZXRESUJDb2xvclRhYmxlKFRoaXMtPmhEQywgMCwgMjU2LCBjb2wpOwogICAgfQoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1NldFBhbGV0dGUoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgSVdpbmVEM0RQYWxldHRlICpQYWwpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBpZmFjZTsKICAgIElXaW5lRDNEUGFsZXR0ZUltcGwgKlBhbEltcGwgPSAoSVdpbmVEM0RQYWxldHRlSW1wbCAqKSBQYWw7CiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIiwgVGhpcywgUGFsKTsKCiAgICBpZihUaGlzLT5wYWxldHRlICE9IE5VTEwpIAogICAgICAgIGlmKFRoaXMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkKICAgICAgICAgICAgVGhpcy0+cGFsZXR0ZS0+RmxhZ3MgJj0gfldJTkVERFBDQVBTX1BSSU1BUllTVVJGQUNFOwoKICAgIGlmKFBhbEltcGwgIT0gTlVMTCkgewogICAgICAgIGlmKFRoaXMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkgewogICAgICAgICAgICAvKiBTZXQgdGhlIGRldmljZSdzIG1haW4gcGFsZXR0ZSBpZiB0aGUgcGFsZXR0ZQogICAgICAgICAgICAgKiB3YXNuJ3QgYSBwcmltYXJ5IHBhbGV0dGUgYmVmb3JlCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZighKFBhbEltcGwtPkZsYWdzICYgV0lORUREUENBUFNfUFJJTUFSWVNVUkZBQ0UpKSB7CiAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZUltcGwgKmRldmljZSA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CiAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgaTsKCiAgICAgICAgICAgICAgICBmb3IoaT0wOyBpIDwgMjU2OyBpKyspIHsKICAgICAgICAgICAgICAgICAgICBkZXZpY2UtPnBhbGV0dGVzW2RldmljZS0+Y3VycmVudFBhbGV0dGVdW2ldID0gUGFsSW1wbC0+cGFsZW50c1tpXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgKFBhbEltcGwpLT5GbGFncyB8PSBXSU5FRERQQ0FQU19QUklNQVJZU1VSRkFDRTsKICAgICAgICB9CiAgICB9CiAgICBUaGlzLT5wYWxldHRlID0gUGFsSW1wbDsKCiAgICByZXR1cm4gSVdpbmVEM0RTdXJmYWNlX1JlYWxpemVQYWxldHRlKGlmYWNlKTsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRDb2xvcktleShJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBEV09SRCBGbGFncywgV0lORUREQ09MT1JLRVkgKkNLZXkpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBpZmFjZTsKICAgIFRSQUNFKCIoJXApLT4oJTA4eCwlcClcbiIsIFRoaXMsIEZsYWdzLCBDS2V5KTsKCiAgICBpZiAoKEZsYWdzICYgV0lORUREQ0tFWV9DT0xPUlNQQUNFKSAhPSAwKSB7CiAgICAgICAgRklYTUUoIiBjb2xvcmtleSB2YWx1ZSBub3Qgc3VwcG9ydGVkICglMDh4KSAhXG4iLCBGbGFncyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgLyogRGlydGlmeSB0aGUgc3VyZmFjZSwgYnV0IG9ubHkgaWYgYSBrZXkgd2FzIGNoYW5nZWQgKi8KICAgIGlmKENLZXkpIHsKICAgICAgICBzd2l0Y2ggKEZsYWdzICYgfldJTkVERENLRVlfQ09MT1JTUEFDRSkgewogICAgICAgICAgICBjYXNlIFdJTkVERENLRVlfREVTVEJMVDoKICAgICAgICAgICAgICAgIFRoaXMtPkRlc3RCbHRDS2V5ID0gKkNLZXk7CiAgICAgICAgICAgICAgICBUaGlzLT5DS2V5RmxhZ3MgfD0gV0lORUREU0RfQ0tERVNUQkxUOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIFdJTkVERENLRVlfREVTVE9WRVJMQVk6CiAgICAgICAgICAgICAgICBUaGlzLT5EZXN0T3ZlcmxheUNLZXkgPSAqQ0tleTsKICAgICAgICAgICAgICAgIFRoaXMtPkNLZXlGbGFncyB8PSBXSU5FRERTRF9DS0RFU1RPVkVSTEFZOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIFdJTkVERENLRVlfU1JDT1ZFUkxBWToKICAgICAgICAgICAgICAgIFRoaXMtPlNyY092ZXJsYXlDS2V5ID0gKkNLZXk7CiAgICAgICAgICAgICAgICBUaGlzLT5DS2V5RmxhZ3MgfD0gV0lORUREU0RfQ0tTUkNPVkVSTEFZOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIFdJTkVERENLRVlfU1JDQkxUOgogICAgICAgICAgICAgICAgVGhpcy0+U3JjQmx0Q0tleSA9ICpDS2V5OwogICAgICAgICAgICAgICAgVGhpcy0+Q0tleUZsYWdzIHw9IFdJTkVERFNEX0NLU1JDQkxUOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQogICAgZWxzZSB7CiAgICAgICAgc3dpdGNoIChGbGFncyAmIH5XSU5FRERDS0VZX0NPTE9SU1BBQ0UpIHsKICAgICAgICAgICAgY2FzZSBXSU5FRERDS0VZX0RFU1RCTFQ6CiAgICAgICAgICAgICAgICBUaGlzLT5DS2V5RmxhZ3MgJj0gfldJTkVERFNEX0NLREVTVEJMVDsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBXSU5FRERDS0VZX0RFU1RPVkVSTEFZOgogICAgICAgICAgICAgICAgVGhpcy0+Q0tleUZsYWdzICY9IH5XSU5FRERTRF9DS0RFU1RPVkVSTEFZOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIFdJTkVERENLRVlfU1JDT1ZFUkxBWToKICAgICAgICAgICAgICAgIFRoaXMtPkNLZXlGbGFncyAmPSB+V0lORUREU0RfQ0tTUkNPVkVSTEFZOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIFdJTkVERENLRVlfU1JDQkxUOgogICAgICAgICAgICAgICAgVGhpcy0+Q0tleUZsYWdzICY9IH5XSU5FRERTRF9DS1NSQ0JMVDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfUHJpdmF0ZVNldHVwKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpIHsKICAgIC8qKiBDaGVjayBhZ2FpbnN0IHRoZSBtYXhpbXVtIHRleHR1cmUgc2l6ZXMgc3VwcG9ydGVkIGJ5IHRoZSB2aWRlbyBjYXJkICoqLwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwoKICAgIFRSQUNFKCIlcFxuIiwgVGhpcyk7CiAgICBpZiAoKFRoaXMtPnBvdzJXaWR0aCA+IEdMX0xJTUlUUyh0ZXh0dXJlX3NpemUpIHx8IFRoaXMtPnBvdzJIZWlnaHQgPiBHTF9MSU1JVFModGV4dHVyZV9zaXplKSkgJiYgIShUaGlzLT5yZXNvdXJjZS51c2FnZSAmIChXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUIHwgV0lORUQzRFVTQUdFX0RFUFRIU1RFTkNJTCkpKSB7CiAgICAgICAgLyogb25lIG9mIHRocmVlIG9wdGlvbnMKICAgICAgICAxOiBEbyB0aGUgc2FtZSBhcyB3ZSBkbyB3aXRoIG5vbnBvdyAyIGFuZCBzY2FsZSB0aGUgdGV4dHVyZSwgKGFueSB0ZXh0dXJlIG9wcyB3b3VsZCByZXF1aXJlIHRoZSB0ZXh0dXJlIHRvIGJlIHNjYWxlZCB3aGljaCBpcyBwb3RlbnRpYWxseSBzbG93KQogICAgICAgIDI6IFNldCB0aGUgdGV4dHVyZSB0byB0aGUgbWF4aXVtIHNpemUgKGJhZCBpZGVhKQogICAgICAgIDM6ICAgIFdBUk4gYW5kIHJldHVybiBXSU5FRDNERVJSX05PVEFWQUlMQUJMRTsKICAgICAgICA0OiBDcmVhdGUgdGhlIHN1cmZhY2UsIGJ1dCBhbGxvdyBpdCB0byBiZSB1c2VkIG9ubHkgZm9yIERpcmVjdERyYXcgQmx0cy4gU29tZSBhcHBzKGUuZy4gU3dhdCAzKSBjcmVhdGUgdGV4dHVyZXMgd2l0aCBhIEhlaWdodCBvZiAxNiBhbmQgYSBXaWR0aCA+IDMwMDAgYW5kIGJsdCAxNngxNiBsZXR0ZXIgYXJlYXMgZnJvbSB0aGVtIHRvIHRoZSByZW5kZXIgdGFyZ2V0LgogICAgICAgICovCiAgICAgICAgV0FSTigiKCVwKSBDcmVhdGluZyBhbiBvdmVyc2l6ZWQgc3VyZmFjZVxuIiwgVGhpcyk7CiAgICAgICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfT1ZFUlNJWkU7CgogICAgICAgIC8qIFRoaXMgd2lsbCBiZSBpbml0aWFsaXplZCBvbiB0aGUgZmlyc3QgYmx0ICovCiAgICAgICAgVGhpcy0+Z2xSZWN0LmxlZnQgPSAwOwogICAgICAgIFRoaXMtPmdsUmVjdC50b3AgPSAwOwogICAgICAgIFRoaXMtPmdsUmVjdC5yaWdodCA9IDA7CiAgICAgICAgVGhpcy0+Z2xSZWN0LmJvdHRvbSA9IDA7CiAgICB9IGVsc2UgewogICAgICAgIC8qIE5vIG92ZXJzaXplLCBnbCByZWN0IGlzIHRoZSBmdWxsIHRleHR1cmUgc2l6ZSAqLwogICAgICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19PVkVSU0laRTsKICAgICAgICBUaGlzLT5nbFJlY3QubGVmdCA9IDA7CiAgICAgICAgVGhpcy0+Z2xSZWN0LnRvcCA9IDA7CiAgICAgICAgVGhpcy0+Z2xSZWN0LnJpZ2h0ID0gVGhpcy0+cG93MldpZHRoOwogICAgICAgIFRoaXMtPmdsUmVjdC5ib3R0b20gPSBUaGlzLT5wb3cySGVpZ2h0OwogICAgfQoKICAgIGlmKEdMX1NVUFBPUlQoQVBQTEVfQ0xJRU5UX1NUT1JBR0UpICYmIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9PSBOVUxMKSB7CiAgICAgICAgLyogTWFrZSBzdXJlIHRoYXQgbWVtb3J5IGlzIGFsbG9jYXRlZCBmcm9tIHRoZSBzdGFydCBpZiB3ZSBhcmUgZ29pbmcgdG8gdXNlIEdMX0FQUExFX2NsaWVudF9zdG9yYWdlLgogICAgICAgICAqIE90aGVyd2lzZSBhIGdsVGV4SW1hZ2UyRCB3aXRoIGEgTlVMTCBwb2ludGVyIG1heSBiZSBkb25lLCBlLmcuIHdoZW4gYmxpdHRpbmcgb3Igd2l0aCBvZmZzY3JlZW4gcmVuZGVyCiAgICAgICAgICogdGFyZ2V0cywgdGh1cyB0aGUgY2xpZW50IHN0b3JhZ2Ugd291bGRuJ3QgYmUgdXNlZCBmb3IgdGhhdCB0ZXh0dXJlCiAgICAgICAgICovCiAgICAgICAgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIFRoaXMtPnJlc291cmNlLnNpemUgKyA0KTsKICAgIH0KICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpEV09SRCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRQaXRjaChJV2luZUQzRFN1cmZhY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CiAgICBEV09SRCByZXQ7CiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CgogICAgLyogRFhUbiBmb3JtYXRzIGRvbid0IGhhdmUgZXhhY3QgcGl0Y2hlcyBhcyB0aGV5IGFyZSB0byB0aGUgbmV3IHJvdyBvZiBibG9ja3MsCiAgICAgICAgIHdoZXJlIGVhY2ggYmxvY2sgaXMgNHg0IHBpeGVscywgOCBieXRlcyAoZHh0MSkgYW5kIDE2IGJ5dGVzIChkeHQyLzMvNC81KQogICAgICAgICAgaWUgcGl0Y2ggPSAod2lkdGgvNCkgKiBieXRlcyBwZXIgYmxvY2sgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgIGlmIChUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQxKSAvKiBEWFQxIGlzIDggYnl0ZXMgcGVyIGJsb2NrICovCiAgICAgICAgcmV0ID0gKChUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCArIDMpID4+IDIpIDw8IDM7CiAgICBlbHNlIGlmIChUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQyIHx8IFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDMgfHwKICAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDQgfHwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNSkgLyogRFhUMi8zLzQvNSBpcyAxNiBieXRlcyBwZXIgYmxvY2sgKi8KICAgICAgICByZXQgPSAoKFRoaXMtPmN1cnJlbnREZXNjLldpZHRoICsgMykgPj4gMikgPDwgNDsKICAgIGVsc2UgewogICAgICAgIHJldCA9IFRoaXMtPmJ5dGVzUGVyUGl4ZWwgKiBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aDsgIC8qIEJ5dGVzIC8gcm93ICovCiAgICAgICAgLyogU3VyZmFjZXMgYXJlIDMyIGJpdCBhbGlnbmVkICovCiAgICAgICAgcmV0ID0gKHJldCArIFNVUkZBQ0VfQUxJR05NRU5UIC0gMSkgJiB+KFNVUkZBQ0VfQUxJR05NRU5UIC0gMSk7CiAgICB9CiAgICBUUkFDRSgiKCVwKSBSZXR1cm5pbmcgJWRcbiIsIFRoaXMsIHJldCk7CiAgICByZXR1cm4gcmV0Owp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1NldE92ZXJsYXlQb3NpdGlvbihJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBMT05HIFgsIExPTkcgWSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwoKICAgIEZJWE1FKCIoJXApLT4oJWQsJWQpIFN0dWIhXG4iLCBUaGlzLCBYLCBZKTsKCiAgICBpZighKFRoaXMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX09WRVJMQVkpKQogICAgewogICAgICAgIFRSQUNFKCIoJXApOiBOb3QgYW4gb3ZlcmxheSBzdXJmYWNlXG4iLCBUaGlzKTsKICAgICAgICByZXR1cm4gV0lORURERVJSX05PVEFPVkVSTEFZU1VSRkFDRTsKICAgIH0KCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRPdmVybGF5UG9zaXRpb24oSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgTE9ORyAqWCwgTE9ORyAqWSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwoKICAgIEZJWE1FKCIoJXApLT4oJXAsJXApIFN0dWIhXG4iLCBUaGlzLCBYLCBZKTsKCiAgICBpZighKFRoaXMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX09WRVJMQVkpKQogICAgewogICAgICAgIFRSQUNFKCIoJXApOiBOb3QgYW4gb3ZlcmxheSBzdXJmYWNlXG4iLCBUaGlzKTsKICAgICAgICByZXR1cm4gV0lORURERVJSX05PVEFPVkVSTEFZU1VSRkFDRTsKICAgIH0KCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9VcGRhdGVPdmVybGF5Wk9yZGVyKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIERXT1JEIEZsYWdzLCBJV2luZUQzRFN1cmZhY2UgKlJlZikgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqUmVmSW1wbCA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIFJlZjsKCiAgICBGSVhNRSgiKCVwKS0+KCUwOHgsJXApIFN0dWIhXG4iLCBUaGlzLCBGbGFncywgUmVmSW1wbCk7CgogICAgaWYoIShUaGlzLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9PVkVSTEFZKSkKICAgIHsKICAgICAgICBUUkFDRSgiKCVwKTogTm90IGFuIG92ZXJsYXkgc3VyZmFjZVxuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIFdJTkVEREVSUl9OT1RBT1ZFUkxBWVNVUkZBQ0U7CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfVXBkYXRlT3ZlcmxheShJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBSRUNUICpTcmNSZWN0LCBJV2luZUQzRFN1cmZhY2UgKkRzdFN1cmZhY2UsIFJFQ1QgKkRzdFJlY3QsIERXT1JEIEZsYWdzLCBXSU5FRERPVkVSTEFZRlggKkZYKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpEc3QgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBEc3RTdXJmYWNlOwogICAgRklYTUUoIiglcCktPiglcCwgJXAsICVwLCAlMDh4LCAlcClcbiIsIFRoaXMsIFNyY1JlY3QsIERzdCwgRHN0UmVjdCwgRmxhZ3MsIEZYKTsKCiAgICBpZighKFRoaXMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX09WRVJMQVkpKQogICAgewogICAgICAgIFRSQUNFKCIoJXApOiBOb3QgYW4gb3ZlcmxheSBzdXJmYWNlXG4iLCBUaGlzKTsKICAgICAgICByZXR1cm4gV0lORURERVJSX05PVEFPVkVSTEFZU1VSRkFDRTsKICAgIH0KCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRDbGlwcGVyKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIElXaW5lRDNEQ2xpcHBlciAqY2xpcHBlcikKewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwogICAgVFJBQ0UoIiglcCktPiglcClcbiIsIFRoaXMsIGNsaXBwZXIpOwoKICAgIFRoaXMtPmNsaXBwZXIgPSBjbGlwcGVyOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0Q2xpcHBlcihJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBJV2luZUQzRENsaXBwZXIgKipjbGlwcGVyKQp7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIiwgVGhpcywgY2xpcHBlcik7CgogICAgKmNsaXBwZXIgPSBUaGlzLT5jbGlwcGVyOwogICAgaWYoKmNsaXBwZXIpIHsKICAgICAgICBJV2luZUQzRENsaXBwZXJfQWRkUmVmKCpjbGlwcGVyKTsKICAgIH0KICAgIHJldHVybiBXSU5FRDNEX09LOwp9Cgpjb25zdCBJV2luZUQzRFN1cmZhY2VWdGJsIElXaW5lRDNEU3VyZmFjZV9WdGJsID0KewogICAgLyogSVVua25vd24gKi8KICAgIElXaW5lRDNEU3VyZmFjZUltcGxfUXVlcnlJbnRlcmZhY2UsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0FkZFJlZiwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfUmVsZWFzZSwKICAgIC8qIElXaW5lRDNEUmVzb3VyY2UgKi8KICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0UGFyZW50LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXREZXZpY2UsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1NldFByaXZhdGVEYXRhLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRQcml2YXRlRGF0YSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfRnJlZVByaXZhdGVEYXRhLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRQcmlvcml0eSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0UHJpb3JpdHksCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1ByZUxvYWQsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldFR5cGUsCiAgICAvKiBJV2luZUQzRFN1cmZhY2UgKi8KICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0Q29udGFpbmVyLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXREZXNjLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9Mb2NrUmVjdCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfVW5sb2NrUmVjdCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0REMsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1JlbGVhc2VEQywKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfRmxpcCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfQmx0LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRCbHRTdGF0dXMsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldEZsaXBTdGF0dXMsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0lzTG9zdCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfUmVzdG9yZSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfQmx0RmFzdCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0UGFsZXR0ZSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0UGFsZXR0ZSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfUmVhbGl6ZVBhbGV0dGUsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1NldENvbG9yS2V5LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRQaXRjaCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0TWVtLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRPdmVybGF5UG9zaXRpb24sCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldE92ZXJsYXlQb3NpdGlvbiwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfVXBkYXRlT3ZlcmxheVpPcmRlciwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfVXBkYXRlT3ZlcmxheSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0Q2xpcHBlciwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0Q2xpcHBlciwKICAgIC8qIEludGVybmFsIHVzZTogKi8KICAgIElXaW5lRDNEU3VyZmFjZUltcGxfQWRkRGlydHlSZWN0LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9Mb2FkVGV4dHVyZSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfU2F2ZVNuYXBzaG90LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRDb250YWluZXIsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1NldEdsVGV4dHVyZURlc2MsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldEdsRGVzYywKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0RGF0YSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0Rm9ybWF0LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9Qcml2YXRlU2V0dXAKfTsK