LyogIAkJCURpcmVjdFNvdW5kCiAqIAogKiBDb3B5cmlnaHQgMTk5OCBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggUm9iIFJpZ2dzCiAqIENvcHlyaWdodCAyMDAwLTIwMDEgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzLCBJbmMuCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KLyoKICogTW9zdCB0aHJlYWQgbG9ja2luZyBpcyBjb21wbGV0ZS4gVGhlcmUgbWF5IGJlIGEgZmV3IHJhY2UKICogY29uZGl0aW9ucyBzdGlsbCBsdXJraW5nLgogKgogKiBUZXN0ZWQgd2l0aCBhIFNvdW5kYmxhc3RlciBjbG9uZSwgYSBHcmF2aXMgVWx0cmFTb3VuZCBDbGFzc2ljLAogKiBhbmQgYSBUdXJ0bGUgQmVhY2ggVHJvcGV6Ky4KICoKICogVE9ETzoKICoJSW1wbGVtZW50IERpcmVjdFNvdW5kQ2FwdHVyZSBBUEkKICoJSW1wbGVtZW50IFNldENvb3BlcmF0aXZlTGV2ZWwgcHJvcGVybHkgKG5lZWQgdG8gYWRkcmVzcyBmb2N1cyBpc3N1ZXMpCiAqCUltcGxlbWVudCBEaXJlY3RTb3VuZDNEQnVmZmVycyAoc3R1YnMgaW4gcGxhY2UpCiAqCVVzZSBoYXJkd2FyZSAzRCBzdXBwb3J0IGlmIGF2YWlsYWJsZQogKiAgICAgIEFkZCBjcml0aWNhbCBzZWN0aW9uIGxvY2tpbmcgaW5zaWRlIFJlbGVhc2UgYW5kIEFkZFJlZiBtZXRob2RzCiAqICAgICAgSGFuZGxlIHN0YXRpYyBidWZmZXJzIC0gcHV0IHRob3NlIGluIGhhcmR3YXJlLCBub24tc3RhdGljIG5vdCBpbiBoYXJkd2FyZQogKiAgICAgIEhhcmR3YXJlIER1cGxpY2F0ZVNvdW5kQnVmZmVyCiAqICAgICAgUHJvcGVyIHZvbHVtZSBjYWxjdWxhdGlvbiwgYW5kIHNldHRpbmcgdm9sdW1lIGluIEhFTCBwcmltYXJ5IGJ1ZmZlcgogKiAgICAgIE9wdGltaXplIFdJTk1NIGFuZCBuZWdvdGlhdGUgZnJhZ21lbnQgc2l6ZSwgZGVjcmVhc2UgRFNfSEVMX01BUkdJTgogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3lzL2ZjbnRsLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxtYXRoLmg+CS8qIEluc29tbmlhIC0gcG93KCkgZnVuY3Rpb24gKi8KCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmdkaS5oIgojaW5jbHVkZSAid2ludXNlci5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIm1tc3lzdGVtLmgiCiNpbmNsdWRlICJtbWRkay5oIgojaW5jbHVkZSAid2luZS93aW5kZWYxNi5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgojaW5jbHVkZSAiZHNvdW5kLmgiCiNpbmNsdWRlICJkc2RyaXZlci5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoZHNvdW5kKTsKCi8qIHRoZXNlIGFyZSBlbGlnaWJsZSBmb3IgdHVuaW5nLi4uIHRoZXkgbXVzdCBiZSBoaWdoIG9uIHNsb3cgbWFjaGluZXMuLi4gKi8KLyogc29tZSBzdHVmZiBtYXkgZ2V0IG1vcmUgcmVzcG9uc2l2ZSB3aXRoIGxvd2VyIHZhbHVlcyB0aG91Z2guLi4gKi8KI2RlZmluZSBEU19FTVVMRFJJVkVSIDEgLyogc29tZSBnYW1lcyAoUXVha2UgMiwgVVQpIHJlZnVzZSB0byBhY2NlcHQKCQkJCWVtdWxhdGVkIGRzb3VuZCBkZXZpY2VzLiBzZXQgdG8gMCAhICovIAojZGVmaW5lIERTX0hFTF9GUkFHUyA0OCAvKiBIRUwgb25seTogbnVtYmVyIG9mIHdhdmVPdXQgZnJhZ21lbnRzIGluIHByaW1hcnkgYnVmZmVyCgkJCSAqIChjaGFuZ2luZyB0aGlzIHdvbid0IGhlbHAgeW91KSAqLwojZGVmaW5lIERTX0hFTF9NQVJHSU4gNSAvKiBIRUwgb25seTogbnVtYmVyIG9mIHdhdmVPdXQgZnJhZ21lbnRzIGFoZWFkIHRvIG1peCBpbiBuZXcgYnVmZmVycwoJCQkgKiAoa2VlcCB0aGlzIGNsb3NlIG9yIGVxdWFsIHRvIERTX0hFTF9RVUVVRSBmb3IgYmVzdCByZXN1bHRzKSAqLwojZGVmaW5lIERTX0hFTF9RVUVVRSAgNSAvKiBIRUwgb25seTogbnVtYmVyIG9mIHdhdmVPdXQgZnJhZ21lbnRzIGFoZWFkIHRvIHF1ZXVlIHRvIGRyaXZlcgoJCQkgKiAodGhpcyB3aWxsIGFmZmVjdCBIRUwgc291bmQgcmVsaWFiaWxpdHkgYW5kIGxhdGVuY3kpICovCgojZGVmaW5lIERTX1NORF9RVUVVRV9NQVggMjggLyogbWF4IG51bWJlciBvZiBmcmFnbWVudHMgdG8gcHJlYnVmZmVyICovCiNkZWZpbmUgRFNfU05EX1FVRVVFX01JTiAxMiAvKiBtaW4gbnVtYmVyIG9mIGZyYWdtZW50cyB0byBwcmVidWZmZXIgKi8KCi8qIExpbnV4IGRvZXMgbm90IHN1cHBvcnQgYmV0dGVyIHRpbWluZyB0aGFuIDEwbXMgKi8KI2RlZmluZSBEU19USU1FX1JFUyAxMCAgLyogUmVzb2x1dGlvbiBvZiBtdWx0aW1lZGlhIHRpbWVyICovCiNkZWZpbmUgRFNfVElNRV9ERUwgMTAgIC8qIERlbGF5IG9mIG11bHRpbWVkaWEgdGltZXIgY2FsbGJhY2ssIGFuZCBkdXJhdGlvbiBvZiBIRUwgZnJhZ21lbnQgKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBQcmVkZWNsYXJlIHRoZSBpbnRlcmZhY2UgaW1wbGVtZW50YXRpb24gc3RydWN0dXJlcwogKi8KdHlwZWRlZiBzdHJ1Y3QgSURpcmVjdFNvdW5kSW1wbCBJRGlyZWN0U291bmRJbXBsOwp0eXBlZGVmIHN0cnVjdCBJRGlyZWN0U291bmRCdWZmZXJJbXBsIElEaXJlY3RTb3VuZEJ1ZmZlckltcGw7CnR5cGVkZWYgc3RydWN0IElEaXJlY3RTb3VuZE5vdGlmeUltcGwgSURpcmVjdFNvdW5kTm90aWZ5SW1wbDsKdHlwZWRlZiBzdHJ1Y3QgSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGwgSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGw7CnR5cGVkZWYgc3RydWN0IElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbCBJRGlyZWN0U291bmQzREJ1ZmZlckltcGw7CnR5cGVkZWYgc3RydWN0IElEaXJlY3RTb3VuZENhcHR1cmVJbXBsIElEaXJlY3RTb3VuZENhcHR1cmVJbXBsOwp0eXBlZGVmIHN0cnVjdCBJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbCBJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbDsKdHlwZWRlZiBzdHJ1Y3QgSUtzUHJvcGVydHlTZXRJbXBsIElLc1Byb3BlcnR5U2V0SW1wbDsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0U291bmQgaW1wbGVtZW50YXRpb24gc3RydWN0dXJlCiAqLwpzdHJ1Y3QgSURpcmVjdFNvdW5kSW1wbAp7CiAgICAvKiBJVW5rbm93biBmaWVsZHMgKi8KICAgIElDT01fVkZJRUxEKElEaXJlY3RTb3VuZCk7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgICByZWY7CiAgICAvKiBJRGlyZWN0U291bmRJbXBsIGZpZWxkcyAqLwogICAgUElEU0RSSVZFUiAgICAgICAgICAgICAgICAgIGRyaXZlcjsKICAgIERTRFJJVkVSREVTQyAgICAgICAgICAgICAgICBkcnZkZXNjOwogICAgRFNEUklWRVJDQVBTICAgICAgICAgICAgICAgIGRydmNhcHM7CiAgICBIV0FWRU9VVCAgICAgICAgICAgICAgICAgICAgaHdvOwogICAgTFBXQVZFSERSICAgICAgICAgICAgICAgICAgIHB3YXZlW0RTX0hFTF9GUkFHU107CiAgICBVSU5UICAgICAgICAgICAgICAgICAgICAgICAgdGltZXJJRCwgcHdwbGF5LCBwd3dyaXRlLCBwd3F1ZXVlLCBwcmVidWY7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgICAgZnJhZ2xlbjsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgICAgICBwcmlvbGV2ZWw7CiAgICBpbnQgICAgICAgICAgICAgICAgICAgICAgICAgbnJvZmJ1ZmZlcnM7CiAgICBJRGlyZWN0U291bmRCdWZmZXJJbXBsKiogICAgYnVmZmVyczsKICAgIElEaXJlY3RTb3VuZEJ1ZmZlckltcGwqICAgICBwcmltYXJ5OwogICAgSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGwqIGxpc3RlbmVyOwogICAgV0FWRUZPUk1BVEVYICAgICAgICAgICAgICAgIHdmeDsgLyogY3VycmVudCBtYWluIHdhdmVmb3JtYXQgKi8KICAgIENSSVRJQ0FMX1NFQ1RJT04JCWxvY2s7Cn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdFNvdW5kQnVmZmVyIGltcGxlbWVudGF0aW9uIHN0cnVjdHVyZQogKi8Kc3RydWN0IElEaXJlY3RTb3VuZEJ1ZmZlckltcGwKewogICAgLyogRklYTUU6IGRvY3VtZW50ICovCiAgICAvKiBJVW5rbm93biBmaWVsZHMgKi8KICAgIElDT01fVkZJRUxEKElEaXJlY3RTb3VuZEJ1ZmZlcik7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWY7CiAgICAvKiBJRGlyZWN0U291bmRCdWZmZXJJbXBsIGZpZWxkcyAqLwogICAgUElEU0RSSVZFUkJVRkZFUiAgICAgICAgICBod2J1ZjsKICAgIFdBVkVGT1JNQVRFWCAgICAgICAgICAgICAgd2Z4OwogICAgTFBCWVRFICAgICAgICAgICAgICAgICAgICBidWZmZXI7CiAgICBJRGlyZWN0U291bmQzREJ1ZmZlckltcGwqIGRzM2RiOwogICAgRFdPUkQgICAgICAgICAgICAgICAgICAgICBwbGF5ZmxhZ3Msc3RhdGUsbGVhZGluOwogICAgRFdPUkQgICAgICAgICAgICAgICAgICAgICBwbGF5cG9zLHN0YXJ0cG9zLHdyaXRlbGVhZCxidWZsZW47CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgIG5BdmdCeXRlc1BlclNlYzsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgICAgZnJlcTsKICAgIERTVk9MVU1FUEFOICAgICAgICAgICAgICAgdm9scGFuOwogICAgSURpcmVjdFNvdW5kQnVmZmVySW1wbCogICBwYXJlbnQ7ICAgICAgICAgLyogZm9yIGR1cGxpY2F0ZXMgKi8KICAgIElEaXJlY3RTb3VuZEltcGwqICAgICAgICAgZHNvdW5kOwogICAgRFNCVUZGRVJERVNDICAgICAgICAgICAgICBkc2JkOwogICAgTFBEU0JQT1NJVElPTk5PVElGWSAgICAgICBub3RpZmllczsKICAgIGludCAgICAgICAgICAgICAgICAgICAgICAgbnJvZm5vdGlmaWVzOwogICAgQ1JJVElDQUxfU0VDVElPTiAgICAgICAgICBsb2NrOwogICAgLyogdXNlZCBmb3IgZnJlcXVlbmN5IGNvbnZlcnNpb24gKFBlcmZlY3RQaXRjaCkgKi8KICAgIFVMT05HICAgICAgICAgICAgICAgICAgICAgZnJlcUFkanVzdCwgZnJlcUFjYzsKICAgIC8qIHVzZWQgZm9yIGludGVsbGlnZW50ICh3ZWxsLCBzb3J0IG9mKSBwcmVidWZmZXJpbmcgKi8KICAgIERXT1JEICAgICAgICAgICAgICAgICAgICAgcHJvYmFibHlfdmFsaWRfdG87CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgIHByaW1hcnlfbWl4cG9zLCBidWZfbWl4cG9zOwogICAgQk9PTCAgICAgICAgICAgICAgICAgICAgICBuZWVkX3JlbWl4Owp9OwoKI2RlZmluZSBTVEFURV9TVE9QUEVEICAwCiNkZWZpbmUgU1RBVEVfU1RBUlRJTkcgMQojZGVmaW5lIFNUQVRFX1BMQVlJTkcgIDIKI2RlZmluZSBTVEFURV9TVE9QUElORyAzCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdFNvdW5kTm90aWZ5IGltcGxlbWVudGF0aW9uIHN0cnVjdHVyZQogKi8Kc3RydWN0IElEaXJlY3RTb3VuZE5vdGlmeUltcGwKewogICAgLyogSVVua25vd24gZmllbGRzICovCiAgICBJQ09NX1ZGSUVMRChJRGlyZWN0U291bmROb3RpZnkpOwogICAgRFdPUkQgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmOwogICAgLyogSURpcmVjdFNvdW5kTm90aWZ5SW1wbCBmaWVsZHMgKi8KICAgIElEaXJlY3RTb3VuZEJ1ZmZlckltcGwqIGRzYjsKfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgSURpcmVjdFNvdW5kM0RMaXN0ZW5lciBpbXBsZW1lbnRhdGlvbiBzdHJ1Y3R1cmUKICovCnN0cnVjdCBJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbAp7CiAgICAvKiBJVW5rbm93biBmaWVsZHMgKi8KICAgIElDT01fVkZJRUxEKElEaXJlY3RTb3VuZDNETGlzdGVuZXIpOwogICAgRFdPUkQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZjsKICAgIC8qIElEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsIGZpZWxkcyAqLwogICAgSURpcmVjdFNvdW5kQnVmZmVySW1wbCogZHNiOwogICAgRFMzRExJU1RFTkVSICAgICAgICAgICAgZHMzZGw7CiAgICBDUklUSUNBTF9TRUNUSU9OICAgICAgICBsb2NrOyAgIAp9OwoKc3RydWN0IElLc1Byb3BlcnR5U2V0SW1wbCAKewogICAgLyogSVVua25vd24gZmllbGRzICovCiAgICBJQ09NX1ZGSUVMRChJS3NQcm9wZXJ0eVNldCk7CiAgICBEV09SRAkJCXJlZjsKICAgIC8qIElLc1Byb3BlcnR5U2V0SW1wbCBmaWVsZHMgKi8KICAgIElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbAkqZHMzZGI7CS8qIGJhY2twdHIsIG5vIHJlZiAqLwp9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3RTb3VuZDNEQnVmZmVyIGltcGxlbWVudGF0aW9uIHN0cnVjdHVyZQogKi8Kc3RydWN0IElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbAp7CiAgICAvKiBJVW5rbm93biBmaWVsZHMgKi8KICAgIElDT01fVkZJRUxEKElEaXJlY3RTb3VuZDNEQnVmZmVyKTsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmOwogICAgLyogSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsIGZpZWxkcyAqLwogICAgSURpcmVjdFNvdW5kQnVmZmVySW1wbCogZHNiOwogICAgRFMzREJVRkZFUiAgICAgICAgICAgICAgZHMzZGI7CiAgICBMUEJZVEUgICAgICAgICAgICAgICAgICBidWZmZXI7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICBidWZsZW47CiAgICBDUklUSUNBTF9TRUNUSU9OICAgICAgICBsb2NrOwogICAgSUtzUHJvcGVydHlTZXRJbXBsKiAgICAgaWtzOwp9OwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0U291bmRDYXB0dXJlIGltcGxlbWVudGF0aW9uIHN0cnVjdHVyZQogKi8Kc3RydWN0IElEaXJlY3RTb3VuZENhcHR1cmVJbXBsCnsKICAgIC8qIElVbmtub3duIGZpZWxkcyAqLwogICAgSUNPTV9WRklFTEQoSURpcmVjdFNvdW5kQ2FwdHVyZSk7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZjsKCiAgICAvKiBJRGlyZWN0U291bmRDYXB0dXJlSW1wbCBmaWVsZHMgKi8KICAgIENSSVRJQ0FMX1NFQ1RJT04gICAgICAgIGxvY2s7Cn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdFNvdW5kQ2FwdHVyZSBpbXBsZW1lbnRhdGlvbiBzdHJ1Y3R1cmUKICovCnN0cnVjdCBJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbAp7CiAgICAvKiBJVW5rbm93biBmaWVsZHMgKi8KICAgIElDT01fVkZJRUxEKElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXIpOwogICAgRFdPUkQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWY7CgogICAgLyogSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGwgZmllbGRzICovCiAgICBDUklUSUNBTF9TRUNUSU9OICAgICAgICBsb2NrOwp9OwoKCi8qICNkZWZpbmUgVVNFX0RTT1VORDNEIDEgKi8KCiNkZWZpbmUgRFNPVU5EX0ZSRVFTSElGVCAoMTQpCgpzdGF0aWMgSURpcmVjdFNvdW5kSW1wbCoJZHNvdW5kID0gTlVMTDsKCnN0YXRpYyBJRGlyZWN0U291bmRCdWZmZXJJbXBsKglwcmltYXJ5YnVmID0gTlVMTDsKCnN0YXRpYyB2b2lkIERTT1VORF9DaGVja0V2ZW50KElEaXJlY3RTb3VuZEJ1ZmZlckltcGwgKmRzYiwgaW50IGxlbik7CnN0YXRpYyB2b2lkIERTT1VORF9NaXhDYW5jZWxBdChJRGlyZWN0U291bmRCdWZmZXJJbXBsICpkc2IsIERXT1JEIGJ1Zl93cml0ZXBvcyk7CgpzdGF0aWMgdm9pZCBEU09VTkRfV2F2ZVF1ZXVlKElEaXJlY3RTb3VuZEltcGwgKmRzb3VuZCwgRFdPUkQgbWl4cSk7CnN0YXRpYyB2b2lkIERTT1VORF9QZXJmb3JtTWl4KHZvaWQpOwpzdGF0aWMgdm9pZCBDQUxMQkFDSyBEU09VTkRfY2FsbGJhY2soSFdBVkVPVVQgaHdvLCBVSU5UIG1zZywgRFdPUkQgZHdVc2VyLCBEV09SRCBkdzEsIERXT1JEIGR3Mik7CgpzdGF0aWMgSFJFU1VMVCBEU09VTkRfQ3JlYXRlRGlyZWN0U291bmRDYXB0dXJlKCBMUFZPSUQqIHBwb2JqICk7CnN0YXRpYyBIUkVTVUxUIERTT1VORF9DcmVhdGVEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXIoIExQQ0RTQ0JVRkZFUkRFU0MgbHBjRFNDQnVmZmVyRGVzYywgTFBWT0lEKiBwcG9iaiApOwoKc3RhdGljIElDT01fVlRBQkxFKElEaXJlY3RTb3VuZENhcHR1cmUpIGRzY3Z0OwpzdGF0aWMgSUNPTV9WVEFCTEUoSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlcikgZHNjYnZ0OwoKc3RhdGljIEhSRVNVTFQgbW1FcnIoVUlOVCBlcnIpCnsKCXN3aXRjaChlcnIpIHsKCWNhc2UgTU1TWVNFUlJfTk9FUlJPUjoKCQlyZXR1cm4gRFNfT0s7CgljYXNlIE1NU1lTRVJSX0FMTE9DQVRFRDoKCQlyZXR1cm4gRFNFUlJfQUxMT0NBVEVEOwoJY2FzZSBNTVNZU0VSUl9JTlZBTEhBTkRMRToKCQlyZXR1cm4gRFNFUlJfR0VORVJJQzsgLyogRklYTUUgKi8KCWNhc2UgTU1TWVNFUlJfTk9EUklWRVI6CgkJcmV0dXJuIERTRVJSX05PRFJJVkVSOwoJY2FzZSBNTVNZU0VSUl9OT01FTToKCQlyZXR1cm4gRFNFUlJfT1VUT0ZNRU1PUlk7CgljYXNlIE1NU1lTRVJSX0lOVkFMUEFSQU06CgkJcmV0dXJuIERTRVJSX0lOVkFMSURQQVJBTTsKCWRlZmF1bHQ6CgkJRklYTUUoIlVua25vd24gTU1TWVMgZXJyb3IgJWRcbiIsZXJyKTsKCQlyZXR1cm4gRFNFUlJfR0VORVJJQzsKCX0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEaXJlY3RTb3VuZEVudW1lcmF0ZUEgW0RTT1VORC4yXSAgCiAqCiAqIEVudW1lcmF0ZSBhbGwgRGlyZWN0U291bmQgZHJpdmVycyBpbnN0YWxsZWQgaW4gdGhlIHN5c3RlbQogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IERTX09LCiAqICAgIEZhaWx1cmU6IERTRVJSX0lOVkFMSURQQVJBTQogKi8KSFJFU1VMVCBXSU5BUEkgRGlyZWN0U291bmRFbnVtZXJhdGVBKAoJTFBEU0VOVU1DQUxMQkFDS0EgbHBEU0VudW1DYWxsYmFjaywKCUxQVk9JRCBscENvbnRleHQpCnsKCVRSQUNFKCJscERTRW51bUNhbGxiYWNrID0gJXAsIGxwQ29udGV4dCA9ICVwXG4iLCAKCQlscERTRW51bUNhbGxiYWNrLCBscENvbnRleHQpOwoKI2lmZGVmIEhBVkVfT1NTCglpZiAobHBEU0VudW1DYWxsYmFjayAhPSBOVUxMKQoJCWxwRFNFbnVtQ2FsbGJhY2soTlVMTCwiV0lORSBEaXJlY3RTb3VuZCIsCgkJICAgICJzb3VuZCIsbHBDb250ZXh0KTsKI2VuZGlmCgoJcmV0dXJuIERTX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERpcmVjdFNvdW5kRW51bWVyYXRlVyBbRFNPVU5ELjNdICAKICoKICogRW51bWVyYXRlIGFsbCBEaXJlY3RTb3VuZCBkcml2ZXJzIGluc3RhbGxlZCBpbiB0aGUgc3lzdGVtCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRFNfT0sKICogICAgRmFpbHVyZTogRFNFUlJfSU5WQUxJRFBBUkFNCiAqLwpIUkVTVUxUIFdJTkFQSSBEaXJlY3RTb3VuZEVudW1lcmF0ZVcoCglMUERTRU5VTUNBTExCQUNLVyBscERTRW51bUNhbGxiYWNrLCAKCUxQVk9JRCBscENvbnRleHQgKQp7CiAgICAgICAgRklYTUUoImxwRFNFbnVtQ2FsbGJhY2sgPSAlcCwgbHBDb250ZXh0ID0gJXA6IHN0dWJcbiIsIAogICAgICAgICAgICAgICAgbHBEU0VudW1DYWxsYmFjaywgbHBDb250ZXh0KTsKCiAgICAgICAgcmV0dXJuIERTX09LOwp9CgoKc3RhdGljIHZvaWQgX2R1bXBfRFNCQ0FQUyhEV09SRCB4bWFzaykgewoJc3RydWN0IHsKCQlEV09SRAltYXNrOwoJCWNoYXIJKm5hbWU7Cgl9IGZsYWdzW10gPSB7CiNkZWZpbmUgRkUoeCkgeyB4LCAjeCB9LAoJCUZFKERTQkNBUFNfUFJJTUFSWUJVRkZFUikKCQlGRShEU0JDQVBTX1NUQVRJQykKCQlGRShEU0JDQVBTX0xPQ0hBUkRXQVJFKQoJCUZFKERTQkNBUFNfTE9DU09GVFdBUkUpCgkJRkUoRFNCQ0FQU19DVFJMM0QpCgkJRkUoRFNCQ0FQU19DVFJMRlJFUVVFTkNZKQoJCUZFKERTQkNBUFNfQ1RSTFBBTikKCQlGRShEU0JDQVBTX0NUUkxWT0xVTUUpCgkJRkUoRFNCQ0FQU19DVFJMUE9TSVRJT05OT1RJRlkpCgkJRkUoRFNCQ0FQU19DVFJMREVGQVVMVCkKCQlGRShEU0JDQVBTX0NUUkxBTEwpCgkJRkUoRFNCQ0FQU19TVElDS1lGT0NVUykKCQlGRShEU0JDQVBTX0dMT0JBTEZPQ1VTKQoJCUZFKERTQkNBUFNfR0VUQ1VSUkVOVFBPU0lUSU9OMikKCQlGRShEU0JDQVBTX01VVEUzREFUTUFYRElTVEFOQ0UpCiN1bmRlZiBGRQoJfTsKCWludAlpOwoKCWZvciAoaT0wO2k8c2l6ZW9mKGZsYWdzKS9zaXplb2YoZmxhZ3NbMF0pO2krKykKCQlpZiAoKGZsYWdzW2ldLm1hc2sgJiB4bWFzaykgPT0gZmxhZ3NbaV0ubWFzaykKCQkJRFBSSU5URigiJXMgIixmbGFnc1tpXS5uYW1lKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgIElLc1Byb3BlcnR5U2V0CiAqLwoKLyogSVVua25vd24gbWV0aG9kcyAqLwojaWZkZWYgVVNFX0RTT1VORDNECnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJS3NQcm9wZXJ0eVNldEltcGxfUXVlcnlJbnRlcmZhY2UoCglMUEtTUFJPUEVSVFlTRVQgaWZhY2UsIFJFRklJRCByaWlkLCBMUFZPSUQgKnBwb2JqCikgewoJSUNPTV9USElTKElLc1Byb3BlcnR5U2V0SW1wbCxpZmFjZSk7CgoJRklYTUUoIiglcCwlcywlcCksIHN0dWIhXG4iLFRoaXMsZGVidWdzdHJfZ3VpZChyaWlkKSxwcG9iaik7CglyZXR1cm4gRV9GQUlMOwp9CiNlbmRpZgoKI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgVUxPTkcgV0lOQVBJIElLc1Byb3BlcnR5U2V0SW1wbF9BZGRSZWYoTFBLU1BST1BFUlRZU0VUIGlmYWNlKSB7CglJQ09NX1RISVMoSUtzUHJvcGVydHlTZXRJbXBsLGlmYWNlKTsKCglUaGlzLT5yZWYrKzsKCXJldHVybiBUaGlzLT5yZWY7Cn0KI2VuZGlmCgojaWZkZWYgVVNFX0RTT1VORDNECnN0YXRpYyBVTE9ORyBXSU5BUEkgSUtzUHJvcGVydHlTZXRJbXBsX1JlbGVhc2UoTFBLU1BST1BFUlRZU0VUIGlmYWNlKSB7CglJQ09NX1RISVMoSUtzUHJvcGVydHlTZXRJbXBsLGlmYWNlKTsKCglUaGlzLT5yZWYtLTsKCXJldHVybiBUaGlzLT5yZWY7Cn0KI2VuZGlmCgojaWZkZWYgVVNFX0RTT1VORDNECnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJS3NQcm9wZXJ0eVNldEltcGxfR2V0KExQS1NQUk9QRVJUWVNFVCBpZmFjZSwKCVJFRkdVSUQgZ3VpZFByb3BTZXQsIFVMT05HIGR3UHJvcElELAoJTFBWT0lEIHBJbnN0YW5jZURhdGEsIFVMT05HIGNiSW5zdGFuY2VEYXRhLAoJTFBWT0lEIHBQcm9wRGF0YSwgVUxPTkcgY2JQcm9wRGF0YSwKCVBVTE9ORyBwY2JSZXR1cm5lZAopIHsKCUlDT01fVEhJUyhJS3NQcm9wZXJ0eVNldEltcGwsaWZhY2UpOwoKCUZJWE1FKCIoJXAsJXMsJWxkLCVwLCVsZCwlcCwlbGQsJXApLCBzdHViIVxuIixUaGlzLGRlYnVnc3RyX2d1aWQoZ3VpZFByb3BTZXQpLGR3UHJvcElELHBJbnN0YW5jZURhdGEsY2JJbnN0YW5jZURhdGEscFByb3BEYXRhLGNiUHJvcERhdGEscGNiUmV0dXJuZWQpOwoJcmV0dXJuIEVfUFJPUF9JRF9VTlNVUFBPUlRFRDsKfQojZW5kaWYKCiNpZmRlZiBVU0VfRFNPVU5EM0QKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElLc1Byb3BlcnR5U2V0SW1wbF9TZXQoTFBLU1BST1BFUlRZU0VUIGlmYWNlLAoJUkVGR1VJRCBndWlkUHJvcFNldCwgVUxPTkcgZHdQcm9wSUQsCglMUFZPSUQgcEluc3RhbmNlRGF0YSwgVUxPTkcgY2JJbnN0YW5jZURhdGEsCglMUFZPSUQgcFByb3BEYXRhLCBVTE9ORyBjYlByb3BEYXRhCikgewoJSUNPTV9USElTKElLc1Byb3BlcnR5U2V0SW1wbCxpZmFjZSk7CgoJRklYTUUoIiglcCwlcywlbGQsJXAsJWxkLCVwLCVsZCksIHN0dWIhXG4iLFRoaXMsZGVidWdzdHJfZ3VpZChndWlkUHJvcFNldCksZHdQcm9wSUQscEluc3RhbmNlRGF0YSxjYkluc3RhbmNlRGF0YSxwUHJvcERhdGEsY2JQcm9wRGF0YSk7CglyZXR1cm4gRV9QUk9QX0lEX1VOU1VQUE9SVEVEOwp9CiNlbmRpZgoKI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUtzUHJvcGVydHlTZXRJbXBsX1F1ZXJ5U3VwcG9ydChMUEtTUFJPUEVSVFlTRVQgaWZhY2UsCglSRUZHVUlEIGd1aWRQcm9wU2V0LCBVTE9ORyBkd1Byb3BJRCwgUFVMT05HIHBUeXBlU3VwcG9ydAopIHsKCUlDT01fVEhJUyhJS3NQcm9wZXJ0eVNldEltcGwsaWZhY2UpOwoKCUZJWE1FKCIoJXAsJXMsJWxkLCVwKSwgc3R1YiFcbiIsVGhpcyxkZWJ1Z3N0cl9ndWlkKGd1aWRQcm9wU2V0KSxkd1Byb3BJRCxwVHlwZVN1cHBvcnQpOwoJcmV0dXJuIEVfUFJPUF9JRF9VTlNVUFBPUlRFRDsKfQojZW5kaWYKCiNpZmRlZiBVU0VfRFNPVU5EM0QKc3RhdGljIElDT01fVlRBQkxFKElLc1Byb3BlcnR5U2V0KSBpa3N2dCA9IHsKCUlDT01fTVNWVEFCTEVfQ09NUEFUX0R1bW15UlRUSVZBTFVFCglJS3NQcm9wZXJ0eVNldEltcGxfUXVlcnlJbnRlcmZhY2UsCglJS3NQcm9wZXJ0eVNldEltcGxfQWRkUmVmLAoJSUtzUHJvcGVydHlTZXRJbXBsX1JlbGVhc2UsCglJS3NQcm9wZXJ0eVNldEltcGxfR2V0LAoJSUtzUHJvcGVydHlTZXRJbXBsX1NldCwKCUlLc1Byb3BlcnR5U2V0SW1wbF9RdWVyeVN1cHBvcnQKfTsKI2VuZGlmCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgSURpcmVjdFNvdW5kM0RCdWZmZXIKICovCgovKiBJVW5rbm93biBtZXRob2RzICovCiNpZmRlZiBVU0VfRFNPVU5EM0QKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9RdWVyeUludGVyZmFjZSgKCUxQRElSRUNUU09VTkQzREJVRkZFUiBpZmFjZSwgUkVGSUlEIHJpaWQsIExQVk9JRCAqcHBvYmopCnsKCUlDT01fVEhJUyhJRGlyZWN0U291bmQzREJ1ZmZlckltcGwsaWZhY2UpOwoKCWlmICggSXNFcXVhbEdVSUQoICZJSURfSUtzUHJvcGVydHlTZXQsIHJpaWQgKSApIHsKCSAgICBJRGlyZWN0U291bmQzREJ1ZmZlcl9BZGRSZWYoaWZhY2UpOwoJICAgICpwcG9iaiA9IFRoaXMtPmlrczsKCSAgICByZXR1cm4gU19PSzsKCX0KCglGSVhNRSgiKCVwLCVzLCVwKSwgbm8gc3VjaCBpbnRlcmZhY2UuXG4iLFRoaXMsZGVidWdzdHJfZ3VpZChyaWlkKSxwcG9iaik7CglyZXR1cm4gRV9GQUlMOwp9CiNlbmRpZgoKI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgVUxPTkcgV0lOQVBJIElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9BZGRSZWYoTFBESVJFQ1RTT1VORDNEQlVGRkVSIGlmYWNlKQp7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsLGlmYWNlKTsKCVRoaXMtPnJlZisrOwoJcmV0dXJuIFRoaXMtPnJlZjsKfQojZW5kaWYKCiNpZmRlZiBVU0VfRFNPVU5EM0QKc3RhdGljIFVMT05HIFdJTkFQSSBJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfUmVsZWFzZShMUERJUkVDVFNPVU5EM0RCVUZGRVIgaWZhY2UpCnsKCUlDT01fVEhJUyhJRGlyZWN0U291bmQzREJ1ZmZlckltcGwsaWZhY2UpOwoKCVRSQUNFKCIoJXApIHJlZiB3YXMgJWxkXG4iLCBUaGlzLCBUaGlzLT5yZWYpOwoKCWlmKC0tVGhpcy0+cmVmKQoJCXJldHVybiBUaGlzLT5yZWY7CgoJaWYgKFRoaXMtPmRzYikKCQlJRGlyZWN0U291bmRCdWZmZXJfUmVsZWFzZSgoTFBESVJFQ1RTT1VOREJVRkZFUilUaGlzLT5kc2IpOwoKCURlbGV0ZUNyaXRpY2FsU2VjdGlvbigmVGhpcy0+bG9jayk7CgoJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLFRoaXMtPmJ1ZmZlcik7CglIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsVGhpcyk7CgoJcmV0dXJuIDA7Cn0KI2VuZGlmCgovKiBJRGlyZWN0U291bmQzREJ1ZmZlciBtZXRob2RzICovCiNpZmRlZiBVU0VfRFNPVU5EM0QKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9HZXRBbGxQYXJhbWV0ZXJzKAoJTFBESVJFQ1RTT1VORDNEQlVGRkVSIGlmYWNlLAoJTFBEUzNEQlVGRkVSIGxwRHMzZEJ1ZmZlcikKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CiNlbmRpZgoKI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX0dldENvbmVBbmdsZXMoCglMUERJUkVDVFNPVU5EM0RCVUZGRVIgaWZhY2UsCglMUERXT1JEIGxwZHdJbnNpZGVDb25lQW5nbGUsCglMUERXT1JEIGxwZHdPdXRzaWRlQ29uZUFuZ2xlKQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KI2VuZGlmCgojaWZkZWYgVVNFX0RTT1VORDNECnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfR2V0Q29uZU9yaWVudGF0aW9uKAoJTFBESVJFQ1RTT1VORDNEQlVGRkVSIGlmYWNlLAoJTFBEM0RWRUNUT1IgbHB2Q29uZU9yaWVudGF0aW9uKQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KI2VuZGlmCgojaWZkZWYgVVNFX0RTT1VORDNECnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfR2V0Q29uZU91dHNpZGVWb2x1bWUoCglMUERJUkVDVFNPVU5EM0RCVUZGRVIgaWZhY2UsCglMUExPTkcgbHBsQ29uZU91dHNpZGVWb2x1bWUpCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQojZW5kaWYKCiNpZmRlZiBVU0VfRFNPVU5EM0QKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9HZXRNYXhEaXN0YW5jZSgKCUxQRElSRUNUU09VTkQzREJVRkZFUiBpZmFjZSwKCUxQRDNEVkFMVUUgbHBmTWF4RGlzdGFuY2UpCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQojZW5kaWYKCiNpZmRlZiBVU0VfRFNPVU5EM0QKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9HZXRNaW5EaXN0YW5jZSgKCUxQRElSRUNUU09VTkQzREJVRkZFUiBpZmFjZSwKCUxQRDNEVkFMVUUgbHBmTWluRGlzdGFuY2UpCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQojZW5kaWYKCiNpZmRlZiBVU0VfRFNPVU5EM0QKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9HZXRNb2RlKAoJTFBESVJFQ1RTT1VORDNEQlVGRkVSIGlmYWNlLAoJTFBEV09SRCBscGR3TW9kZSkKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CiNlbmRpZgoKI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX0dldFBvc2l0aW9uKAoJTFBESVJFQ1RTT1VORDNEQlVGRkVSIGlmYWNlLAoJTFBEM0RWRUNUT1IgbHB2UG9zaXRpb24pCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQojZW5kaWYKCiNpZmRlZiBVU0VfRFNPVU5EM0QKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9HZXRWZWxvY2l0eSgKCUxQRElSRUNUU09VTkQzREJVRkZFUiBpZmFjZSwKCUxQRDNEVkVDVE9SIGxwdlZlbG9jaXR5KQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KI2VuZGlmCgojaWZkZWYgVVNFX0RTT1VORDNECnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfU2V0QWxsUGFyYW1ldGVycygKCUxQRElSRUNUU09VTkQzREJVRkZFUiBpZmFjZSwKCUxQQ0RTM0RCVUZGRVIgbHBjRHMzZEJ1ZmZlciwKCURXT1JEIGR3QXBwbHkpCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQojZW5kaWYKCiNpZmRlZiBVU0VfRFNPVU5EM0QKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9TZXRDb25lQW5nbGVzKAoJTFBESVJFQ1RTT1VORDNEQlVGRkVSIGlmYWNlLAoJRFdPUkQgZHdJbnNpZGVDb25lQW5nbGUsCglEV09SRCBkd091dHNpZGVDb25lQW5nbGUsCglEV09SRCBkd0FwcGx5KQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KI2VuZGlmCgojaWZkZWYgVVNFX0RTT1VORDNECnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfU2V0Q29uZU9yaWVudGF0aW9uKAoJTFBESVJFQ1RTT1VORDNEQlVGRkVSIGlmYWNlLAoJRDNEVkFMVUUgeCwgRDNEVkFMVUUgeSwgRDNEVkFMVUUgeiwKCURXT1JEIGR3QXBwbHkpCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQojZW5kaWYKCiNpZmRlZiBVU0VfRFNPVU5EM0QKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9TZXRDb25lT3V0c2lkZVZvbHVtZSgKCUxQRElSRUNUU09VTkQzREJVRkZFUiBpZmFjZSwKCUxPTkcgbENvbmVPdXRzaWRlVm9sdW1lLAoJRFdPUkQgZHdBcHBseSkKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CiNlbmRpZgoKI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX1NldE1heERpc3RhbmNlKAoJTFBESVJFQ1RTT1VORDNEQlVGRkVSIGlmYWNlLAoJRDNEVkFMVUUgZk1heERpc3RhbmNlLAoJRFdPUkQgZHdBcHBseSkKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CiNlbmRpZgoKI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX1NldE1pbkRpc3RhbmNlKAoJTFBESVJFQ1RTT1VORDNEQlVGRkVSIGlmYWNlLAoJRDNEVkFMVUUgZk1pbkRpc3RhbmNlLAoJRFdPUkQgZHdBcHBseSkKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CiNlbmRpZgoKI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX1NldE1vZGUoCglMUERJUkVDVFNPVU5EM0RCVUZGRVIgaWZhY2UsCglEV09SRCBkd01vZGUsCglEV09SRCBkd0FwcGx5KQp7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsLGlmYWNlKTsKCVRSQUNFKCJtb2RlID0gJWx4XG4iLCBkd01vZGUpOwoJVGhpcy0+ZHMzZGIuZHdNb2RlID0gZHdNb2RlOwoJcmV0dXJuIERTX09LOwp9CiNlbmRpZgoKI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX1NldFBvc2l0aW9uKAoJTFBESVJFQ1RTT1VORDNEQlVGRkVSIGlmYWNlLAoJRDNEVkFMVUUgeCwgRDNEVkFMVUUgeSwgRDNEVkFMVUUgeiwKCURXT1JEIGR3QXBwbHkpCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQojZW5kaWYKCiNpZmRlZiBVU0VfRFNPVU5EM0QKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9TZXRWZWxvY2l0eSgKCUxQRElSRUNUU09VTkQzREJVRkZFUiBpZmFjZSwKCUQzRFZBTFVFIHgsIEQzRFZBTFVFIHksIEQzRFZBTFVFIHosCglEV09SRCBkd0FwcGx5KQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KI2VuZGlmCgojaWZkZWYgVVNFX0RTT1VORDNECnN0YXRpYyBJQ09NX1ZUQUJMRShJRGlyZWN0U291bmQzREJ1ZmZlcikgZHMzZGJ2dCA9IAp7CglJQ09NX01TVlRBQkxFX0NPTVBBVF9EdW1teVJUVElWQUxVRQoJLyogSVVua25vd24gbWV0aG9kcyAqLwoJSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX1F1ZXJ5SW50ZXJmYWNlLAoJSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX0FkZFJlZiwKCUlEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9SZWxlYXNlLAoJLyogSURpcmVjdFNvdW5kM0RCdWZmZXIgbWV0aG9kcyAqLwoJSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX0dldEFsbFBhcmFtZXRlcnMsCglJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfR2V0Q29uZUFuZ2xlcywKCUlEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9HZXRDb25lT3JpZW50YXRpb24sCglJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfR2V0Q29uZU91dHNpZGVWb2x1bWUsCglJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfR2V0TWF4RGlzdGFuY2UsCglJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfR2V0TWluRGlzdGFuY2UsCglJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfR2V0TW9kZSwKCUlEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9HZXRQb3NpdGlvbiwKCUlEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9HZXRWZWxvY2l0eSwKCUlEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9TZXRBbGxQYXJhbWV0ZXJzLAoJSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX1NldENvbmVBbmdsZXMsCglJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfU2V0Q29uZU9yaWVudGF0aW9uLAoJSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX1NldENvbmVPdXRzaWRlVm9sdW1lLAoJSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX1NldE1heERpc3RhbmNlLAoJSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX1NldE1pbkRpc3RhbmNlLAoJSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX1NldE1vZGUsCglJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfU2V0UG9zaXRpb24sCglJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfU2V0VmVsb2NpdHksCn07CiNlbmRpZgoKI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgaW50IERTT1VORF9DcmVhdGUzREJ1ZmZlcihJRGlyZWN0U291bmRCdWZmZXJJbXBsKiBkc2IpCnsKCURXT1JECWksIHRlbXAsIGlTaXplLCBvU2l6ZSwgb2Zmc2V0OwoJTFBCWVRFCWJJYnVmLCBiT2J1ZiwgYlRidWYgPSBOVUxMOwoJTFBXT1JECXdJYnVmLCB3T2J1Ziwgd1RidWYgPSBOVUxMOwoKCS8qIEluc2lkZSBEaXJlY3RYIHNheXMgaXQncyBzdHVwaWQgYnV0IGFsbG93ZWQgKi8KCWlmIChkc2ItPndmeC5uQ2hhbm5lbHMgPT0gMikgewoJCS8qIENvbnZlcnQgdG8gbW9ubyAqLwoJCWlmIChkc2ItPndmeC53Qml0c1BlclNhbXBsZSA9PSAxNikgewoJCQlpU2l6ZSA9IGRzYi0+YnVmbGVuIC8gNDsKCQkJd1RidWYgPSBtYWxsb2MoZHNiLT5idWZsZW4gLyAyKTsKCQkJaWYgKHdUYnVmID09IE5VTEwpCgkJCQlyZXR1cm4gRFNFUlJfT1VUT0ZNRU1PUlk7CgkJCWZvciAoaSA9IDA7IGkgPCBpU2l6ZTsgaSsrKQoJCQkJd1RidWZbaV0gPSAoZHNiLT5idWZmZXJbaSAqIDJdICsgZHNiLT5idWZmZXJbKGkgKiAyKSArIDFdKSAvIDI7CgkJCXdJYnVmID0gd1RidWY7CgkJfSBlbHNlIHsKCQkJaVNpemUgPSBkc2ItPmJ1ZmxlbiAvIDI7CgkJCWJUYnVmID0gbWFsbG9jKGRzYi0+YnVmbGVuIC8gMik7CgkJCWlmIChiVGJ1ZiA9PSBOVUxMKQoJCQkJcmV0dXJuIERTRVJSX09VVE9GTUVNT1JZOwoJCQlmb3IgKGkgPSAwOyBpIDwgaVNpemU7IGkrKykKCQkJCWJUYnVmW2ldID0gKGRzYi0+YnVmZmVyW2kgKiAyXSArIGRzYi0+YnVmZmVyWyhpICogMikgKyAxXSkgLyAyOwoJCQliSWJ1ZiA9IGJUYnVmOwoJCX0KCX0gZWxzZSB7CgkJaWYgKGRzYi0+d2Z4LndCaXRzUGVyU2FtcGxlID09IDE2KSB7CgkJCWlTaXplID0gZHNiLT5idWZsZW4gLyAyOwoJCQl3SWJ1ZiA9IChMUFdPUkQpIGRzYi0+YnVmZmVyOwoJCX0gZWxzZSB7CgkJCWJJYnVmID0gKExQQllURSkgZHNiLT5idWZmZXI7CgkJCWlTaXplID0gZHNiLT5idWZsZW47CgkJfQoJfQoKCWlmIChwcmltYXJ5YnVmLT53Zngud0JpdHNQZXJTYW1wbGUgPT0gMTYpIHsKCQl3T2J1ZiA9IChMUFdPUkQpIGRzYi0+ZHMzZGItPmJ1ZmZlcjsKCQlvU2l6ZSA9IGRzYi0+ZHMzZGItPmJ1ZmxlbiAvIDI7Cgl9IGVsc2UgewoJCWJPYnVmID0gKExQQllURSkgZHNiLT5kczNkYi0+YnVmZmVyOwoJCW9TaXplID0gZHNiLT5kczNkYi0+YnVmbGVuOwoJfQoKCW9mZnNldCA9IHByaW1hcnlidWYtPndmeC5uU2FtcGxlc1BlclNlYyAvIDEwMDsJCS8qIDEwbXMgKi8KCWlmIChwcmltYXJ5YnVmLT53Zngud0JpdHNQZXJTYW1wbGUgPT0gMTYgJiYgZHNiLT53Zngud0JpdHNQZXJTYW1wbGUgPT0gMTYpCgkJZm9yIChpID0gMDsgaSA8IGlTaXplOyBpKyspIHsKCQkJdGVtcCA9IHdJYnVmW2ldOwoJCQlpZiAoaSA+PSBvZmZzZXQpCgkJCQl0ZW1wICs9IHdJYnVmW2kgLSBvZmZzZXRdID4+IDk7CgkJCWVsc2UKCQkJCXRlbXAgKz0gd0lidWZbaSArIGlTaXplIC0gb2Zmc2V0XSA+PiA5OwoJCQl3T2J1ZltpICogMl0gPSB0ZW1wOwoJCQl3T2J1ZlsoaSAqIDIpICsgMV0gPSB0ZW1wOwoJCX0KCWVsc2UgaWYgKHByaW1hcnlidWYtPndmeC53Qml0c1BlclNhbXBsZSA9PSA4ICYmIGRzYi0+d2Z4LndCaXRzUGVyU2FtcGxlID09IDgpCgkJZm9yIChpID0gMDsgaSA8IGlTaXplOyBpKyspIHsKCQkJdGVtcCA9IGJJYnVmW2ldOwoJCQlpZiAoaSA+PSBvZmZzZXQpCgkJCQl0ZW1wICs9IGJJYnVmW2kgLSBvZmZzZXRdID4+IDU7CgkJCWVsc2UKCQkJCXRlbXAgKz0gYklidWZbaSArIGlTaXplIC0gb2Zmc2V0XSA+PiA1OwoJCQliT2J1ZltpICogMl0gPSB0ZW1wOwoJCQliT2J1ZlsoaSAqIDIpICsgMV0gPSB0ZW1wOwoJCX0KCQoJaWYgKHdUYnVmKQoJCWZyZWUod1RidWYpOwoJaWYgKGJUYnVmKQoJCWZyZWUoYlRidWYpOwoKCXJldHVybiBEU19PSzsKfQojZW5kaWYKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgIElEaXJlY3RTb3VuZDNETGlzdGVuZXIKICovCgovKiBJVW5rbm93biBtZXRob2RzICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9RdWVyeUludGVyZmFjZSgKCUxQRElSRUNUU09VTkQzRExJU1RFTkVSIGlmYWNlLCBSRUZJSUQgcmlpZCwgTFBWT0lEICpwcG9iaikKewoJSUNPTV9USElTKElEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsLGlmYWNlKTsKCglUUkFDRSgiKCVwLCVzLCVwKVxuIixUaGlzLGRlYnVnc3RyX2d1aWQocmlpZCkscHBvYmopOwoJcmV0dXJuIEVfRkFJTDsKfQoJCnN0YXRpYyBVTE9ORyBXSU5BUEkgSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfQWRkUmVmKExQRElSRUNUU09VTkQzRExJU1RFTkVSIGlmYWNlKQp7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGwsaWZhY2UpOwoJVGhpcy0+cmVmKys7CglyZXR1cm4gVGhpcy0+cmVmOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIElEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX1JlbGVhc2UoTFBESVJFQ1RTT1VORDNETElTVEVORVIgaWZhY2UpCnsKCVVMT05HIHVsUmV0dXJuOwoJSUNPTV9USElTKElEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsLGlmYWNlKTsKCglUUkFDRSgiKCVwKSByZWYgd2FzICVsZFxuIiwgVGhpcywgVGhpcy0+cmVmKTsKCgl1bFJldHVybiA9IC0tVGhpcy0+cmVmOwoKCS8qIEZyZWUgYWxsIHJlc291cmNlcyAqLwoJaWYoIHVsUmV0dXJuID09IDAgKSB7CgkJaWYoVGhpcy0+ZHNiKQoJCQlJRGlyZWN0U291bmRCdWZmZXJfUmVsZWFzZSgoTFBESVJFQ1RTT1VOREJVRkZFUilUaGlzLT5kc2IpOwoJCURlbGV0ZUNyaXRpY2FsU2VjdGlvbigmVGhpcy0+bG9jayk7CgkJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLFRoaXMpOwoJfQoKCXJldHVybiB1bFJldHVybjsKfQoKLyogSURpcmVjdFNvdW5kM0RMaXN0ZW5lciBtZXRob2RzICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9HZXRBbGxQYXJhbWV0ZXIoCglMUERJUkVDVFNPVU5EM0RMSVNURU5FUiBpZmFjZSwKCUxQRFMzRExJU1RFTkVSIGxwRFMzREwpCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX0dldERpc3RhbmNlRmFjdG9yKAoJTFBESVJFQ1RTT1VORDNETElTVEVORVIgaWZhY2UsCglMUEQzRFZBTFVFIGxwZkRpc3RhbmNlRmFjdG9yKQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9HZXREb3BwbGVyRmFjdG9yKAoJTFBESVJFQ1RTT1VORDNETElTVEVORVIgaWZhY2UsCglMUEQzRFZBTFVFIGxwZkRvcHBsZXJGYWN0b3IpCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX0dldE9yaWVudGF0aW9uKAoJTFBESVJFQ1RTT1VORDNETElTVEVORVIgaWZhY2UsCglMUEQzRFZFQ1RPUiBscHZPcmllbnRGcm9udCwKCUxQRDNEVkVDVE9SIGxwdk9yaWVudFRvcCkKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfR2V0UG9zaXRpb24oCglMUERJUkVDVFNPVU5EM0RMSVNURU5FUiBpZmFjZSwKCUxQRDNEVkVDVE9SIGxwdlBvc2l0aW9uKQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9HZXRSb2xsb2ZmRmFjdG9yKAoJTFBESVJFQ1RTT1VORDNETElTVEVORVIgaWZhY2UsCglMUEQzRFZBTFVFIGxwZlJvbGxvZmZGYWN0b3IpCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX0dldFZlbG9jaXR5KAoJTFBESVJFQ1RTT1VORDNETElTVEVORVIgaWZhY2UsCglMUEQzRFZFQ1RPUiBscHZWZWxvY2l0eSkKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfU2V0QWxsUGFyYW1ldGVycygKCUxQRElSRUNUU09VTkQzRExJU1RFTkVSIGlmYWNlLAoJTFBDRFMzRExJU1RFTkVSIGxwY0RTM0RMLAoJRFdPUkQgZHdBcHBseSkKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfU2V0RGlzdGFuY2VGYWN0b3IoCglMUERJUkVDVFNPVU5EM0RMSVNURU5FUiBpZmFjZSwKCUQzRFZBTFVFIGZEaXN0YW5jZUZhY3RvciwKCURXT1JEIGR3QXBwbHkpCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX1NldERvcHBsZXJGYWN0b3IoCglMUERJUkVDVFNPVU5EM0RMSVNURU5FUiBpZmFjZSwKCUQzRFZBTFVFIGZEb3BwbGVyRmFjdG9yLAoJRFdPUkQgZHdBcHBseSkKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfU2V0T3JpZW50YXRpb24oCglMUERJUkVDVFNPVU5EM0RMSVNURU5FUiBpZmFjZSwKCUQzRFZBTFVFIHhGcm9udCwgRDNEVkFMVUUgeUZyb250LCBEM0RWQUxVRSB6RnJvbnQsCglEM0RWQUxVRSB4VG9wLCBEM0RWQUxVRSB5VG9wLCBEM0RWQUxVRSB6VG9wLAoJRFdPUkQgZHdBcHBseSkKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfU2V0UG9zaXRpb24oCglMUERJUkVDVFNPVU5EM0RMSVNURU5FUiBpZmFjZSwKCUQzRFZBTFVFIHgsIEQzRFZBTFVFIHksIEQzRFZBTFVFIHosCglEV09SRCBkd0FwcGx5KQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9TZXRSb2xsb2ZmRmFjdG9yKAoJTFBESVJFQ1RTT1VORDNETElTVEVORVIgaWZhY2UsCglEM0RWQUxVRSBmUm9sbG9mZkZhY3RvciwKCURXT1JEIGR3QXBwbHkpCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX1NldFZlbG9jaXR5KAoJTFBESVJFQ1RTT1VORDNETElTVEVORVIgaWZhY2UsCglEM0RWQUxVRSB4LCBEM0RWQUxVRSB5LCBEM0RWQUxVRSB6LAoJRFdPUkQgZHdBcHBseSkKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfQ29tbWl0RGVmZXJyZWRTZXR0aW5ncygKCUxQRElSRUNUU09VTkQzRExJU1RFTkVSIGlmYWNlKQoKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSUNPTV9WVEFCTEUoSURpcmVjdFNvdW5kM0RMaXN0ZW5lcikgZHMzZGx2dCA9IAp7CglJQ09NX01TVlRBQkxFX0NPTVBBVF9EdW1teVJUVElWQUxVRQoJLyogSVVua25vd24gbWV0aG9kcyAqLwoJSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfUXVlcnlJbnRlcmZhY2UsCglJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9BZGRSZWYsCglJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9SZWxlYXNlLAoJLyogSURpcmVjdFNvdW5kM0RMaXN0ZW5lciBtZXRob2RzICovCglJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9HZXRBbGxQYXJhbWV0ZXIsCglJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9HZXREaXN0YW5jZUZhY3RvciwKCUlEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX0dldERvcHBsZXJGYWN0b3IsCglJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9HZXRPcmllbnRhdGlvbiwKCUlEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX0dldFBvc2l0aW9uLAoJSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfR2V0Um9sbG9mZkZhY3RvciwKCUlEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX0dldFZlbG9jaXR5LAoJSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfU2V0QWxsUGFyYW1ldGVycywKCUlEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX1NldERpc3RhbmNlRmFjdG9yLAoJSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfU2V0RG9wcGxlckZhY3RvciwKCUlEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX1NldE9yaWVudGF0aW9uLAoJSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfU2V0UG9zaXRpb24sCglJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9TZXRSb2xsb2ZmRmFjdG9yLAoJSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfU2V0VmVsb2NpdHksCglJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9Db21taXREZWZlcnJlZFNldHRpbmdzLAp9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUlEaXJlY3RTb3VuZE5vdGlmeQogKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZE5vdGlmeUltcGxfUXVlcnlJbnRlcmZhY2UoCglMUERJUkVDVFNPVU5ETk9USUZZIGlmYWNlLFJFRklJRCByaWlkLExQVk9JRCAqcHBvYmoKKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kTm90aWZ5SW1wbCxpZmFjZSk7CgoJVFJBQ0UoIiglcCwlcywlcClcbiIsVGhpcyxkZWJ1Z3N0cl9ndWlkKHJpaWQpLHBwb2JqKTsKCXJldHVybiBFX0ZBSUw7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSURpcmVjdFNvdW5kTm90aWZ5SW1wbF9BZGRSZWYoTFBESVJFQ1RTT1VORE5PVElGWSBpZmFjZSkgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZE5vdGlmeUltcGwsaWZhY2UpOwoJcmV0dXJuICsrKFRoaXMtPnJlZik7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSURpcmVjdFNvdW5kTm90aWZ5SW1wbF9SZWxlYXNlKExQRElSRUNUU09VTkROT1RJRlkgaWZhY2UpIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmROb3RpZnlJbXBsLGlmYWNlKTsKCglUUkFDRSgiKCVwKSByZWYgd2FzICVsZFxuIiwgVGhpcywgVGhpcy0+cmVmKTsKCglUaGlzLT5yZWYtLTsKCWlmICghVGhpcy0+cmVmKSB7CgkJSURpcmVjdFNvdW5kQnVmZmVyX1JlbGVhc2UoKExQRElSRUNUU09VTkRCVUZGRVIpVGhpcy0+ZHNiKTsKCQlIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsVGhpcyk7CgkJcmV0dXJuIDA7Cgl9CglyZXR1cm4gVGhpcy0+cmVmOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kTm90aWZ5SW1wbF9TZXROb3RpZmljYXRpb25Qb3NpdGlvbnMoCglMUERJUkVDVFNPVU5ETk9USUZZIGlmYWNlLERXT1JEIGhvd211Y2gsTFBDRFNCUE9TSVRJT05OT1RJRlkgbm90aWZ5CikgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZE5vdGlmeUltcGwsaWZhY2UpOwoJaW50CWk7CgoJaWYgKFRSQUNFX09OKGRzb3VuZCkpIHsKCSAgICBUUkFDRSgiKCVwLDB4JTA4bHgsJXApXG4iLFRoaXMsaG93bXVjaCxub3RpZnkpOwoJICAgIGZvciAoaT0wO2k8aG93bXVjaDtpKyspCgkJICAgIFRSQUNFKCJub3RpZnkgYXQgJWxkIHRvIDB4JTA4bHhcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3RpZnlbaV0uZHdPZmZzZXQsKERXT1JEKW5vdGlmeVtpXS5oRXZlbnROb3RpZnkpOwoJfQoJVGhpcy0+ZHNiLT5ub3RpZmllcyA9IEhlYXBSZUFsbG9jKEdldFByb2Nlc3NIZWFwKCksSEVBUF9aRVJPX01FTU9SWSxUaGlzLT5kc2ItPm5vdGlmaWVzLChUaGlzLT5kc2ItPm5yb2Zub3RpZmllcytob3dtdWNoKSpzaXplb2YoRFNCUE9TSVRJT05OT1RJRlkpKTsKCW1lbWNweSgJVGhpcy0+ZHNiLT5ub3RpZmllcytUaGlzLT5kc2ItPm5yb2Zub3RpZmllcywKCQlub3RpZnksCgkJaG93bXVjaCpzaXplb2YoRFNCUE9TSVRJT05OT1RJRlkpCgkpOwoJVGhpcy0+ZHNiLT5ucm9mbm90aWZpZXMrPWhvd211Y2g7CgoJcmV0dXJuIFNfT0s7Cn0KCnN0YXRpYyBJQ09NX1ZUQUJMRShJRGlyZWN0U291bmROb3RpZnkpIGRzbnZ0ID0gCnsKCUlDT01fTVNWVEFCTEVfQ09NUEFUX0R1bW15UlRUSVZBTFVFCglJRGlyZWN0U291bmROb3RpZnlJbXBsX1F1ZXJ5SW50ZXJmYWNlLAoJSURpcmVjdFNvdW5kTm90aWZ5SW1wbF9BZGRSZWYsCglJRGlyZWN0U291bmROb3RpZnlJbXBsX1JlbGVhc2UsCglJRGlyZWN0U291bmROb3RpZnlJbXBsX1NldE5vdGlmaWNhdGlvblBvc2l0aW9ucywKfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlJRGlyZWN0U291bmRCdWZmZXIKICovCgpzdGF0aWMgdm9pZCBEU09VTkRfUmVjYWxjVm9sUGFuKFBEU1ZPTFVNRVBBTiB2b2xwYW4pCnsKCWRvdWJsZSB0ZW1wOwoKCS8qIHRoZSBBbXBGYWN0b3JzIGFyZSBleHByZXNzZWQgaW4gMTYuMTYgZml4ZWQgcG9pbnQgKi8KCXZvbHBhbi0+ZHdWb2xBbXBGYWN0b3IgPSAoVUxPTkcpIChwb3coMi4wLCB2b2xwYW4tPmxWb2x1bWUgLyA2MDAuMCkgKiA2NTUzNik7CgkvKiBGSVhNRTogZHdQYW57TGVmdHxSaWdodH1BbXBGYWN0b3IgKi8KCgkvKiBGSVhNRTogdXNlIGNhbGN1bGF0ZWQgdm9sIGFuZCBwYW4gYW1wZmFjdG9ycyAqLwoJdGVtcCA9IChkb3VibGUpICh2b2xwYW4tPmxWb2x1bWUgLSAodm9scGFuLT5sUGFuID4gMCA/IHZvbHBhbi0+bFBhbiA6IDApKTsKCXZvbHBhbi0+ZHdUb3RhbExlZnRBbXBGYWN0b3IgPSAoVUxPTkcpIChwb3coMi4wLCB0ZW1wIC8gNjAwLjApICogNjU1MzYpOwoJdGVtcCA9IChkb3VibGUpICh2b2xwYW4tPmxWb2x1bWUgKyAodm9scGFuLT5sUGFuIDwgMCA/IHZvbHBhbi0+bFBhbiA6IDApKTsKCXZvbHBhbi0+ZHdUb3RhbFJpZ2h0QW1wRmFjdG9yID0gKFVMT05HKSAocG93KDIuMCwgdGVtcCAvIDYwMC4wKSAqIDY1NTM2KTsKCglUUkFDRSgibGVmdCA9ICVseCwgcmlnaHQgPSAlbHhcbiIsIHZvbHBhbi0+ZHdUb3RhbExlZnRBbXBGYWN0b3IsIHZvbHBhbi0+ZHdUb3RhbFJpZ2h0QW1wRmFjdG9yKTsKfQoKc3RhdGljIHZvaWQgRFNPVU5EX1JlY2FsY0Zvcm1hdChJRGlyZWN0U291bmRCdWZmZXJJbXBsICpkc2IpCnsKCURXT1JEIHN3OwoKCXN3ID0gZHNiLT53ZngubkNoYW5uZWxzICogKGRzYi0+d2Z4LndCaXRzUGVyU2FtcGxlIC8gOCk7CglpZiAoKGRzYi0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19QUklNQVJZQlVGRkVSKSAmJiBkc2ItPmh3YnVmKSB7CgkJRFdPUkQgZnJhZ2xlbjsKCQkvKiBsZXQgZnJhZ21lbnQgc2l6ZSBhcHByb3hpbWF0ZSB0aGUgdGltZXIgZGVsYXkgKi8KCQlmcmFnbGVuID0gKGRzYi0+ZnJlcSAqIERTX1RJTUVfREVMIC8gMTAwMCkgKiBzdzsKCQkvKiByZWR1Y2UgZnJhZ21lbnQgc2l6ZSB1bnRpbCBhbiBpbnRlZ2VyIG51bWJlciBvZiB0aGVtIGZpdHMgaW4gdGhlIGJ1ZmZlciAqLwoJCS8qIChGSVhNRTogdGhpcyBtYXkgb3IgbWF5IG5vdCBiZSBhIGdvb2QgaWRlYSkgKi8KCQl3aGlsZSAoZHNiLT5idWZsZW4gJSBmcmFnbGVuKSBmcmFnbGVuIC09IHN3OwoJCWRzYi0+ZHNvdW5kLT5mcmFnbGVuID0gZnJhZ2xlbjsKCQlUUkFDRSgiZnJhZ2xlbj0lbGRcbiIsIGRzYi0+ZHNvdW5kLT5mcmFnbGVuKTsKCX0KCS8qIGNhbGN1bGF0ZSB0aGUgMTBtcyB3cml0ZSBsZWFkICovCglkc2ItPndyaXRlbGVhZCA9IChkc2ItPmZyZXEgLyAxMDApICogc3c7Cn0KCnN0YXRpYyBIUkVTVUxUIERTT1VORF9QcmltYXJ5T3BlbihJRGlyZWN0U291bmRCdWZmZXJJbXBsICpkc2IpCnsKCUhSRVNVTFQgZXJyID0gRFNfT0s7CgoJLyogYXJlIHdlIHVzaW5nIHdhdmVPdXQgc3R1ZmY/ICovCglpZiAoIWRzYi0+aHdidWYpIHsKCQlMUEJZVEUgbmV3YnVmOwoJCURXT1JEIGJ1ZmxlbjsKCQlIUkVTVUxUIG1lcnIgPSBEU19PSzsKCQkvKiBTdGFydCBpbiBwYXVzZSBtb2RlLCB0byBhbGxvdyBidWZmZXJzIHRvIGdldCBmaWxsZWQgKi8KCQl3YXZlT3V0UGF1c2UoZHNiLT5kc291bmQtPmh3byk7CgkJaWYgKGRzYi0+c3RhdGUgPT0gU1RBVEVfUExBWUlORykgZHNiLT5zdGF0ZSA9IFNUQVRFX1NUQVJUSU5HOwoJCWVsc2UgaWYgKGRzYi0+c3RhdGUgPT0gU1RBVEVfU1RPUFBJTkcpIGRzYi0+c3RhdGUgPSBTVEFURV9TVE9QUEVEOwoJCS8qIHVzZSBmcmFnbWVudHMgb2YgMTBtcyAoMS8xMDBzKSBlYWNoICh3aGljaCBzaG91bGQgZ2V0IHVzIHdpdGhpbgoJCSAqIHRoZSBkb2N1bWVudGVkIHdyaXRlIGN1cnNvciBsZWFkIG9mIDEwLTE1bXMpICovCgkJYnVmbGVuID0gKChkc2ItPndmeC5uQXZnQnl0ZXNQZXJTZWMgLyAxMDApICYgfjMpICogRFNfSEVMX0ZSQUdTOwoJCVRSQUNFKCJkZXNpcmVkIGJ1Zmxlbj0lbGQsIG9sZCBidWZmZXI9JXBcbiIsIGJ1ZmxlbiwgZHNiLT5idWZmZXIpOwoJCS8qIHJlYWxsb2NhdGUgZW11bGF0ZWQgcHJpbWFyeSBidWZmZXIgKi8KCQluZXdidWYgPSAoTFBCWVRFKUhlYXBSZUFsbG9jKEdldFByb2Nlc3NIZWFwKCksMCxkc2ItPmJ1ZmZlcixidWZsZW4pOwoJCWlmIChuZXdidWYgPT0gTlVMTCkgewoJCQlFUlIoImZhaWxlZCB0byBhbGxvY2F0ZSBwcmltYXJ5IGJ1ZmZlclxuIik7CgkJCW1lcnIgPSBEU0VSUl9PVVRPRk1FTU9SWTsKCQkJLyogYnV0IHRoZSBvbGQgYnVmZmVyIG1pZ2h0IHN0aWxsIGV4aXN0cyBhbmQgbXVzdCBiZSByZS1wcmVwYXJlZCAqLwoJCX0gZWxzZSB7CgkJCWRzYi0+YnVmZmVyID0gbmV3YnVmOwoJCQlkc2ItPmJ1ZmxlbiA9IGJ1ZmxlbjsKCQl9CgkJaWYgKGRzYi0+YnVmZmVyKSB7CgkJCXVuc2lnbmVkIGM7CgkJCUlEaXJlY3RTb3VuZEltcGwgKmRzID0gZHNiLT5kc291bmQ7CgoJCQlkcy0+ZnJhZ2xlbiA9IGRzYi0+YnVmbGVuIC8gRFNfSEVMX0ZSQUdTOwoKCQkJLyogcHJlcGFyZSBmcmFnbWVudCBoZWFkZXJzICovCgkJCWZvciAoYz0wOyBjPERTX0hFTF9GUkFHUzsgYysrKSB7CgkJCQlkcy0+cHdhdmVbY10tPmxwRGF0YSA9IGRzYi0+YnVmZmVyICsgYypkcy0+ZnJhZ2xlbjsKCQkJCWRzLT5wd2F2ZVtjXS0+ZHdCdWZmZXJMZW5ndGggPSBkcy0+ZnJhZ2xlbjsKCQkJCWRzLT5wd2F2ZVtjXS0+ZHdVc2VyID0gKERXT1JEKWRzYjsKCQkJCWRzLT5wd2F2ZVtjXS0+ZHdGbGFncyA9IDA7CgkJCQlkcy0+cHdhdmVbY10tPmR3TG9vcHMgPSAwOwoJCQkJZXJyID0gbW1FcnIod2F2ZU91dFByZXBhcmVIZWFkZXIoZHMtPmh3byxkcy0+cHdhdmVbY10sc2l6ZW9mKFdBVkVIRFIpKSk7CgkJCQlpZiAoZXJyICE9IERTX09LKSB7CgkJCQkJd2hpbGUgKGMtLSkKCQkJCQkJd2F2ZU91dFVucHJlcGFyZUhlYWRlcihkcy0+aHdvLGRzLT5wd2F2ZVtjXSxzaXplb2YoV0FWRUhEUikpOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQl9CgoJCQlkcy0+cHdwbGF5ID0gMDsKCQkJZHMtPnB3d3JpdGUgPSAwOwoJCQlkcy0+cHdxdWV1ZSA9IDA7CgkJCW1lbXNldChkc2ItPmJ1ZmZlciwgKGRzYi0+d2Z4LndCaXRzUGVyU2FtcGxlID09IDE2KSA/IDAgOiAxMjgsIGRzYi0+YnVmbGVuKTsKCQkJVFJBQ0UoImZyYWdsZW49JWxkXG4iLCBkcy0+ZnJhZ2xlbik7CgkJCURTT1VORF9XYXZlUXVldWUoZHNiLT5kc291bmQsIChEV09SRCktMSk7CgkJfQoJCWlmICgoZXJyID09IERTX09LKSAmJiAobWVyciAhPSBEU19PSykpCgkJCWVyciA9IG1lcnI7Cgl9CglyZXR1cm4gZXJyOwp9CgoKc3RhdGljIHZvaWQgRFNPVU5EX1ByaW1hcnlDbG9zZShJRGlyZWN0U291bmRCdWZmZXJJbXBsICpkc2IpCnsKCS8qIGFyZSB3ZSB1c2luZyB3YXZlT3V0IHN0dWZmPyAqLwoJaWYgKCFkc2ItPmh3YnVmKSB7CgkJdW5zaWduZWQgYzsKCQlJRGlyZWN0U291bmRJbXBsICpkcyA9IGRzYi0+ZHNvdW5kOwoKCQlkcy0+cHdxdWV1ZSA9IChEV09SRCktMTsgLyogcmVzZXR0aW5nIHF1ZXVlcyAqLwoJCXdhdmVPdXRSZXNldChkcy0+aHdvKTsKCQlmb3IgKGM9MDsgYzxEU19IRUxfRlJBR1M7IGMrKykKCQkJd2F2ZU91dFVucHJlcGFyZUhlYWRlcihkcy0+aHdvLCBkcy0+cHdhdmVbY10sIHNpemVvZihXQVZFSERSKSk7CgkJZHMtPnB3cXVldWUgPSAwOwoJfQp9CgpzdGF0aWMgSFJFU1VMVCBEU09VTkRfUHJpbWFyeVBsYXkoSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiKQp7CglIUkVTVUxUIGVyciA9IERTX09LOwoJaWYgKGRzYi0+aHdidWYpCgkJZXJyID0gSURzRHJpdmVyQnVmZmVyX1BsYXkoZHNiLT5od2J1ZiwgMCwgMCwgRFNCUExBWV9MT09QSU5HKTsKCWVsc2UKCQllcnIgPSBtbUVycih3YXZlT3V0UmVzdGFydChkc2ItPmRzb3VuZC0+aHdvKSk7CglyZXR1cm4gZXJyOwp9CgpzdGF0aWMgSFJFU1VMVCBEU09VTkRfUHJpbWFyeVN0b3AoSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiKQp7CglIUkVTVUxUIGVyciA9IERTX09LOwoKCVRSQUNFKCJcbiIpOwoKCWlmIChkc2ItPmh3YnVmKSB7CgkJZXJyID0gSURzRHJpdmVyQnVmZmVyX1N0b3AoZHNiLT5od2J1Zik7CgkJaWYgKGVyciA9PSBEU0VSUl9CVUZGRVJMT1NUKSB7CgkJCS8qIFdpbmUtb25seTogdGhlIGRyaXZlciB3YW50cyB1cyB0byByZW9wZW4gdGhlIGRldmljZSAqLwoJCQkvKiBGSVhNRTogY2hlY2sgZm9yIGVycm9ycyAqLwoJCQlJRHNEcml2ZXJCdWZmZXJfUmVsZWFzZShwcmltYXJ5YnVmLT5od2J1Zik7CgkJCXdhdmVPdXRDbG9zZShkc2ItPmRzb3VuZC0+aHdvKTsKCQkJZHNiLT5kc291bmQtPmh3byA9IDA7CgkJCWVyciA9IG1tRXJyKHdhdmVPdXRPcGVuKCYoZHNiLT5kc291bmQtPmh3byksIGRzYi0+ZHNvdW5kLT5kcnZkZXNjLmRuRGV2Tm9kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJihwcmltYXJ5YnVmLT53ZngpLCAoRFdPUkQpRFNPVU5EX2NhbGxiYWNrLCAoRFdPUkQpZHNiLT5kc291bmQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENBTExCQUNLX0ZVTkNUSU9OIHwgV0FWRV9ESVJFQ1RTT1VORCkpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyID09IERTX09LKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyID0gSURzRHJpdmVyX0NyZWF0ZVNvdW5kQnVmZmVyKGRzYi0+ZHNvdW5kLT5kcml2ZXIsJihkc2ItPndmeCksZHNiLT5kc2JkLmR3RmxhZ3MsMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmKGRzYi0+YnVmbGVuKSwmKGRzYi0+YnVmZmVyKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBWT0lEKSYoZHNiLT5od2J1ZikpOwoJCX0KCX0KCWVsc2UKCQllcnIgPSBtbUVycih3YXZlT3V0UGF1c2UoZHNiLT5kc291bmQtPmh3bykpOwoJcmV0dXJuIGVycjsKfQoKLyogVGhpcyBzZXRzIHRoaXMgZm9ybWF0IGZvciB0aGUgPGVtPlByaW1hcnkgQnVmZmVyIE9ubHk8L2VtPiAqLwovKiBTZWUgZmlsZTovLy9jZHJvbS9zZGs1Mi9kb2NzL3dvcmRkb2MvZHNvdW5kLmRvYyBwYWdlIDEyMCAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kQnVmZmVySW1wbF9TZXRGb3JtYXQoCglMUERJUkVDVFNPVU5EQlVGRkVSIGlmYWNlLExQV0FWRUZPUk1BVEVYIHdmZXgKKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQnVmZmVySW1wbCxpZmFjZSk7CglJRGlyZWN0U291bmRCdWZmZXJJbXBsKiogZHNiOwoJSFJFU1VMVCBlcnIgPSBEU19PSzsKCWludAkJCWk7CgoJLyogTGV0J3MgYmUgcGVkYW50aWMhICovCglpZiAoKHdmZXggPT0gTlVMTCkgfHwKCSAgICAod2ZleC0+d0Zvcm1hdFRhZyAhPSBXQVZFX0ZPUk1BVF9QQ00pIHx8CgkgICAgKHdmZXgtPm5DaGFubmVscyA8IDEpIHx8ICh3ZmV4LT5uQ2hhbm5lbHMgPiAyKSB8fAoJICAgICh3ZmV4LT5uU2FtcGxlc1BlclNlYyA8IDEpIHx8CgkgICAgKHdmZXgtPm5CbG9ja0FsaWduIDwgMSkgfHwgKHdmZXgtPm5DaGFubmVscyA+IDQpIHx8CgkgICAgKCh3ZmV4LT53Qml0c1BlclNhbXBsZSAhPSA4KSAmJiAod2ZleC0+d0JpdHNQZXJTYW1wbGUgIT0gMTYpKSkgewoJCVRSQUNFKCJmYWlsZWQgcGVkYW50aWMgY2hlY2shXG4iKTsKCQlyZXR1cm4gRFNFUlJfSU5WQUxJRFBBUkFNOwoJfQoKCS8qICoqKiogKi8KCUVudGVyQ3JpdGljYWxTZWN0aW9uKCYoVGhpcy0+ZHNvdW5kLT5sb2NrKSk7CgoJaWYgKHByaW1hcnlidWYtPndmeC5uU2FtcGxlc1BlclNlYyAhPSB3ZmV4LT5uU2FtcGxlc1BlclNlYykgewoJCWRzYiA9IGRzb3VuZC0+YnVmZmVyczsKCQlmb3IgKGkgPSAwOyBpIDwgZHNvdW5kLT5ucm9mYnVmZmVyczsgaSsrLCBkc2IrKykgewoJCQkvKiAqKioqICovCgkJCUVudGVyQ3JpdGljYWxTZWN0aW9uKCYoKCpkc2IpLT5sb2NrKSk7CgoJCQkoKmRzYiktPmZyZXFBZGp1c3QgPSAoKCpkc2IpLT5mcmVxIDw8IERTT1VORF9GUkVRU0hJRlQpIC8KCQkJCXdmZXgtPm5TYW1wbGVzUGVyU2VjOwoKCQkJTGVhdmVDcml0aWNhbFNlY3Rpb24oJigoKmRzYiktPmxvY2spKTsKCQkJLyogKioqKiAqLwoJCX0KCX0KCgltZW1jcHkoJihwcmltYXJ5YnVmLT53ZngpLCB3ZmV4LCBzaXplb2YocHJpbWFyeWJ1Zi0+d2Z4KSk7CgoJVFJBQ0UoIihmb3JtYXR0YWc9MHglMDR4LGNoYW5zPSVkLHNhbXBsZXJhdGU9JWxkLCIKCQkgICAiYnl0ZXNwZXJzZWM9JWxkLGJsb2NrYWxpZ249JWQsYml0c3BlcnNhbXA9JWQsY2JTaXplPSVkKVxuIiwKCQkgICB3ZmV4LT53Rm9ybWF0VGFnLCB3ZmV4LT5uQ2hhbm5lbHMsIHdmZXgtPm5TYW1wbGVzUGVyU2VjLAoJCSAgIHdmZXgtPm5BdmdCeXRlc1BlclNlYywgd2ZleC0+bkJsb2NrQWxpZ24sIAoJCSAgIHdmZXgtPndCaXRzUGVyU2FtcGxlLCB3ZmV4LT5jYlNpemUpOwoKCXByaW1hcnlidWYtPndmeC5uQXZnQnl0ZXNQZXJTZWMgPQoJCVRoaXMtPndmeC5uU2FtcGxlc1BlclNlYyAqIFRoaXMtPndmeC5uQmxvY2tBbGlnbjsKCglpZiAocHJpbWFyeWJ1Zi0+ZHNvdW5kLT5kcnZkZXNjLmR3RmxhZ3MgJiBEU0RERVNDX0RPTU1TWVNURU1TRVRGT1JNQVQpIHsKCQkvKiBGSVhNRTogY2hlY2sgZm9yIGVycm9ycyAqLwoJCURTT1VORF9QcmltYXJ5Q2xvc2UocHJpbWFyeWJ1Zik7CgkJd2F2ZU91dENsb3NlKFRoaXMtPmRzb3VuZC0+aHdvKTsKCQlUaGlzLT5kc291bmQtPmh3byA9IDA7CiAgICAgICAgICAgICAgICBlcnIgPSBtbUVycih3YXZlT3V0T3BlbigmKFRoaXMtPmRzb3VuZC0+aHdvKSwgVGhpcy0+ZHNvdW5kLT5kcnZkZXNjLmRuRGV2Tm9kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYocHJpbWFyeWJ1Zi0+d2Z4KSwgKERXT1JEKURTT1VORF9jYWxsYmFjaywgKERXT1JEKVRoaXMtPmRzb3VuZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENBTExCQUNLX0ZVTkNUSU9OIHwgV0FWRV9ESVJFQ1RTT1VORCkpOwogICAgICAgICAgICAgICAgaWYgKGVyciA9PSBEU19PSykKICAgICAgICAgICAgICAgICAgICBEU09VTkRfUHJpbWFyeU9wZW4ocHJpbWFyeWJ1Zik7Cgl9CglpZiAocHJpbWFyeWJ1Zi0+aHdidWYpIHsKCQllcnIgPSBJRHNEcml2ZXJCdWZmZXJfU2V0Rm9ybWF0KHByaW1hcnlidWYtPmh3YnVmLCAmKHByaW1hcnlidWYtPndmeCkpOwoJCWlmIChlcnIgPT0gRFNFUlJfQlVGRkVSTE9TVCkgewoJCQkvKiBXaW5lLW9ubHk6IHRoZSBkcml2ZXIgd2FudHMgdXMgdG8gcmVjcmVhdGUgdGhlIEhXIGJ1ZmZlciAqLwoJCQlJRHNEcml2ZXJCdWZmZXJfUmVsZWFzZShwcmltYXJ5YnVmLT5od2J1Zik7CgkJCWVyciA9IElEc0RyaXZlcl9DcmVhdGVTb3VuZEJ1ZmZlcihwcmltYXJ5YnVmLT5kc291bmQtPmRyaXZlciwmKHByaW1hcnlidWYtPndmeCkscHJpbWFyeWJ1Zi0+ZHNiZC5kd0ZsYWdzLDAsCgkJCQkJCQkgICYocHJpbWFyeWJ1Zi0+YnVmbGVuKSwmKHByaW1hcnlidWYtPmJ1ZmZlciksCgkJCQkJCQkgIChMUFZPSUQpJihwcmltYXJ5YnVmLT5od2J1ZikpOwoJCQlpZiAocHJpbWFyeWJ1Zi0+c3RhdGUgPT0gU1RBVEVfUExBWUlORykgcHJpbWFyeWJ1Zi0+c3RhdGUgPSBTVEFURV9TVEFSVElORzsKCQkJZWxzZSBpZiAocHJpbWFyeWJ1Zi0+c3RhdGUgPT0gU1RBVEVfU1RPUFBJTkcpIHByaW1hcnlidWYtPnN0YXRlID0gU1RBVEVfU1RPUFBFRDsKCQl9CiAgICAgICAgICAgICAgICAvKiBGSVhNRTogc2hvdWxkIHdlIHNldCBlcnIgYmFjayB0byBEU19PSyBpbiBhbGwgY2FzZXMgPyAqLwoJfQoJRFNPVU5EX1JlY2FsY0Zvcm1hdChwcmltYXJ5YnVmKTsKCglMZWF2ZUNyaXRpY2FsU2VjdGlvbigmKFRoaXMtPmRzb3VuZC0+bG9jaykpOwoJLyogKioqKiAqLwoKCXJldHVybiBlcnI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmRCdWZmZXJJbXBsX1NldFZvbHVtZSgKCUxQRElSRUNUU09VTkRCVUZGRVIgaWZhY2UsTE9ORyB2b2wKKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQnVmZmVySW1wbCxpZmFjZSk7CgoJVFJBQ0UoIiglcCwlbGQpXG4iLFRoaXMsdm9sKTsKCgkvKiBJJ20gbm90IHN1cmUgaWYgd2UgbmVlZCB0aGlzIGZvciBwcmltYXJ5IGJ1ZmZlciAqLwoJaWYgKCEoVGhpcy0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19DVFJMVk9MVU1FKSkKCQlyZXR1cm4gRFNFUlJfQ09OVFJPTFVOQVZBSUw7CgoJaWYgKCh2b2wgPiBEU0JWT0xVTUVfTUFYKSB8fCAodm9sIDwgRFNCVk9MVU1FX01JTikpCgkJcmV0dXJuIERTRVJSX0lOVkFMSURQQVJBTTsKCgkvKiAqKioqICovCglFbnRlckNyaXRpY2FsU2VjdGlvbigmKFRoaXMtPmxvY2spKTsKCglUaGlzLT52b2xwYW4ubFZvbHVtZSA9IHZvbDsKCglEU09VTkRfUmVjYWxjVm9sUGFuKCYoVGhpcy0+dm9scGFuKSk7CgoJaWYgKFRoaXMtPmh3YnVmKSB7CgkJSURzRHJpdmVyQnVmZmVyX1NldFZvbHVtZVBhbihUaGlzLT5od2J1ZiwgJihUaGlzLT52b2xwYW4pKTsKCX0KCWVsc2UgaWYgKFRoaXMtPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfUFJJTUFSWUJVRkZFUikgewojaWYgMCAvKiBzaG91bGQgd2UgcmVhbGx5IGRvIHRoaXM/ICovCgkJLyogdGhlIERTIHZvbHVtZSByYW5nZXMgZnJvbSAwIChtYXgsIDBkQiBhdHRlbnVhdGlvbikgdG8gLTEwMDAwIChtaW4sIDEwMGRCIGF0dGVudWF0aW9uKSAqLwoJCS8qIHRoZSBNTSB2b2x1bWUgcmFuZ2VzIGZyb20gMCB0byAweGZmZmYgaW4gYW4gdW5zcGVjaWZpZWQgbG9nYXJpdGhtaWMgc2NhbGUgKi8KCQlXT1JEIGN2b2wgPSAweGZmZmYgKyB2b2wqNiArIHZvbC8yOwoJCURXT1JEIHZvbCA9IGN2b2wgfCAoKERXT1JEKWN2b2wgPDwgMTYpCgkJd2F2ZU91dFNldFZvbHVtZShUaGlzLT5kc291bmQtPmh3bywgdm9sKTsKI2VuZGlmCgl9CgoJTGVhdmVDcml0aWNhbFNlY3Rpb24oJihUaGlzLT5sb2NrKSk7CgkvKiAqKioqICovCgoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kQnVmZmVySW1wbF9HZXRWb2x1bWUoCglMUERJUkVDVFNPVU5EQlVGRkVSIGlmYWNlLExQTE9ORyB2b2wKKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQnVmZmVySW1wbCxpZmFjZSk7CglUUkFDRSgiKCVwLCVwKVxuIixUaGlzLHZvbCk7CgoJaWYgKHZvbCA9PSBOVUxMKQoJCXJldHVybiBEU0VSUl9JTlZBTElEUEFSQU07CgoJKnZvbCA9IFRoaXMtPnZvbHBhbi5sVm9sdW1lOwoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kQnVmZmVySW1wbF9TZXRGcmVxdWVuY3koCglMUERJUkVDVFNPVU5EQlVGRkVSIGlmYWNlLERXT1JEIGZyZXEKKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQnVmZmVySW1wbCxpZmFjZSk7CglUUkFDRSgiKCVwLCVsZClcbiIsVGhpcyxmcmVxKTsKCgkvKiBZb3UgY2Fubm90IHNldCB0aGUgZnJlcXVlbmN5IG9mIHRoZSBwcmltYXJ5IGJ1ZmZlciAqLwoJaWYgKCEoVGhpcy0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19DVFJMRlJFUVVFTkNZKSB8fAoJICAgIChUaGlzLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX1BSSU1BUllCVUZGRVIpKQoJCXJldHVybiBEU0VSUl9DT05UUk9MVU5BVkFJTDsKCglpZiAoIWZyZXEpIGZyZXEgPSBUaGlzLT53ZngublNhbXBsZXNQZXJTZWM7CgoJaWYgKChmcmVxIDwgRFNCRlJFUVVFTkNZX01JTikgfHwgKGZyZXEgPiBEU0JGUkVRVUVOQ1lfTUFYKSkKCQlyZXR1cm4gRFNFUlJfSU5WQUxJRFBBUkFNOwoKCS8qICoqKiogKi8KCUVudGVyQ3JpdGljYWxTZWN0aW9uKCYoVGhpcy0+bG9jaykpOwoKCVRoaXMtPmZyZXEgPSBmcmVxOwoJVGhpcy0+ZnJlcUFkanVzdCA9IChmcmVxIDw8IERTT1VORF9GUkVRU0hJRlQpIC8gcHJpbWFyeWJ1Zi0+d2Z4Lm5TYW1wbGVzUGVyU2VjOwoJVGhpcy0+bkF2Z0J5dGVzUGVyU2VjID0gZnJlcSAqIFRoaXMtPndmeC5uQmxvY2tBbGlnbjsKCURTT1VORF9SZWNhbGNGb3JtYXQoVGhpcyk7CgoJTGVhdmVDcml0aWNhbFNlY3Rpb24oJihUaGlzLT5sb2NrKSk7CgkvKiAqKioqICovCgoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kQnVmZmVySW1wbF9QbGF5KAoJTFBESVJFQ1RTT1VOREJVRkZFUiBpZmFjZSxEV09SRCByZXNlcnZlZDEsRFdPUkQgcmVzZXJ2ZWQyLERXT1JEIGZsYWdzCikgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwsaWZhY2UpOwoJVFJBQ0UoIiglcCwlMDhseCwlMDhseCwlMDhseClcbiIsCgkJVGhpcyxyZXNlcnZlZDEscmVzZXJ2ZWQyLGZsYWdzCgkpOwoKCS8qICoqKiogKi8KCUVudGVyQ3JpdGljYWxTZWN0aW9uKCYoVGhpcy0+bG9jaykpOwoKCVRoaXMtPnBsYXlmbGFncyA9IGZsYWdzOwoJaWYgKFRoaXMtPnN0YXRlID09IFNUQVRFX1NUT1BQRUQpIHsKCQlUaGlzLT5sZWFkaW4gPSBUUlVFOwoJCVRoaXMtPnN0YXJ0cG9zID0gVGhpcy0+YnVmX21peHBvczsKCQlUaGlzLT5zdGF0ZSA9IFNUQVRFX1NUQVJUSU5HOwoJfSBlbHNlIGlmIChUaGlzLT5zdGF0ZSA9PSBTVEFURV9TVE9QUElORykKCQlUaGlzLT5zdGF0ZSA9IFNUQVRFX1BMQVlJTkc7CglpZiAoIShUaGlzLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX1BSSU1BUllCVUZGRVIpICYmIFRoaXMtPmh3YnVmKSB7CgkJSURzRHJpdmVyQnVmZmVyX1BsYXkoVGhpcy0+aHdidWYsIDAsIDAsIFRoaXMtPnBsYXlmbGFncyk7CgkJVGhpcy0+c3RhdGUgPSBTVEFURV9QTEFZSU5HOwoJfQoKCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCYoVGhpcy0+bG9jaykpOwoJLyogKioqKiAqLwoKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZEJ1ZmZlckltcGxfU3RvcChMUERJUkVDVFNPVU5EQlVGRkVSIGlmYWNlKQp7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQnVmZmVySW1wbCxpZmFjZSk7CglUUkFDRSgiKCVwKVxuIixUaGlzKTsKCgkvKiAqKioqICovCglFbnRlckNyaXRpY2FsU2VjdGlvbigmKFRoaXMtPmxvY2spKTsKCglpZiAoVGhpcy0+c3RhdGUgPT0gU1RBVEVfUExBWUlORykKCQlUaGlzLT5zdGF0ZSA9IFNUQVRFX1NUT1BQSU5HOwoJZWxzZSBpZiAoVGhpcy0+c3RhdGUgPT0gU1RBVEVfU1RBUlRJTkcpCgkJVGhpcy0+c3RhdGUgPSBTVEFURV9TVE9QUEVEOwoJaWYgKCEoVGhpcy0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19QUklNQVJZQlVGRkVSKSAmJiBUaGlzLT5od2J1ZikgewoJCUlEc0RyaXZlckJ1ZmZlcl9TdG9wKFRoaXMtPmh3YnVmKTsKCQlUaGlzLT5zdGF0ZSA9IFNUQVRFX1NUT1BQRUQ7Cgl9CglEU09VTkRfQ2hlY2tFdmVudChUaGlzLCAwKTsKCglMZWF2ZUNyaXRpY2FsU2VjdGlvbigmKFRoaXMtPmxvY2spKTsKCS8qICoqKiogKi8KCglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBEV09SRCBXSU5BUEkgSURpcmVjdFNvdW5kQnVmZmVySW1wbF9BZGRSZWYoTFBESVJFQ1RTT1VOREJVRkZFUiBpZmFjZSkgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwsaWZhY2UpOwoJRFdPUkQgcmVmOwoKCVRSQUNFKCIoJXApIHJlZiB3YXMgJWxkLCB0aHJlYWQgaXMgJWx4XG4iLFRoaXMsIFRoaXMtPnJlZiwgR2V0Q3VycmVudFRocmVhZElkKCkpOwoKCXJlZiA9IEludGVybG9ja2VkSW5jcmVtZW50KCYoVGhpcy0+cmVmKSk7CglpZiAoIXJlZikgewoJCUZJWE1FKCJ0aHJlYWQtc2FmZXR5IGFsZXJ0ISBBZGRSZWYtaW5nIHdpdGggYSB6ZXJvIHJlZmNvdW50IVxuIik7Cgl9CglyZXR1cm4gcmVmOwp9CnN0YXRpYyBEV09SRCBXSU5BUEkgSURpcmVjdFNvdW5kQnVmZmVySW1wbF9SZWxlYXNlKExQRElSRUNUU09VTkRCVUZGRVIgaWZhY2UpIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRCdWZmZXJJbXBsLGlmYWNlKTsKCWludAlpOwoJRFdPUkQgcmVmOwoKCVRSQUNFKCIoJXApIHJlZiB3YXMgJWxkLCB0aHJlYWQgaXMgJWx4XG4iLFRoaXMsIFRoaXMtPnJlZiwgR2V0Q3VycmVudFRocmVhZElkKCkpOwoKCXJlZiA9IEludGVybG9ja2VkRGVjcmVtZW50KCYoVGhpcy0+cmVmKSk7CglpZiAocmVmKSByZXR1cm4gcmVmOwoKCUVudGVyQ3JpdGljYWxTZWN0aW9uKCYoVGhpcy0+ZHNvdW5kLT5sb2NrKSk7Cglmb3IgKGk9MDtpPFRoaXMtPmRzb3VuZC0+bnJvZmJ1ZmZlcnM7aSsrKQoJCWlmIChUaGlzLT5kc291bmQtPmJ1ZmZlcnNbaV0gPT0gVGhpcykKCQkJYnJlYWs7CgoJaWYgKGkgPCBUaGlzLT5kc291bmQtPm5yb2ZidWZmZXJzKSB7CgkJLyogUHV0IHRoZSBsYXN0IGJ1ZmZlciBvZiB0aGUgbGlzdCBpbiB0aGUgKG5vdyBlbXB0eSkgcG9zaXRpb24gKi8KCQlUaGlzLT5kc291bmQtPmJ1ZmZlcnNbaV0gPSBUaGlzLT5kc291bmQtPmJ1ZmZlcnNbVGhpcy0+ZHNvdW5kLT5ucm9mYnVmZmVycyAtIDFdOwoJCVRoaXMtPmRzb3VuZC0+bnJvZmJ1ZmZlcnMtLTsKCQlUaGlzLT5kc291bmQtPmJ1ZmZlcnMgPSBIZWFwUmVBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLDAsVGhpcy0+ZHNvdW5kLT5idWZmZXJzLHNpemVvZihMUERJUkVDVFNPVU5EQlVGRkVSKSpUaGlzLT5kc291bmQtPm5yb2ZidWZmZXJzKTsKCQlUUkFDRSgiYnVmZmVyIGNvdW50IGlzIG5vdyAlZFxuIiwgVGhpcy0+ZHNvdW5kLT5ucm9mYnVmZmVycyk7CgkJSURpcmVjdFNvdW5kX1JlbGVhc2UoKExQRElSRUNUU09VTkQpVGhpcy0+ZHNvdW5kKTsKCX0KCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCYoVGhpcy0+ZHNvdW5kLT5sb2NrKSk7CgoJRGVsZXRlQ3JpdGljYWxTZWN0aW9uKCYoVGhpcy0+bG9jaykpOwoJaWYgKFRoaXMtPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfUFJJTUFSWUJVRkZFUikKCQlEU09VTkRfUHJpbWFyeUNsb3NlKFRoaXMpOwoJaWYgKFRoaXMtPmh3YnVmKSB7CgkJSURzRHJpdmVyQnVmZmVyX1JlbGVhc2UoVGhpcy0+aHdidWYpOwoJfQoJaWYgKFRoaXMtPmRzM2RiKQoJCUlEaXJlY3RTb3VuZDNEQnVmZmVyX1JlbGVhc2UoKExQRElSRUNUU09VTkQzREJVRkZFUilUaGlzLT5kczNkYik7CglpZiAoVGhpcy0+cGFyZW50KQoJCS8qIHRoaXMgaXMgYSBkdXBsaWNhdGUgYnVmZmVyICovCgkJSURpcmVjdFNvdW5kQnVmZmVyX1JlbGVhc2UoKExQRElSRUNUU09VTkRCVUZGRVIpVGhpcy0+cGFyZW50KTsKCWVsc2UKCQkvKiB0aGlzIGlzIGEgdG9wbGV2ZWwgYnVmZmVyICovCgkJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLFRoaXMtPmJ1ZmZlcik7CgoJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLFRoaXMpOwoJCglpZiAoVGhpcyA9PSBwcmltYXJ5YnVmKQoJCXByaW1hcnlidWYgPSBOVUxMOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgRFdPUkQgRFNPVU5EX0NhbGNQbGF5UG9zaXRpb24oSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqVGhpcywKCQkJCSAgICAgRFdPUkQgc3RhdGUsIERXT1JEIHBwbGF5LCBEV09SRCBwd3JpdGUsIERXT1JEIHBtaXgsIERXT1JEIGJtaXgpCnsKCURXT1JEIGJwbGF5OwoKCVRSQUNFKCJwcmltYXJ5IHBsYXlwb3M9JWxkLCBtaXhwb3M9JWxkXG4iLCBwcGxheSwgcG1peCk7CglUUkFDRSgidGhpcyBtaXhwb3M9JWxkLCB0aW1lPSVsZFxuIiwgYm1peCwgR2V0VGlja0NvdW50KCkpOwoKCS8qIHRoZSBhY3R1YWwgcHJpbWFyeSBwbGF5IHBvc2l0aW9uIChwcGxheSkgaXMgYWx3YXlzIGJlaGluZCBsYXN0IG1peGVkIChwbWl4KSwKCSAqIHVubGVzcyB0aGUgY29tcHV0ZXIgaXMgdG9vIHNsb3cgb3Igc29tZXRoaW5nICovCgkvKiB3ZSBuZWVkIHRvIGtub3cgaG93IGZhciBhd2F5IHdlIGFyZSBmcm9tIHRoZXJlICovCiNpZiAwIC8qIHdlJ2xsIG5ldmVyIGZpbGwgdGhlIHByaW1hcnkgZW50aXJlbHkgKi8KCWlmIChwbWl4ID09IHBwbGF5KSB7CgkJaWYgKChzdGF0ZSA9PSBTVEFURV9QTEFZSU5HKSB8fCAoc3RhdGUgPT0gU1RBVEVfU1RPUFBJTkcpKSB7CgkJCS8qIHdvdywgdGhlIHNvZnR3YXJlIG1peGVyIGlzIHJlYWxseSBkb2luZyB3ZWxsLAoJCQkgKiBzZWVtcyB0aGUgZW50aXJlIHByaW1hcnkgYnVmZmVyIGlzIGZpbGxlZCEgKi8KCQkJcG1peCArPSBwcmltYXJ5YnVmLT5idWZsZW47CgkJfQoJCS8qIGVsc2U6IHRoZSBwcmltYXJ5IGJ1ZmZlciBpcyBub3QgcGxheWluZywgc28gcHJvYmFibHkgZW1wdHkgKi8KCX0KI2VuZGlmCglpZiAocG1peCA8IHBwbGF5KSBwbWl4ICs9IHByaW1hcnlidWYtPmJ1ZmxlbjsgLyogd3JhcGFyb3VuZCAqLwoJcG1peCAtPSBwcGxheTsKCS8qIGRldGVjdCBidWZmZXIgdW5kZXJydW4gKi8KCWlmIChwd3JpdGUgPCBwcGxheSkgcHdyaXRlICs9IHByaW1hcnlidWYtPmJ1ZmxlbjsgLyogd3JhcGFyb3VuZCAqLwoJcHdyaXRlIC09IHBwbGF5OwoJaWYgKHBtaXggPiAoRFNfU05EX1FVRVVFX01BWCAqIHByaW1hcnlidWYtPmRzb3VuZC0+ZnJhZ2xlbiArIHB3cml0ZSArIHByaW1hcnlidWYtPndyaXRlbGVhZCkpIHsKCQlXQVJOKCJkZXRlY3RlZCBhbiB1bmRlcnJ1bjogcHJpbWFyeSBxdWV1ZSB3YXMgJWxkXG4iLHBtaXgpOwoJCXBtaXggPSAwOwoJfQoJLyogZGl2aWRlIHRoZSBvZmZzZXQgYnkgaXRzIHNhbXBsZSBzaXplICovCglwbWl4IC89IHByaW1hcnlidWYtPndmeC5uQmxvY2tBbGlnbjsKCVRSQUNFKCJwcmltYXJ5IGJhY2stc2FtcGxlcz0lbGRcbiIscG1peCk7CgkvKiBhZGp1c3QgZm9yIG91ciBmcmVxdWVuY3kgKi8KCXBtaXggPSAocG1peCAqIFRoaXMtPmZyZXFBZGp1c3QpID4+IERTT1VORF9GUkVRU0hJRlQ7CgkvKiBtdWx0aXBseSBieSBvdXIgb3duIHNhbXBsZSBzaXplICovCglwbWl4ICo9IFRoaXMtPndmeC5uQmxvY2tBbGlnbjsKCVRSQUNFKCJ0aGlzIGJhY2stb2Zmc2V0PSVsZFxuIiwgcG1peCk7CgkvKiBzdWJ0cmFjdCBmcm9tIG91ciBsYXN0IG1peGVkIHBvc2l0aW9uICovCglicGxheSA9IGJtaXg7Cgl3aGlsZSAoYnBsYXkgPCBwbWl4KSBicGxheSArPSBUaGlzLT5idWZsZW47IC8qIHdyYXBhcm91bmQgKi8KCWJwbGF5IC09IHBtaXg7CglpZiAoVGhpcy0+bGVhZGluICYmICgoYnBsYXkgPCBUaGlzLT5zdGFydHBvcykgfHwgKGJwbGF5ID4gYm1peCkpKSB7CgkJLyogc2VlbXMgd2UgaGF2ZW4ndCBzdGFydGVkIHBsYXlpbmcgeWV0ICovCgkJVFJBQ0UoInRoaXMgc3RpbGwgaW4gbGVhZC1pbiBwaGFzZVxuIik7CgkJYnBsYXkgPSBUaGlzLT5zdGFydHBvczsKCX0KCS8qIHJldHVybiB0aGUgcmVzdWx0ICovCglyZXR1cm4gYnBsYXk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmRCdWZmZXJJbXBsX0dldEN1cnJlbnRQb3NpdGlvbigKCUxQRElSRUNUU09VTkRCVUZGRVIgaWZhY2UsTFBEV09SRCBwbGF5cG9zLExQRFdPUkQgd3JpdGVwb3MKKSB7CglIUkVTVUxUCWhyZXM7IAoJSUNPTV9USElTKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwsaWZhY2UpOwoJVFJBQ0UoIiglcCwlcCwlcClcbiIsVGhpcyxwbGF5cG9zLHdyaXRlcG9zKTsKCWlmIChUaGlzLT5od2J1ZikgewoJCWhyZXM9SURzRHJpdmVyQnVmZmVyX0dldFBvc2l0aW9uKFRoaXMtPmh3YnVmLHBsYXlwb3Msd3JpdGVwb3MpOwoJCWlmIChocmVzKQoJCSAgICByZXR1cm4gaHJlczsKCX0KCWVsc2UgaWYgKFRoaXMtPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfUFJJTUFSWUJVRkZFUikgewoJCWlmIChwbGF5cG9zKSB7CgkJCU1NVElNRSBtdGltZTsKCQkJbXRpbWUud1R5cGUgPSBUSU1FX0JZVEVTOwoJCQl3YXZlT3V0R2V0UG9zaXRpb24oVGhpcy0+ZHNvdW5kLT5od28sICZtdGltZSwgc2l6ZW9mKG10aW1lKSk7CgkJCW10aW1lLnUuY2IgPSBtdGltZS51LmNiICUgVGhpcy0+YnVmbGVuOwoJCQkqcGxheXBvcyA9IG10aW1lLnUuY2I7CgkJfQoJCWlmICh3cml0ZXBvcykgewoJCQkvKiB0aGUgd3JpdGVwb3Mgc2hvdWxkIG9ubHkgYmUgdXNlZCBieSBhcHBzIHdpdGggV1JJVEVQUklNQVJZIHByaW9yaXR5LAoJCQkgKiBpbiB3aGljaCBjYXNlIG91ciBzb2Z0d2FyZSBtaXhlciBpcyBkaXNhYmxlZCBhbnl3YXkgKi8KCQkJKndyaXRlcG9zID0gKFRoaXMtPmRzb3VuZC0+cHdwbGF5ICsgRFNfSEVMX01BUkdJTikgKiBUaGlzLT5kc291bmQtPmZyYWdsZW47CgkJCXdoaWxlICgqd3JpdGVwb3MgPj0gVGhpcy0+YnVmbGVuKQoJCQkJKndyaXRlcG9zIC09IFRoaXMtPmJ1ZmxlbjsKCQl9Cgl9IGVsc2UgewoJCWlmIChwbGF5cG9zICYmIChUaGlzLT5zdGF0ZSAhPSBTVEFURV9QTEFZSU5HKSkgewoJCQkvKiB3ZSBoYXZlbid0IGJlZW4gbWVyZ2VkIGludG8gdGhlIHByaW1hcnkgYnVmZmVyICh5ZXQpICovCgkJCSpwbGF5cG9zID0gVGhpcy0+YnVmX21peHBvczsKCQl9CgkJZWxzZSBpZiAocGxheXBvcykgewoJCQlEV09SRCBwcGxheSwgcHdyaXRlLCBscGxheSwgc3BsYXksIHBzdGF0ZTsKCQkJLyogbGV0J3MgZ2V0IHRoaXMgZXhhY3Q7IGZpcnN0LCByZWN1cnNpdmVseSBjYWxsIEdldFBvc2l0aW9uIG9uIHRoZSBwcmltYXJ5ICovCgkJCUVudGVyQ3JpdGljYWxTZWN0aW9uKCYocHJpbWFyeWJ1Zi0+bG9jaykpOwoJCQlJRGlyZWN0U291bmRCdWZmZXJJbXBsX0dldEN1cnJlbnRQb3NpdGlvbigoTFBESVJFQ1RTT1VOREJVRkZFUilwcmltYXJ5YnVmLCAmcHBsYXksICZwd3JpdGUpOwoJCQkvKiBkZXRlY3QgSEVMIG1vZGUgdW5kZXJydW4gKi8KCQkJcHN0YXRlID0gcHJpbWFyeWJ1Zi0+c3RhdGU7CgkJCWlmICghKHByaW1hcnlidWYtPmh3YnVmIHx8IHByaW1hcnlidWYtPmRzb3VuZC0+cHdxdWV1ZSkpIHsKCQkJCVRSQUNFKCJkZXRlY3RlZCBhbiB1bmRlcnJ1blxuIik7CgkJCQkvKiBwcGxheSA9ID8gKi8KCQkJCWlmIChwc3RhdGUgPT0gU1RBVEVfUExBWUlORykKCQkJCQlwc3RhdGUgPSBTVEFURV9TVEFSVElORzsKCQkJCWVsc2UgaWYgKHBzdGF0ZSA9PSBTVEFURV9TVE9QUElORykKCQkJCQlwc3RhdGUgPSBTVEFURV9TVE9QUEVEOwoJCQl9CgkJCS8qIGdldCBkYXRhIGZvciBvdXJzZWx2ZXMgd2hpbGUgd2Ugc3RpbGwgaGF2ZSB0aGUgbG9jayAqLwoJCQlwc3RhdGUgJj0gVGhpcy0+c3RhdGU7CgkJCWxwbGF5ID0gVGhpcy0+cHJpbWFyeV9taXhwb3M7CgkJCXNwbGF5ID0gVGhpcy0+YnVmX21peHBvczsKCQkJaWYgKChUaGlzLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX0dFVENVUlJFTlRQT1NJVElPTjIpIHx8IHByaW1hcnlidWYtPmh3YnVmKSB7CgkJCQkvKiBjYWxjdWxhdGUgcGxheSBwb3NpdGlvbiB1c2luZyB0aGlzICovCgkJCQkqcGxheXBvcyA9IERTT1VORF9DYWxjUGxheVBvc2l0aW9uKFRoaXMsIHBzdGF0ZSwgcHBsYXksIHB3cml0ZSwgbHBsYXksIHNwbGF5KTsKCQkJfSBlbHNlIHsKCQkJCS8qICh1bmxlc3MgdGhlIGFwcCBpc24ndCB1c2luZyBHRVRDVVJSRU5UUE9TSVRJT04yKSAqLwoJCQkJLyogZG9uJ3Qga25vdyBleGFjdGx5IGhvdyB0aGlzIHNob3VsZCBiZSBoYW5kbGVkLi4uCgkJCQkgKiB0aGUgZG9jcyBzYXlzIHRoYXQgcGxheSBjdXJzb3IgaXMgcmVwb3J0ZWQgYXMgZGlyZWN0bHkKCQkJCSAqIGJlaGluZCB3cml0ZSBjdXJzb3IsIGhtbS4uLiAqLwoJCQkJLyogbGV0J3MganVzdCBkbyB3aGF0IG1pZ2h0IHdvcmsgZm9yIEhhbGYtTGlmZSAqLwoJCQkJRFdPUkQgd3A7CgkJCQl3cCA9IChUaGlzLT5kc291bmQtPnB3cGxheSArIERTX0hFTF9NQVJHSU4pICogVGhpcy0+ZHNvdW5kLT5mcmFnbGVuOwoJCQkJd2hpbGUgKHdwID49IHByaW1hcnlidWYtPmJ1ZmxlbikKCQkJCQl3cCAtPSBwcmltYXJ5YnVmLT5idWZsZW47CgkJCQkqcGxheXBvcyA9IERTT1VORF9DYWxjUGxheVBvc2l0aW9uKFRoaXMsIHBzdGF0ZSwgd3AsIHB3cml0ZSwgbHBsYXksIHNwbGF5KTsKCQkJfQoJCQlMZWF2ZUNyaXRpY2FsU2VjdGlvbigmKHByaW1hcnlidWYtPmxvY2spKTsKCQl9CgkJaWYgKHdyaXRlcG9zKSAqd3JpdGVwb3MgPSBUaGlzLT5idWZfbWl4cG9zOwoJfQoJaWYgKHdyaXRlcG9zKSB7CgkJaWYgKFRoaXMtPnN0YXRlICE9IFNUQVRFX1NUT1BQRUQpCgkJCS8qIGFwcGx5IHRoZSBkb2N1bWVudGVkIDEwbXMgbGVhZCB0byB3cml0ZXBvcyAqLwoJCQkqd3JpdGVwb3MgKz0gVGhpcy0+d3JpdGVsZWFkOwoJCXdoaWxlICgqd3JpdGVwb3MgPj0gVGhpcy0+YnVmbGVuKSAqd3JpdGVwb3MgLT0gVGhpcy0+YnVmbGVuOwoJfQoJVFJBQ0UoInBsYXlwb3MgPSAlbGQsIHdyaXRlcG9zID0gJWxkICglcCwgdGltZT0lbGQpXG4iLCBwbGF5cG9zPypwbGF5cG9zOjAsIHdyaXRlcG9zPyp3cml0ZXBvczowLCBUaGlzLCBHZXRUaWNrQ291bnQoKSk7CglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmRCdWZmZXJJbXBsX0dldFN0YXR1cygKCUxQRElSRUNUU09VTkRCVUZGRVIgaWZhY2UsTFBEV09SRCBzdGF0dXMKKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQnVmZmVySW1wbCxpZmFjZSk7CglUUkFDRSgiKCVwLCVwKSwgdGhyZWFkIGlzICVseFxuIixUaGlzLHN0YXR1cyxHZXRDdXJyZW50VGhyZWFkSWQoKSk7CgoJaWYgKHN0YXR1cyA9PSBOVUxMKQoJCXJldHVybiBEU0VSUl9JTlZBTElEUEFSQU07CgoJKnN0YXR1cyA9IDA7CglpZiAoKFRoaXMtPnN0YXRlID09IFNUQVRFX1NUQVJUSU5HKSB8fCAoVGhpcy0+c3RhdGUgPT0gU1RBVEVfUExBWUlORykpIHsKCQkqc3RhdHVzIHw9IERTQlNUQVRVU19QTEFZSU5HOwoJCWlmIChUaGlzLT5wbGF5ZmxhZ3MgJiBEU0JQTEFZX0xPT1BJTkcpCgkJCSpzdGF0dXMgfD0gRFNCU1RBVFVTX0xPT1BJTkc7Cgl9CgoJVFJBQ0UoInN0YXR1cz0lbHhcbiIsICpzdGF0dXMpOwoJcmV0dXJuIERTX09LOwp9CgoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZEJ1ZmZlckltcGxfR2V0Rm9ybWF0KAoJTFBESVJFQ1RTT1VOREJVRkZFUiBpZmFjZSxMUFdBVkVGT1JNQVRFWCBscHdmLERXT1JEIHdmc2l6ZSxMUERXT1JEIHdmd3JpdHRlbgopIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRCdWZmZXJJbXBsLGlmYWNlKTsKCVRSQUNFKCIoJXAsJXAsJWxkLCVwKVxuIixUaGlzLGxwd2Ysd2ZzaXplLHdmd3JpdHRlbik7CgoJaWYgKHdmc2l6ZT5zaXplb2YoVGhpcy0+d2Z4KSkKCQl3ZnNpemUgPSBzaXplb2YoVGhpcy0+d2Z4KTsKCWlmIChscHdmKSB7CS8qIE5VTEwgaXMgdmFsaWQgKi8KCQltZW1jcHkobHB3ZiwmKFRoaXMtPndmeCksd2ZzaXplKTsKCQlpZiAod2Z3cml0dGVuKQoJCQkqd2Z3cml0dGVuID0gd2ZzaXplOwoJfSBlbHNlCgkJaWYgKHdmd3JpdHRlbikKCQkJKndmd3JpdHRlbiA9IHNpemVvZihUaGlzLT53ZngpOwoJCWVsc2UKCQkJcmV0dXJuIERTRVJSX0lOVkFMSURQQVJBTTsKCglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmRCdWZmZXJJbXBsX0xvY2soCglMUERJUkVDVFNPVU5EQlVGRkVSIGlmYWNlLERXT1JEIHdyaXRlY3Vyc29yLERXT1JEIHdyaXRlYnl0ZXMsTFBWT0lEIGxwbHBhdWRpb3B0cjEsTFBEV09SRCBhdWRpb2J5dGVzMSxMUFZPSUQgbHBscGF1ZGlvcHRyMixMUERXT1JEIGF1ZGlvYnl0ZXMyLERXT1JEIGZsYWdzCikgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwsaWZhY2UpOwoJRFdPUkQgY2FwZjsKCglUUkFDRSgiKCVwLCVsZCwlbGQsJXAsJXAsJXAsJXAsMHglMDhseCkgYXQgJWxkXG4iLAoJCVRoaXMsCgkJd3JpdGVjdXJzb3IsCgkJd3JpdGVieXRlcywKCQlscGxwYXVkaW9wdHIxLAoJCWF1ZGlvYnl0ZXMxLAoJCWxwbHBhdWRpb3B0cjIsCgkJYXVkaW9ieXRlczIsCgkJZmxhZ3MsCgkJR2V0VGlja0NvdW50KCkKCSk7CgoJaWYgKGZsYWdzICYgRFNCTE9DS19GUk9NV1JJVEVDVVJTT1IpIHsKCQlEV09SRCB3cml0ZXBvczsKCQkvKiBHZXRDdXJyZW50UG9zaXRpb24gZG9lcyB0b28gbXVjaCBtYWdpYyB0byBkdXBsaWNhdGUgaGVyZSAqLwoJCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGxfR2V0Q3VycmVudFBvc2l0aW9uKGlmYWNlLCBOVUxMLCAmd3JpdGVwb3MpOwoJCXdyaXRlY3Vyc29yICs9IHdyaXRlcG9zOwoJfQoJaWYgKGZsYWdzICYgRFNCTE9DS19FTlRJUkVCVUZGRVIpCgkJd3JpdGVieXRlcyA9IFRoaXMtPmJ1ZmxlbjsKCWlmICh3cml0ZWJ5dGVzID4gVGhpcy0+YnVmbGVuKQoJCXdyaXRlYnl0ZXMgPSBUaGlzLT5idWZsZW47CgoJYXNzZXJ0KGF1ZGlvYnl0ZXMxIT1hdWRpb2J5dGVzMik7Cglhc3NlcnQobHBscGF1ZGlvcHRyMSE9bHBscGF1ZGlvcHRyMik7CgoJaWYgKCh3cml0ZWJ5dGVzID09IFRoaXMtPmJ1ZmxlbikgJiYKCSAgICAoKFRoaXMtPnN0YXRlID09IFNUQVRFX1NUQVJUSU5HKSB8fAoJICAgICAoVGhpcy0+c3RhdGUgPT0gU1RBVEVfUExBWUlORykpKQoJCS8qIHNvbWUgZ2FtZXMsIGxpa2UgSGFsZi1MaWZlLCB0cnkgdG8gYmUgY2xldmVyIChub3QpIGFuZAoJCSAqIGtlZXAgb25lIHNlY29uZGFyeSBidWZmZXIsIGFuZCBtaXggc291bmRzIGludG8gaXQgaXRzZWxmLAoJCSAqIGxvY2tpbmcgdGhlIGVudGlyZSBidWZmZXIgZXZlcnkgdGltZS4uLiBzbyB3ZSBjYW4ganVzdCBmb3JnZXQKCQkgKiBhYm91dCB0cmFja2luZyB0aGUgbGFzdC13cml0dGVuLXRvLXBvc2l0aW9uLi4uICovCgkJVGhpcy0+cHJvYmFibHlfdmFsaWRfdG8gPSAoRFdPUkQpLTE7CgllbHNlCgkJVGhpcy0+cHJvYmFibHlfdmFsaWRfdG8gPSB3cml0ZWN1cnNvcjsKCglpZiAoVGhpcy0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19QUklNQVJZQlVGRkVSKQoJCWNhcGYgPSBEU0RERVNDX0RPTlRORUVEUFJJTUFSWUxPQ0s7CgllbHNlCgkJY2FwZiA9IERTRERFU0NfRE9OVE5FRURTRUNPTkRBUllMT0NLOwoJaWYgKCEoVGhpcy0+ZHNvdW5kLT5kcnZkZXNjLmR3RmxhZ3MgJiBjYXBmKSAmJiBUaGlzLT5od2J1ZikgewoJCUlEc0RyaXZlckJ1ZmZlcl9Mb2NrKFRoaXMtPmh3YnVmLAoJCQkJICAgICBscGxwYXVkaW9wdHIxLCBhdWRpb2J5dGVzMSwKCQkJCSAgICAgbHBscGF1ZGlvcHRyMiwgYXVkaW9ieXRlczIsCgkJCQkgICAgIHdyaXRlY3Vyc29yLCB3cml0ZWJ5dGVzLAoJCQkJICAgICAwKTsKCX0KCWVsc2UgewoJCUJPT0wgcmVtaXggPSBGQUxTRTsKCQlpZiAod3JpdGVjdXJzb3Ird3JpdGVieXRlcyA8PSBUaGlzLT5idWZsZW4pIHsKCQkJKihMUEJZVEUqKWxwbHBhdWRpb3B0cjEgPSBUaGlzLT5idWZmZXIrd3JpdGVjdXJzb3I7CgkJCSphdWRpb2J5dGVzMSA9IHdyaXRlYnl0ZXM7CgkJCWlmIChscGxwYXVkaW9wdHIyKQoJCQkJKihMUEJZVEUqKWxwbHBhdWRpb3B0cjIgPSBOVUxMOwoJCQlpZiAoYXVkaW9ieXRlczIpCgkJCQkqYXVkaW9ieXRlczIgPSAwOwoJCQlUUkFDRSgiLT4lbGQuMFxuIix3cml0ZWJ5dGVzKTsKCQl9IGVsc2UgewoJCQkqKExQQllURSopbHBscGF1ZGlvcHRyMSA9IFRoaXMtPmJ1ZmZlcit3cml0ZWN1cnNvcjsKCQkJKmF1ZGlvYnl0ZXMxID0gVGhpcy0+YnVmbGVuLXdyaXRlY3Vyc29yOwoJCQlpZiAobHBscGF1ZGlvcHRyMikKCQkJCSooTFBCWVRFKilscGxwYXVkaW9wdHIyID0gVGhpcy0+YnVmZmVyOwoJCQlpZiAoYXVkaW9ieXRlczIpCgkJCQkqYXVkaW9ieXRlczIgPSB3cml0ZWJ5dGVzLShUaGlzLT5idWZsZW4td3JpdGVjdXJzb3IpOwoJCQlUUkFDRSgiLT4lbGQuJWxkXG4iLCphdWRpb2J5dGVzMSxhdWRpb2J5dGVzMj8qYXVkaW9ieXRlczI6MCk7CgkJfQoJCS8qIGlmIHRoZSBzZWdtZW50IGJldHdlZW4gcGxheXBvcyBhbmQgYnVmX21peHBvcyBpcyB0b3VjaGVkLAoJCSAqIHdlIG5lZWQgdG8gY2FuY2VsIHNvbWUgbWl4aW5nICovCgkJaWYgKFRoaXMtPmJ1Zl9taXhwb3MgPj0gVGhpcy0+cGxheXBvcykgewoJCQlpZiAoVGhpcy0+YnVmX21peHBvcyA+IHdyaXRlY3Vyc29yICYmCgkJCSAgICBUaGlzLT5wbGF5cG9zIDw9IHdyaXRlY3Vyc29yK3dyaXRlYnl0ZXMpCgkJCQlyZW1peCA9IFRSVUU7CgkJfQoJCWVsc2UgewoJCQlpZiAoVGhpcy0+YnVmX21peHBvcyA+IHdyaXRlY3Vyc29yIHx8CgkJCSAgICBUaGlzLT5wbGF5cG9zIDw9IHdyaXRlY3Vyc29yK3dyaXRlYnl0ZXMpCgkJCQlyZW1peCA9IFRSVUU7CgkJfQoJCWlmIChyZW1peCkgewoJCQlUUkFDRSgibG9ja2luZyBwcmVidWZmZXJlZCByZWdpb24sIG91Y2hcbiIpOwoJCQlEU09VTkRfTWl4Q2FuY2VsQXQoVGhpcywgd3JpdGVjdXJzb3IpOwoJCX0KCX0KCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZEJ1ZmZlckltcGxfU2V0Q3VycmVudFBvc2l0aW9uKAoJTFBESVJFQ1RTT1VOREJVRkZFUiBpZmFjZSxEV09SRCBuZXdwb3MKKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQnVmZmVySW1wbCxpZmFjZSk7CglUUkFDRSgiKCVwLCVsZClcbiIsVGhpcyxuZXdwb3MpOwoKCS8qICoqKiogKi8KCUVudGVyQ3JpdGljYWxTZWN0aW9uKCYoVGhpcy0+bG9jaykpOwoKCVRoaXMtPmJ1Zl9taXhwb3MgPSBuZXdwb3M7CglpZiAoVGhpcy0+aHdidWYpCgkJSURzRHJpdmVyQnVmZmVyX1NldFBvc2l0aW9uKFRoaXMtPmh3YnVmLCBUaGlzLT5idWZfbWl4cG9zKTsKCglMZWF2ZUNyaXRpY2FsU2VjdGlvbigmKFRoaXMtPmxvY2spKTsKCS8qICoqKiogKi8KCglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmRCdWZmZXJJbXBsX1NldFBhbigKCUxQRElSRUNUU09VTkRCVUZGRVIgaWZhY2UsTE9ORyBwYW4KKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQnVmZmVySW1wbCxpZmFjZSk7CgoJVFJBQ0UoIiglcCwlbGQpXG4iLFRoaXMscGFuKTsKCglpZiAoKHBhbiA+IERTQlBBTl9SSUdIVCkgfHwgKHBhbiA8IERTQlBBTl9MRUZUKSkKCQlyZXR1cm4gRFNFUlJfSU5WQUxJRFBBUkFNOwoKCS8qIFlvdSBjYW5ub3Qgc2V0IHRoZSBwYW4gb2YgdGhlIHByaW1hcnkgYnVmZmVyICovCgkvKiBhbmQgeW91IGNhbm5vdCB1c2UgYm90aCBwYW4gYW5kIDNEIGNvbnRyb2xzICovCglpZiAoIShUaGlzLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX0NUUkxQQU4pIHx8CgkgICAgKFRoaXMtPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfQ1RSTDNEKSB8fAoJICAgIChUaGlzLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX1BSSU1BUllCVUZGRVIpKQoJCXJldHVybiBEU0VSUl9DT05UUk9MVU5BVkFJTDsKCgkvKiAqKioqICovCglFbnRlckNyaXRpY2FsU2VjdGlvbigmKFRoaXMtPmxvY2spKTsKCglUaGlzLT52b2xwYW4ubFBhbiA9IHBhbjsKCglEU09VTkRfUmVjYWxjVm9sUGFuKCYoVGhpcy0+dm9scGFuKSk7CgoJaWYgKFRoaXMtPmh3YnVmKSB7CgkJSURzRHJpdmVyQnVmZmVyX1NldFZvbHVtZVBhbihUaGlzLT5od2J1ZiwgJihUaGlzLT52b2xwYW4pKTsKCX0KCglMZWF2ZUNyaXRpY2FsU2VjdGlvbigmKFRoaXMtPmxvY2spKTsKCS8qICoqKiogKi8KCglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmRCdWZmZXJJbXBsX0dldFBhbigKCUxQRElSRUNUU09VTkRCVUZGRVIgaWZhY2UsTFBMT05HIHBhbgopIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRCdWZmZXJJbXBsLGlmYWNlKTsKCVRSQUNFKCIoJXAsJXApXG4iLFRoaXMscGFuKTsKCglpZiAocGFuID09IE5VTEwpCgkJcmV0dXJuIERTRVJSX0lOVkFMSURQQVJBTTsKCgkqcGFuID0gVGhpcy0+dm9scGFuLmxQYW47CgoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kQnVmZmVySW1wbF9VbmxvY2soCglMUERJUkVDVFNPVU5EQlVGRkVSIGlmYWNlLExQVk9JRCBwMSxEV09SRCB4MSxMUFZPSUQgcDIsRFdPUkQgeDIKKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQnVmZmVySW1wbCxpZmFjZSk7CglEV09SRCBjYXBmLCBwcm9iYWJseV92YWxpZF90bzsKCglUUkFDRSgiKCVwLCVwLCVsZCwlcCwlbGQpOnN0dWJcbiIsIFRoaXMscDEseDEscDIseDIpOwoKI2lmIDAKCS8qIFByZXByb2Nlc3MgM0QgYnVmZmVycy4uLiAqLwoKCS8qIFRoaXMgaXMgaGlnaGx5IGV4cGVyaW1lbnRhbCBhbmQgbGlhYmxlIHRvIGJyZWFrIHRoaW5ncyAqLwoJaWYgKFRoaXMtPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfQ1RSTDNEKQoJCURTT1VORF9DcmVhdGUzREJ1ZmZlcihUaGlzKTsKI2VuZGlmCgoJaWYgKFRoaXMtPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfUFJJTUFSWUJVRkZFUikKCQljYXBmID0gRFNEREVTQ19ET05UTkVFRFBSSU1BUllMT0NLOwoJZWxzZQoJCWNhcGYgPSBEU0RERVNDX0RPTlRORUVEU0VDT05EQVJZTE9DSzsKCWlmICghKFRoaXMtPmRzb3VuZC0+ZHJ2ZGVzYy5kd0ZsYWdzICYgY2FwZikgJiYgVGhpcy0+aHdidWYpIHsKCQlJRHNEcml2ZXJCdWZmZXJfVW5sb2NrKFRoaXMtPmh3YnVmLCBwMSwgeDEsIHAyLCB4Mik7Cgl9CgoJaWYgKHAyKSBwcm9iYWJseV92YWxpZF90byA9ICgoKExQQllURSlwMiktVGhpcy0+YnVmZmVyKSArIHgyOwoJZWxzZSBwcm9iYWJseV92YWxpZF90byA9ICgoKExQQllURSlwMSktVGhpcy0+YnVmZmVyKSArIHgxOwoJd2hpbGUgKHByb2JhYmx5X3ZhbGlkX3RvID49IFRoaXMtPmJ1ZmxlbikKCQlwcm9iYWJseV92YWxpZF90byAtPSBUaGlzLT5idWZsZW47CglpZiAoKHByb2JhYmx5X3ZhbGlkX3RvID09IDApICYmICgoeDEreDIpID09IFRoaXMtPmJ1ZmxlbikgJiYKCSAgICAoKFRoaXMtPnN0YXRlID09IFNUQVRFX1NUQVJUSU5HKSB8fAoJICAgICAoVGhpcy0+c3RhdGUgPT0gU1RBVEVfUExBWUlORykpKQoJCS8qIHNlZSBJRGlyZWN0U291bmRCdWZmZXJJbXBsX0xvY2sgKi8KCQlwcm9iYWJseV92YWxpZF90byA9IChEV09SRCktMTsKCVRoaXMtPnByb2JhYmx5X3ZhbGlkX3RvID0gcHJvYmFibHlfdmFsaWRfdG87CgoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kQnVmZmVySW1wbF9SZXN0b3JlKAoJTFBESVJFQ1RTT1VOREJVRkZFUiBpZmFjZQopIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRCdWZmZXJJbXBsLGlmYWNlKTsKCUZJWE1FKCIoJXApOnN0dWJcbiIsVGhpcyk7CglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmRCdWZmZXJJbXBsX0dldEZyZXF1ZW5jeSgKCUxQRElSRUNUU09VTkRCVUZGRVIgaWZhY2UsTFBEV09SRCBmcmVxCikgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwsaWZhY2UpOwoJVFJBQ0UoIiglcCwlcClcbiIsVGhpcyxmcmVxKTsKCglpZiAoZnJlcSA9PSBOVUxMKQoJCXJldHVybiBEU0VSUl9JTlZBTElEUEFSQU07CgoJKmZyZXEgPSBUaGlzLT5mcmVxOwoJVFJBQ0UoIi0+ICVsZFxuIiwgKmZyZXEpOwoKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZEJ1ZmZlckltcGxfSW5pdGlhbGl6ZSgKCUxQRElSRUNUU09VTkRCVUZGRVIgaWZhY2UsTFBESVJFQ1RTT1VORCBkc291bmQsTFBEU0JVRkZFUkRFU0MgZGJzZAopIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRCdWZmZXJJbXBsLGlmYWNlKTsKCUZJWE1FKCIoJXAsJXAsJXApOnN0dWJcbiIsVGhpcyxkc291bmQsZGJzZCk7CglEUFJJTlRGKCJSZS1Jbml0ISEhXG4iKTsKCXJldHVybiBEU0VSUl9BTFJFQURZSU5JVElBTElaRUQ7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmRCdWZmZXJJbXBsX0dldENhcHMoCglMUERJUkVDVFNPVU5EQlVGRkVSIGlmYWNlLExQRFNCQ0FQUyBjYXBzCikgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwsaWZhY2UpOwogIAlUUkFDRSgiKCVwKS0+KCVwKVxuIixUaGlzLGNhcHMpOwogIAoJaWYgKGNhcHMgPT0gTlVMTCkKCQlyZXR1cm4gRFNFUlJfSU5WQUxJRFBBUkFNOwoKCS8qIEkgdGhpbmsgd2Ugc2hvdWxkIGNoZWNrIHRoaXMgdmFsdWUsIG5vdCBzZXQgaXQuIFNlZSAqLwoJLyogSW5zaWRlIERpcmVjdFgsIHAyMTUuIFRoYXQgc2hvdWxkIGFwcGx5IGhlcmUsIHRvby4gKi8KCWNhcHMtPmR3U2l6ZSA9IHNpemVvZigqY2Fwcyk7CgoJY2Fwcy0+ZHdGbGFncyA9IFRoaXMtPmRzYmQuZHdGbGFnczsKCWlmIChUaGlzLT5od2J1ZikgY2Fwcy0+ZHdGbGFncyB8PSBEU0JDQVBTX0xPQ0hBUkRXQVJFOwoJZWxzZSBjYXBzLT5kd0ZsYWdzIHw9IERTQkNBUFNfTE9DU09GVFdBUkU7CgoJY2Fwcy0+ZHdCdWZmZXJCeXRlcyA9IFRoaXMtPmJ1ZmxlbjsKCgkvKiBUaGlzIHZhbHVlIHJlcHJlc2VudHMgdGhlIHNwZWVkIG9mIHRoZSAidW5sb2NrIiBjb21tYW5kLgoJICAgQXMgdW5sb2NrIGlzIHF1aXRlIGZhc3QgKGl0IGRvZXMgbm90IGRvIGFueXRoaW5nKSwgSSBwdXQKCSAgIDQwOTYga28vcyA9IDQgTW8gLyBzICovCgkvKiBGSVhNRTogaHdidWYgc3BlZWQgKi8KCWNhcHMtPmR3VW5sb2NrVHJhbnNmZXJSYXRlID0gNDA5NjsKCWNhcHMtPmR3UGxheUNwdU92ZXJoZWFkID0gMDsKCglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmRCdWZmZXJJbXBsX1F1ZXJ5SW50ZXJmYWNlKAoJTFBESVJFQ1RTT1VOREJVRkZFUiBpZmFjZSxSRUZJSUQgcmlpZCxMUFZPSUQgKnBwb2JqCikgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwsaWZhY2UpOwoKCVRSQUNFKCIoJXAsJXMsJXApXG4iLFRoaXMsZGVidWdzdHJfZ3VpZChyaWlkKSxwcG9iaik7CgoJaWYgKCBJc0VxdWFsR1VJRCggJklJRF9JRGlyZWN0U291bmROb3RpZnksIHJpaWQgKSApIHsKCQlJRGlyZWN0U291bmROb3RpZnlJbXBsCSpkc247CgoJCWRzbiA9IChJRGlyZWN0U291bmROb3RpZnlJbXBsKilIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwwLHNpemVvZigqZHNuKSk7CgkJZHNuLT5yZWYgPSAxOwoJCWRzbi0+ZHNiID0gVGhpczsKCQlJRGlyZWN0U291bmRCdWZmZXJfQWRkUmVmKGlmYWNlKTsKCQlJQ09NX1ZUQkwoZHNuKSA9ICZkc252dDsKCQkqcHBvYmogPSAoTFBWT0lEKWRzbjsKCQlyZXR1cm4gU19PSzsKCX0KCiNpZmRlZiBVU0VfRFNPVU5EM0QKCWlmICggSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdFNvdW5kM0RCdWZmZXIsIHJpaWQgKSApIHsKICAgICAgICAgICAgICAgIElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbCAgICAgICAgKmRzM2RiOwoKCQkqcHBvYmogPSBUaGlzLT5kczNkYjsKCQlpZiAoKnBwb2JqKSB7CgkJCUlEaXJlY3RTb3VuZDNEQnVmZmVyX0FkZFJlZigoTFBESVJFQ1RTT1VORDNEQlVGRkVSKVRoaXMtPmRzM2RiKTsKCQkJcmV0dXJuIFNfT0s7CgkJfQoKICAgICAgICAgICAgICAgIGRzM2RiID0gKElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbCopSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksCiAgICAgICAgICAgICAgICAgICAgICAgIDAsc2l6ZW9mKCpkczNkYikpOwogICAgICAgICAgICAgICAgZHMzZGItPnJlZiA9IDE7CiAgICAgICAgICAgICAgICBkczNkYi0+ZHNiID0gVGhpczsKICAgICAgICAgICAgICAgIElDT01fVlRCTChkczNkYikgPSAmZHMzZGJ2dDsKCQlJbml0aWFsaXplQ3JpdGljYWxTZWN0aW9uKCZkczNkYi0+bG9jayk7CgoJCUlEaXJlY3RTb3VuZEJ1ZmZlcl9BZGRSZWYoaWZhY2UpOwoKICAgICAgICAgICAgICAgIGRzM2RiLT5kczNkYi5kd1NpemUgPSBzaXplb2YoRFMzREJVRkZFUik7CiAgICAgICAgICAgICAgICBkczNkYi0+ZHMzZGIudlBvc2l0aW9uLnUxLnggPSAwLjA7CiAgICAgICAgICAgICAgICBkczNkYi0+ZHMzZGIudlBvc2l0aW9uLnUyLnkgPSAwLjA7CiAgICAgICAgICAgICAgICBkczNkYi0+ZHMzZGIudlBvc2l0aW9uLnUzLnogPSAwLjA7CiAgICAgICAgICAgICAgICBkczNkYi0+ZHMzZGIudlZlbG9jaXR5LnUxLnggPSAwLjA7CiAgICAgICAgICAgICAgICBkczNkYi0+ZHMzZGIudlZlbG9jaXR5LnUyLnkgPSAwLjA7CiAgICAgICAgICAgICAgICBkczNkYi0+ZHMzZGIudlZlbG9jaXR5LnUzLnogPSAwLjA7CiAgICAgICAgICAgICAgICBkczNkYi0+ZHMzZGIuZHdJbnNpZGVDb25lQW5nbGUgPSBEUzNEX0RFRkFVTFRDT05FQU5HTEU7CiAgICAgICAgICAgICAgICBkczNkYi0+ZHMzZGIuZHdPdXRzaWRlQ29uZUFuZ2xlID0gRFMzRF9ERUZBVUxUQ09ORUFOR0xFOwogICAgICAgICAgICAgICAgZHMzZGItPmRzM2RiLnZDb25lT3JpZW50YXRpb24udTEueCA9IDAuMDsKICAgICAgICAgICAgICAgIGRzM2RiLT5kczNkYi52Q29uZU9yaWVudGF0aW9uLnUyLnkgPSAwLjA7CiAgICAgICAgICAgICAgICBkczNkYi0+ZHMzZGIudkNvbmVPcmllbnRhdGlvbi51My56ID0gMC4wOwogICAgICAgICAgICAgICAgZHMzZGItPmRzM2RiLmxDb25lT3V0c2lkZVZvbHVtZSA9IERTM0RfREVGQVVMVENPTkVPVVRTSURFVk9MVU1FOyAgICAgICAgICAgICAgICBkczNkYi0+ZHMzZGIuZmxNaW5EaXN0YW5jZSA9IERTM0RfREVGQVVMVE1JTkRJU1RBTkNFOwogICAgICAgICAgICAgICAgZHMzZGItPmRzM2RiLmZsTWF4RGlzdGFuY2UgPSBEUzNEX0RFRkFVTFRNQVhESVNUQU5DRTsKICAgICAgICAgICAgICAgIGRzM2RiLT5kczNkYi5kd01vZGUgPSBEUzNETU9ERV9OT1JNQUw7CiAgICAgICAgICAgICAgICBkczNkYi0+YnVmbGVuID0gKFRoaXMtPmJ1ZmxlbiAqIHByaW1hcnlidWYtPndmeC5uQmxvY2tBbGlnbikgLwogICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT53ZngubkJsb2NrQWxpZ247CiAgICAgICAgICAgICAgICBkczNkYi0+YnVmZmVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGRzM2RiLT5idWZsZW4pOwogICAgICAgICAgICAgICAgaWYgKGRzM2RiLT5idWZmZXIgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICBkczNkYi0+YnVmbGVuID0gMDsKICAgICAgICAgICAgICAgICAgICAgICAgZHMzZGItPmRzM2RiLmR3TW9kZSA9IERTM0RNT0RFX0RJU0FCTEU7CiAgICAgICAgICAgICAgICB9CgoJCWRzM2RiLT5pa3MgPSAoSUtzUHJvcGVydHlTZXRJbXBsKilIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwwLHNpemVvZigqKGRzM2RiLT5pa3MpKSk7CgkJZHMzZGItPmlrcy0+cmVmID0gMTsKCQlkczNkYi0+aWtzLT5kczNkYiA9IGRzM2RiOwoJCUlDT01fVlRCTChkczNkYi0+aWtzKSA9ICZpa3N2dDsKCgkJcmV0dXJuIFNfT0s7Cgl9CiNlbHNlCglpZiAoIElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3RTb3VuZDNEQnVmZmVyLCByaWlkICkgKSB7CgkJRklYTUUoIiVzOiBJIGtub3cgYWJvdXQgdGhpcyBHVUlELCBidXQgZG9uJ3Qgc3VwcG9ydCBpdCB5ZXRcbiIsCgkJICAgICAgZGVidWdzdHJfZ3VpZCggcmlpZCApKTsKCQkqcHBvYmogPSBOVUxMOwoJCXJldHVybiBFX0ZBSUw7Cgl9CiNlbmRpZgoKI2lmIFVTRV9EU09VTkQzRAogICAgICAgIGlmICggSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdFNvdW5kM0RMaXN0ZW5lciwgcmlpZCApICkgewoJCUlEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsKiBkc2w7CgoJCWlmIChUaGlzLT5kc291bmQtPmxpc3RlbmVyKSB7CgkJCSpwcG9iaiA9IFRoaXMtPmRzb3VuZC0+bGlzdGVuZXI7CiAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3RTb3VuZDNETGlzdGVuZXJfQWRkUmVmKChMUERJUkVDVFNPVU5EM0RMSVNURU5FUilUaGlzLT5kc291bmQtPmxpc3RlbmVyKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIERTX09LOwoJCX0KCgkJZHNsID0gKElEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsKilIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwwLHNpemVvZigqZHNsKSk7CgkJZHNsLT5yZWYgPSAxOwoJCUlDT01fVlRCTChkc2wpID0gJmRzM2RsdnQ7CgkJKnBwb2JqID0gKExQVk9JRClkc2w7CgogICAgICAgICAgICAgICAgZHNsLT5kczNkbC5kd1NpemUgPSBzaXplb2YoRFMzRExJU1RFTkVSKTsKICAgICAgICAgICAgICAgIGRzbC0+ZHMzZGwudlBvc2l0aW9uLnUxLnggPSAwLjA7CiAgICAgICAgICAgICAgICBkc2wtPmRzM2RsLnZQb3NpdGlvbi51Mi55ID0gMC4wOwogICAgICAgICAgICAgICAgZHNsLT5kczNkbC52UG9zaXRpb24udTMueiA9IDAuMDsKICAgICAgICAgICAgICAgIGRzbC0+ZHMzZGwudlZlbG9jaXR5LnUxLnggPSAwLjA7CiAgICAgICAgICAgICAgICBkc2wtPmRzM2RsLnZWZWxvY2l0eS51Mi55ID0gMC4wOwogICAgICAgICAgICAgICAgZHNsLT5kczNkbC52VmVsb2NpdHkudTMueiA9IDAuMDsKICAgICAgICAgICAgICAgIGRzbC0+ZHMzZGwudk9yaWVudEZyb250LnUxLnggPSAwLjA7CiAgICAgICAgICAgICAgICBkc2wtPmRzM2RsLnZPcmllbnRGcm9udC51Mi55ID0gMC4wOwogICAgICAgICAgICAgICAgZHNsLT5kczNkbC52T3JpZW50RnJvbnQudTMueiA9IDEuMDsKICAgICAgICAgICAgICAgIGRzbC0+ZHMzZGwudk9yaWVudFRvcC51MS54ID0gMC4wOwogICAgICAgICAgICAgICAgZHNsLT5kczNkbC52T3JpZW50VG9wLnUyLnkgPSAxLjA7CiAgICAgICAgICAgICAgICBkc2wtPmRzM2RsLnZPcmllbnRUb3AudTMueiA9IDAuMDsKICAgICAgICAgICAgICAgIGRzbC0+ZHMzZGwuZmxEaXN0YW5jZUZhY3RvciA9IERTM0RfREVGQVVMVERJU1RBTkNFRkFDVE9SOwogICAgICAgICAgICAgICAgZHNsLT5kczNkbC5mbFJvbGxvZmZGYWN0b3IgPSBEUzNEX0RFRkFVTFRST0xMT0ZGRkFDVE9SOwoKCQlJbml0aWFsaXplQ3JpdGljYWxTZWN0aW9uKCZkc2wtPmxvY2spOwoKCQlkc2wtPmRzYiA9IFRoaXM7CgkJSURpcmVjdFNvdW5kQnVmZmVyX0FkZFJlZihpZmFjZSk7CgoJCVRoaXMtPmRzb3VuZC0+bGlzdGVuZXIgPSBkc2w7CgkJSURpcmVjdFNvdW5kM0RMaXN0ZW5lcl9BZGRSZWYoKExQRElSRUNUU09VTkQzRExJU1RFTkVSKWRzbCk7CgoJCXJldHVybiBTX09LOwoJfQojZWxzZQoJaWYgKCBJc0VxdWFsR1VJRCggJklJRF9JRGlyZWN0U291bmQzRExpc3RlbmVyLCByaWlkICkgKSB7CgkJRklYTUUoIiVzOiBJIGtub3cgYWJvdXQgdGhpcyBHVUlELCBidXQgZG9uJ3Qgc3VwcG9ydCBpdCB5ZXRcbiIsCgkJICAgICAgZGVidWdzdHJfZ3VpZCggcmlpZCApKTsKCQkqcHBvYmogPSBOVUxMOwoJCXJldHVybiBFX0ZBSUw7Cgl9CiNlbmRpZgoKCUZJWE1FKCAiVW5rbm93biBHVUlEICVzXG4iLCBkZWJ1Z3N0cl9ndWlkKCByaWlkICkgKTsKCgkqcHBvYmogPSBOVUxMOwoKCXJldHVybiBFX0ZBSUw7Cn0KCnN0YXRpYyBJQ09NX1ZUQUJMRShJRGlyZWN0U291bmRCdWZmZXIpIGRzYnZ0ID0gCnsKCUlDT01fTVNWVEFCTEVfQ09NUEFUX0R1bW15UlRUSVZBTFVFCglJRGlyZWN0U291bmRCdWZmZXJJbXBsX1F1ZXJ5SW50ZXJmYWNlLAoJSURpcmVjdFNvdW5kQnVmZmVySW1wbF9BZGRSZWYsCglJRGlyZWN0U291bmRCdWZmZXJJbXBsX1JlbGVhc2UsCglJRGlyZWN0U291bmRCdWZmZXJJbXBsX0dldENhcHMsCglJRGlyZWN0U291bmRCdWZmZXJJbXBsX0dldEN1cnJlbnRQb3NpdGlvbiwKCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGxfR2V0Rm9ybWF0LAoJSURpcmVjdFNvdW5kQnVmZmVySW1wbF9HZXRWb2x1bWUsCglJRGlyZWN0U291bmRCdWZmZXJJbXBsX0dldFBhbiwKICAgICAgICBJRGlyZWN0U291bmRCdWZmZXJJbXBsX0dldEZyZXF1ZW5jeSwKCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGxfR2V0U3RhdHVzLAoJSURpcmVjdFNvdW5kQnVmZmVySW1wbF9Jbml0aWFsaXplLAoJSURpcmVjdFNvdW5kQnVmZmVySW1wbF9Mb2NrLAoJSURpcmVjdFNvdW5kQnVmZmVySW1wbF9QbGF5LAoJSURpcmVjdFNvdW5kQnVmZmVySW1wbF9TZXRDdXJyZW50UG9zaXRpb24sCglJRGlyZWN0U291bmRCdWZmZXJJbXBsX1NldEZvcm1hdCwKCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGxfU2V0Vm9sdW1lLAoJSURpcmVjdFNvdW5kQnVmZmVySW1wbF9TZXRQYW4sCglJRGlyZWN0U291bmRCdWZmZXJJbXBsX1NldEZyZXF1ZW5jeSwKCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGxfU3RvcCwKCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGxfVW5sb2NrLAoJSURpcmVjdFNvdW5kQnVmZmVySW1wbF9SZXN0b3JlCn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJSURpcmVjdFNvdW5kCiAqLwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZEltcGxfU2V0Q29vcGVyYXRpdmVMZXZlbCgKCUxQRElSRUNUU09VTkQgaWZhY2UsSFdORCBod25kLERXT1JEIGxldmVsCikgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEltcGwsaWZhY2UpOwoKCUZJWE1FKCIoJXAsJTA4bHgsJWxkKTpzdHViXG4iLFRoaXMsKERXT1JEKWh3bmQsbGV2ZWwpOwoKCVRoaXMtPnByaW9sZXZlbCA9IGxldmVsOwoKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZEltcGxfQ3JlYXRlU291bmRCdWZmZXIoCglMUERJUkVDVFNPVU5EIGlmYWNlLExQRFNCVUZGRVJERVNDIGRzYmQsTFBMUERJUkVDVFNPVU5EQlVGRkVSIHBwZHNiLExQVU5LTk9XTiBscHVuawopIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRJbXBsLGlmYWNlKTsKCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGwqKiBpcHBkc2I9KElEaXJlY3RTb3VuZEJ1ZmZlckltcGwqKilwcGRzYjsKCUxQV0FWRUZPUk1BVEVYCXdmZXg7CglIUkVTVUxUIGVyciA9IERTX09LOwoKCVRSQUNFKCIoJXAsJXAsJXAsJXApXG4iLFRoaXMsZHNiZCxpcHBkc2IsbHB1bmspOwoJCglpZiAoKFRoaXMgPT0gTlVMTCkgfHwgKGRzYmQgPT0gTlVMTCkgfHwgKGlwcGRzYiA9PSBOVUxMKSkKCQlyZXR1cm4gRFNFUlJfSU5WQUxJRFBBUkFNOwoJCglpZiAoVFJBQ0VfT04oZHNvdW5kKSkgewoJCVRSQUNFKCIoc3RydWN0c2l6ZT0lbGQpXG4iLGRzYmQtPmR3U2l6ZSk7CgkJVFJBQ0UoIihmbGFncz0weCUwOGx4OlxuIixkc2JkLT5kd0ZsYWdzKTsKCQlfZHVtcF9EU0JDQVBTKGRzYmQtPmR3RmxhZ3MpOwoJCURQUklOVEYoIilcbiIpOwoJCVRSQUNFKCIoYnVmZmVyYnl0ZXM9JWxkKVxuIixkc2JkLT5kd0J1ZmZlckJ5dGVzKTsKCQlUUkFDRSgiKGxwd2Z4Rm9ybWF0PSVwKVxuIixkc2JkLT5scHdmeEZvcm1hdCk7Cgl9CgoJd2ZleCA9IGRzYmQtPmxwd2Z4Rm9ybWF0OwoKCWlmICh3ZmV4KQoJCVRSQUNFKCIoZm9ybWF0dGFnPTB4JTA0eCxjaGFucz0lZCxzYW1wbGVyYXRlPSVsZCwiCgkJICAgImJ5dGVzcGVyc2VjPSVsZCxibG9ja2FsaWduPSVkLGJpdHNwZXJzYW1wPSVkLGNiU2l6ZT0lZClcbiIsCgkJICAgd2ZleC0+d0Zvcm1hdFRhZywgd2ZleC0+bkNoYW5uZWxzLCB3ZmV4LT5uU2FtcGxlc1BlclNlYywKCQkgICB3ZmV4LT5uQXZnQnl0ZXNQZXJTZWMsIHdmZXgtPm5CbG9ja0FsaWduLCAKCQkgICB3ZmV4LT53Qml0c1BlclNhbXBsZSwgd2ZleC0+Y2JTaXplKTsKCglpZiAoZHNiZC0+ZHdGbGFncyAmIERTQkNBUFNfUFJJTUFSWUJVRkZFUikgewoJCWlmIChwcmltYXJ5YnVmKSB7CgkJCUlEaXJlY3RTb3VuZEJ1ZmZlcl9BZGRSZWYoKExQRElSRUNUU09VTkRCVUZGRVIpcHJpbWFyeWJ1Zik7CgkJCSppcHBkc2IgPSBwcmltYXJ5YnVmOwoJCQlwcmltYXJ5YnVmLT5kc2JkLmR3RmxhZ3MgPSBkc2JkLT5kd0ZsYWdzOwoJCQlyZXR1cm4gRFNfT0s7CgkJfSAvKiBFbHNlIGNyZWF0ZSBwcmltYXJ5IGJ1ZmZlciAqLwoJfSBlbHNlIHsKCQlpZiAoZHNiZC0+ZHdCdWZmZXJCeXRlcyA8IERTQlNJWkVfTUlOIHx8IGRzYmQtPmR3QnVmZmVyQnl0ZXMgPiBEU0JTSVpFX01BWCkgewoJCQlFUlIoImludmFsaWQgc291bmQgYnVmZmVyIHNpemUgJWxkXG4iLCBkc2JkLT5kd0J1ZmZlckJ5dGVzKTsKCQkJcmV0dXJuIERTRVJSX0lOVkFMSURQQVJBTTsgLyogRklYTUU6IHdoaWNoIGVycm9yPyAqLwoJCX0KCX0KCgkqaXBwZHNiID0gKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwqKUhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLEhFQVBfWkVST19NRU1PUlksc2l6ZW9mKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwpKTsKCWlmICgqaXBwZHNiID09IE5VTEwpCgkJcmV0dXJuIERTRVJSX09VVE9GTUVNT1JZOwoJSUNPTV9WVEJMKCppcHBkc2IpID0gJmRzYnZ0OwoJKCppcHBkc2IpLT5yZWYgPSAxOwoJKCppcHBkc2IpLT5kc291bmQgPSBUaGlzOwoJKCppcHBkc2IpLT5wYXJlbnQgPSBOVUxMOwoJKCppcHBkc2IpLT5idWZmZXIgPSBOVUxMOwoKCW1lbWNweSgmKCgqaXBwZHNiKS0+ZHNiZCksZHNiZCxzaXplb2YoKmRzYmQpKTsKCWlmIChkc2JkLT5scHdmeEZvcm1hdCkKCQltZW1jcHkoJigoKmlwcGRzYiktPndmeCksIGRzYmQtPmxwd2Z4Rm9ybWF0LCBzaXplb2YoKCppcHBkc2IpLT53ZngpKTsKCglUUkFDRSgiQ3JlYXRlZCBidWZmZXIgYXQgJXBcbiIsICppcHBkc2IpOwoKCWlmIChkc2JkLT5kd0ZsYWdzICYgRFNCQ0FQU19QUklNQVJZQlVGRkVSKSB7CgkJKCppcHBkc2IpLT5idWZsZW4gPSBkc291bmQtPndmeC5uQXZnQnl0ZXNQZXJTZWM7CgkJKCppcHBkc2IpLT5mcmVxID0gZHNvdW5kLT53ZngublNhbXBsZXNQZXJTZWM7CgoJCS8qIEZJWE1FOiB2ZXJpZnkgdGhhdCBoYXJkd2FyZSBjYXBhYmlsaXRpZXMgKERTQ0FQU19QUklNQVJZIGZsYWdzKSBtYXRjaCAqLwoKCQlpZiAoVGhpcy0+ZHJpdmVyKSB7CgkJCWVyciA9IElEc0RyaXZlcl9DcmVhdGVTb3VuZEJ1ZmZlcihUaGlzLT5kcml2ZXIsd2ZleCxkc2JkLT5kd0ZsYWdzLDAsCgkJCQkJCQkgICYoKCppcHBkc2IpLT5idWZsZW4pLCYoKCppcHBkc2IpLT5idWZmZXIpLAoJCQkJCQkJICAoTFBWT0lEKikmKCgqaXBwZHNiKS0+aHdidWYpKTsKCQl9CgkJaWYgKGVyciA9PSBEU19PSykKCQkJZXJyID0gRFNPVU5EX1ByaW1hcnlPcGVuKCppcHBkc2IpOwoJfSBlbHNlIHsKCQlEV09SRCBjYXBmID0gMDsKCQlpbnQgdXNlX2h3OwoKCQkoKmlwcGRzYiktPmJ1ZmxlbiA9IGRzYmQtPmR3QnVmZmVyQnl0ZXM7CgkJKCppcHBkc2IpLT5mcmVxID0gZHNiZC0+bHB3ZnhGb3JtYXQtPm5TYW1wbGVzUGVyU2VjOwoKCQkvKiBDaGVjayBuZWNlc3NhcnkgaGFyZHdhcmUgbWl4aW5nIGNhcGFiaWxpdGllcyAqLwoJCWlmICh3ZmV4LT5uQ2hhbm5lbHM9PTIpIGNhcGYgfD0gRFNDQVBTX1NFQ09OREFSWVNURVJFTzsKCQllbHNlIGNhcGYgfD0gRFNDQVBTX1NFQ09OREFSWU1PTk87CgkJaWYgKHdmZXgtPndCaXRzUGVyU2FtcGxlPT0xNikgY2FwZiB8PSBEU0NBUFNfU0VDT05EQVJZMTZCSVQ7CgkJZWxzZSBjYXBmIHw9IERTQ0FQU19TRUNPTkRBUlk4QklUOwoJCXVzZV9odyA9IChUaGlzLT5kcnZjYXBzLmR3RmxhZ3MgJiBjYXBmKSA9PSBjYXBmOwoKCQkvKiBGSVhNRTogY2hlY2sgaGFyZHdhcmUgc2FtcGxlIHJhdGUgbWl4aW5nIGNhcGFiaWxpdGllcyAqLwoJCS8qIEZJWE1FOiBjaGVjayBhcHAgaGludHMgZm9yIHNvZnR3YXJlL2hhcmR3YXJlIGJ1ZmZlciAoU1RBVElDLCBMT0NIQVJEV0FSRSwgZXRjKSAqLwoJCS8qIEZJWE1FOiBjaGVjayB3aGV0aGVyIGFueSBoYXJkd2FyZSBidWZmZXJzIGFyZSBsZWZ0ICovCgkJLyogRklYTUU6IGhhbmRsZSBEU0RIRUFQX0NSRUFURUhFQVAgZm9yIGhhcmR3YXJlIGJ1ZmZlcnMgKi8KCgkJLyogQWxsb2NhdGUgc3lzdGVtIG1lbW9yeSBpZiBhcHBsaWNhYmxlICovCgkJaWYgKChUaGlzLT5kcnZkZXNjLmR3RmxhZ3MgJiBEU0RERVNDX1VTRVNZU1RFTU1FTU9SWSkgfHwgIXVzZV9odykgewoJCQkoKmlwcGRzYiktPmJ1ZmZlciA9IChMUEJZVEUpSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksMCwoKmlwcGRzYiktPmJ1Zmxlbik7CgkJCWlmICgoKmlwcGRzYiktPmJ1ZmZlciA9PSBOVUxMKQoJCQkJZXJyID0gRFNFUlJfT1VUT0ZNRU1PUlk7CgkJfQoKCQkvKiBBbGxvY2F0ZSB0aGUgaGFyZHdhcmUgYnVmZmVyICovCgkJaWYgKHVzZV9odyAmJiAoZXJyID09IERTX09LKSkgewoJCQllcnIgPSBJRHNEcml2ZXJfQ3JlYXRlU291bmRCdWZmZXIoVGhpcy0+ZHJpdmVyLHdmZXgsZHNiZC0+ZHdGbGFncywwLAoJCQkJCQkJICAmKCgqaXBwZHNiKS0+YnVmbGVuKSwmKCgqaXBwZHNiKS0+YnVmZmVyKSwKCQkJCQkJCSAgKExQVk9JRCopJigoKmlwcGRzYiktPmh3YnVmKSk7CgkJfQoJfQoKCWlmIChlcnIgIT0gRFNfT0spIHsKCQlpZiAoKCppcHBkc2IpLT5idWZmZXIpCgkJCUhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCwoKmlwcGRzYiktPmJ1ZmZlcik7CgkJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLCgqaXBwZHNiKSk7CgkJKmlwcGRzYiA9IE5VTEw7CgkJcmV0dXJuIGVycjsKCX0KCS8qIGNhbGN1bGF0ZSBmcmFnbWVudCBzaXplIGFuZCB3cml0ZSBsZWFkICovCglEU09VTkRfUmVjYWxjRm9ybWF0KCppcHBkc2IpOwoKCS8qIEl0J3Mgbm90IG5lY2Vzc2FyeSB0byBpbml0aWFsaXplIHZhbHVlcyB0byB6ZXJvIHNpbmNlICovCgkvKiB3ZSBhbGxvY2F0ZWQgdGhpcyBzdHJ1Y3R1cmUgd2l0aCBIRUFQX1pFUk9fTUVNT1JZLi4uICovCgkoKmlwcGRzYiktPnBsYXlwb3MgPSAwOwoJKCppcHBkc2IpLT5idWZfbWl4cG9zID0gMDsKCSgqaXBwZHNiKS0+c3RhdGUgPSBTVEFURV9TVE9QUEVEOwoJRFNPVU5EX1JlY2FsY1ZvbFBhbigmKCgqaXBwZHNiKS0+dm9scGFuKSk7CgoJaWYgKCEoZHNiZC0+ZHdGbGFncyAmIERTQkNBUFNfUFJJTUFSWUJVRkZFUikpIHsKCQkoKmlwcGRzYiktPmZyZXFBZGp1c3QgPSAoKCppcHBkc2IpLT5mcmVxIDw8IERTT1VORF9GUkVRU0hJRlQpIC8KCQkJcHJpbWFyeWJ1Zi0+d2Z4Lm5TYW1wbGVzUGVyU2VjOwoJCSgqaXBwZHNiKS0+bkF2Z0J5dGVzUGVyU2VjID0gKCppcHBkc2IpLT5mcmVxICoKCQkJZHNiZC0+bHB3ZnhGb3JtYXQtPm5CbG9ja0FsaWduOwoJfQoKCUVudGVyQ3JpdGljYWxTZWN0aW9uKCYoVGhpcy0+bG9jaykpOwoJLyogcmVnaXN0ZXIgYnVmZmVyICovCglpZiAoIShkc2JkLT5kd0ZsYWdzICYgRFNCQ0FQU19QUklNQVJZQlVGRkVSKSkgewoJCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGwgKipuZXdidWZmZXJzID0gKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwqKilIZWFwUmVBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLDAsVGhpcy0+YnVmZmVycyxzaXplb2YoSURpcmVjdFNvdW5kQnVmZmVySW1wbCopKihUaGlzLT5ucm9mYnVmZmVycysxKSk7CgkJaWYgKG5ld2J1ZmZlcnMpIHsKCQkJVGhpcy0+YnVmZmVycyA9IG5ld2J1ZmZlcnM7CgkJCVRoaXMtPmJ1ZmZlcnNbVGhpcy0+bnJvZmJ1ZmZlcnNdID0gKmlwcGRzYjsKCQkJVGhpcy0+bnJvZmJ1ZmZlcnMrKzsKCQkJVFJBQ0UoImJ1ZmZlciBjb3VudCBpcyBub3cgJWRcbiIsIFRoaXMtPm5yb2ZidWZmZXJzKTsKCQl9IGVsc2UgewoJCQlFUlIoIm91dCBvZiBtZW1vcnkgZm9yIGJ1ZmZlciBsaXN0ISBDdXJyZW50IGJ1ZmZlciBjb3VudCBpcyAlZFxuIiwgVGhpcy0+bnJvZmJ1ZmZlcnMpOwoJCQllcnIgPSBEU0VSUl9PVVRPRk1FTU9SWTsKCQl9Cgl9CglMZWF2ZUNyaXRpY2FsU2VjdGlvbigmKFRoaXMtPmxvY2spKTsKCglJRGlyZWN0U291bmRfQWRkUmVmKGlmYWNlKTsKCglJbml0aWFsaXplQ3JpdGljYWxTZWN0aW9uKCYoKCppcHBkc2IpLT5sb2NrKSk7CgoJaWYgKGVyciAhPSBEU19PSykgewoJCS8qIG9vcHMuLi4gKi8KCQlJRGlyZWN0U291bmRCdWZmZXJfUmVsZWFzZSgqcHBkc2IpOwoJCSppcHBkc2IgPSBOVUxMOwoJCXJldHVybiBlcnI7Cgl9CgkKI2lmZGVmIFVTRV9EU09VTkQzRAoJaWYgKGRzYmQtPmR3RmxhZ3MgJiBEU0JDQVBTX0NUUkwzRCkgewoJCUlEaXJlY3RTb3VuZDNEQnVmZmVySW1wbAkqZHMzZGI7CgoJCWRzM2RiID0gKElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbCopSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksCgkJCTAsc2l6ZW9mKCpkczNkYikpOwoJCUlDT01fVlRCTChkczNkYikgPSAmZHMzZGJ2dDsKCQlkczNkYi0+cmVmID0gMTsKCQkoKmlwcGRzYiktPmRzM2RiID0gZHMzZGI7CgoJCWRzM2RiLT5kc2IgPSAoKmlwcGRzYik7CgkJSURpcmVjdFNvdW5kQnVmZmVySW1wbF9BZGRSZWYoKExQRElSRUNUU09VTkRCVUZGRVIpKCppcHBkc2IpKTsKCgkJSW5pdGlhbGl6ZUNyaXRpY2FsU2VjdGlvbigmZHMzZGItPmxvY2spOwoKCQlkczNkYi0+ZHMzZGIuZHdTaXplID0gc2l6ZW9mKERTM0RCVUZGRVIpOwoJCWRzM2RiLT5kczNkYi52UG9zaXRpb24udTEueCA9IDAuMDsKCQlkczNkYi0+ZHMzZGIudlBvc2l0aW9uLnUyLnkgPSAwLjA7CgkJZHMzZGItPmRzM2RiLnZQb3NpdGlvbi51My56ID0gMC4wOwoJCWRzM2RiLT5kczNkYi52VmVsb2NpdHkudTEueCA9IDAuMDsKCQlkczNkYi0+ZHMzZGIudlZlbG9jaXR5LnUyLnkgPSAwLjA7CgkJZHMzZGItPmRzM2RiLnZWZWxvY2l0eS51My56ID0gMC4wOwoJCWRzM2RiLT5kczNkYi5kd0luc2lkZUNvbmVBbmdsZSA9IERTM0RfREVGQVVMVENPTkVBTkdMRTsKCQlkczNkYi0+ZHMzZGIuZHdPdXRzaWRlQ29uZUFuZ2xlID0gRFMzRF9ERUZBVUxUQ09ORUFOR0xFOwoJCWRzM2RiLT5kczNkYi52Q29uZU9yaWVudGF0aW9uLnUxLnggPSAwLjA7CgkJZHMzZGItPmRzM2RiLnZDb25lT3JpZW50YXRpb24udTIueSA9IDAuMDsKCQlkczNkYi0+ZHMzZGIudkNvbmVPcmllbnRhdGlvbi51My56ID0gMC4wOwoJCWRzM2RiLT5kczNkYi5sQ29uZU91dHNpZGVWb2x1bWUgPSBEUzNEX0RFRkFVTFRDT05FT1VUU0lERVZPTFVNRTsKCQlkczNkYi0+ZHMzZGIuZmxNaW5EaXN0YW5jZSA9IERTM0RfREVGQVVMVE1JTkRJU1RBTkNFOwoJCWRzM2RiLT5kczNkYi5mbE1heERpc3RhbmNlID0gRFMzRF9ERUZBVUxUTUFYRElTVEFOQ0U7CgkJZHMzZGItPmRzM2RiLmR3TW9kZSA9IERTM0RNT0RFX05PUk1BTDsKCQlkczNkYi0+YnVmbGVuID0gKCgqaXBwZHNiKS0+YnVmbGVuICogcHJpbWFyeWJ1Zi0+d2Z4Lm5CbG9ja0FsaWduKSAvCgkJCSgqaXBwZHNiKS0+d2Z4Lm5CbG9ja0FsaWduOwoJCWRzM2RiLT5idWZmZXIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZHMzZGItPmJ1Zmxlbik7CgkJaWYgKGRzM2RiLT5idWZmZXIgPT0gTlVMTCkgewoJCQlkczNkYi0+YnVmbGVuID0gMDsKCQkJZHMzZGItPmRzM2RiLmR3TW9kZSA9IERTM0RNT0RFX0RJU0FCTEU7CgkJfQoJCWRzM2RiLT5pa3MgPSAoSUtzUHJvcGVydHlTZXRJbXBsKilIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwwLHNpemVvZigqKGRzM2RiLT5pa3MpKSk7CgkJZHMzZGItPmlrcy0+cmVmID0gMTsKCQlkczNkYi0+aWtzLT5kczNkYiA9IGRzM2RiOwoJCUlDT01fVlRCTChkczNkYi0+aWtzKSA9ICZpa3N2dDsKCgl9CiNlbmRpZgoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kSW1wbF9EdXBsaWNhdGVTb3VuZEJ1ZmZlcigKCUxQRElSRUNUU09VTkQgaWZhY2UsTFBESVJFQ1RTT1VOREJVRkZFUiBwZHNiLExQTFBESVJFQ1RTT1VOREJVRkZFUiBwcGRzYgopIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRJbXBsLGlmYWNlKTsKCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGwqIGlwZHNiPShJRGlyZWN0U291bmRCdWZmZXJJbXBsKilwZHNiOwoJSURpcmVjdFNvdW5kQnVmZmVySW1wbCoqIGlwcGRzYj0oSURpcmVjdFNvdW5kQnVmZmVySW1wbCoqKXBwZHNiOwoJVFJBQ0UoIiglcCwlcCwlcClcbiIsVGhpcyxpcGRzYixpcHBkc2IpOwoKCWlmIChpcGRzYi0+aHdidWYpIHsKCQlGSVhNRSgibmVlZCB0byBkdXBsaWNhdGUgaGFyZHdhcmUgYnVmZmVyXG4iKTsKCX0KCgkqaXBwZHNiID0gKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwqKUhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLEhFQVBfWkVST19NRU1PUlksc2l6ZW9mKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwpKTsKCglJRGlyZWN0U291bmRCdWZmZXJfQWRkUmVmKHBkc2IpOwoJbWVtY3B5KCppcHBkc2IsIGlwZHNiLCBzaXplb2YoSURpcmVjdFNvdW5kQnVmZmVySW1wbCkpOwoJKCppcHBkc2IpLT5yZWYgPSAxOwoJKCppcHBkc2IpLT5zdGF0ZSA9IFNUQVRFX1NUT1BQRUQ7CgkoKmlwcGRzYiktPnBsYXlwb3MgPSAwOwoJKCppcHBkc2IpLT5idWZfbWl4cG9zID0gMDsKCSgqaXBwZHNiKS0+ZHNvdW5kID0gVGhpczsKCSgqaXBwZHNiKS0+cGFyZW50ID0gaXBkc2I7CgltZW1jcHkoJigoKmlwcGRzYiktPndmeCksICYoaXBkc2ItPndmeCksIHNpemVvZigoKmlwcGRzYiktPndmeCkpOwoJSW5pdGlhbGl6ZUNyaXRpY2FsU2VjdGlvbigmKCppcHBkc2IpLT5sb2NrKTsKCS8qIHJlZ2lzdGVyIGJ1ZmZlciAqLwoJRW50ZXJDcml0aWNhbFNlY3Rpb24oJihUaGlzLT5sb2NrKSk7Cgl7CgkJSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqKm5ld2J1ZmZlcnMgPSAoSURpcmVjdFNvdW5kQnVmZmVySW1wbCoqKUhlYXBSZUFsbG9jKEdldFByb2Nlc3NIZWFwKCksMCxUaGlzLT5idWZmZXJzLHNpemVvZihJRGlyZWN0U291bmRCdWZmZXJJbXBsKiopKihUaGlzLT5ucm9mYnVmZmVycysxKSk7CgkJaWYgKG5ld2J1ZmZlcnMpIHsKCQkJVGhpcy0+YnVmZmVycyA9IG5ld2J1ZmZlcnM7CgkJCVRoaXMtPmJ1ZmZlcnNbVGhpcy0+bnJvZmJ1ZmZlcnNdID0gKmlwcGRzYjsKCQkJVGhpcy0+bnJvZmJ1ZmZlcnMrKzsKCQkJVFJBQ0UoImJ1ZmZlciBjb3VudCBpcyBub3cgJWRcbiIsIFRoaXMtPm5yb2ZidWZmZXJzKTsKCQl9IGVsc2UgewoJCQlFUlIoIm91dCBvZiBtZW1vcnkgZm9yIGJ1ZmZlciBsaXN0ISBDdXJyZW50IGJ1ZmZlciBjb3VudCBpcyAlZFxuIiwgVGhpcy0+bnJvZmJ1ZmZlcnMpOwoJCQkvKiBGSVhNRTogcmVsZWFzZSBidWZmZXIgKi8KCQl9Cgl9CglMZWF2ZUNyaXRpY2FsU2VjdGlvbigmKFRoaXMtPmxvY2spKTsKCUlEaXJlY3RTb3VuZF9BZGRSZWYoaWZhY2UpOwoJcmV0dXJuIERTX09LOwp9CgoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZEltcGxfR2V0Q2FwcyhMUERJUkVDVFNPVU5EIGlmYWNlLExQRFNDQVBTIGNhcHMpIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRJbXBsLGlmYWNlKTsKCVRSQUNFKCIoJXAsJXApXG4iLFRoaXMsY2Fwcyk7CglUUkFDRSgiKGZsYWdzPTB4JTA4bHgpXG4iLGNhcHMtPmR3RmxhZ3MpOwoKCWlmIChjYXBzID09IE5VTEwpCgkJcmV0dXJuIERTRVJSX0lOVkFMSURQQVJBTTsKCgkvKiBXZSBzaG91bGQgY2hlY2sgdGhpcyB2YWx1ZSwgbm90IHNldCBpdC4gU2VlIEluc2lkZSBEaXJlY3RYLCBwMjE1LiAqLwoJY2Fwcy0+ZHdTaXplID0gc2l6ZW9mKCpjYXBzKTsKCgljYXBzLT5kd0ZsYWdzID0gVGhpcy0+ZHJ2Y2Fwcy5kd0ZsYWdzOwoKCS8qIEZJWE1FOiBjb3B5IGNhcHMgZnJvbSBUaGlzLT5kcnZjYXBzICovCgljYXBzLT5kd01pblNlY29uZGFyeVNhbXBsZVJhdGUJCT0gRFNCRlJFUVVFTkNZX01JTjsKCWNhcHMtPmR3TWF4U2Vjb25kYXJ5U2FtcGxlUmF0ZQkJPSBEU0JGUkVRVUVOQ1lfTUFYOwoKCWNhcHMtPmR3UHJpbWFyeUJ1ZmZlcnMJCQk9IDE7CgoJY2Fwcy0+ZHdNYXhId01peGluZ0FsbEJ1ZmZlcnMJCT0gMDsKCWNhcHMtPmR3TWF4SHdNaXhpbmdTdGF0aWNCdWZmZXJzCT0gMDsKCWNhcHMtPmR3TWF4SHdNaXhpbmdTdHJlYW1pbmdCdWZmZXJzCT0gMDsKCgljYXBzLT5kd0ZyZWVId01peGluZ0FsbEJ1ZmZlcnMJCT0gMDsKCWNhcHMtPmR3RnJlZUh3TWl4aW5nU3RhdGljQnVmZmVycwk9IDA7CgljYXBzLT5kd0ZyZWVId01peGluZ1N0cmVhbWluZ0J1ZmZlcnMJPSAwOwoKCWNhcHMtPmR3TWF4SHczREFsbEJ1ZmZlcnMJCT0gMDsKCWNhcHMtPmR3TWF4SHczRFN0YXRpY0J1ZmZlcnMJCT0gMDsKCWNhcHMtPmR3TWF4SHczRFN0cmVhbWluZ0J1ZmZlcnMJCT0gMDsKCgljYXBzLT5kd0ZyZWVIdzNEQWxsQnVmZmVycwkJPSAwOwoJY2Fwcy0+ZHdGcmVlSHczRFN0YXRpY0J1ZmZlcnMJCT0gMDsKCWNhcHMtPmR3RnJlZUh3M0RTdHJlYW1pbmdCdWZmZXJzCT0gMDsKCgljYXBzLT5kd1RvdGFsSHdNZW1CeXRlcwkJCT0gMDsKCgljYXBzLT5kd0ZyZWVId01lbUJ5dGVzCQkJPSAwOwoKCWNhcHMtPmR3TWF4Q29udGlnRnJlZUh3TWVtQnl0ZXMJCT0gMDsKCgljYXBzLT5kd1VubG9ja1RyYW5zZmVyUmF0ZUh3QnVmZmVycwk9IDQwOTY7CS8qIEJ1dCB3ZSBoYXZlIG5vbmUuLi4gKi8KCgljYXBzLT5kd1BsYXlDcHVPdmVyaGVhZFN3QnVmZmVycwk9IDE7CS8qIDElICovCgoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIElEaXJlY3RTb3VuZEltcGxfQWRkUmVmKExQRElSRUNUU09VTkQgaWZhY2UpIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRJbXBsLGlmYWNlKTsKCXJldHVybiArKyhUaGlzLT5yZWYpOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIElEaXJlY3RTb3VuZEltcGxfUmVsZWFzZShMUERJUkVDVFNPVU5EIGlmYWNlKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kSW1wbCxpZmFjZSk7CglUUkFDRSgiKCVwKSwgcmVmIHdhcyAlbGRcbiIsVGhpcyxUaGlzLT5yZWYpOwoJaWYgKCEtLShUaGlzLT5yZWYpKSB7CgkJVUlOVCBpOwoKCQl0aW1lS2lsbEV2ZW50KFRoaXMtPnRpbWVySUQpOwoJCXRpbWVFbmRQZXJpb2QoRFNfVElNRV9SRVMpOwoKCQlpZiAocHJpbWFyeWJ1ZikKCQkJSURpcmVjdFNvdW5kQnVmZmVyX1JlbGVhc2UoKExQRElSRUNUU09VTkRCVUZGRVIpcHJpbWFyeWJ1Zik7CgoJCWlmIChUaGlzLT5idWZmZXJzKSB7CgkJCWZvciggaT0wO2k8VGhpcy0+bnJvZmJ1ZmZlcnM7aSsrKQkKCQkJCUlEaXJlY3RTb3VuZEJ1ZmZlcl9SZWxlYXNlKChMUERJUkVDVFNPVU5EQlVGRkVSKVRoaXMtPmJ1ZmZlcnNbaV0pOwoJCX0KCgkJaWYgKFRoaXMtPnByaW1hcnkpCgkJCUlEaXJlY3RTb3VuZEJ1ZmZlcl9SZWxlYXNlKChMUERJUkVDVFNPVU5EQlVGRkVSKVRoaXMtPnByaW1hcnkpOwoKCQlEZWxldGVDcml0aWNhbFNlY3Rpb24oJlRoaXMtPmxvY2spOwoJCWlmIChUaGlzLT5kcml2ZXIpIHsKCQkJSURzRHJpdmVyX0Nsb3NlKFRoaXMtPmRyaXZlcik7CgkJfSBlbHNlIHsKCQkJdW5zaWduZWQgYzsKCQkJZm9yIChjPTA7IGM8RFNfSEVMX0ZSQUdTOyBjKyspCgkJCQlIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsVGhpcy0+cHdhdmVbY10pOwoJCX0KCQlpZiAoVGhpcy0+ZHJ2ZGVzYy5kd0ZsYWdzICYgRFNEREVTQ19ET01NU1lTVEVNT1BFTikgewoJCQl3YXZlT3V0Q2xvc2UoVGhpcy0+aHdvKTsKCQl9CgkJaWYgKFRoaXMtPmRyaXZlcikKCQkJSURzRHJpdmVyX1JlbGVhc2UoVGhpcy0+ZHJpdmVyKTsKCgkJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLFRoaXMpOwoJCWRzb3VuZCA9IE5VTEw7CgkJcmV0dXJuIDA7Cgl9CglyZXR1cm4gVGhpcy0+cmVmOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kSW1wbF9TZXRTcGVha2VyQ29uZmlnKAoJTFBESVJFQ1RTT1VORCBpZmFjZSxEV09SRCBjb25maWcKKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kSW1wbCxpZmFjZSk7CglGSVhNRSgiKCVwLDB4JTA4bHgpOnN0dWJcbiIsVGhpcyxjb25maWcpOwoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kSW1wbF9RdWVyeUludGVyZmFjZSgKCUxQRElSRUNUU09VTkQgaWZhY2UsUkVGSUlEIHJpaWQsTFBWT0lEICpwcG9iagopIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRJbXBsLGlmYWNlKTsKCglpZiAoIElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3RTb3VuZDNETGlzdGVuZXIsIHJpaWQgKSApIHsKCgkJaWYgKFRoaXMtPmxpc3RlbmVyKSB7CgkJCSpwcG9iaiA9IFRoaXMtPmxpc3RlbmVyOwoJCQlJRGlyZWN0U291bmQzRExpc3RlbmVyX0FkZFJlZigoTFBESVJFQ1RTT1VORDNETElTVEVORVIpVGhpcy0+bGlzdGVuZXIpOwoJCQlyZXR1cm4gRFNfT0s7CgkJfQoKCQlUaGlzLT5saXN0ZW5lciA9IChJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbCopSGVhcEFsbG9jKAoJCQlHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoKihUaGlzLT5saXN0ZW5lcikpKTsKCQlUaGlzLT5saXN0ZW5lci0+cmVmID0gMTsKCQlJQ09NX1ZUQkwoVGhpcy0+bGlzdGVuZXIpID0gJmRzM2RsdnQ7CgkJKnBwb2JqID0gKExQVk9JRClUaGlzLT5saXN0ZW5lcjsKCQlJRGlyZWN0U291bmQzRExpc3RlbmVyX0FkZFJlZigoTFBESVJFQ1RTT1VORDNETElTVEVORVIpKnBwb2JqKTsJCgoJCVRoaXMtPmxpc3RlbmVyLT5kc2IgPSBOVUxMOyAKCgkJVGhpcy0+bGlzdGVuZXItPmRzM2RsLmR3U2l6ZSA9IHNpemVvZihEUzNETElTVEVORVIpOwoJCVRoaXMtPmxpc3RlbmVyLT5kczNkbC52UG9zaXRpb24udTEueCA9IDAuMDsKCQlUaGlzLT5saXN0ZW5lci0+ZHMzZGwudlBvc2l0aW9uLnUyLnkgPSAwLjA7CgkJVGhpcy0+bGlzdGVuZXItPmRzM2RsLnZQb3NpdGlvbi51My56ID0gMC4wOwoJCVRoaXMtPmxpc3RlbmVyLT5kczNkbC52VmVsb2NpdHkudTEueCA9IDAuMDsKCQlUaGlzLT5saXN0ZW5lci0+ZHMzZGwudlZlbG9jaXR5LnUyLnkgPSAwLjA7CgkJVGhpcy0+bGlzdGVuZXItPmRzM2RsLnZWZWxvY2l0eS51My56ID0gMC4wOwoJCVRoaXMtPmxpc3RlbmVyLT5kczNkbC52T3JpZW50RnJvbnQudTEueCA9IDAuMDsKCQlUaGlzLT5saXN0ZW5lci0+ZHMzZGwudk9yaWVudEZyb250LnUyLnkgPSAwLjA7CgkJVGhpcy0+bGlzdGVuZXItPmRzM2RsLnZPcmllbnRGcm9udC51My56ID0gMS4wOwoJCVRoaXMtPmxpc3RlbmVyLT5kczNkbC52T3JpZW50VG9wLnUxLnggPSAwLjA7CgkJVGhpcy0+bGlzdGVuZXItPmRzM2RsLnZPcmllbnRUb3AudTIueSA9IDEuMDsKCQlUaGlzLT5saXN0ZW5lci0+ZHMzZGwudk9yaWVudFRvcC51My56ID0gMC4wOwoJCVRoaXMtPmxpc3RlbmVyLT5kczNkbC5mbERpc3RhbmNlRmFjdG9yID0gRFMzRF9ERUZBVUxURElTVEFOQ0VGQUNUT1I7CgkJVGhpcy0+bGlzdGVuZXItPmRzM2RsLmZsUm9sbG9mZkZhY3RvciA9IERTM0RfREVGQVVMVFJPTExPRkZGQUNUT1I7CgkJVGhpcy0+bGlzdGVuZXItPmRzM2RsLmZsRG9wcGxlckZhY3RvciA9IERTM0RfREVGQVVMVERPUFBMRVJGQUNUT1I7CgoJCUluaXRpYWxpemVDcml0aWNhbFNlY3Rpb24oJlRoaXMtPmxpc3RlbmVyLT5sb2NrKTsKCgkJcmV0dXJuIERTX09LOwoJfQoKCUZJWE1FKCIoJXAsJXMsJXApXG4iLFRoaXMsZGVidWdzdHJfZ3VpZChyaWlkKSxwcG9iaik7CglyZXR1cm4gRV9GQUlMOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kSW1wbF9Db21wYWN0KAoJTFBESVJFQ1RTT1VORCBpZmFjZSkKewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEltcGwsaWZhY2UpOwoJVFJBQ0UoIiglcClcbiIsIFRoaXMpOwoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kSW1wbF9HZXRTcGVha2VyQ29uZmlnKAoJTFBESVJFQ1RTT1VORCBpZmFjZSwKCUxQRFdPUkQgbHBkd1NwZWFrZXJDb25maWcpCnsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRJbXBsLGlmYWNlKTsKCVRSQUNFKCIoJXAsICVwKVxuIiwgVGhpcywgbHBkd1NwZWFrZXJDb25maWcpOwoJKmxwZHdTcGVha2VyQ29uZmlnID0gRFNTUEVBS0VSX1NURVJFTyB8IChEU1NQRUFLRVJfR0VPTUVUUllfTkFSUk9XIDw8IDE2KTsKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZEltcGxfSW5pdGlhbGl6ZSgKCUxQRElSRUNUU09VTkQgaWZhY2UsCglMUENHVUlEIGxwY0d1aWQpCnsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRJbXBsLGlmYWNlKTsKCVRSQUNFKCIoJXAsICVwKVxuIiwgVGhpcywgbHBjR3VpZCk7CglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBJQ09NX1ZUQUJMRShJRGlyZWN0U291bmQpIGRzdnQgPSAKewoJSUNPTV9NU1ZUQUJMRV9DT01QQVRfRHVtbXlSVFRJVkFMVUUKCUlEaXJlY3RTb3VuZEltcGxfUXVlcnlJbnRlcmZhY2UsCglJRGlyZWN0U291bmRJbXBsX0FkZFJlZiwKCUlEaXJlY3RTb3VuZEltcGxfUmVsZWFzZSwKCUlEaXJlY3RTb3VuZEltcGxfQ3JlYXRlU291bmRCdWZmZXIsCglJRGlyZWN0U291bmRJbXBsX0dldENhcHMsCglJRGlyZWN0U291bmRJbXBsX0R1cGxpY2F0ZVNvdW5kQnVmZmVyLAoJSURpcmVjdFNvdW5kSW1wbF9TZXRDb29wZXJhdGl2ZUxldmVsLAoJSURpcmVjdFNvdW5kSW1wbF9Db21wYWN0LAoJSURpcmVjdFNvdW5kSW1wbF9HZXRTcGVha2VyQ29uZmlnLAoJSURpcmVjdFNvdW5kSW1wbF9TZXRTcGVha2VyQ29uZmlnLAoJSURpcmVjdFNvdW5kSW1wbF9Jbml0aWFsaXplCn07CgoKc3RhdGljIHZvaWQgRFNPVU5EX0NoZWNrRXZlbnQoSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiLCBpbnQgbGVuKQp7CglpbnQJCQlpOwoJRFdPUkQJCQlvZmZzZXQ7CglMUERTQlBPU0lUSU9OTk9USUZZCWV2ZW50OwoKCWlmIChkc2ItPm5yb2Zub3RpZmllcyA9PSAwKQoJCXJldHVybjsKCglUUkFDRSgiKCVwKSBidWZsZW4gPSAlbGQsIHBsYXlwb3MgPSAlbGQsIGxlbiA9ICVkXG4iLAoJCWRzYiwgZHNiLT5idWZsZW4sIGRzYi0+cGxheXBvcywgbGVuKTsKCWZvciAoaSA9IDA7IGkgPCBkc2ItPm5yb2Zub3RpZmllcyA7IGkrKykgewoJCWV2ZW50ID0gZHNiLT5ub3RpZmllcyArIGk7CgkJb2Zmc2V0ID0gZXZlbnQtPmR3T2Zmc2V0OwoJCVRSQUNFKCJjaGVja2luZyAlZCwgcG9zaXRpb24gJWxkLCBldmVudCA9ICVkXG4iLAoJCQlpLCBvZmZzZXQsIGV2ZW50LT5oRXZlbnROb3RpZnkpOwoJCS8qIERTQlBOX09GRlNFVFNUT1AgaGFzIHRvIGJlIHRoZSBsYXN0IGVsZW1lbnQuIFNvIHRoaXMgaXMgKi8KCQkvKiBPSy4gW0luc2lkZSBEaXJlY3RYLCBwMjc0XSAqLwoJCS8qICAqLwoJCS8qIFRoaXMgYWxzbyBtZWFucyB3ZSBjYW4ndCBzb3J0IHRoZSBlbnRyaWVzIGJ5IG9mZnNldCwgKi8KCQkvKiBiZWNhdXNlIERTQlBOX09GRlNFVFNUT1AgPT0gLTEgKi8KCQlpZiAob2Zmc2V0ID09IERTQlBOX09GRlNFVFNUT1ApIHsKCQkJaWYgKGRzYi0+c3RhdGUgPT0gU1RBVEVfU1RPUFBFRCkgewoJCQkJU2V0RXZlbnQoZXZlbnQtPmhFdmVudE5vdGlmeSk7CgkJCQlUUkFDRSgic2lnbmFsbGVkIGV2ZW50ICVkICglZClcbiIsIGV2ZW50LT5oRXZlbnROb3RpZnksIGkpOwoJCQkJcmV0dXJuOwoJCQl9IGVsc2UKCQkJCXJldHVybjsKCQl9CgkJaWYgKChkc2ItPnBsYXlwb3MgKyBsZW4pID49IGRzYi0+YnVmbGVuKSB7CgkJCWlmICgob2Zmc2V0IDwgKChkc2ItPnBsYXlwb3MgKyBsZW4pICUgZHNiLT5idWZsZW4pKSB8fAoJCQkgICAgKG9mZnNldCA+PSBkc2ItPnBsYXlwb3MpKSB7CgkJCQlUUkFDRSgic2lnbmFsbGVkIGV2ZW50ICVkICglZClcbiIsIGV2ZW50LT5oRXZlbnROb3RpZnksIGkpOwoJCQkJU2V0RXZlbnQoZXZlbnQtPmhFdmVudE5vdGlmeSk7CgkJCX0KCQl9IGVsc2UgewoJCQlpZiAoKG9mZnNldCA+PSBkc2ItPnBsYXlwb3MpICYmIChvZmZzZXQgPCAoZHNiLT5wbGF5cG9zICsgbGVuKSkpIHsKCQkJCVRSQUNFKCJzaWduYWxsZWQgZXZlbnQgJWQgKCVkKVxuIiwgZXZlbnQtPmhFdmVudE5vdGlmeSwgaSk7CgkJCQlTZXRFdmVudChldmVudC0+aEV2ZW50Tm90aWZ5KTsKCQkJfQoJCX0KCX0KfQoKLyogV0FWIGZvcm1hdCBpbmZvIGNhbiBiZSBmb3VuZCBhdDogKi8KLyogKi8KLyoJaHR0cDovL3d3dy5jd2kubmwvZnRwL2F1ZGlvL0F1ZGlvRm9ybWF0cy5wYXJ0MiAqLwovKglmdHA6Ly9mdHAuY3dpLm5sL3B1Yi9hdWRpby9SSUZGLWZvcm1hdCAqLwovKiAqLwovKiBJbXBvcnQgcG9pbnRzIHRvIHJlbWVtYmVyOiAqLwovKiAqLwovKgk4LWJpdCBXQVYgaXMgdW5zaWduZWQgKi8KLyoJMTYtYml0IFdBViBpcyBzaWduZWQgKi8KCnN0YXRpYyBpbmxpbmUgSU5UMTYgY3Z0VTh0b1MxNihCWVRFIGJ5dGUpCnsKCUlOVDE2CXMgPSAoYnl0ZSAtIDEyOCkgPDwgODsKCglyZXR1cm4gczsKfQoKc3RhdGljIGlubGluZSBCWVRFIGN2dFMxNnRvVTgoSU5UMTYgd29yZCkKewoJQllURQliID0gKHdvcmQgKyAzMjc2OCkgPj4gODsKCQoJcmV0dXJuIGI7Cn0KCgovKiBXZSBzaG91bGQgYmUgYWJsZSB0byBvcHRpbWl6ZSB0aGVzZSB0d28gaW5saW5lIGZ1bmN0aW9ucyAqLwovKiBzbyB0aGF0IHdlIGFyZW4ndCBkb2luZyA4LT4xNi0+OCBjb252ZXJzaW9ucyB3aGVuIGl0IGlzICovCi8qIG5vdCBuZWNlc3NhcnkuIEJ1dCB0aGlzIGlzIHN0aWxsIGEgV0lQLiBPcHRpbWl6ZSBsYXRlci4gKi8Kc3RhdGljIGlubGluZSB2b2lkIGdldF9maWVsZHMoY29uc3QgSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiLCBCWVRFICpidWYsIElOVCAqZmwsIElOVCAqZnIpCnsKCUlOVDE2CSpidWZzID0gKElOVDE2ICopIGJ1ZjsKCgkvKiBUUkFDRSgiKCVwKVxuIiwgYnVmKTsgKi8KCWlmICgoZHNiLT53Zngud0JpdHNQZXJTYW1wbGUgPT0gOCkgJiYgZHNiLT53ZngubkNoYW5uZWxzID09IDIpIHsKCQkqZmwgPSBjdnRVOHRvUzE2KCpidWYpOwoJCSpmciA9IGN2dFU4dG9TMTYoKihidWYgKyAxKSk7CgkJcmV0dXJuOwoJfQoKCWlmICgoZHNiLT53Zngud0JpdHNQZXJTYW1wbGUgPT0gMTYpICYmIGRzYi0+d2Z4Lm5DaGFubmVscyA9PSAyKSB7CgkJKmZsID0gKmJ1ZnM7CgkJKmZyID0gKihidWZzICsgMSk7CgkJcmV0dXJuOwoJfQoKCWlmICgoZHNiLT53Zngud0JpdHNQZXJTYW1wbGUgPT0gOCkgJiYgZHNiLT53ZngubkNoYW5uZWxzID09IDEpIHsKCQkqZmwgPSBjdnRVOHRvUzE2KCpidWYpOwoJCSpmciA9ICpmbDsKCQlyZXR1cm47Cgl9CgoJaWYgKChkc2ItPndmeC53Qml0c1BlclNhbXBsZSA9PSAxNikgJiYgZHNiLT53ZngubkNoYW5uZWxzID09IDEpIHsKCQkqZmwgPSAqYnVmczsKCQkqZnIgPSAqYnVmczsKCQlyZXR1cm47Cgl9CgoJRklYTUUoImdldF9maWVsZHMgZm91bmQgYW4gdW5zdXBwb3J0ZWQgY29uZmlndXJhdGlvblxuIik7CglyZXR1cm47Cn0KCnN0YXRpYyBpbmxpbmUgdm9pZCBzZXRfZmllbGRzKEJZVEUgKmJ1ZiwgSU5UIGZsLCBJTlQgZnIpCnsKCUlOVDE2ICpidWZzID0gKElOVDE2ICopIGJ1ZjsKCglpZiAoKHByaW1hcnlidWYtPndmeC53Qml0c1BlclNhbXBsZSA9PSA4KSAmJiAocHJpbWFyeWJ1Zi0+d2Z4Lm5DaGFubmVscyA9PSAyKSkgewoJCSpidWYgPSBjdnRTMTZ0b1U4KGZsKTsKCQkqKGJ1ZiArIDEpID0gY3Z0UzE2dG9VOChmcik7CgkJcmV0dXJuOwoJfQoKCWlmICgocHJpbWFyeWJ1Zi0+d2Z4LndCaXRzUGVyU2FtcGxlID09IDE2KSAmJiAocHJpbWFyeWJ1Zi0+d2Z4Lm5DaGFubmVscyA9PSAyKSkgewoJCSpidWZzID0gZmw7CgkJKihidWZzICsgMSkgPSBmcjsKCQlyZXR1cm47Cgl9CgoJaWYgKChwcmltYXJ5YnVmLT53Zngud0JpdHNQZXJTYW1wbGUgPT0gOCkgJiYgKHByaW1hcnlidWYtPndmeC5uQ2hhbm5lbHMgPT0gMSkpIHsKCQkqYnVmID0gY3Z0UzE2dG9VOCgoZmwgKyBmcikgPj4gMSk7CgkJcmV0dXJuOwoJfQoKCWlmICgocHJpbWFyeWJ1Zi0+d2Z4LndCaXRzUGVyU2FtcGxlID09IDE2KSAmJiAocHJpbWFyeWJ1Zi0+d2Z4Lm5DaGFubmVscyA9PSAxKSkgewoJCSpidWZzID0gKGZsICsgZnIpID4+IDE7CgkJcmV0dXJuOwoJfQoJRklYTUUoInNldF9maWVsZHMgZm91bmQgYW4gdW5zdXBwb3J0ZWQgY29uZmlndXJhdGlvblxuIik7CglyZXR1cm47Cn0KCi8qIE5vdyB3aXRoIFBlcmZlY3RQaXRjaCAodG0pIHRlY2hub2xvZ3kgKi8Kc3RhdGljIElOVCBEU09VTkRfTWl4ZXJOb3JtKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwgKmRzYiwgQllURSAqYnVmLCBJTlQgbGVuKQp7CglJTlQJaSwgc2l6ZSwgaXBvcywgaWxlbiwgZmllbGRMLCBmaWVsZFI7CglCWVRFCSppYnAsICpvYnA7CglJTlQJaUFkdmFuY2UgPSBkc2ItPndmeC5uQmxvY2tBbGlnbjsKCUlOVAlvQWR2YW5jZSA9IHByaW1hcnlidWYtPndmeC5uQmxvY2tBbGlnbjsKCglpYnAgPSBkc2ItPmJ1ZmZlciArIGRzYi0+YnVmX21peHBvczsKCW9icCA9IGJ1ZjsKCglUUkFDRSgiKCVwLCAlcCwgJXApLCBidWZfbWl4cG9zPSVsZFxuIiwgZHNiLCBpYnAsIG9icCwgZHNiLT5idWZfbWl4cG9zKTsKCS8qIENoZWNrIGZvciB0aGUgYmVzdCBjYXNlICovCglpZiAoKGRzYi0+ZnJlcSA9PSBwcmltYXJ5YnVmLT53ZngublNhbXBsZXNQZXJTZWMpICYmCgkgICAgKGRzYi0+d2Z4LndCaXRzUGVyU2FtcGxlID09IHByaW1hcnlidWYtPndmeC53Qml0c1BlclNhbXBsZSkgJiYKCSAgICAoZHNiLT53ZngubkNoYW5uZWxzID09IHByaW1hcnlidWYtPndmeC5uQ2hhbm5lbHMpKSB7CgkgICAgICAgIERXT1JEIGJ5dGVzbGVmdCA9IGRzYi0+YnVmbGVuIC0gZHNiLT5idWZfbWl4cG9zOwoJCVRSQUNFKCIoJXApIEJlc3QgY2FzZVxuIiwgZHNiKTsKCSAgICAJaWYgKGxlbiA8PSBieXRlc2xlZnQgKQoJCQltZW1jcHkob2JwLCBpYnAsIGxlbik7CgkJZWxzZSB7IC8qIHdyYXAgKi8KCQkJbWVtY3B5KG9icCwgaWJwLCBieXRlc2xlZnQgKTsKCQkJbWVtY3B5KG9icCArIGJ5dGVzbGVmdCwgZHNiLT5idWZmZXIsIGxlbiAtIGJ5dGVzbGVmdCk7CgkJfQoJCXJldHVybiBsZW47Cgl9CgkKCS8qIENoZWNrIGZvciBzYW1lIHNhbXBsZSByYXRlICovCglpZiAoZHNiLT5mcmVxID09IHByaW1hcnlidWYtPndmeC5uU2FtcGxlc1BlclNlYykgewoJCVRSQUNFKCIoJXApIFNhbWUgc2FtcGxlIHJhdGUgJWxkID0gcHJpbWFyeSAlbGRcbiIsIGRzYiwKCQkJZHNiLT5mcmVxLCBwcmltYXJ5YnVmLT53ZngublNhbXBsZXNQZXJTZWMpOwoJCWlsZW4gPSAwOwoJCWZvciAoaSA9IDA7IGkgPCBsZW47IGkgKz0gb0FkdmFuY2UpIHsKCQkJZ2V0X2ZpZWxkcyhkc2IsIGlicCwgJmZpZWxkTCwgJmZpZWxkUik7CgkJCWlicCArPSBpQWR2YW5jZTsKCQkJaWxlbiArPSBpQWR2YW5jZTsKCQkJc2V0X2ZpZWxkcyhvYnAsIGZpZWxkTCwgZmllbGRSKTsKCQkJb2JwICs9IG9BZHZhbmNlOwoJCQlpZiAoaWJwID49IChCWVRFICopKGRzYi0+YnVmZmVyICsgZHNiLT5idWZsZW4pKQoJCQkJaWJwID0gZHNiLT5idWZmZXI7CS8qIHdyYXAgKi8KCQl9CgkJcmV0dXJuIChpbGVuKTsJCgl9CgoJLyogTWl4IGluIGRpZmZlcmVudCBzYW1wbGUgcmF0ZXMgKi8KCS8qICovCgkvKiBOZXcgUGVyZmVjdFBpdGNoKHRtKSBUZWNobm9sb2d5IChjKSAxOTk4IFJvYiBSaWdncyAqLwoJLyogUGF0ZW50IFBlbmRpbmcgOi1dICovCgoJLyogUGF0ZW50IGVuaGFuY2VtZW50cyAoYykgMjAwMCBPdmUgS+V2ZW4sCgkgKiBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMgSW5jLiAqLwoKCUZJWE1FKCIoJXApIEFkanVzdGluZyBmcmVxdWVuY3k6ICVsZCAtPiAlbGQgKG5lZWQgb3B0aW1pemF0aW9uKVxuIiwKCQlkc2IsIGRzYi0+ZnJlcSwgcHJpbWFyeWJ1Zi0+d2Z4Lm5TYW1wbGVzUGVyU2VjKTsKCglzaXplID0gbGVuIC8gb0FkdmFuY2U7CglpbGVuID0gMDsKCWlwb3MgPSBkc2ItPmJ1Zl9taXhwb3M7Cglmb3IgKGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJZ2V0X2ZpZWxkcyhkc2IsIChkc2ItPmJ1ZmZlciArIGlwb3MpLCAmZmllbGRMLCAmZmllbGRSKTsKCQlzZXRfZmllbGRzKG9icCwgZmllbGRMLCBmaWVsZFIpOwoJCW9icCArPSBvQWR2YW5jZTsKCgkJZHNiLT5mcmVxQWNjICs9IGRzYi0+ZnJlcUFkanVzdDsKCQlpZiAoZHNiLT5mcmVxQWNjID49ICgxPDxEU09VTkRfRlJFUVNISUZUKSkgewoJCQlVTE9ORyBhZHYgPSAoZHNiLT5mcmVxQWNjPj5EU09VTkRfRlJFUVNISUZUKSAqIGlBZHZhbmNlOwoJCQlkc2ItPmZyZXFBY2MgJj0gKDE8PERTT1VORF9GUkVRU0hJRlQpLTE7CgkJCWlwb3MgKz0gYWR2OyBpbGVuICs9IGFkdjsKCQkJd2hpbGUgKGlwb3MgPj0gZHNiLT5idWZsZW4pCgkJCQlpcG9zIC09IGRzYi0+YnVmbGVuOwoJCX0KCX0KCXJldHVybiBpbGVuOwp9CgpzdGF0aWMgdm9pZCBEU09VTkRfTWl4ZXJWb2woSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiLCBCWVRFICpidWYsIElOVCBsZW4pCnsKCUlOVAlpLCBpbmMgPSBwcmltYXJ5YnVmLT53Zngud0JpdHNQZXJTYW1wbGUgPj4gMzsKCUJZVEUJKmJwYyA9IGJ1ZjsKCUlOVDE2CSpicHMgPSAoSU5UMTYgKikgYnVmOwoJCglUUkFDRSgiKCVwKSBsZWZ0ID0gJWx4LCByaWdodCA9ICVseFxuIiwgZHNiLAoJCWRzYi0+dm9scGFuLmR3VG90YWxMZWZ0QW1wRmFjdG9yLCBkc2ItPnZvbHBhbi5kd1RvdGFsUmlnaHRBbXBGYWN0b3IpOwoJaWYgKCghKGRzYi0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19DVFJMUEFOKSB8fCAoZHNiLT52b2xwYW4ubFBhbiA9PSAwKSkgJiYKCSAgICAoIShkc2ItPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfQ1RSTFZPTFVNRSkgfHwgKGRzYi0+dm9scGFuLmxWb2x1bWUgPT0gMCkpICYmCgkgICAgIShkc2ItPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfQ1RSTDNEKSkKCQlyZXR1cm47CQkvKiBOb3RoaW5nIHRvIGRvICovCgoJLyogSWYgd2UgZW5kIHVwIHdpdGggc29tZSBib3pvIGNvZGVyIHVzaW5nIHBhbm5pbmcgb3IgM0Qgc291bmQgKi8KCS8qIHdpdGggYSBtb25vIHByaW1hcnkgYnVmZmVyLCBpdCBjb3VsZCBzb3VuZCB2ZXJ5IHdlaXJkIHVzaW5nICovCgkvKiB0aGlzIG1ldGhvZC4gT2ggd2VsbCwgdG91Z2ggcGF0b290aWVzLiAqLwoKCWZvciAoaSA9IDA7IGkgPCBsZW47IGkgKz0gaW5jKSB7CgkJSU5UCXZhbDsKCgkJc3dpdGNoIChpbmMpIHsKCgkJY2FzZSAxOgoJCQkvKiA4LWJpdCBXQVYgaXMgdW5zaWduZWQsIGJ1dCB3ZSBuZWVkIHRvIG9wZXJhdGUgKi8KCQkJLyogb24gc2lnbmVkIGRhdGEgZm9yIHRoaXMgdG8gd29yayBwcm9wZXJseSAqLwoJCQl2YWwgPSAqYnBjIC0gMTI4OwoJCQl2YWwgPSAoKHZhbCAqIChpICYgaW5jID8gZHNiLT52b2xwYW4uZHdUb3RhbFJpZ2h0QW1wRmFjdG9yIDogZHNiLT52b2xwYW4uZHdUb3RhbExlZnRBbXBGYWN0b3IpKSA+PiAxNik7CgkJCSpicGMgPSB2YWwgKyAxMjg7CgkJCWJwYysrOwoJCQlicmVhazsKCQljYXNlIDI6CgkJCS8qIDE2LWJpdCBXQVYgaXMgc2lnbmVkIC0tIG11Y2ggYmV0dGVyICovCgkJCXZhbCA9ICpicHM7CgkJCXZhbCA9ICgodmFsICogKChpICYgaW5jKSA/IGRzYi0+dm9scGFuLmR3VG90YWxSaWdodEFtcEZhY3RvciA6IGRzYi0+dm9scGFuLmR3VG90YWxMZWZ0QW1wRmFjdG9yKSkgPj4gMTYpOwoJCQkqYnBzID0gdmFsOwoJCQlicHMrKzsKCQkJYnJlYWs7CgkJZGVmYXVsdDoKCQkJLyogVmVyeSB1Z2x5ISAqLwoJCQlGSVhNRSgiTWl4ZXJWb2wgaGFkIGEgbmFzdHkgZXJyb3JcbiIpOwoJCX0KCX0JCQp9CgojaWZkZWYgVVNFX0RTT1VORDNECnN0YXRpYyB2b2lkIERTT1VORF9NaXhlcjNEKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwgKmRzYiwgQllURSAqYnVmLCBJTlQgbGVuKQp7CglCWVRFCSppYnAsICpvYnA7CglEV09SRAlidWZsZW4sIGJ1Zl9taXhwb3M7CgoJYnVmbGVuID0gZHNiLT5kczNkYi0+YnVmbGVuOwoJYnVmX21peHBvcyA9IChkc2ItPmJ1Zl9taXhwb3MgKiBwcmltYXJ5YnVmLT53ZngubkJsb2NrQWxpZ24pIC8gZHNiLT53ZngubkJsb2NrQWxpZ247CglpYnAgPSBkc2ItPmRzM2RiLT5idWZmZXIgKyBidWZfbWl4cG9zOwoJb2JwID0gYnVmOwoKCWlmIChidWZfbWl4cG9zID4gYnVmbGVuKSB7CgkJRklYTUUoIk1ham9yIGJyZWFrYWdlXG4iKTsKCQlyZXR1cm47Cgl9CgoJaWYgKGxlbiA8PSAoYnVmX21peHBvcyArIGJ1ZmxlbikpCgkJbWVtY3B5KG9icCwgaWJwLCBsZW4pOwoJZWxzZSB7IC8qIHdyYXAgKi8KCQltZW1jcHkob2JwLCBpYnAsIGJ1ZmxlbiAtIGJ1Zl9taXhwb3MpOwoJCW1lbWNweShvYnAgKyAoYnVmbGVuIC0gYnVmX21peHBvcyksCgkJICAgIGRzYi0+YnVmZmVyLAoJCSAgICBsZW4gLSAoYnVmbGVuIC0gYnVmX21peHBvcykpOwoJfQoJcmV0dXJuOwp9CiNlbmRpZgoKc3RhdGljIHZvaWQgKnRtcF9idWZmZXI7CnN0YXRpYyBzaXplX3QgdG1wX2J1ZmZlcl9sZW4gPSAwOwoKc3RhdGljIHZvaWQgKkRTT1VORF90bXBidWZmZXIoc2l6ZV90IGxlbikKewogIGlmIChsZW4+dG1wX2J1ZmZlcl9sZW4pIHsKICAgIHZvaWQgKm5ld19idWZmZXIgPSByZWFsbG9jKHRtcF9idWZmZXIsIGxlbik7CiAgICBpZiAobmV3X2J1ZmZlcikgewogICAgICB0bXBfYnVmZmVyID0gbmV3X2J1ZmZlcjsKICAgICAgdG1wX2J1ZmZlcl9sZW4gPSBsZW47CiAgICB9CiAgICByZXR1cm4gbmV3X2J1ZmZlcjsKICB9CiAgcmV0dXJuIHRtcF9idWZmZXI7Cn0KCnN0YXRpYyBEV09SRCBEU09VTkRfTWl4SW5CdWZmZXIoSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiLCBEV09SRCB3cml0ZXBvcywgRFdPUkQgZnJhZ2xlbikKewoJSU5UCWksIGxlbiwgaWxlbiwgdGVtcCwgZmllbGQ7CglJTlQJYWR2YW5jZSA9IHByaW1hcnlidWYtPndmeC53Qml0c1BlclNhbXBsZSA+PiAzOwoJQllURQkqYnVmLCAqaWJ1ZiwgKm9idWY7CglJTlQxNgkqaWJ1ZnMsICpvYnVmczsKCglsZW4gPSBmcmFnbGVuOwoJaWYgKCEoZHNiLT5wbGF5ZmxhZ3MgJiBEU0JQTEFZX0xPT1BJTkcpKSB7CgkJdGVtcCA9IE11bERpdihwcmltYXJ5YnVmLT53ZngubkF2Z0J5dGVzUGVyU2VjLCBkc2ItPmJ1ZmxlbiwKCQkJZHNiLT5uQXZnQnl0ZXNQZXJTZWMpIC0KCQkgICAgICAgTXVsRGl2KHByaW1hcnlidWYtPndmeC5uQXZnQnl0ZXNQZXJTZWMsIGRzYi0+YnVmX21peHBvcywKCQkJZHNiLT5uQXZnQnl0ZXNQZXJTZWMpOwoJCWxlbiA9IChsZW4gPiB0ZW1wKSA/IHRlbXAgOiBsZW47Cgl9CglsZW4gJj0gfjM7CQkJCS8qIDQgYnl0ZSBhbGlnbm1lbnQgKi8KCglpZiAobGVuID09IDApIHsKCQkvKiBUaGlzIHNob3VsZCBvbmx5IGhhcHBlbiBpZiB3ZSBhcmVuJ3QgbG9vcGluZyBhbmQgdGVtcCA8IDQgKi8KCgkJLyogV2Ugc2tpcCB0aGUgcmVtYWluZGVyLCBzbyBjaGVjayBmb3IgcG9zc2libGUgZXZlbnRzICovCgkJRFNPVU5EX0NoZWNrRXZlbnQoZHNiLCBkc2ItPmJ1ZmxlbiAtIGRzYi0+YnVmX21peHBvcyk7CgkJLyogU3RvcCAqLwoJCWRzYi0+c3RhdGUgPSBTVEFURV9TVE9QUEVEOwoJCWRzYi0+cGxheXBvcyA9IDA7CgkJZHNiLT5idWZfbWl4cG9zID0gMDsKCQlkc2ItPmxlYWRpbiA9IEZBTFNFOwoJCS8qIENoZWNrIGZvciBEU0JQTl9PRkZTRVRTVE9QICovCgkJRFNPVU5EX0NoZWNrRXZlbnQoZHNiLCAwKTsKCQlyZXR1cm4gMDsKCX0KCgkvKiBCZWVuIHNlZWluZyBzZWdmYXVsdHMgaW4gbWFsbG9jKCkgZm9yIHNvbWUgcmVhc29uLi4uICovCglUUkFDRSgiYWxsb2NhdGluZyBidWZmZXIgKHNpemUgPSAlZClcbiIsIGxlbik7CglpZiAoKGJ1ZiA9IGlidWYgPSAoQllURSAqKSBEU09VTkRfdG1wYnVmZmVyKGxlbikpID09IE5VTEwpCgkJcmV0dXJuIDA7CgoJVFJBQ0UoIk1peEluQnVmZmVyICglcCkgbGVuID0gJWQsIGRlc3QgPSAlbGRcbiIsIGRzYiwgbGVuLCB3cml0ZXBvcyk7CgoJaWxlbiA9IERTT1VORF9NaXhlck5vcm0oZHNiLCBpYnVmLCBsZW4pOwoJaWYgKChkc2ItPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfQ1RSTFBBTikgfHwKCSAgICAoZHNiLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX0NUUkxWT0xVTUUpKQoJCURTT1VORF9NaXhlclZvbChkc2IsIGlidWYsIGxlbik7CgoJb2J1ZiA9IHByaW1hcnlidWYtPmJ1ZmZlciArIHdyaXRlcG9zOwoJZm9yIChpID0gMDsgaSA8IGxlbjsgaSArPSBhZHZhbmNlKSB7CgkJb2J1ZnMgPSAoSU5UMTYgKikgb2J1ZjsKCQlpYnVmcyA9IChJTlQxNiAqKSBpYnVmOwoJCWlmIChwcmltYXJ5YnVmLT53Zngud0JpdHNQZXJTYW1wbGUgPT0gOCkgewoJCQkvKiA4LWJpdCBXQVYgaXMgdW5zaWduZWQgKi8KCQkJZmllbGQgPSAoKmlidWYgLSAxMjgpOwoJCQlmaWVsZCArPSAoKm9idWYgLSAxMjgpOwoJCQlmaWVsZCA9IGZpZWxkID4gMTI3ID8gMTI3IDogZmllbGQ7CgkJCWZpZWxkID0gZmllbGQgPCAtMTI4ID8gLTEyOCA6IGZpZWxkOwoJCQkqb2J1ZiA9IGZpZWxkICsgMTI4OwoJCX0gZWxzZSB7CgkJCS8qIDE2LWJpdCBXQVYgaXMgc2lnbmVkICovCgkJCWZpZWxkID0gKmlidWZzOwoJCQlmaWVsZCArPSAqb2J1ZnM7CgkJCWZpZWxkID0gZmllbGQgPiAzMjc2NyA/IDMyNzY3IDogZmllbGQ7CgkJCWZpZWxkID0gZmllbGQgPCAtMzI3NjggPyAtMzI3NjggOiBmaWVsZDsKCQkJKm9idWZzID0gZmllbGQ7CgkJfQoJCWlidWYgKz0gYWR2YW5jZTsKCQlvYnVmICs9IGFkdmFuY2U7CgkJaWYgKG9idWYgPj0gKEJZVEUgKikocHJpbWFyeWJ1Zi0+YnVmZmVyICsgcHJpbWFyeWJ1Zi0+YnVmbGVuKSkKCQkJb2J1ZiA9IHByaW1hcnlidWYtPmJ1ZmZlcjsKCX0KCS8qIGZyZWUoYnVmKTsgKi8KCglpZiAoZHNiLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX0NUUkxQT1NJVElPTk5PVElGWSkKCQlEU09VTkRfQ2hlY2tFdmVudChkc2IsIGlsZW4pOwoKCWlmIChkc2ItPmxlYWRpbiAmJiAoZHNiLT5zdGFydHBvcyA+IGRzYi0+YnVmX21peHBvcykgJiYgKGRzYi0+c3RhcnRwb3MgPD0gZHNiLT5idWZfbWl4cG9zICsgaWxlbikpIHsKCQkvKiBIQUNLLi4uIGxlYWRpbiBzaG91bGQgYmUgcmVzZXQgd2hlbiB0aGUgUExBWSBwb3NpdGlvbiByZWFjaGVzIHRoZSBzdGFydHBvcywKCQkgKiBub3QgdGhlIE1JWCBwb3NpdGlvbi4uLiBidXQgaWYgdGhlIHNvdW5kIGJ1ZmZlciBpcyBiaWdnZXIgdGhhbiBvdXIgcHJlYnVmZmVyaW5nCgkJICogKHdoaWNoIG11c3QgYmUgdGhlIGNhc2UgZm9yIHRoZSBzdHJlYW1pbmcgYnVmZmVycyB0aGF0IG5lZWQgdGhpcyBoYWNrIGFueXdheSkKCQkgKiBwbHVzIERTX0hFTF9NQVJHSU4gb3IgZXF1aXZhbGVudCwgdGhlbiB0aGlzIG91Z2h0IHRvIHdvcmsgYW55d2F5LiAqLwoJCWRzYi0+bGVhZGluID0gRkFMU0U7Cgl9CgoJZHNiLT5idWZfbWl4cG9zICs9IGlsZW47CgkKCWlmIChkc2ItPmJ1Zl9taXhwb3MgPj0gZHNiLT5idWZsZW4pIHsKCQlpZiAoIShkc2ItPnBsYXlmbGFncyAmIERTQlBMQVlfTE9PUElORykpIHsKCQkJZHNiLT5zdGF0ZSA9IFNUQVRFX1NUT1BQRUQ7CgkJCWRzYi0+cGxheXBvcyA9IDA7CgkJCWRzYi0+YnVmX21peHBvcyA9IDA7CgkJCWRzYi0+bGVhZGluID0gRkFMU0U7CgkJCURTT1VORF9DaGVja0V2ZW50KGRzYiwgMCk7CQkvKiBGb3IgRFNCUE5fT0ZGU0VUU1RPUCAqLwoJCX0gZWxzZSB7CgkJCS8qIHdyYXAgKi8KCQkJd2hpbGUgKGRzYi0+YnVmX21peHBvcyA+PSBkc2ItPmJ1ZmxlbikKCQkJCWRzYi0+YnVmX21peHBvcyAtPSBkc2ItPmJ1ZmxlbjsKCQkJaWYgKGRzYi0+bGVhZGluICYmIChkc2ItPnN0YXJ0cG9zIDw9IGRzYi0+YnVmX21peHBvcykpCgkJCQlkc2ItPmxlYWRpbiA9IEZBTFNFOyAvKiBIQUNLOiBzZWUgYWJvdmUgKi8KCQl9Cgl9CgoJcmV0dXJuIGxlbjsKfQoKc3RhdGljIHZvaWQgRFNPVU5EX1BoYXNlQ2FuY2VsKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwgKmRzYiwgRFdPUkQgd3JpdGVwb3MsIERXT1JEIGxlbikKewoJSU5UICAgICBpLCBpbGVuLCBmaWVsZDsKCUlOVCAgICAgYWR2YW5jZSA9IHByaW1hcnlidWYtPndmeC53Qml0c1BlclNhbXBsZSA+PiAzOwoJQllURQkqYnVmLCAqaWJ1ZiwgKm9idWY7CglJTlQxNgkqaWJ1ZnMsICpvYnVmczsKCglsZW4gJj0gfjM7CQkJCS8qIDQgYnl0ZSBhbGlnbm1lbnQgKi8KCglUUkFDRSgiYWxsb2NhdGluZyBidWZmZXIgKHNpemUgPSAlbGQpXG4iLCBsZW4pOwoJaWYgKChidWYgPSBpYnVmID0gKEJZVEUgKikgRFNPVU5EX3RtcGJ1ZmZlcihsZW4pKSA9PSBOVUxMKQoJCXJldHVybjsKCglUUkFDRSgiUGhhc2VDYW5jZWwgKCVwKSBsZW4gPSAlbGQsIGRlc3QgPSAlbGRcbiIsIGRzYiwgbGVuLCB3cml0ZXBvcyk7CgoJaWxlbiA9IERTT1VORF9NaXhlck5vcm0oZHNiLCBpYnVmLCBsZW4pOwoJaWYgKChkc2ItPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfQ1RSTFBBTikgfHwKCSAgICAoZHNiLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX0NUUkxWT0xVTUUpKQoJCURTT1VORF9NaXhlclZvbChkc2IsIGlidWYsIGxlbik7CgoJLyogc3VidHJhY3QgaW5zdGVhZCBvZiBhZGQsIHRvIHBoYXNlIG91dCBwcmVtaXhlZCBkYXRhICovCglvYnVmID0gcHJpbWFyeWJ1Zi0+YnVmZmVyICsgd3JpdGVwb3M7Cglmb3IgKGkgPSAwOyBpIDwgbGVuOyBpICs9IGFkdmFuY2UpIHsKCQlvYnVmcyA9IChJTlQxNiAqKSBvYnVmOwoJCWlidWZzID0gKElOVDE2ICopIGlidWY7CgkJaWYgKHByaW1hcnlidWYtPndmeC53Qml0c1BlclNhbXBsZSA9PSA4KSB7CgkJCS8qIDgtYml0IFdBViBpcyB1bnNpZ25lZCAqLwoJCQlmaWVsZCA9ICgqaWJ1ZiAtIDEyOCk7CgkJCWZpZWxkIC09ICgqb2J1ZiAtIDEyOCk7CgkJCWZpZWxkID0gZmllbGQgPiAxMjcgPyAxMjcgOiBmaWVsZDsKCQkJZmllbGQgPSBmaWVsZCA8IC0xMjggPyAtMTI4IDogZmllbGQ7CgkJCSpvYnVmID0gZmllbGQgKyAxMjg7CgkJfSBlbHNlIHsKCQkJLyogMTYtYml0IFdBViBpcyBzaWduZWQgKi8KCQkJZmllbGQgPSAqaWJ1ZnM7CgkJCWZpZWxkIC09ICpvYnVmczsKCQkJZmllbGQgPSBmaWVsZCA+IDMyNzY3ID8gMzI3NjcgOiBmaWVsZDsKCQkJZmllbGQgPSBmaWVsZCA8IC0zMjc2OCA/IC0zMjc2OCA6IGZpZWxkOwoJCQkqb2J1ZnMgPSBmaWVsZDsKCQl9CgkJaWJ1ZiArPSBhZHZhbmNlOwoJCW9idWYgKz0gYWR2YW5jZTsKCQlpZiAob2J1ZiA+PSAoQllURSAqKShwcmltYXJ5YnVmLT5idWZmZXIgKyBwcmltYXJ5YnVmLT5idWZsZW4pKQoJCQlvYnVmID0gcHJpbWFyeWJ1Zi0+YnVmZmVyOwoJfQoJLyogZnJlZShidWYpOyAqLwp9CgpzdGF0aWMgdm9pZCBEU09VTkRfTWl4Q2FuY2VsKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwgKmRzYiwgRFdPUkQgd3JpdGVwb3MsIEJPT0wgY2FuY2VsKQp7CglEV09SRCAgIHNpemUsIGZsZW4sIGxlbiwgbnBvcywgbmxlbjsKCUlOVAlpQWR2YW5jZSA9IGRzYi0+d2Z4Lm5CbG9ja0FsaWduOwoJSU5UCW9BZHZhbmNlID0gcHJpbWFyeWJ1Zi0+d2Z4Lm5CbG9ja0FsaWduOwoJLyogZGV0ZXJtaW5lIGFtb3VudCBvZiBwcmVtaXhlZCBkYXRhIHRvIGNhbmNlbCAqLwoJRFdPUkQgcHJpbWFyeV9kb25lID0KCQkoKGRzYi0+cHJpbWFyeV9taXhwb3MgPCB3cml0ZXBvcykgPyBwcmltYXJ5YnVmLT5idWZsZW4gOiAwKSArCgkJZHNiLT5wcmltYXJ5X21peHBvcyAtIHdyaXRlcG9zOwoKCVRSQUNFKCIoJXAsICVsZCksIGJ1Zl9taXhwb3M9JWxkXG4iLCBkc2IsIHdyaXRlcG9zLCBkc2ItPmJ1Zl9taXhwb3MpOwoKCS8qIGJhY2t0cmFjayB0aGUgbWl4IHBvc2l0aW9uICovCglzaXplID0gcHJpbWFyeV9kb25lIC8gb0FkdmFuY2U7CglmbGVuID0gc2l6ZSAqIGRzYi0+ZnJlcUFkanVzdDsKCWxlbiA9IChmbGVuID4+IERTT1VORF9GUkVRU0hJRlQpICogaUFkdmFuY2U7CglmbGVuICY9ICgxPDxEU09VTkRfRlJFUVNISUZUKS0xOwoJd2hpbGUgKGRzYi0+ZnJlcUFjYyA8IGZsZW4pIHsKCQlsZW4gKz0gaUFkdmFuY2U7CgkJZHNiLT5mcmVxQWNjICs9IDE8PERTT1VORF9GUkVRU0hJRlQ7Cgl9CglsZW4gJT0gZHNiLT5idWZsZW47CglucG9zID0gKChkc2ItPmJ1Zl9taXhwb3MgPCBsZW4pID8gZHNiLT5idWZsZW4gOiAwKSArCgkJZHNiLT5idWZfbWl4cG9zIC0gbGVuOwoJaWYgKGRzYi0+bGVhZGluICYmIChkc2ItPnN0YXJ0cG9zID4gbnBvcykgJiYgKGRzYi0+c3RhcnRwb3MgPD0gbnBvcyArIGxlbikpIHsKCQkvKiBzdG9wIGJhY2t0cmFja2luZyBhdCBzdGFydHBvcyAqLwoJCW5wb3MgPSBkc2ItPnN0YXJ0cG9zOwoJCWxlbiA9ICgoZHNiLT5idWZfbWl4cG9zIDwgbnBvcykgPyBkc2ItPmJ1ZmxlbiA6IDApICsKCQkJZHNiLT5idWZfbWl4cG9zIC0gbnBvczsKCQlmbGVuID0gZHNiLT5mcmVxQWNjOwoJCW5sZW4gPSBsZW4gLyBkc2ItPndmeC5uQmxvY2tBbGlnbjsKCQlubGVuID0gKChubGVuIDw8IERTT1VORF9GUkVRU0hJRlQpICsgZmxlbikgLyBkc2ItPmZyZXFBZGp1c3Q7CgkJbmxlbiAqPSBwcmltYXJ5YnVmLT53ZngubkJsb2NrQWxpZ247CgkJd3JpdGVwb3MgPQoJCQkoKGRzYi0+cHJpbWFyeV9taXhwb3MgPCBubGVuKSA/IHByaW1hcnlidWYtPmJ1ZmxlbiA6IDApICsKCQkJZHNiLT5wcmltYXJ5X21peHBvcyAtIG5sZW47Cgl9CgoJZHNiLT5mcmVxQWNjIC09IGZsZW47Cglkc2ItPmJ1Zl9taXhwb3MgPSBucG9zOwoJZHNiLT5wcmltYXJ5X21peHBvcyA9IHdyaXRlcG9zOwoKCVRSQUNFKCJuZXcgYnVmX21peHBvcz0lbGQsIHByaW1hcnlfbWl4cG9zPSVsZCAobGVuPSVsZClcbiIsCgkgICAgICBkc2ItPmJ1Zl9taXhwb3MsIGRzYi0+cHJpbWFyeV9taXhwb3MsIGxlbik7CgoJaWYgKGNhbmNlbCkgRFNPVU5EX1BoYXNlQ2FuY2VsKGRzYiwgd3JpdGVwb3MsIGxlbik7Cn0KCnN0YXRpYyB2b2lkIERTT1VORF9NaXhDYW5jZWxBdChJRGlyZWN0U291bmRCdWZmZXJJbXBsICpkc2IsIERXT1JEIGJ1Zl93cml0ZXBvcykKewojaWYgMAoJRFdPUkQgICBpLCBzaXplLCBmbGVuLCBsZW4sIG5wb3MsIG5sZW47CglJTlQJaUFkdmFuY2UgPSBkc2ItPndmeC5uQmxvY2tBbGlnbjsKCUlOVAlvQWR2YW5jZSA9IHByaW1hcnlidWYtPndmeC5uQmxvY2tBbGlnbjsKCS8qIGRldGVybWluZSBhbW91bnQgb2YgcHJlbWl4ZWQgZGF0YSB0byBjYW5jZWwgKi8KCURXT1JEIGJ1Zl9kb25lID0KCQkoKGRzYi0+YnVmX21peHBvcyA8IGJ1Zl93cml0ZXBvcykgPyBkc2ItPmJ1ZmxlbiA6IDApICsKCQlkc2ItPmJ1Zl9taXhwb3MgLSBidWZfd3JpdGVwb3M7CiNlbmRpZgoKCVdBUk4oIiglcCwgJWxkKSwgYnVmX21peHBvcz0lbGRcbiIsIGRzYiwgYnVmX3dyaXRlcG9zLCBkc2ItPmJ1Zl9taXhwb3MpOwoJLyogc2luY2UgdGhpcyBpcyBub3QgaW1wbGVtZW50ZWQgeWV0LCBqdXN0IGNhbmNlbCAqQUxMKiBwcmVidWZmZXJpbmcgZm9yIG5vdwoJICogKHdoaWNoIGlzIGZhc3RlciBhbnl3YXkgd2hlbiB0aGVyZSdzIG9uZSBhIHNpbmdsZSBzZWNvbmRhcnkgYnVmZmVyKSAqLwoJcHJpbWFyeWJ1Zi0+bmVlZF9yZW1peCA9IFRSVUU7Cn0KCnN0YXRpYyBEV09SRCBEU09VTkRfTWl4T25lKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwgKmRzYiwgRFdPUkQgcGxheXBvcywgRFdPUkQgd3JpdGVwb3MsIERXT1JEIG1peGxlbikKewoJRFdPUkQgbGVuLCBzbGVuOwoJLyogZGV0ZXJtaW5lIHRoaXMgYnVmZmVyJ3Mgd3JpdGUgcG9zaXRpb24gKi8KCURXT1JEIGJ1Zl93cml0ZXBvcyA9IERTT1VORF9DYWxjUGxheVBvc2l0aW9uKGRzYiwgZHNiLT5zdGF0ZSAmIHByaW1hcnlidWYtPnN0YXRlLCB3cml0ZXBvcywKCQkJCQkJICAgICB3cml0ZXBvcywgZHNiLT5wcmltYXJ5X21peHBvcywgZHNiLT5idWZfbWl4cG9zKTsKCS8qIGRldGVybWluZSBob3cgbXVjaCBhbHJlYWR5LW1peGVkIGRhdGEgZXhpc3RzICovCglEV09SRCBidWZfZG9uZSA9CgkJKChkc2ItPmJ1Zl9taXhwb3MgPCBidWZfd3JpdGVwb3MpID8gZHNiLT5idWZsZW4gOiAwKSArCgkJZHNiLT5idWZfbWl4cG9zIC0gYnVmX3dyaXRlcG9zOwoJRFdPUkQgcHJpbWFyeV9kb25lID0KCQkoKGRzYi0+cHJpbWFyeV9taXhwb3MgPCB3cml0ZXBvcykgPyBwcmltYXJ5YnVmLT5idWZsZW4gOiAwKSArCgkJZHNiLT5wcmltYXJ5X21peHBvcyAtIHdyaXRlcG9zOwoJRFdPUkQgYWR2X2RvbmUgPQoJCSgocHJpbWFyeWJ1Zi0+YnVmX21peHBvcyA8IHdyaXRlcG9zKSA/IHByaW1hcnlidWYtPmJ1ZmxlbiA6IDApICsKCQlwcmltYXJ5YnVmLT5idWZfbWl4cG9zIC0gd3JpdGVwb3M7CglpbnQgc3RpbGxfYmVoaW5kOwoKCVRSQUNFKCJidWZfd3JpdGVwb3M9JWxkLCBwcmltYXJ5X3dyaXRlcG9zPSVsZFxuIiwgYnVmX3dyaXRlcG9zLCB3cml0ZXBvcyk7CglUUkFDRSgiYnVmX2RvbmU9JWxkLCBwcmltYXJ5X2RvbmU9JWxkXG4iLCBidWZfZG9uZSwgcHJpbWFyeV9kb25lKTsKCVRSQUNFKCJidWZfbWl4cG9zPSVsZCwgcHJpbWFyeV9taXhwb3M9JWxkLCBtaXhsZW49JWxkXG4iLCBkc2ItPmJ1Zl9taXhwb3MsIGRzYi0+cHJpbWFyeV9taXhwb3MsCgkgICAgICBtaXhsZW4pOwoJVFJBQ0UoImxvb3Bpbmc9JWxkLCBzdGFydHBvcz0lbGQsIGxlYWRpbj0lbGRcbiIsIGRzYi0+cGxheWZsYWdzLCBkc2ItPnN0YXJ0cG9zLCBkc2ItPmxlYWRpbik7CgoJLyogc2F2ZSB3cml0ZSBwb3NpdGlvbiBmb3Igbm9uLUdFVENVUlJFTlRQT1NJVElPTjIuLi4gKi8KCWRzYi0+cGxheXBvcyA9IGJ1Zl93cml0ZXBvczsKCgkvKiBjaGVjayB3aGV0aGVyIENhbGNQbGF5UG9zaXRpb24gZGV0ZWN0ZWQgYSBtaXhpbmcgdW5kZXJydW4gKi8KCWlmICgoYnVmX2RvbmUgPT0gMCkgJiYgKGRzYi0+cHJpbWFyeV9taXhwb3MgIT0gd3JpdGVwb3MpKSB7CgkJLyogaXQgZGlkLCBidXQgZGlkIHdlIGhhdmUgbW9yZSB0byBwbGF5PyAqLwoJCWlmICgoZHNiLT5wbGF5ZmxhZ3MgJiBEU0JQTEFZX0xPT1BJTkcpIHx8CgkJICAgIChkc2ItPmJ1Zl9taXhwb3MgPCBkc2ItPmJ1ZmxlbikpIHsKCQkJLyogeWVzLCBoYXZlIHRvIHJlY292ZXIgKi8KCQkJRVJSKCJ1bmRlcnJ1biBvbiBzb3VuZCBidWZmZXIgJXBcbiIsIGRzYik7CgkJCVRSQUNFKCJyZWNvdmVyaW5nIGZyb20gdW5kZXJydW46IHByaW1hcnlfbWl4cG9zPSVsZFxuIiwgd3JpdGVwb3MpOwoJCX0KCQlkc2ItPnByaW1hcnlfbWl4cG9zID0gd3JpdGVwb3M7CgkJcHJpbWFyeV9kb25lID0gMDsKCX0KCS8qIGRldGVybWluZSBob3cgZmFyIGFoZWFkIHdlIHNob3VsZCBtaXggKi8KCWlmICgoKGRzYi0+cGxheWZsYWdzICYgRFNCUExBWV9MT09QSU5HKSB8fAoJICAgICAoZHNiLT5sZWFkaW4gJiYgKGRzYi0+cHJvYmFibHlfdmFsaWRfdG8gIT0gMCkpKSAmJgoJICAgICEoZHNiLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX1NUQVRJQykpIHsKCQkvKiBpZiB0aGlzIGlzIGEgc3RyZWFtaW5nIGJ1ZmZlciwgaXQgdHlwaWNhbGx5IG1lYW5zIHRoYXQKCQkgKiB3ZSBzaG91bGQgZGVmZXIgbWl4aW5nIHBhc3QgcHJvYmFibHlfdmFsaWRfdG8gYXMgbG9uZwoJCSAqIGFzIHdlIGNhbiwgdG8gYXZvaWQgdW5uZWNlc3NhcnkgcmVtaXhpbmcgKi8KCQkvKiB0aGUgaGVhdnktbG9va2luZyBjYWxjdWxhdGlvbnMgc2hvdWxkbid0IGJlIHRoYXQgYmFkLAoJCSAqIGFzIGFueSBnYW1lIGlzbid0IGxpa2VseSB0byBiZSBoYXZlIG1vcmUgdGhhbiAxIG9yIDIKCQkgKiBzdHJlYW1pbmcgYnVmZmVycyBpbiB1c2UgYXQgYW55IHRpbWUgYW55d2F5Li4uICovCgkJRFdPUkQgcHJvYmFibHlfdmFsaWRfbGVmdCA9CgkJCShkc2ItPnByb2JhYmx5X3ZhbGlkX3RvID09IChEV09SRCktMSkgPyBkc2ItPmJ1ZmxlbiA6CgkJCSgoZHNiLT5wcm9iYWJseV92YWxpZF90byA8IGJ1Zl93cml0ZXBvcykgPyBkc2ItPmJ1ZmxlbiA6IDApICsKCQkJZHNiLT5wcm9iYWJseV92YWxpZF90byAtIGJ1Zl93cml0ZXBvczsKCQkvKiBjaGVjayBmb3IgbGVhZGluIGNvbmRpdGlvbiAqLwoJCWlmICgocHJvYmFibHlfdmFsaWRfbGVmdCA9PSAwKSAmJgoJCSAgICAoZHNiLT5wcm9iYWJseV92YWxpZF90byA9PSBkc2ItPnN0YXJ0cG9zKSAmJgoJCSAgICBkc2ItPmxlYWRpbikKCQkJcHJvYmFibHlfdmFsaWRfbGVmdCA9IGRzYi0+YnVmbGVuOwoJCVRSQUNFKCJzdHJlYW1pbmcgYnVmZmVyIHByb2JhYmx5X3ZhbGlkX3RvPSVsZCwgcHJvYmFibHlfdmFsaWRfbGVmdD0lbGRcbiIsCgkJICAgICAgZHNiLT5wcm9iYWJseV92YWxpZF90bywgcHJvYmFibHlfdmFsaWRfbGVmdCk7CgkJLyogY2hlY2sgd2hldGhlciB0aGUgYXBwJ3MgdGltZSBpcyBhbHJlYWR5IHVwICovCgkJaWYgKHByb2JhYmx5X3ZhbGlkX2xlZnQgPCBkc2ItPndyaXRlbGVhZCkgewoJCQlXQVJOKCJwcm9iYWJseV92YWxpZF90byBub3cgd2l0aGluIHdyaXRlbGVhZCwgcG9zc2libGUgc3RyZWFtaW5nIHVuZGVycnVuXG4iKTsKCQkJLyogb25jZSB3ZSBwYXNzIHRoZSBwb2ludCBvZiBubyByZXR1cm4sCgkJCSAqIG5vIHJlYXNvbiB0byBob2xkIGJhY2sgYW55bW9yZSAqLwoJCQlkc2ItPnByb2JhYmx5X3ZhbGlkX3RvID0gKERXT1JEKS0xOwoJCQkvKiB3ZSBqdXN0IGhhdmUgdG8gZ28gYWhlYWQgYW5kIG1peCB3aGF0IHdlIGhhdmUsCgkJCSAqIHRoZXJlJ3Mgbm8gdGVsbGluZyB3aGF0IHRoZSBhcHAgaXMgdGhpbmtpbmcgYW55d2F5ICovCgkJfSBlbHNlIHsKCQkJLyogYWRqdXN0IGZvciBvdXIgZnJlcXVlbmN5IGFuZCBvdXIgc2FtcGxlIHNpemUgKi8KCQkJcHJvYmFibHlfdmFsaWRfbGVmdCA9IE11bERpdihwcm9iYWJseV92YWxpZF9sZWZ0LAoJCQkJCQkgICAgIDEgPDwgRFNPVU5EX0ZSRVFTSElGVCwKCQkJCQkJICAgICBkc2ItPndmeC5uQmxvY2tBbGlnbiAqIGRzYi0+ZnJlcUFkanVzdCkgKgoJCQkJICAgICAgICAgICAgICBwcmltYXJ5YnVmLT53ZngubkJsb2NrQWxpZ247CgkJCS8qIGNoZWNrIHdoZXRoZXIgdG8gY2xpcCBtaXhfbGVuICovCgkJCWlmIChwcm9iYWJseV92YWxpZF9sZWZ0IDwgbWl4bGVuKSB7CgkJCQlUUkFDRSgiY2xpcHBpbmcgdG8gcHJvYmFibHlfdmFsaWRfbGVmdD0lbGRcbiIsIHByb2JhYmx5X3ZhbGlkX2xlZnQpOwoJCQkJbWl4bGVuID0gcHJvYmFibHlfdmFsaWRfbGVmdDsKCQkJfQoJCX0KCX0KCS8qIGN1dCBtaXhsZW4gd2l0aCB3aGF0J3MgYWxyZWFkeSBiZWVuIG1peGVkICovCglpZiAobWl4bGVuIDwgcHJpbWFyeV9kb25lKSB7CgkJLyogaHVoPyBhbmQgc3RpbGwgQ2FsY1BsYXlQb3NpdGlvbiBkaWRuJ3QKCQkgKiBkZXRlY3QgYW4gdW5kZXJydW4/ICovCgkJRklYTUUoInByb2JsZW0gd2l0aCB1bmRlcnJ1biBkZXRlY3Rpb24gKG1peGxlbj0lbGQgPCBwcmltYXJ5X2RvbmU9JWxkKVxuIiwgbWl4bGVuLCBwcmltYXJ5X2RvbmUpOwoJCXJldHVybiAwOwoJfQoJbGVuID0gbWl4bGVuIC0gcHJpbWFyeV9kb25lOwoJVFJBQ0UoInJlbWFpbmluZyBtaXhsZW49JWxkXG4iLCBsZW4pOwoKCWlmIChsZW4gPCBwcmltYXJ5YnVmLT5kc291bmQtPmZyYWdsZW4pIHsKCQkvKiBzbWFsbGVyIHRoYW4gYSBmcmFnbWVudCwgd2FpdCB1bnRpbCBpdCBnZXRzIGxhcmdlcgoJCSAqIGJlZm9yZSB3ZSB0YWtlIHRoZSBtaXhpbmcgb3ZlcmhlYWQgKi8KCQlUUkFDRSgibWl4bGVuIG5vdCB3b3J0aCBpdCwgZGVmZXJyaW5nIG1peGluZ1xuIik7CgkJcmV0dXJuIDA7Cgl9CgoJLyogb2ssIHdlIGtub3cgaG93IG11Y2ggdG8gbWl4LCBsZXQncyBnbyAqLwoJc3RpbGxfYmVoaW5kID0gKGFkdl9kb25lID4gcHJpbWFyeV9kb25lKTsKCXdoaWxlIChsZW4pIHsKCQlzbGVuID0gcHJpbWFyeWJ1Zi0+YnVmbGVuIC0gZHNiLT5wcmltYXJ5X21peHBvczsKCQlpZiAoc2xlbiA+IGxlbikgc2xlbiA9IGxlbjsKCQlzbGVuID0gRFNPVU5EX01peEluQnVmZmVyKGRzYiwgZHNiLT5wcmltYXJ5X21peHBvcywgc2xlbik7CgoJCWlmICgoZHNiLT5wcmltYXJ5X21peHBvcyA8IHByaW1hcnlidWYtPmJ1Zl9taXhwb3MpICYmCgkJICAgIChkc2ItPnByaW1hcnlfbWl4cG9zICsgc2xlbiA+PSBwcmltYXJ5YnVmLT5idWZfbWl4cG9zKSkKCQkJc3RpbGxfYmVoaW5kID0gRkFMU0U7CgoJCWRzYi0+cHJpbWFyeV9taXhwb3MgKz0gc2xlbjsgbGVuIC09IHNsZW47CgkJd2hpbGUgKGRzYi0+cHJpbWFyeV9taXhwb3MgPj0gcHJpbWFyeWJ1Zi0+YnVmbGVuKQoJCQlkc2ItPnByaW1hcnlfbWl4cG9zIC09IHByaW1hcnlidWYtPmJ1ZmxlbjsKCgkJaWYgKChkc2ItPnN0YXRlID09IFNUQVRFX1NUT1BQRUQpIHx8ICFzbGVuKSBicmVhazsKCX0KCVRSQUNFKCJuZXcgcHJpbWFyeV9taXhwb3M9JWxkLCBwcmltYXJ5X2FkdmJhc2U9JWxkXG4iLCBkc2ItPnByaW1hcnlfbWl4cG9zLCBwcmltYXJ5YnVmLT5idWZfbWl4cG9zKTsKCVRSQUNFKCJtaXhlZCBkYXRhIGxlbj0lbGQsIHN0aWxsX2JlaGluZD0lZFxuIiwgbWl4bGVuLWxlbiwgc3RpbGxfYmVoaW5kKTsKCS8qIHJldHVybiBob3cgZmFyIHdlIHRoaW5rIHRoZSBwcmltYXJ5IGJ1ZmZlciBjYW4KCSAqIGFkdmFuY2UgaXRzIHVuZGVycnVuIGRldGVjdG9yLi4uKi8KCWlmIChzdGlsbF9iZWhpbmQpIHJldHVybiAwOwoJaWYgKChtaXhsZW4gLSBsZW4pIDwgcHJpbWFyeV9kb25lKSByZXR1cm4gMDsKCXNsZW4gPSAoKGRzYi0+cHJpbWFyeV9taXhwb3MgPCBwcmltYXJ5YnVmLT5idWZfbWl4cG9zKSA/CgkJcHJpbWFyeWJ1Zi0+YnVmbGVuIDogMCkgKyBkc2ItPnByaW1hcnlfbWl4cG9zIC0KCQlwcmltYXJ5YnVmLT5idWZfbWl4cG9zOwoJaWYgKHNsZW4gPiBtaXhsZW4pIHsKCQkvKiB0aGUgcHJpbWFyeV9kb25lIGFuZCBzdGlsbF9iZWhpbmQgY2hlY2tzIGFib3ZlIHNob3VsZCBoYXZlIHdvcmtlZCAqLwoJCUZJWE1FKCJwcm9ibGVtIHdpdGggYWR2YW5jZW1lbnQgY2FsY3VsYXRpb24gKGFkdmxlbj0lbGQgPiBtaXhsZW49JWxkKVxuIiwgc2xlbiwgbWl4bGVuKTsKCQlzbGVuID0gMDsKCX0KCXJldHVybiBzbGVuOwp9CgpzdGF0aWMgRFdPUkQgRFNPVU5EX01peFRvUHJpbWFyeShEV09SRCBwbGF5cG9zLCBEV09SRCB3cml0ZXBvcywgRFdPUkQgbWl4bGVuLCBCT09MIHJlY292ZXIpCnsKCUlOVAkJCWksIGxlbiwgbWF4bGVuID0gMDsKCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGwJKmRzYjsKCglUUkFDRSgiKCVsZCwlbGQsJWxkKVxuIiwgcGxheXBvcywgd3JpdGVwb3MsIG1peGxlbik7Cglmb3IgKGkgPSBkc291bmQtPm5yb2ZidWZmZXJzIC0gMTsgaSA+PSAwOyBpLS0pIHsKCQlkc2IgPSBkc291bmQtPmJ1ZmZlcnNbaV07CgoJCWlmICghZHNiIHx8ICEoSUNPTV9WVEJMKGRzYikpKQoJCQljb250aW51ZTsKCQlpZiAoZHNiLT5idWZsZW4gJiYgZHNiLT5zdGF0ZSAmJiAhZHNiLT5od2J1ZikgewoJCQlUUkFDRSgiQ2hlY2tpbmcgJXAsIG1peGxlbj0lbGRcbiIsIGRzYiwgbWl4bGVuKTsKCQkJRW50ZXJDcml0aWNhbFNlY3Rpb24oJihkc2ItPmxvY2spKTsKCQkJaWYgKGRzYi0+c3RhdGUgPT0gU1RBVEVfU1RPUFBJTkcpIHsKCQkJCURTT1VORF9NaXhDYW5jZWwoZHNiLCB3cml0ZXBvcywgVFJVRSk7CgkJCQlkc2ItPnN0YXRlID0gU1RBVEVfU1RPUFBFRDsKCQkJfSBlbHNlIHsKCQkJCWlmICgoZHNiLT5zdGF0ZSA9PSBTVEFURV9TVEFSVElORykgfHwgcmVjb3ZlcikKCQkJCQlkc2ItPnByaW1hcnlfbWl4cG9zID0gd3JpdGVwb3M7CgkJCQlsZW4gPSBEU09VTkRfTWl4T25lKGRzYiwgcGxheXBvcywgd3JpdGVwb3MsIG1peGxlbik7CgkJCQlpZiAoZHNiLT5zdGF0ZSA9PSBTVEFURV9TVEFSVElORykKCQkJCQlkc2ItPnN0YXRlID0gU1RBVEVfUExBWUlORzsKCQkJCW1heGxlbiA9IChsZW4gPiBtYXhsZW4pID8gbGVuIDogbWF4bGVuOwoJCQl9CgkJCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCYoZHNiLT5sb2NrKSk7CgkJfQoJfQoJCglyZXR1cm4gbWF4bGVuOwp9CgpzdGF0aWMgdm9pZCBEU09VTkRfTWl4UmVzZXQoRFdPUkQgd3JpdGVwb3MpCnsKCUlOVAkJCWk7CglJRGlyZWN0U291bmRCdWZmZXJJbXBsCSpkc2I7CglpbnQgbmZpbGxlcjsKCglUUkFDRSgiKCVsZClcbiIsIHdyaXRlcG9zKTsKCgkvKiB0aGUgc291bmQgb2Ygc2lsZW5jZSAqLwoJbmZpbGxlciA9IHByaW1hcnlidWYtPndmeC53Qml0c1BlclNhbXBsZSA9PSA4ID8gMTI4IDogMDsKCgkvKiByZXNldCBhbGwgYnVmZmVyIG1peCBwb3NpdGlvbnMgKi8KCWZvciAoaSA9IGRzb3VuZC0+bnJvZmJ1ZmZlcnMgLSAxOyBpID49IDA7IGktLSkgewoJCWRzYiA9IGRzb3VuZC0+YnVmZmVyc1tpXTsKCgkJaWYgKCFkc2IgfHwgIShJQ09NX1ZUQkwoZHNiKSkpCgkJCWNvbnRpbnVlOwoJCWlmIChkc2ItPmJ1ZmxlbiAmJiBkc2ItPnN0YXRlICYmICFkc2ItPmh3YnVmKSB7CgkJCVRSQUNFKCJSZXNldHRpbmcgJXBcbiIsIGRzYik7CgkJCUVudGVyQ3JpdGljYWxTZWN0aW9uKCYoZHNiLT5sb2NrKSk7CgkJCWlmIChkc2ItPnN0YXRlID09IFNUQVRFX1NUT1BQSU5HKSB7CgkJCQlkc2ItPnN0YXRlID0gU1RBVEVfU1RPUFBFRDsKCQkJfQoJCQllbHNlIGlmIChkc2ItPnN0YXRlID09IFNUQVRFX1NUQVJUSU5HKSB7CgkJCQkvKiBub3RoaW5nICovCgkJCX0gZWxzZSB7CgkJCQlEU09VTkRfTWl4Q2FuY2VsKGRzYiwgd3JpdGVwb3MsIEZBTFNFKTsKCQkJfQoJCQlMZWF2ZUNyaXRpY2FsU2VjdGlvbigmKGRzYi0+bG9jaykpOwoJCX0KCX0KCgkvKiB3aXBlIG91dCBwcmVtaXhlZCBkYXRhICovCglpZiAocHJpbWFyeWJ1Zi0+YnVmX21peHBvcyA8IHdyaXRlcG9zKSB7CgkJbWVtc2V0KHByaW1hcnlidWYtPmJ1ZmZlciArIHdyaXRlcG9zLCBuZmlsbGVyLCBwcmltYXJ5YnVmLT5idWZsZW4gLSB3cml0ZXBvcyk7CgkJbWVtc2V0KHByaW1hcnlidWYtPmJ1ZmZlciwgbmZpbGxlciwgcHJpbWFyeWJ1Zi0+YnVmX21peHBvcyk7Cgl9IGVsc2UgewoJCW1lbXNldChwcmltYXJ5YnVmLT5idWZmZXIgKyB3cml0ZXBvcywgbmZpbGxlciwgcHJpbWFyeWJ1Zi0+YnVmX21peHBvcyAtIHdyaXRlcG9zKTsKCX0KCgkvKiByZXNldCBwcmltYXJ5IG1peCBwb3NpdGlvbiAqLwoJcHJpbWFyeWJ1Zi0+YnVmX21peHBvcyA9IHdyaXRlcG9zOwp9CgpzdGF0aWMgdm9pZCBEU09VTkRfQ2hlY2tSZXNldChJRGlyZWN0U291bmRJbXBsICpkc291bmQsIERXT1JEIHdyaXRlcG9zKQp7CglpZiAocHJpbWFyeWJ1Zi0+bmVlZF9yZW1peCkgewoJCURTT1VORF9NaXhSZXNldCh3cml0ZXBvcyk7CgkJcHJpbWFyeWJ1Zi0+bmVlZF9yZW1peCA9IEZBTFNFOwoJCS8qIG1heGltaXplIEhhbGYtTGlmZSBwZXJmb3JtYW5jZSAqLwoJCWRzb3VuZC0+cHJlYnVmID0gRFNfU05EX1FVRVVFX01JTjsKCX0gZWxzZSB7CgkJLyogaWYgKGRzb3VuZC0+cHJlYnVmIDwgRFNfU05EX1FVRVVFX01BWCkgZHNvdW5kLT5wcmVidWYrKzsgKi8KCX0KCVRSQUNFKCJwcmVtaXggYWRqdXN0OiAlZFxuIiwgZHNvdW5kLT5wcmVidWYpOwp9CgpzdGF0aWMgdm9pZCBEU09VTkRfV2F2ZVF1ZXVlKElEaXJlY3RTb3VuZEltcGwgKmRzb3VuZCwgRFdPUkQgbWl4cSkKewoJaWYgKG1peHEgKyBkc291bmQtPnB3cXVldWUgPiBEU19IRUxfUVVFVUUpIG1peHEgPSBEU19IRUxfUVVFVUUgLSBkc291bmQtPnB3cXVldWU7CglUUkFDRSgicXVldWVpbmcgJWxkIGJ1ZmZlcnMsIHN0YXJ0aW5nIGF0ICVkXG4iLCBtaXhxLCBkc291bmQtPnB3d3JpdGUpOwoJZm9yICg7IG1peHE7IG1peHEtLSkgewoJCXdhdmVPdXRXcml0ZShkc291bmQtPmh3bywgZHNvdW5kLT5wd2F2ZVtkc291bmQtPnB3d3JpdGVdLCBzaXplb2YoV0FWRUhEUikpOwoJCWRzb3VuZC0+cHd3cml0ZSsrOwoJCWlmIChkc291bmQtPnB3d3JpdGUgPj0gRFNfSEVMX0ZSQUdTKSBkc291bmQtPnB3d3JpdGUgPSAwOwoJCWRzb3VuZC0+cHdxdWV1ZSsrOwoJfQp9CgovKiAjZGVmaW5lIFNZTkNfQ0FMTEJBQ0sgKi8KCnN0YXRpYyB2b2lkIERTT1VORF9QZXJmb3JtTWl4KHZvaWQpCnsKCWludCBuZmlsbGVyOwoJQk9PTCBmb3JjZWQ7CglIUkVTVUxUIGhyZXM7CgoJRW50ZXJDcml0aWNhbFNlY3Rpb24oJihkc291bmQtPmxvY2spKTsKCglpZiAoIXByaW1hcnlidWYgfHwgIXByaW1hcnlidWYtPnJlZikgewoJCS8qIHNlZW1zIHRoZSBwcmltYXJ5IGJ1ZmZlciBpcyBjdXJyZW50bHkgYmVpbmcgcmVsZWFzZWQgKi8KCQlMZWF2ZUNyaXRpY2FsU2VjdGlvbigmKGRzb3VuZC0+bG9jaykpOwoJCXJldHVybjsKCX0KCgkvKiB0aGUgc291bmQgb2Ygc2lsZW5jZSAqLwoJbmZpbGxlciA9IHByaW1hcnlidWYtPndmeC53Qml0c1BlclNhbXBsZSA9PSA4ID8gMTI4IDogMDsKCgkvKiB3aGV0aGVyIHRoZSBwcmltYXJ5IGlzIGZvcmNlZCB0byBwbGF5IGV2ZW4gd2l0aG91dCBzZWNvbmRhcnkgYnVmZmVycyAqLwoJZm9yY2VkID0gKChwcmltYXJ5YnVmLT5zdGF0ZSA9PSBTVEFURV9QTEFZSU5HKSB8fCAocHJpbWFyeWJ1Zi0+c3RhdGUgPT0gU1RBVEVfU1RBUlRJTkcpKTsKCiAgICAgICAgVFJBQ0UoImVudGVyaW5nIGF0ICVsZFxuIiwgR2V0VGlja0NvdW50KCkpOwoJaWYgKGRzb3VuZC0+cHJpb2xldmVsICE9IERTU0NMX1dSSVRFUFJJTUFSWSkgewoJCUJPT0wgcGF1c2VkID0gKChwcmltYXJ5YnVmLT5zdGF0ZSA9PSBTVEFURV9TVE9QUEVEKSB8fCAocHJpbWFyeWJ1Zi0+c3RhdGUgPT0gU1RBVEVfU1RBUlRJTkcpKTsKCQkvKiBGSVhNRTogZG9jdW1lbnQgdmFyaWFibGVzICovCiAJCURXT1JEIHBsYXlwb3MsIHdyaXRlcG9zLCBpbnEsIG1heHEsIGZyYWc7CiAJCWlmIChwcmltYXJ5YnVmLT5od2J1ZikgewoJCQlocmVzID0gSURzRHJpdmVyQnVmZmVyX0dldFBvc2l0aW9uKHByaW1hcnlidWYtPmh3YnVmLCAmcGxheXBvcywgJndyaXRlcG9zKTsKCQkJaWYgKGhyZXMpIHsKCQkJICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCYoZHNvdW5kLT5sb2NrKSk7CgkJCSAgICByZXR1cm47CgkJCX0KCQkJLyogV2VsbCwgd2UgKmNvdWxkKiBkbyBKdXN0LUluLVRpbWUgbWl4aW5nIHVzaW5nIHRoZSB3cml0ZXBvcywKCQkJICogYnV0IHRoYXQncyBhIGxpdHRsZSBiaXQgYW1iaXRpb3VzIGFuZCB1bm5lY2Vzc2FyeS4uLiAqLwoJCQkvKiByYXRoZXIgYWRkIG91ciBzYWZldHkgbWFyZ2luIHRvIHRoZSB3cml0ZXBvcywgaWYgd2UncmUgcGxheWluZyAqLwoJCQlpZiAoIXBhdXNlZCkgewoJCQkJd3JpdGVwb3MgKz0gcHJpbWFyeWJ1Zi0+d3JpdGVsZWFkOwoJCQkJd2hpbGUgKHdyaXRlcG9zID49IHByaW1hcnlidWYtPmJ1ZmxlbikKCQkJCQl3cml0ZXBvcyAtPSBwcmltYXJ5YnVmLT5idWZsZW47CgkJCX0gZWxzZSB3cml0ZXBvcyA9IHBsYXlwb3M7CgkJfQoJCWVsc2UgewogCQkJcGxheXBvcyA9IGRzb3VuZC0+cHdwbGF5ICogZHNvdW5kLT5mcmFnbGVuOwogCQkJd3JpdGVwb3MgPSBwbGF5cG9zOwogCQkJaWYgKCFwYXVzZWQpIHsKCSAJCQl3cml0ZXBvcyArPSBEU19IRUxfTUFSR0lOICogZHNvdW5kLT5mcmFnbGVuOwoJIAkJCXdoaWxlICh3cml0ZXBvcyA+PSBwcmltYXJ5YnVmLT5idWZsZW4pCiAJCQkJCXdyaXRlcG9zIC09IHByaW1hcnlidWYtPmJ1ZmxlbjsKCSAJCX0KCQl9CgkJVFJBQ0UoInByaW1hcnkgcGxheXBvcz0lbGQsIHdyaXRlcG9zPSVsZCwgY2xycG9zPSVsZCwgbWl4cG9zPSVsZFxuIiwKCQkgICAgICBwbGF5cG9zLHdyaXRlcG9zLHByaW1hcnlidWYtPnBsYXlwb3MscHJpbWFyeWJ1Zi0+YnVmX21peHBvcyk7CgkJLyogd2lwZSBvdXQganVzdC1wbGF5ZWQgc291bmQgZGF0YSAqLwoJCWlmIChwbGF5cG9zIDwgcHJpbWFyeWJ1Zi0+cGxheXBvcykgewoJCQltZW1zZXQocHJpbWFyeWJ1Zi0+YnVmZmVyICsgcHJpbWFyeWJ1Zi0+cGxheXBvcywgbmZpbGxlciwgcHJpbWFyeWJ1Zi0+YnVmbGVuIC0gcHJpbWFyeWJ1Zi0+cGxheXBvcyk7CgkJCW1lbXNldChwcmltYXJ5YnVmLT5idWZmZXIsIG5maWxsZXIsIHBsYXlwb3MpOwoJCX0gZWxzZSB7CgkJCW1lbXNldChwcmltYXJ5YnVmLT5idWZmZXIgKyBwcmltYXJ5YnVmLT5wbGF5cG9zLCBuZmlsbGVyLCBwbGF5cG9zIC0gcHJpbWFyeWJ1Zi0+cGxheXBvcyk7CgkJfQoJCXByaW1hcnlidWYtPnBsYXlwb3MgPSBwbGF5cG9zOwoKCQlFbnRlckNyaXRpY2FsU2VjdGlvbigmKHByaW1hcnlidWYtPmxvY2spKTsKCgkJLyogcmVzZXQgbWl4aW5nIGlmIG5lY2Vzc2FyeSAqLwoJCURTT1VORF9DaGVja1Jlc2V0KGRzb3VuZCwgd3JpdGVwb3MpOwoKCQkvKiBjaGVjayBob3cgbXVjaCBwcmVidWZmZXJpbmcgaXMgbGVmdCAqLwoJCWlucSA9IHByaW1hcnlidWYtPmJ1Zl9taXhwb3M7CgkJaWYgKGlucSA8IHdyaXRlcG9zKQoJCQlpbnEgKz0gcHJpbWFyeWJ1Zi0+YnVmbGVuOwoJCWlucSAtPSB3cml0ZXBvczsKCgkJLyogZmluZCB0aGUgbWF4aW11bSB3ZSBjYW4gcHJlYnVmZmVyICovCgkJaWYgKCFwYXVzZWQpIHsKCQkJbWF4cSA9IHBsYXlwb3M7CgkJCWlmIChtYXhxIDwgd3JpdGVwb3MpCgkJCQltYXhxICs9IHByaW1hcnlidWYtPmJ1ZmxlbjsKCQkJbWF4cSAtPSB3cml0ZXBvczsKCQl9IGVsc2UgbWF4cSA9IHByaW1hcnlidWYtPmJ1ZmxlbjsKCgkJLyogY2xpcCBtYXhxIHRvIGRzb3VuZC0+cHJlYnVmICovCgkJZnJhZyA9IGRzb3VuZC0+cHJlYnVmICogZHNvdW5kLT5mcmFnbGVuOwoJCWlmIChtYXhxID4gZnJhZykgbWF4cSA9IGZyYWc7CgoJCS8qIGNoZWNrIGZvciBjb25zaXN0ZW5jeSAqLwoJCWlmIChpbnEgPiBtYXhxKSB7CgkJCS8qIHRoZSBwbGF5YmFjayBwb3NpdGlvbiBtdXN0IGhhdmUgcGFzc2VkIG91ciBsYXN0CgkJCSAqIG1peGVkIHBvc2l0aW9uLCBpLmUuIGl0J3MgYW4gdW5kZXJydW4sIG9yIHdlIGhhdmUKCQkJICogbm90aGluZyBtb3JlIHRvIHBsYXkgKi8KCQkJVFJBQ0UoInJlYWNoZWQgZW5kIG9mIG1peGVkIGRhdGEgKGlucT0lbGQsIG1heHE9JWxkKVxuIiwgaW5xLCBtYXhxKTsKCQkJaW5xID0gMDsKCQkJLyogc3RvcCB0aGUgcGxheWJhY2sgbm93LCB0byBhbGxvdyBidWZmZXJzIHRvIHJlZmlsbCAqLwoJCQlpZiAocHJpbWFyeWJ1Zi0+c3RhdGUgPT0gU1RBVEVfUExBWUlORykgewoJCQkJcHJpbWFyeWJ1Zi0+c3RhdGUgPSBTVEFURV9TVEFSVElORzsKCQkJfQoJCQllbHNlIGlmIChwcmltYXJ5YnVmLT5zdGF0ZSA9PSBTVEFURV9TVE9QUElORykgewoJCQkJcHJpbWFyeWJ1Zi0+c3RhdGUgPSBTVEFURV9TVE9QUEVEOwoJCQl9CgkJCWVsc2UgewoJCQkJLyogaG93IGNhbiB3ZSBoYXZlIGFuIHVuZGVycnVuIGlmIHdlIGFyZW4ndCBwbGF5aW5nPyAqLwoJCQkJV0FSTigidW5leHBlY3RlZCBwcmltYXJ5IHN0YXRlICglbGQpXG4iLCBwcmltYXJ5YnVmLT5zdGF0ZSk7CgkJCX0KI2lmZGVmIFNZTkNfQ0FMTEJBQ0sKCQkJLyogRFNPVU5EX2NhbGxiYWNrIG1heSBuZWVkIHRoaXMgbG9jayAqLwoJCQlMZWF2ZUNyaXRpY2FsU2VjdGlvbigmKHByaW1hcnlidWYtPmxvY2spKTsKI2VuZGlmCgkJCURTT1VORF9QcmltYXJ5U3RvcChwcmltYXJ5YnVmKTsKI2lmZGVmIFNZTkNfQ0FMTEJBQ0sKCQkJRW50ZXJDcml0aWNhbFNlY3Rpb24oJihwcmltYXJ5YnVmLT5sb2NrKSk7CiNlbmRpZgoJCQlpZiAocHJpbWFyeWJ1Zi0+aHdidWYpIHsKCQkJCS8qIHRoZSBTdG9wIGlzIHN1cHBvc2VkIHRvIHJlc2V0IHBsYXkgcG9zaXRpb24gdG8gYmVnaW5uaW5nIG9mIGJ1ZmZlciAqLwoJCQkJLyogdW5mb3J0dW5hdGVseSwgT1NTIGlzIG5vdCBhYmxlIHRvIGRvIHNvLCBzbyBnZXQgY3VycmVudCBwb2ludGVyICovCgkJCQlocmVzID0gSURzRHJpdmVyQnVmZmVyX0dldFBvc2l0aW9uKHByaW1hcnlidWYtPmh3YnVmLCAmcGxheXBvcywgTlVMTCk7CgkJCQlpZiAoaHJlcykgewoJCQkJCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCYoZHNvdW5kLT5sb2NrKSk7CgkJCQkJTGVhdmVDcml0aWNhbFNlY3Rpb24oJihwcmltYXJ5YnVmLT5sb2NrKSk7CgkJCQkJcmV0dXJuOwoJCQkJfQoJCQl9IGVsc2UgewoJIAkJCXBsYXlwb3MgPSBkc291bmQtPnB3cGxheSAqIGRzb3VuZC0+ZnJhZ2xlbjsKCQkJfQoJCQl3cml0ZXBvcyA9IHBsYXlwb3M7CgkJCXByaW1hcnlidWYtPnBsYXlwb3MgPSBwbGF5cG9zOwoJCQlwcmltYXJ5YnVmLT5idWZfbWl4cG9zID0gd3JpdGVwb3M7CgkJCWlucSA9IDA7CgkJCW1heHEgPSBwcmltYXJ5YnVmLT5idWZsZW47CgkJCWlmIChtYXhxID4gZnJhZykgbWF4cSA9IGZyYWc7CgkJCW1lbXNldChwcmltYXJ5YnVmLT5idWZmZXIsIG5maWxsZXIsIHByaW1hcnlidWYtPmJ1Zmxlbik7CgkJCXBhdXNlZCA9IFRSVUU7CgkJfQoKCQkvKiBkbyB0aGUgbWl4aW5nICovCgkJZnJhZyA9IERTT1VORF9NaXhUb1ByaW1hcnkocGxheXBvcywgd3JpdGVwb3MsIG1heHEsIHBhdXNlZCk7CgkJaWYgKGZvcmNlZCkgZnJhZyA9IG1heHEgLSBpbnE7CgkJcHJpbWFyeWJ1Zi0+YnVmX21peHBvcyArPSBmcmFnOwoJCXdoaWxlIChwcmltYXJ5YnVmLT5idWZfbWl4cG9zID49IHByaW1hcnlidWYtPmJ1ZmxlbikKCQkJcHJpbWFyeWJ1Zi0+YnVmX21peHBvcyAtPSBwcmltYXJ5YnVmLT5idWZsZW47CgoJCWlmIChmcmFnKSB7CgkJCS8qIGJ1ZmZlcnMgaGF2ZSBiZWVuIGZpbGxlZCwgcmVzdGFydCBwbGF5YmFjayAqLwoJCQlpZiAocHJpbWFyeWJ1Zi0+c3RhdGUgPT0gU1RBVEVfU1RBUlRJTkcpIHsKCQkJCXByaW1hcnlidWYtPnN0YXRlID0gU1RBVEVfUExBWUlORzsKCQkJfQoJCQllbHNlIGlmIChwcmltYXJ5YnVmLT5zdGF0ZSA9PSBTVEFURV9TVE9QUEVEKSB7CgkJCQkvKiB0aGUgcHJpbWFyeWJ1ZiBpcyBzdXBwb3NlZCB0byBwbGF5IGlmIHRoZXJlJ3Mgc29tZXRoaW5nIHRvIHBsYXkKCQkJCSAqIGV2ZW4gaWYgaXQgaXMgcmVwb3J0ZWQgYXMgc3RvcHBlZCwgc28gZG9uJ3QgbGV0IHRoaXMgY29uZnVzZSB5b3UgKi8KCQkJCXByaW1hcnlidWYtPnN0YXRlID0gU1RBVEVfU1RPUFBJTkc7CgkJCX0KCQkJTGVhdmVDcml0aWNhbFNlY3Rpb24oJihwcmltYXJ5YnVmLT5sb2NrKSk7CgkJCWlmIChwYXVzZWQpIHsKCQkJCURTT1VORF9QcmltYXJ5UGxheShwcmltYXJ5YnVmKTsKCQkJCVRSQUNFKCJzdGFydGluZyBwbGF5YmFja1xuIik7CgkJCX0KCQl9CgkJZWxzZQoJCQlMZWF2ZUNyaXRpY2FsU2VjdGlvbigmKHByaW1hcnlidWYtPmxvY2spKTsKCX0gZWxzZSB7CgkJLyogaW4gdGhlIERTU0NMX1dSSVRFUFJJTUFSWSBtb2RlLCB0aGUgYXBwIGlzIHRvdGFsbHkgaW4gY2hhcmdlLi4uICovCgkJaWYgKHByaW1hcnlidWYtPnN0YXRlID09IFNUQVRFX1NUQVJUSU5HKSB7CgkJCURTT1VORF9QcmltYXJ5UGxheShwcmltYXJ5YnVmKTsKCQkJcHJpbWFyeWJ1Zi0+c3RhdGUgPSBTVEFURV9QTEFZSU5HOwoJCX0gCgkJZWxzZSBpZiAocHJpbWFyeWJ1Zi0+c3RhdGUgPT0gU1RBVEVfU1RPUFBJTkcpIHsKCQkJRFNPVU5EX1ByaW1hcnlTdG9wKHByaW1hcnlidWYpOwoJCQlwcmltYXJ5YnVmLT5zdGF0ZSA9IFNUQVRFX1NUT1BQRUQ7CgkJfQoJfQoJVFJBQ0UoImNvbXBsZXRlZCBwcm9jZXNzaW5nIGF0ICVsZFxuIiwgR2V0VGlja0NvdW50KCkpOwoJTGVhdmVDcml0aWNhbFNlY3Rpb24oJihkc291bmQtPmxvY2spKTsKfQoKc3RhdGljIHZvaWQgQ0FMTEJBQ0sgRFNPVU5EX3RpbWVyKFVJTlQgdGltZXJJRCwgVUlOVCBtc2csIERXT1JEIGR3VXNlciwgRFdPUkQgZHcxLCBEV09SRCBkdzIpCnsKCWlmICghZHNvdW5kIHx8ICFwcmltYXJ5YnVmKSB7CgkJRVJSKCJkc291bmQgZGllZCB3aXRob3V0IGtpbGxpbmcgdXM/XG4iKTsKCQl0aW1lS2lsbEV2ZW50KHRpbWVySUQpOwoJCXRpbWVFbmRQZXJpb2QoRFNfVElNRV9SRVMpOwoJCXJldHVybjsKCX0KCglUUkFDRSgiZW50ZXJlZFxuIik7CglEU09VTkRfUGVyZm9ybU1peCgpOwp9CgpzdGF0aWMgdm9pZCBDQUxMQkFDSyBEU09VTkRfY2FsbGJhY2soSFdBVkVPVVQgaHdvLCBVSU5UIG1zZywgRFdPUkQgZHdVc2VyLCBEV09SRCBkdzEsIERXT1JEIGR3MikKewogICAgICAgIElEaXJlY3RTb3VuZEltcGwqIFRoaXMgPSAoSURpcmVjdFNvdW5kSW1wbCopZHdVc2VyOwoJVFJBQ0UoImVudGVyaW5nIGF0ICVsZCwgbXNnPSUwOHhcbiIsIEdldFRpY2tDb3VudCgpLCBtc2cpOwoJaWYgKG1zZyA9PSBNTV9XT01fRE9ORSkgewoJCURXT1JEIGlucSwgbWl4cSwgZnJhZ2xlbiwgYnVmbGVuLCBwd3BsYXksIHBsYXlwb3MsIG1peHBvczsKCQlpZiAoVGhpcy0+cHdxdWV1ZSA9PSAoRFdPUkQpLTEpIHsKCQkJVFJBQ0UoImNvbXBsZXRlZCBkdWUgdG8gcmVzZXRcbiIpOwoJCQlyZXR1cm47CgkJfQovKiBpdCBjb3VsZCBiZSBhIGJhZCBpZGVhIHRvIGVudGVyIGNyaXRpY2FsIHNlY3Rpb24gaGVyZS4uLiBpZiB0aGVyZSdzIGxvY2sgY29udGVudGlvbiwKICogdGhlIHJlc3VsdGluZyBzY2hlZHVsaW5nIGRlbGF5cyBtaWdodCBvYnN0cnVjdCB0aGUgd2lubW0gcGxheWVyIHRocmVhZCAqLwojaWZkZWYgU1lOQ19DQUxMQkFDSwoJCUVudGVyQ3JpdGljYWxTZWN0aW9uKCYocHJpbWFyeWJ1Zi0+bG9jaykpOwojZW5kaWYKCQkvKiByZXRyaWV2ZSBjdXJyZW50IHZhbHVlcyAqLwoJCWZyYWdsZW4gPSBkc291bmQtPmZyYWdsZW47CgkJYnVmbGVuID0gcHJpbWFyeWJ1Zi0+YnVmbGVuOwoJCXB3cGxheSA9IGRzb3VuZC0+cHdwbGF5OwoJCXBsYXlwb3MgPSBwd3BsYXkgKiBmcmFnbGVuOwoJCW1peHBvcyA9IHByaW1hcnlidWYtPmJ1Zl9taXhwb3M7CgkJLyogY2hlY2sgcmVtYWluaW5nIG1peGVkIGRhdGEgKi8KCQlpbnEgPSAoKG1peHBvcyA8IHBsYXlwb3MpID8gYnVmbGVuIDogMCkgKyBtaXhwb3MgLSBwbGF5cG9zOwoJCW1peHEgPSBpbnEgLyBmcmFnbGVuOwoJCWlmICgoaW5xIC0gKG1peHEgKiBmcmFnbGVuKSkgPiAwKSBtaXhxKys7CgkJLyogY29tcGxldGUgdGhlIHBsYXlpbmcgYnVmZmVyICovCgkJVFJBQ0UoImRvbmUgcGxheWluZyBwcmltYXJ5IHBvcz0lbGRcbiIsIHBsYXlwb3MpOwoJCXB3cGxheSsrOwoJCWlmIChwd3BsYXkgPj0gRFNfSEVMX0ZSQUdTKSBwd3BsYXkgPSAwOwoJCS8qIHdyaXRlIG5ldyB2YWx1ZXMgKi8KCQlkc291bmQtPnB3cGxheSA9IHB3cGxheTsKCQlkc291bmQtPnB3cXVldWUtLTsKCQkvKiBxdWV1ZSBuZXcgYnVmZmVyIGlmIHdlIGhhdmUgZGF0YSBmb3IgaXQgKi8KCQlpZiAoaW5xPjEpIERTT1VORF9XYXZlUXVldWUoVGhpcywgaW5xLTEpOwojaWZkZWYgU1lOQ19DQUxMQkFDSwoJCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCYocHJpbWFyeWJ1Zi0+bG9jaykpOwojZW5kaWYKCX0KCVRSQUNFKCJjb21wbGV0ZWRcbiIpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJRGlyZWN0U291bmRDcmVhdGUgKERTT1VORC4xKQogKi8KSFJFU1VMVCBXSU5BUEkgRGlyZWN0U291bmRDcmVhdGUoUkVGR1VJRCBscEdVSUQsTFBESVJFQ1RTT1VORCAqcHBEUyxJVW5rbm93biAqcFVua091dGVyICkKewoJSURpcmVjdFNvdW5kSW1wbCoqIGlwcERTPShJRGlyZWN0U291bmRJbXBsKiopcHBEUzsKCVBJRFNEUklWRVIgZHJ2ID0gTlVMTDsKCVdBVkVPVVRDQVBTQSB3Y2FwczsKCXVuc2lnbmVkIHdvZCwgd29kbjsKCUhSRVNVTFQgZXJyID0gRFNfT0s7CgoJaWYgKGxwR1VJRCkKCQlUUkFDRSgiKCVwLCVwLCVwKVxuIixscEdVSUQsaXBwRFMscFVua091dGVyKTsKCWVsc2UKCQlUUkFDRSgiRGlyZWN0U291bmRDcmVhdGUgKCVwKVxuIiwgaXBwRFMpOwoKCWlmIChpcHBEUyA9PSBOVUxMKQoJCXJldHVybiBEU0VSUl9JTlZBTElEUEFSQU07CgoJaWYgKHByaW1hcnlidWYpIHsKCQlJRGlyZWN0U291bmRfQWRkUmVmKChMUERJUkVDVFNPVU5EKWRzb3VuZCk7CgkJKmlwcERTID0gZHNvdW5kOwoJCXJldHVybiBEU19PSzsKCX0KCgkvKiBFbnVtZXJhdGUgV0lOTU0gYXVkaW8gZGV2aWNlcyBhbmQgZmluZCB0aGUgb25lIHdlIHdhbnQgKi8KCXdvZG4gPSB3YXZlT3V0R2V0TnVtRGV2cygpOwoJaWYgKCF3b2RuKSByZXR1cm4gRFNFUlJfTk9EUklWRVI7CgoJLyogRklYTUU6IEhvdyBkbyB3ZSBmaW5kIHRoZSBHVUlEIG9mIGFuIGF1ZGlvIGRldmljZT8gKi8KCXdvZCA9IDA7IC8qIHN0YXJ0IGF0IHRoZSBmaXJzdCBhdWRpbyBkZXZpY2UgKi8KCgkvKiBHZXQgb3V0cHV0IGRldmljZSBjYXBzICovCgl3YXZlT3V0R2V0RGV2Q2Fwc0Eod29kLCAmd2NhcHMsIHNpemVvZih3Y2FwcykpOwoJLyogRFJWX1FVRVJZRFNPVU5ESUZBQ0UgaXMgYSAiV2luZSBleHRlbnNpb24iIHRvIGdldCB0aGUgRFNvdW5kIGludGVyZmFjZSAqLwoJd2F2ZU91dE1lc3NhZ2Uod29kLCBEUlZfUVVFUllEU09VTkRJRkFDRSwgKERXT1JEKSZkcnYsIDApOwoKCS8qIEFsbG9jYXRlIG1lbW9yeSAqLwoJKmlwcERTID0gKElEaXJlY3RTb3VuZEltcGwqKUhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLDAsc2l6ZW9mKElEaXJlY3RTb3VuZEltcGwpKTsKCWlmICgqaXBwRFMgPT0gTlVMTCkKCQlyZXR1cm4gRFNFUlJfT1VUT0ZNRU1PUlk7CgoJSUNPTV9WVEJMKCppcHBEUykJPSAmZHN2dDsKCSgqaXBwRFMpLT5yZWYJCT0gMTsKCgkoKmlwcERTKS0+ZHJpdmVyCT0gZHJ2OwoJKCppcHBEUyktPmZyYWdsZW4JPSAwOwoJKCppcHBEUyktPnByaW9sZXZlbAk9IERTU0NMX05PUk1BTDsgCgkoKmlwcERTKS0+bnJvZmJ1ZmZlcnMJPSAwOwoJKCppcHBEUyktPmJ1ZmZlcnMJPSBOVUxMOwoJKCppcHBEUyktPnByaW1hcnkJPSBOVUxMOyAKCSgqaXBwRFMpLT5saXN0ZW5lcgk9IE5VTEw7IAoKCSgqaXBwRFMpLT5wcmVidWYJPSBEU19TTkRfUVVFVUVfTUFYOwoKCS8qIEdldCBkcml2ZXIgZGVzY3JpcHRpb24gKi8KCWlmIChkcnYpIHsKCQlJRHNEcml2ZXJfR2V0RHJpdmVyRGVzYyhkcnYsJigoKmlwcERTKS0+ZHJ2ZGVzYykpOwoJfSBlbHNlIHsKCQkvKiBpZiBubyBEaXJlY3RTb3VuZCBpbnRlcmZhY2UgYXZhaWxhYmxlLCB1c2UgV0lOTU0gQVBJIGluc3RlYWQgKi8KCQkoKmlwcERTKS0+ZHJ2ZGVzYy5kd0ZsYWdzID0gRFNEREVTQ19ET01NU1lTVEVNT1BFTiB8IERTRERFU0NfRE9NTVNZU1RFTVNFVEZPUk1BVDsKCQkoKmlwcERTKS0+ZHJ2ZGVzYy5kbkRldk5vZGUgPSB3b2Q7IC8qIEZJWE1FPyAqLwoJfQoKCS8qIFNldCBkZWZhdWx0IHdhdmUgZm9ybWF0IChtYXkgbmVlZCBpdCBmb3Igd2F2ZU91dE9wZW4pICovCgkoKmlwcERTKS0+d2Z4LndGb3JtYXRUYWcJPSBXQVZFX0ZPUk1BVF9QQ007CgkoKmlwcERTKS0+d2Z4Lm5DaGFubmVscwkJPSAyOwoJKCppcHBEUyktPndmeC5uU2FtcGxlc1BlclNlYwk9IDIyMDUwOwoJKCppcHBEUyktPndmeC5uQXZnQnl0ZXNQZXJTZWMJPSA0NDEwMDsKCSgqaXBwRFMpLT53ZngubkJsb2NrQWxpZ24JPSAyOwoJKCppcHBEUyktPndmeC53Qml0c1BlclNhbXBsZQk9IDg7CgoJLyogSWYgdGhlIGRyaXZlciByZXF1ZXN0cyBiZWluZyBvcGVuZWQgdGhyb3VnaCBNTVNZU1RFTQoJICogKHdoaWNoIGlzIHJlY29tbWVuZGVkIGJ5IHRoZSBEREspLCBpdCBpcyBzdXBwb3NlZCB0byBoYXBwZW4KCSAqIGJlZm9yZSB0aGUgRGlyZWN0U291bmQgaW50ZXJmYWNlIGlzIG9wZW5lZCAqLwoJaWYgKCgqaXBwRFMpLT5kcnZkZXNjLmR3RmxhZ3MgJiBEU0RERVNDX0RPTU1TWVNURU1PUEVOKQoJewoJCS8qIEZJWE1FOiBpcyB0aGlzIHJpZ2h0PyAqLwoKCSAgICAgICAgKCppcHBEUyktPmRydmRlc2MuZG5EZXZOb2RlID0gMDsKCQllcnIgPSBEU0VSUl9BTExPQ0FURUQ7CgoJCS8qIGlmIHRoaXMgZGV2aWNlIGlzIGJ1c3kgdHJ5IHRoZSBuZXh0IG9uZSAqLwoJCXdoaWxlKChlcnIgPT0gRFNFUlJfQUxMT0NBVEVEKSAmJiAKCQkJKCgqaXBwRFMpLT5kcnZkZXNjLmRuRGV2Tm9kZSA8IHdvZG4pKQogIAkJewoJCSAgZXJyID0gbW1FcnIod2F2ZU91dE9wZW4oJigoKmlwcERTKS0+aHdvKSwgCgkJCSgqaXBwRFMpLT5kcnZkZXNjLmRuRGV2Tm9kZSwgJigoKmlwcERTKS0+d2Z4KSwKCQkJKERXT1JEKURTT1VORF9jYWxsYmFjaywgKERXT1JEKSgqaXBwRFMpLAoJCQlDQUxMQkFDS19GVU5DVElPTiB8IFdBVkVfRElSRUNUU09VTkQpKTsKICAgICAgICAgICAgICAgICAgKCppcHBEUyktPmRydmRlc2MuZG5EZXZOb2RlKys7IC8qIG5leHQgd2F2ZSBkZXZpY2UgKi8KCQl9CgogICAgICAgICAgICAgICAgKCppcHBEUyktPmRydmRlc2MuZG5EZXZOb2RlLS07IC8qIHRha2UgYXdheSBsYXN0IGluY3JlbWVudCAqLwoJCQoJfQoKCWlmIChkcnYgJiYgKGVyciA9PSBEU19PSykpCgkJZXJyID0gSURzRHJpdmVyX09wZW4oZHJ2KTsKCgkvKiBGSVhNRTogZG8gd2Ugd2FudCB0byBoYW5kbGUgYSB0ZW1wb3JhcmlseSBidXN5IGRldmljZT8gKi8KCWlmIChlcnIgIT0gRFNfT0spIHsKCQlIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsKmlwcERTKTsKCQkqaXBwRFMgPSBOVUxMOwoJCXJldHVybiBlcnI7Cgl9CgoJLyogdGhlIGRyaXZlciBpcyBub3cgb3Blbiwgc28gaXQncyBub3cgYWxsb3dlZCB0byBjYWxsIEdldENhcHMgKi8KCWlmIChkcnYpIHsKCQlJRHNEcml2ZXJfR2V0Q2FwcyhkcnYsJigoKmlwcERTKS0+ZHJ2Y2FwcykpOwoJfSBlbHNlIHsKCQl1bnNpZ25lZCBjOwoKCQkvKiBGSVhNRTogbG9vayBhdCB3Y2FwcyAqLwoJCSgqaXBwRFMpLT5kcnZjYXBzLmR3RmxhZ3MgPQoJCQlEU0NBUFNfUFJJTUFSWTE2QklUIHwgRFNDQVBTX1BSSU1BUllTVEVSRU87CgkJaWYgKERTX0VNVUxEUklWRVIpCgkJICAgICgqaXBwRFMpLT5kcnZjYXBzLmR3RmxhZ3MgfD0gRFNDQVBTX0VNVUxEUklWRVI7CgoJCS8qIEFsbG9jYXRlIG1lbW9yeSBmb3IgSEVMIGJ1ZmZlciBoZWFkZXJzICovCgkJZm9yIChjPTA7IGM8RFNfSEVMX0ZSQUdTOyBjKyspIHsKCQkJKCppcHBEUyktPnB3YXZlW2NdID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksSEVBUF9aRVJPX01FTU9SWSxzaXplb2YoV0FWRUhEUikpOwoJCQlpZiAoISgqaXBwRFMpLT5wd2F2ZVtjXSkgewoJCQkJLyogQXJnaCwgb3V0IG9mIG1lbW9yeSAqLwoJCQkJd2hpbGUgKGMtLSkgewoJCQkJCUhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCwoKmlwcERTKS0+cHdhdmVbY10pOwoJCQkJCXdhdmVPdXRDbG9zZSgoKmlwcERTKS0+aHdvKTsKCQkJCQlIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsKmlwcERTKTsKCQkJCQkqaXBwRFMgPSBOVUxMOwoJCQkJCXJldHVybiBEU0VSUl9PVVRPRk1FTU9SWTsKCQkJCX0KCQkJfQoJCX0KCX0KCglJbml0aWFsaXplQ3JpdGljYWxTZWN0aW9uKCYoKCppcHBEUyktPmxvY2spKTsKCglpZiAoIWRzb3VuZCkgewoJCWRzb3VuZCA9ICgqaXBwRFMpOwoJCWlmIChwcmltYXJ5YnVmID09IE5VTEwpIHsKCQkJRFNCVUZGRVJERVNDCWRzYmQ7CgkJCUhSRVNVTFQJCWhyOwoKCQkJZHNiZC5kd1NpemUgPSBzaXplb2YoRFNCVUZGRVJERVNDKTsKCQkJZHNiZC5kd0ZsYWdzID0gRFNCQ0FQU19QUklNQVJZQlVGRkVSOwoJCQlkc2JkLmR3QnVmZmVyQnl0ZXMgPSAwOwoJCQlkc2JkLmxwd2Z4Rm9ybWF0ID0gJihkc291bmQtPndmeCk7CgkJCWhyID0gSURpcmVjdFNvdW5kX0NyZWF0ZVNvdW5kQnVmZmVyKCpwcERTLCAmZHNiZCwgKExQRElSRUNUU09VTkRCVUZGRVIqKSZwcmltYXJ5YnVmLCBOVUxMKTsKCQkJaWYgKGhyICE9IERTX09LKQoJCQkJcmV0dXJuIGhyOwoKCQkJLyogZHNvdW5kLT5wcmltYXJ5IGlzIE5VTEwgLSBkb24ndCBuZWVkIHRvIFJlbGVhc2UgKi8KCQkJZHNvdW5kLT5wcmltYXJ5ID0gcHJpbWFyeWJ1ZjsKCQkJSURpcmVjdFNvdW5kQnVmZmVyX0FkZFJlZigoTFBESVJFQ1RTT1VOREJVRkZFUilwcmltYXJ5YnVmKTsKCQl9CgkJdGltZUJlZ2luUGVyaW9kKERTX1RJTUVfUkVTKTsKCQlkc291bmQtPnRpbWVySUQgPSB0aW1lU2V0RXZlbnQoRFNfVElNRV9ERUwsIERTX1RJTUVfUkVTLCBEU09VTkRfdGltZXIsCgkJCQkJICAgICAgIChEV09SRClkc291bmQsIFRJTUVfUEVSSU9ESUMgfCBUSU1FX0NBTExCQUNLX0ZVTkNUSU9OKTsKCX0KCXJldHVybiBEU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEaXJlY3RTb3VuZENhcHR1cmVDcmVhdGUgW0RTT1VORC42XQogKgogKiBDcmVhdGUgYW5kIGluaXRpYWxpemUgYSBEaXJlY3RTb3VuZENhcHR1cmUgaW50ZXJmYWNlCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRFNfT0sKICogICAgRmFpbHVyZTogRFNFUlJfTk9BR0dSRUdBVElPTiwgRFNFUlJfQUxMT0NBVEVELCBEU0VSUl9JTlZBTElEUEFSQU0sCiAqICAgICAgICAgICAgIERTRVJSX09VVE9GTUVNT1JZCiAqLwpIUkVTVUxUIFdJTkFQSSBEaXJlY3RTb3VuZENhcHR1cmVDcmVhdGUoCglMUENHVUlEIGxwY0dVSUQsCglMUERJUkVDVFNPVU5EQ0FQVFVSRSogbHBscERTQywKCUxQVU5LTk9XTiBwVW5rT3V0ZXIgKQp7CglUUkFDRSgiKCVzLCVwLCVwKVxuIiwgZGVidWdzdHJfZ3VpZChscGNHVUlEKSwgbHBscERTQywgcFVua091dGVyKTsKCglpZiggcFVua091dGVyICkgewoJCXJldHVybiBEU0VSUl9OT0FHR1JFR0FUSU9OOwoJfQoKCS8qIERlZmF1bHQgZGV2aWNlPyAqLwoJaWYgKCAhbHBjR1VJRCApIHsKCQlyZXR1cm4gRFNPVU5EX0NyZWF0ZURpcmVjdFNvdW5kQ2FwdHVyZSggKExQVk9JRCopbHBscERTQyApOwoJfQoKCUZJWE1FKCAiVW5rbm93biBHVUlEICVzXG4iLCBkZWJ1Z3N0cl9ndWlkKGxwY0dVSUQpICk7CgkqbHBscERTQyA9IE5VTEw7CgoJcmV0dXJuIERTRVJSX09VVE9GTUVNT1JZOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERpcmVjdFNvdW5kQ2FwdHVyZUVudW1lcmF0ZUEgW0RTT1VORC43XQogKgogKiBFbnVtZXJhdGUgYWxsIERpcmVjdFNvdW5kIGRyaXZlcnMgaW5zdGFsbGVkIGluIHRoZSBzeXN0ZW0KICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBEU19PSwogKiAgICBGYWlsdXJlOiBEU0VSUl9JTlZBTElEUEFSQU0KICovCkhSRVNVTFQgV0lOQVBJIERpcmVjdFNvdW5kQ2FwdHVyZUVudW1lcmF0ZUEoCiAgICAgICAgTFBEU0VOVU1DQUxMQkFDS0EgbHBEU0VudW1DYWxsYmFjaywKICAgICAgICBMUFZPSUQgbHBDb250ZXh0KQp7CglUUkFDRSgiKCVwLCVwKVxuIiwgbHBEU0VudW1DYWxsYmFjaywgbHBDb250ZXh0ICk7CgoJaWYgKCBscERTRW51bUNhbGxiYWNrICkKCQlscERTRW51bUNhbGxiYWNrKE5VTEwsIldJTkUgUHJpbWFyeSBTb3VuZCBDYXB0dXJlIERyaXZlciIsCiAgICAgICAgICAgICAgICAgICAgIlNvdW5kQ2FwIixscENvbnRleHQpOwoKCglyZXR1cm4gRFNfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGlyZWN0U291bmRDYXB0dXJlRW51bWVyYXRlVyBbRFNPVU5ELjhdCiAqCiAqIEVudW1lcmF0ZSBhbGwgRGlyZWN0U291bmQgZHJpdmVycyBpbnN0YWxsZWQgaW4gdGhlIHN5c3RlbQogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IERTX09LCiAqICAgIEZhaWx1cmU6IERTRVJSX0lOVkFMSURQQVJBTQogKi8KSFJFU1VMVCBXSU5BUEkgRGlyZWN0U291bmRDYXB0dXJlRW51bWVyYXRlVygKICAgICAgICBMUERTRU5VTUNBTExCQUNLVyBscERTRW51bUNhbGxiYWNrLAogICAgICAgIExQVk9JRCBscENvbnRleHQpCnsKICAgICAgICBGSVhNRSgiKCVwLCVwKTpzdHViXG4iLCBscERTRW51bUNhbGxiYWNrLCBscENvbnRleHQgKTsKICAgICAgICByZXR1cm4gRFNfT0s7Cn0gCgpzdGF0aWMgSFJFU1VMVApEU09VTkRfQ3JlYXRlRGlyZWN0U291bmRDYXB0dXJlKCBMUFZPSUQqIHBwb2JqICkKewoJKnBwb2JqID0gSGVhcEFsbG9jKCBHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoIElEaXJlY3RTb3VuZENhcHR1cmVJbXBsICkgKTsKCglpZiAoICpwcG9iaiA9PSBOVUxMICkgewoJCXJldHVybiBEU0VSUl9PVVRPRk1FTU9SWTsKCX0KCgl7CgkJSUNPTV9USElTKElEaXJlY3RTb3VuZENhcHR1cmVJbXBsLCpwcG9iaik7CgoJCVRoaXMtPnJlZiA9IDE7CgkJSUNPTV9WVEJMKFRoaXMpID0gJmRzY3Z0OwoKCQlJbml0aWFsaXplQ3JpdGljYWxTZWN0aW9uKCAmVGhpcy0+bG9jayApOwoJfQoKCXJldHVybiBTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdFNvdW5kQ2FwdHVyZUltcGxfUXVlcnlJbnRlcmZhY2UoCglMUERJUkVDVFNPVU5EQ0FQVFVSRSBpZmFjZSwKCVJFRklJRCByaWlkLAoJTFBWT0lEKiBwcG9iaiApCnsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRDYXB0dXJlSW1wbCxpZmFjZSk7CgoJRklYTUUoICIoJXApLT4oJXMsJXApOiBzdHViXG4iLCBUaGlzLCBkZWJ1Z3N0cl9ndWlkKHJpaWQpLCBwcG9iaiApOwoKCXJldHVybiBFX0ZBSUw7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkKSURpcmVjdFNvdW5kQ2FwdHVyZUltcGxfQWRkUmVmKCBMUERJUkVDVFNPVU5EQ0FQVFVSRSBpZmFjZSApCnsKCVVMT05HIHVSZWY7CiAgICAgICAgSUNPTV9USElTKElEaXJlY3RTb3VuZENhcHR1cmVJbXBsLGlmYWNlKTsKCglFbnRlckNyaXRpY2FsU2VjdGlvbiggJlRoaXMtPmxvY2sgKTsKCglUUkFDRSggIiglcCkgd2FzIDB4JTA4bHhcbiIsIFRoaXMsIFRoaXMtPnJlZiApOwoJdVJlZiA9ICsrKFRoaXMtPnJlZik7CgoJTGVhdmVDcml0aWNhbFNlY3Rpb24oICZUaGlzLT5sb2NrICk7CgogICAgICAgIHJldHVybiB1UmVmOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJCklEaXJlY3RTb3VuZENhcHR1cmVJbXBsX1JlbGVhc2UoIExQRElSRUNUU09VTkRDQVBUVVJFIGlmYWNlICkKewoJVUxPTkcgdVJlZjsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRDYXB0dXJlSW1wbCxpZmFjZSk7CgoJRW50ZXJDcml0aWNhbFNlY3Rpb24oICZUaGlzLT5sb2NrICk7CgoJVFJBQ0UoICIoJXApIHdhcyAweCUwOGx4XG4iLCBUaGlzLCBUaGlzLT5yZWYgKTsKCXVSZWYgPSAtLShUaGlzLT5yZWYpOwoKCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCAmVGhpcy0+bG9jayApOwoKCWlmICggdVJlZiA9PSAwICkgewoJCURlbGV0ZUNyaXRpY2FsU2VjdGlvbiggJlRoaXMtPmxvY2sgKTsKCQlIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcyApOwoJfQoKCXJldHVybiB1UmVmOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdFNvdW5kQ2FwdHVyZUltcGxfQ3JlYXRlQ2FwdHVyZUJ1ZmZlcigKCUxQRElSRUNUU09VTkRDQVBUVVJFIGlmYWNlLAoJTFBDRFNDQlVGRkVSREVTQyBscGNEU0NCdWZmZXJEZXNjLAoJTFBESVJFQ1RTT1VORENBUFRVUkVCVUZGRVIqIGxwbHBEU0NhcHR1cmVCdWZmZXIsIAoJTFBVTktOT1dOIHBVbmsgKQp7CglIUkVTVUxUIGhyOwoJSUNPTV9USElTKElEaXJlY3RTb3VuZENhcHR1cmVJbXBsLGlmYWNlKTsKCglUUkFDRSggIiglcCktPiglcCwlcCwlcClcbiIsIFRoaXMsIGxwY0RTQ0J1ZmZlckRlc2MsIGxwbHBEU0NhcHR1cmVCdWZmZXIsIHBVbmsgKTsKCglpZiAoIHBVbmsgKSB7CgkJcmV0dXJuIERTRVJSX0lOVkFMSURQQVJBTTsKCX0KCglociA9IERTT1VORF9DcmVhdGVEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXIoIGxwY0RTQ0J1ZmZlckRlc2MsIChMUFZPSUQqKWxwbHBEU0NhcHR1cmVCdWZmZXIgKTsKCglyZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0U291bmRDYXB0dXJlSW1wbF9HZXRDYXBzKAoJTFBESVJFQ1RTT1VORENBUFRVUkUgaWZhY2UsCglMUERTQ0NBUFMgbHBEU0NDYXBzICkKewogICAgICAgIElDT01fVEhJUyhJRGlyZWN0U291bmRDYXB0dXJlSW1wbCxpZmFjZSk7CgogICAgICAgIEZJWE1FKCAiKCVwKS0+KCVwKTogc3R1YlxuIiwgVGhpcywgbHBEU0NDYXBzICk7CgogICAgICAgIHJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3RTb3VuZENhcHR1cmVJbXBsX0luaXRpYWxpemUoCglMUERJUkVDVFNPVU5EQ0FQVFVSRSBpZmFjZSwKCUxQQ0dVSUQgbHBjR1VJRCApCnsKICAgICAgICBJQ09NX1RISVMoSURpcmVjdFNvdW5kQ2FwdHVyZUltcGwsaWZhY2UpOwoKICAgICAgICBGSVhNRSggIiglcCktPiglcCk6IHN0dWJcbiIsIFRoaXMsIGxwY0dVSUQgKTsKCiAgICAgICAgcmV0dXJuIERTX09LOwp9CgoKc3RhdGljIElDT01fVlRBQkxFKElEaXJlY3RTb3VuZENhcHR1cmUpIGRzY3Z0ID0KewogICAgICAgIElDT01fTVNWVEFCTEVfQ09NUEFUX0R1bW15UlRUSVZBTFVFCiAgICAgICAgLyogSVVua25vd24gbWV0aG9kcyAqLwogICAgICAgIElEaXJlY3RTb3VuZENhcHR1cmVJbXBsX1F1ZXJ5SW50ZXJmYWNlLAogICAgICAgIElEaXJlY3RTb3VuZENhcHR1cmVJbXBsX0FkZFJlZiwKICAgICAgICBJRGlyZWN0U291bmRDYXB0dXJlSW1wbF9SZWxlYXNlLAoKICAgICAgICAvKiBJRGlyZWN0U291bmRDYXB0dXJlIG1ldGhvZHMgKi8KICAgICAgICBJRGlyZWN0U291bmRDYXB0dXJlSW1wbF9DcmVhdGVDYXB0dXJlQnVmZmVyLAogICAgICAgIElEaXJlY3RTb3VuZENhcHR1cmVJbXBsX0dldENhcHMsCiAgICAgICAgSURpcmVjdFNvdW5kQ2FwdHVyZUltcGxfSW5pdGlhbGl6ZSAKfTsKCnN0YXRpYyBIUkVTVUxUCkRTT1VORF9DcmVhdGVEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXIoIExQQ0RTQ0JVRkZFUkRFU0MgbHBjRFNDQnVmZmVyRGVzYywgTFBWT0lEKiBwcG9iaiApCnsKCglGSVhNRSggIiglcCwlcCk6IGlnbm9yaW5nIGxwY0RTQ0J1ZmZlckRlc2NcbiIsIGxwY0RTQ0J1ZmZlckRlc2MsIHBwb2JqICk7CgoJKnBwb2JqID0gSGVhcEFsbG9jKCBHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoIElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsICkgKTsKCglpZiAoICpwcG9iaiA9PSBOVUxMICkgewoJCXJldHVybiBEU0VSUl9PVVRPRk1FTU9SWTsKCX0KCgl7CgkJSUNPTV9USElTKElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsLCpwcG9iaik7CgoJCVRoaXMtPnJlZiA9IDE7CgkJSUNPTV9WVEJMKFRoaXMpID0gJmRzY2J2dDsKCgkJSW5pdGlhbGl6ZUNyaXRpY2FsU2VjdGlvbiggJlRoaXMtPmxvY2sgKTsKCX0KCglyZXR1cm4gU19PSzsKfQoKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbF9RdWVyeUludGVyZmFjZSgKICAgICAgICBMUERJUkVDVFNPVU5EQ0FQVFVSRUJVRkZFUiBpZmFjZSwKICAgICAgICBSRUZJSUQgcmlpZCwKICAgICAgICBMUFZPSUQqIHBwb2JqICkKewogICAgICAgIElDT01fVEhJUyhJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbCxpZmFjZSk7CgogICAgICAgIEZJWE1FKCAiKCVwKS0+KCVzLCVwKTogc3R1YlxuIiwgVGhpcywgZGVidWdzdHJfZ3VpZChyaWlkKSwgcHBvYmogKTsKCiAgICAgICAgcmV0dXJuIEVfRkFJTDsKfQoKc3RhdGljIFVMT05HIFdJTkFQSQpJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbF9BZGRSZWYoIExQRElSRUNUU09VTkRDQVBUVVJFQlVGRkVSIGlmYWNlICkKewogICAgICAgIFVMT05HIHVSZWY7CiAgICAgICAgSUNPTV9USElTKElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsLGlmYWNlKTsKCiAgICAgICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oICZUaGlzLT5sb2NrICk7CgoJVFJBQ0UoICIoJXApIHdhcyAweCUwOGx4XG4iLCBUaGlzLCBUaGlzLT5yZWYgKTsKICAgICAgICB1UmVmID0gKysoVGhpcy0+cmVmKTsKCiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oICZUaGlzLT5sb2NrICk7CgogICAgICAgIHJldHVybiB1UmVmOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJCklEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX1JlbGVhc2UoIExQRElSRUNUU09VTkRDQVBUVVJFQlVGRkVSIGlmYWNlICkKewogICAgICAgIFVMT05HIHVSZWY7CiAgICAgICAgSUNPTV9USElTKElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsLGlmYWNlKTsKCiAgICAgICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oICZUaGlzLT5sb2NrICk7CgoJVFJBQ0UoICIoJXApIHdhcyAweCUwOGx4XG4iLCBUaGlzLCBUaGlzLT5yZWYgKTsKICAgICAgICB1UmVmID0gLS0oVGhpcy0+cmVmKTsKCiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oICZUaGlzLT5sb2NrICk7CgogICAgICAgIGlmICggdVJlZiA9PSAwICkgewoJCURlbGV0ZUNyaXRpY2FsU2VjdGlvbiggJlRoaXMtPmxvY2sgKTsKICAgICAgICAgICAgICAgIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzICk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdVJlZjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX0dldENhcHMoCiAgICAgICAgTFBESVJFQ1RTT1VORENBUFRVUkVCVUZGRVIgaWZhY2UsCglMUERTQ0JDQVBTIGxwRFNDQkNhcHMgKQp7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGwsaWZhY2UpOwoKCUZJWE1FKCAiKCVwKS0+KCVwKTogc3R1YlxuIiwgVGhpcywgbHBEU0NCQ2FwcyApOwoKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX0dldEN1cnJlbnRQb3NpdGlvbigKICAgICAgICBMUERJUkVDVFNPVU5EQ0FQVFVSRUJVRkZFUiBpZmFjZSwKCUxQRFdPUkQgbHBkd0NhcHR1cmVQb3NpdGlvbiwKCUxQRFdPUkQgbHBkd1JlYWRQb3NpdGlvbiApCnsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbCxpZmFjZSk7CgoJRklYTUUoICIoJXApLT4oJXAsJXApOiBzdHViXG4iLCBUaGlzLCBscGR3Q2FwdHVyZVBvc2l0aW9uLCBscGR3UmVhZFBvc2l0aW9uICk7CgoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGxfR2V0Rm9ybWF0KAogICAgICAgIExQRElSRUNUU09VTkRDQVBUVVJFQlVGRkVSIGlmYWNlLAoJTFBXQVZFRk9STUFURVggbHB3ZnhGb3JtYXQsIAoJRFdPUkQgZHdTaXplQWxsb2NhdGVkLCAKCUxQRFdPUkQgbHBkd1NpemVXcml0dGVuICkKewoJSUNPTV9USElTKElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsLGlmYWNlKTsKCglGSVhNRSggIiglcCktPiglcCwweCUwOGx4LCVwKTogc3R1YlxuIiwgVGhpcywgbHB3ZnhGb3JtYXQsIGR3U2l6ZUFsbG9jYXRlZCwgbHBkd1NpemVXcml0dGVuICk7CgoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGxfR2V0U3RhdHVzKAogICAgICAgIExQRElSRUNUU09VTkRDQVBUVVJFQlVGRkVSIGlmYWNlLAoJTFBEV09SRCBscGR3U3RhdHVzICkKewoJSUNPTV9USElTKElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsLGlmYWNlKTsKCglGSVhNRSggIiglcCktPiglcCk6IHN0dWJcbiIsIFRoaXMsIGxwZHdTdGF0dXMgKTsKCglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbF9Jbml0aWFsaXplKAogICAgICAgIExQRElSRUNUU09VTkRDQVBUVVJFQlVGRkVSIGlmYWNlLAoJTFBESVJFQ1RTT1VORENBUFRVUkUgbHBEU0MsIAoJTFBDRFNDQlVGRkVSREVTQyBscGNEU0NCRGVzYyApCnsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbCxpZmFjZSk7CgoJRklYTUUoICIoJXApLT4oJXAsJXApOiBzdHViXG4iLCBUaGlzLCBscERTQywgbHBjRFNDQkRlc2MgKTsKCglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbF9Mb2NrKAogICAgICAgIExQRElSRUNUU09VTkRDQVBUVVJFQlVGRkVSIGlmYWNlLAoJRFdPUkQgZHdSZWFkQ3Vzb3IsIAoJRFdPUkQgZHdSZWFkQnl0ZXMsIAoJTFBWT0lEKiBscGxwdkF1ZGlvUHRyMSwgCglMUERXT1JEIGxwZHdBdWRpb0J5dGVzMSwgCglMUFZPSUQqIGxwbHB2QXVkaW9QdHIyLCAKCUxQRFdPUkQgbHBkd0F1ZGlvQnl0ZXMyLCAKCURXT1JEIGR3RmxhZ3MgKQp7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGwsaWZhY2UpOwoKCUZJWE1FKCAiKCVwKS0+KCUwOGx1LCUwOGx1LCVwLCVwLCVwLCVwLDB4JTA4bHgpOiBzdHViXG4iLCBUaGlzLCBkd1JlYWRDdXNvciwgZHdSZWFkQnl0ZXMsIGxwbHB2QXVkaW9QdHIxLCBscGR3QXVkaW9CeXRlczEsIGxwbHB2QXVkaW9QdHIyLCBscGR3QXVkaW9CeXRlczIsIGR3RmxhZ3MgKTsKCglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbF9TdGFydCgKICAgICAgICBMUERJUkVDVFNPVU5EQ0FQVFVSRUJVRkZFUiBpZmFjZSwKCURXT1JEIGR3RmxhZ3MgKQp7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGwsaWZhY2UpOwoKCUZJWE1FKCAiKCVwKS0+KDB4JTA4bHgpOiBzdHViXG4iLCBUaGlzLCBkd0ZsYWdzICk7CgoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGxfU3RvcCggTFBESVJFQ1RTT1VORENBUFRVUkVCVUZGRVIgaWZhY2UgKQp7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGwsaWZhY2UpOwoKCUZJWE1FKCAiKCVwKTogc3R1YlxuIiwgVGhpcyApOwoKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX1VubG9jaygKICAgICAgICBMUERJUkVDVFNPVU5EQ0FQVFVSRUJVRkZFUiBpZmFjZSwKCUxQVk9JRCBscHZBdWRpb1B0cjEsIAoJRFdPUkQgZHdBdWRpb0J5dGVzMSwgCglMUFZPSUQgbHB2QXVkaW9QdHIyLCAKCURXT1JEIGR3QXVkaW9CeXRlczIgKQp7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGwsaWZhY2UpOwoKCUZJWE1FKCAiKCVwKS0+KCVwLCUwOGx1LCVwLCUwOGx1KTogc3R1YlxuIiwgVGhpcywgbHB2QXVkaW9QdHIxLCBkd0F1ZGlvQnl0ZXMxLCBscHZBdWRpb1B0cjIsIGR3QXVkaW9CeXRlczIgKTsKCglyZXR1cm4gRFNfT0s7Cn0KCgpzdGF0aWMgSUNPTV9WVEFCTEUoSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlcikgZHNjYnZ0ID0KewogICAgICAgIElDT01fTVNWVEFCTEVfQ09NUEFUX0R1bW15UlRUSVZBTFVFCiAgICAgICAgLyogSVVua25vd24gbWV0aG9kcyAqLwogICAgICAgIElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX1F1ZXJ5SW50ZXJmYWNlLAogICAgICAgIElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX0FkZFJlZiwKICAgICAgICBJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbF9SZWxlYXNlLAoKICAgICAgICAvKiBJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVyIG1ldGhvZHMgKi8KICAgICAgICBJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbF9HZXRDYXBzLAogICAgICAgIElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX0dldEN1cnJlbnRQb3NpdGlvbiwKICAgICAgICBJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbF9HZXRGb3JtYXQsCiAgICAgICAgSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGxfR2V0U3RhdHVzLAogICAgICAgIElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX0luaXRpYWxpemUsCiAgICAgICAgSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGxfTG9jaywKICAgICAgICBJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbF9TdGFydCwKICAgICAgICBJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbF9TdG9wLAogICAgICAgIElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX1VubG9jawp9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGlyZWN0U291bmQgQ2xhc3NGYWN0b3J5CiAqLwp0eXBlZGVmIHN0cnVjdAp7CiAgICAvKiBJVW5rbm93biBmaWVsZHMgKi8KICAgIElDT01fVkZJRUxEKElDbGFzc0ZhY3RvcnkpOwogICAgRFdPUkQgICAgICAgICAgICAgICAgICAgICAgIHJlZjsKfSBJQ2xhc3NGYWN0b3J5SW1wbDsKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSAKRFNDRl9RdWVyeUludGVyZmFjZShMUENMQVNTRkFDVE9SWSBpZmFjZSxSRUZJSUQgcmlpZCxMUFZPSUQgKnBwb2JqKSB7CglJQ09NX1RISVMoSUNsYXNzRmFjdG9yeUltcGwsaWZhY2UpOwoKCUZJWE1FKCIoJXApLT4oJXMsJXApLHN0dWIhXG4iLFRoaXMsZGVidWdzdHJfZ3VpZChyaWlkKSxwcG9iaik7CglyZXR1cm4gRV9OT0lOVEVSRkFDRTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSQpEU0NGX0FkZFJlZihMUENMQVNTRkFDVE9SWSBpZmFjZSkgewoJSUNPTV9USElTKElDbGFzc0ZhY3RvcnlJbXBsLGlmYWNlKTsKCXJldHVybiArKyhUaGlzLT5yZWYpOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIERTQ0ZfUmVsZWFzZShMUENMQVNTRkFDVE9SWSBpZmFjZSkgewoJSUNPTV9USElTKElDbGFzc0ZhY3RvcnlJbXBsLGlmYWNlKTsKCS8qIHN0YXRpYyBjbGFzcywgd29uJ3QgYmUgIGZyZWVkICovCglyZXR1cm4gLS0oVGhpcy0+cmVmKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIERTQ0ZfQ3JlYXRlSW5zdGFuY2UoCglMUENMQVNTRkFDVE9SWSBpZmFjZSxMUFVOS05PV04gcE91dGVyLFJFRklJRCByaWlkLExQVk9JRCAqcHBvYmoKKSB7CglJQ09NX1RISVMoSUNsYXNzRmFjdG9yeUltcGwsaWZhY2UpOwoKCVRSQUNFKCIoJXApLT4oJXAsJXMsJXApXG4iLFRoaXMscE91dGVyLGRlYnVnc3RyX2d1aWQocmlpZCkscHBvYmopOwoJaWYgKCBJc0VxdWFsR1VJRCggJklJRF9JRGlyZWN0U291bmQsIHJpaWQgKSApIHsKCQkvKiBGSVhNRTogcmV1c2UgYWxyZWFkeSBjcmVhdGVkIGRzb3VuZCBpZiBwcmVzZW50PyAqLwoJCXJldHVybiBEaXJlY3RTb3VuZENyZWF0ZShyaWlkLChMUERJUkVDVFNPVU5EKilwcG9iaixwT3V0ZXIpOwoJfQoJcmV0dXJuIEVfTk9JTlRFUkZBQ0U7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBEU0NGX0xvY2tTZXJ2ZXIoTFBDTEFTU0ZBQ1RPUlkgaWZhY2UsQk9PTCBkb2xvY2spIHsKCUlDT01fVEhJUyhJQ2xhc3NGYWN0b3J5SW1wbCxpZmFjZSk7CglGSVhNRSgiKCVwKS0+KCVkKSxzdHViIVxuIixUaGlzLGRvbG9jayk7CglyZXR1cm4gU19PSzsKfQoKc3RhdGljIElDT01fVlRBQkxFKElDbGFzc0ZhY3RvcnkpIERTQ0ZfVnRibCA9IHsKCUlDT01fTVNWVEFCTEVfQ09NUEFUX0R1bW15UlRUSVZBTFVFCglEU0NGX1F1ZXJ5SW50ZXJmYWNlLAoJRFNDRl9BZGRSZWYsCglEU0NGX1JlbGVhc2UsCglEU0NGX0NyZWF0ZUluc3RhbmNlLAoJRFNDRl9Mb2NrU2VydmVyCn07CnN0YXRpYyBJQ2xhc3NGYWN0b3J5SW1wbCBEU09VTkRfQ0YgPSB7JkRTQ0ZfVnRibCwgMSB9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGxsR2V0Q2xhc3NPYmplY3QgW0RTT1VORC41XQogKiBSZXRyaWV2ZXMgY2xhc3Mgb2JqZWN0IGZyb20gYSBETEwgb2JqZWN0CiAqCiAqIE5PVEVTCiAqICAgIERvY3Mgc2F5IHJldHVybnMgU1REQVBJCiAqCiAqIFBBUkFNUwogKiAgICByY2xzaWQgW0ldIENMU0lEIGZvciB0aGUgY2xhc3Mgb2JqZWN0CiAqICAgIHJpaWQgICBbSV0gUmVmZXJlbmNlIHRvIGlkZW50aWZpZXIgb2YgaW50ZXJmYWNlIGZvciBjbGFzcyBvYmplY3QKICogICAgcHB2ICAgIFtPXSBBZGRyZXNzIG9mIHZhcmlhYmxlIHRvIHJlY2VpdmUgaW50ZXJmYWNlIHBvaW50ZXIgZm9yIHJpaWQKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBTX09LCiAqICAgIEZhaWx1cmU6IENMQVNTX0VfQ0xBU1NOT1RBVkFJTEFCTEUsIEVfT1VUT0ZNRU1PUlksIEVfSU5WQUxJREFSRywKICogICAgICAgICAgICAgRV9VTkVYUEVDVEVECiAqLwpEV09SRCBXSU5BUEkgRFNPVU5EX0RsbEdldENsYXNzT2JqZWN0KFJFRkNMU0lEIHJjbHNpZCxSRUZJSUQgcmlpZCxMUFZPSUQgKnBwdikKewogICAgVFJBQ0UoIiglcCwlcCwlcClcbiIsIGRlYnVnc3RyX2d1aWQocmNsc2lkKSwgZGVidWdzdHJfZ3VpZChyaWlkKSwgcHB2KTsKICAgIGlmICggSXNFcXVhbENMU0lEKCAmSUlEX0lDbGFzc0ZhY3RvcnksIHJpaWQgKSApIHsKICAgIAkqcHB2ID0gKExQVk9JRCkmRFNPVU5EX0NGOwoJSUNsYXNzRmFjdG9yeV9BZGRSZWYoKElDbGFzc0ZhY3RvcnkqKSpwcHYpOwogICAgcmV0dXJuIFNfT0s7CiAgICB9CgogICAgRklYTUUoIiglcCwlcCwlcCk6IG5vIGludGVyZmFjZSBmb3VuZC5cbiIsIGRlYnVnc3RyX2d1aWQocmNsc2lkKSwgZGVidWdzdHJfZ3VpZChyaWlkKSwgcHB2KTsKICAgIHJldHVybiBDTEFTU19FX0NMQVNTTk9UQVZBSUxBQkxFOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGxsQ2FuVW5sb2FkTm93IFtEU09VTkQuNF0gIERldGVybWluZXMgd2hldGhlciB0aGUgRExMIGlzIGluIHVzZS4KICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBTX09LCiAqICAgIEZhaWx1cmU6IFNfRkFMU0UKICovCkRXT1JEIFdJTkFQSSBEU09VTkRfRGxsQ2FuVW5sb2FkTm93KHZvaWQpCnsKICAgIEZJWE1FKCIodm9pZCk6IHN0dWJcbiIpOwogICAgcmV0dXJuIFNfRkFMU0U7Cn0K