LyogIAkJCURpcmVjdFNvdW5kCiAqIAogKiBDb3B5cmlnaHQgMTk5OCBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggUm9iIFJpZ2dzCiAqIENvcHlyaWdodCAyMDAwLTIwMDEgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzLCBJbmMuCiAqLwovKgogKiBNb3N0IHRocmVhZCBsb2NraW5nIGlzIGNvbXBsZXRlLiBUaGVyZSBtYXkgYmUgYSBmZXcgcmFjZQogKiBjb25kaXRpb25zIHN0aWxsIGx1cmtpbmcuCiAqCiAqIFRlc3RlZCB3aXRoIGEgU291bmRibGFzdGVyIGNsb25lLCBhIEdyYXZpcyBVbHRyYVNvdW5kIENsYXNzaWMsCiAqIGFuZCBhIFR1cnRsZSBCZWFjaCBUcm9wZXorLgogKgogKiBUT0RPOgogKglJbXBsZW1lbnQgRGlyZWN0U291bmRDYXB0dXJlIEFQSQogKglJbXBsZW1lbnQgU2V0Q29vcGVyYXRpdmVMZXZlbCBwcm9wZXJseSAobmVlZCB0byBhZGRyZXNzIGZvY3VzIGlzc3VlcykKICoJSW1wbGVtZW50IERpcmVjdFNvdW5kM0RCdWZmZXJzIChzdHVicyBpbiBwbGFjZSkKICoJVXNlIGhhcmR3YXJlIDNEIHN1cHBvcnQgaWYgYXZhaWxhYmxlCiAqICAgICAgQWRkIGNyaXRpY2FsIHNlY3Rpb24gbG9ja2luZyBpbnNpZGUgUmVsZWFzZSBhbmQgQWRkUmVmIG1ldGhvZHMKICogICAgICBIYW5kbGUgc3RhdGljIGJ1ZmZlcnMgLSBwdXQgdGhvc2UgaW4gaGFyZHdhcmUsIG5vbi1zdGF0aWMgbm90IGluIGhhcmR3YXJlCiAqICAgICAgSGFyZHdhcmUgRHVwbGljYXRlU291bmRCdWZmZXIKICogICAgICBQcm9wZXIgdm9sdW1lIGNhbGN1bGF0aW9uLCBhbmQgc2V0dGluZyB2b2x1bWUgaW4gSEVMIHByaW1hcnkgYnVmZmVyCiAqICAgICAgT3B0aW1pemUgV0lOTU0gYW5kIG5lZ290aWF0ZSBmcmFnbWVudCBzaXplLCBkZWNyZWFzZSBEU19IRUxfTUFSR0lOCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSA8YXNzZXJ0Lmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlIDxzeXMvZmNudGwuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPG1hdGguaD4JLyogSW5zb21uaWEgLSBwb3coKSBmdW5jdGlvbiAqLwoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2luZ2RpLmgiCiNpbmNsdWRlICJ3aW51c2VyLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAibW1zeXN0ZW0uaCIKI2luY2x1ZGUgIm1tZGRrLmgiCiNpbmNsdWRlICJ3aW5lL3dpbmRlZjE2LmgiCiNpbmNsdWRlICJkZWJ1Z3Rvb2xzLmgiCiNpbmNsdWRlICJkc291bmQuaCIKI2luY2x1ZGUgImRzZHJpdmVyLmgiCgpERUZBVUxUX0RFQlVHX0NIQU5ORUwoZHNvdW5kKTsKCi8qIHRoZXNlIGFyZSBlbGlnaWJsZSBmb3IgdHVuaW5nLi4uIHRoZXkgbXVzdCBiZSBoaWdoIG9uIHNsb3cgbWFjaGluZXMuLi4gKi8KLyogc29tZSBzdHVmZiBtYXkgZ2V0IG1vcmUgcmVzcG9uc2l2ZSB3aXRoIGxvd2VyIHZhbHVlcyB0aG91Z2guLi4gKi8KI2RlZmluZSBEU19FTVVMRFJJVkVSIDEgLyogc29tZSBnYW1lcyAoUXVha2UgMiwgVVQpIHJlZnVzZSB0byBhY2NlcHQKCQkJCWVtdWxhdGVkIGRzb3VuZCBkZXZpY2VzLiBzZXQgdG8gMCAhICovIAojZGVmaW5lIERTX0hFTF9GUkFHUyA0OCAvKiBIRUwgb25seTogbnVtYmVyIG9mIHdhdmVPdXQgZnJhZ21lbnRzIGluIHByaW1hcnkgYnVmZmVyCgkJCSAqIChjaGFuZ2luZyB0aGlzIHdvbid0IGhlbHAgeW91KSAqLwojZGVmaW5lIERTX0hFTF9NQVJHSU4gNSAvKiBIRUwgb25seTogbnVtYmVyIG9mIHdhdmVPdXQgZnJhZ21lbnRzIGFoZWFkIHRvIG1peCBpbiBuZXcgYnVmZmVycwoJCQkgKiAoa2VlcCB0aGlzIGNsb3NlIG9yIGVxdWFsIHRvIERTX0hFTF9RVUVVRSBmb3IgYmVzdCByZXN1bHRzKSAqLwojZGVmaW5lIERTX0hFTF9RVUVVRSAgNSAvKiBIRUwgb25seTogbnVtYmVyIG9mIHdhdmVPdXQgZnJhZ21lbnRzIGFoZWFkIHRvIHF1ZXVlIHRvIGRyaXZlcgoJCQkgKiAodGhpcyB3aWxsIGFmZmVjdCBIRUwgc291bmQgcmVsaWFiaWxpdHkgYW5kIGxhdGVuY3kpICovCgojZGVmaW5lIERTX1NORF9RVUVVRV9NQVggMjggLyogbWF4IG51bWJlciBvZiBmcmFnbWVudHMgdG8gcHJlYnVmZmVyICovCiNkZWZpbmUgRFNfU05EX1FVRVVFX01JTiAxMiAvKiBtaW4gbnVtYmVyIG9mIGZyYWdtZW50cyB0byBwcmVidWZmZXIgKi8KCi8qIExpbnV4IGRvZXMgbm90IHN1cHBvcnQgYmV0dGVyIHRpbWluZyB0aGFuIDEwbXMgKi8KI2RlZmluZSBEU19USU1FX1JFUyAxMCAgLyogUmVzb2x1dGlvbiBvZiBtdWx0aW1lZGlhIHRpbWVyICovCiNkZWZpbmUgRFNfVElNRV9ERUwgMTAgIC8qIERlbGF5IG9mIG11bHRpbWVkaWEgdGltZXIgY2FsbGJhY2ssIGFuZCBkdXJhdGlvbiBvZiBIRUwgZnJhZ21lbnQgKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBQcmVkZWNsYXJlIHRoZSBpbnRlcmZhY2UgaW1wbGVtZW50YXRpb24gc3RydWN0dXJlcwogKi8KdHlwZWRlZiBzdHJ1Y3QgSURpcmVjdFNvdW5kSW1wbCBJRGlyZWN0U291bmRJbXBsOwp0eXBlZGVmIHN0cnVjdCBJRGlyZWN0U291bmRCdWZmZXJJbXBsIElEaXJlY3RTb3VuZEJ1ZmZlckltcGw7CnR5cGVkZWYgc3RydWN0IElEaXJlY3RTb3VuZE5vdGlmeUltcGwgSURpcmVjdFNvdW5kTm90aWZ5SW1wbDsKdHlwZWRlZiBzdHJ1Y3QgSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGwgSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGw7CnR5cGVkZWYgc3RydWN0IElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbCBJRGlyZWN0U291bmQzREJ1ZmZlckltcGw7CnR5cGVkZWYgc3RydWN0IElEaXJlY3RTb3VuZENhcHR1cmVJbXBsIElEaXJlY3RTb3VuZENhcHR1cmVJbXBsOwp0eXBlZGVmIHN0cnVjdCBJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbCBJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbDsKdHlwZWRlZiBzdHJ1Y3QgSUtzUHJvcGVydHlTZXRJbXBsIElLc1Byb3BlcnR5U2V0SW1wbDsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0U291bmQgaW1wbGVtZW50YXRpb24gc3RydWN0dXJlCiAqLwpzdHJ1Y3QgSURpcmVjdFNvdW5kSW1wbAp7CiAgICAvKiBJVW5rbm93biBmaWVsZHMgKi8KICAgIElDT01fVkZJRUxEKElEaXJlY3RTb3VuZCk7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgICByZWY7CiAgICAvKiBJRGlyZWN0U291bmRJbXBsIGZpZWxkcyAqLwogICAgUElEU0RSSVZFUiAgICAgICAgICAgICAgICAgIGRyaXZlcjsKICAgIERTRFJJVkVSREVTQyAgICAgICAgICAgICAgICBkcnZkZXNjOwogICAgRFNEUklWRVJDQVBTICAgICAgICAgICAgICAgIGRydmNhcHM7CiAgICBIV0FWRU9VVCAgICAgICAgICAgICAgICAgICAgaHdvOwogICAgTFBXQVZFSERSICAgICAgICAgICAgICAgICAgIHB3YXZlW0RTX0hFTF9GUkFHU107CiAgICBVSU5UICAgICAgICAgICAgICAgICAgICAgICAgdGltZXJJRCwgcHdwbGF5LCBwd3dyaXRlLCBwd3F1ZXVlLCBwcmVidWY7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgICAgZnJhZ2xlbjsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgICAgICBwcmlvbGV2ZWw7CiAgICBpbnQgICAgICAgICAgICAgICAgICAgICAgICAgbnJvZmJ1ZmZlcnM7CiAgICBJRGlyZWN0U291bmRCdWZmZXJJbXBsKiogICAgYnVmZmVyczsKICAgIElEaXJlY3RTb3VuZEJ1ZmZlckltcGwqICAgICBwcmltYXJ5OwogICAgSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGwqIGxpc3RlbmVyOwogICAgV0FWRUZPUk1BVEVYICAgICAgICAgICAgICAgIHdmeDsgLyogY3VycmVudCBtYWluIHdhdmVmb3JtYXQgKi8KICAgIENSSVRJQ0FMX1NFQ1RJT04JCWxvY2s7Cn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdFNvdW5kQnVmZmVyIGltcGxlbWVudGF0aW9uIHN0cnVjdHVyZQogKi8Kc3RydWN0IElEaXJlY3RTb3VuZEJ1ZmZlckltcGwKewogICAgLyogRklYTUU6IGRvY3VtZW50ICovCiAgICAvKiBJVW5rbm93biBmaWVsZHMgKi8KICAgIElDT01fVkZJRUxEKElEaXJlY3RTb3VuZEJ1ZmZlcik7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWY7CiAgICAvKiBJRGlyZWN0U291bmRCdWZmZXJJbXBsIGZpZWxkcyAqLwogICAgUElEU0RSSVZFUkJVRkZFUiAgICAgICAgICBod2J1ZjsKICAgIFdBVkVGT1JNQVRFWCAgICAgICAgICAgICAgd2Z4OwogICAgTFBCWVRFICAgICAgICAgICAgICAgICAgICBidWZmZXI7CiAgICBJRGlyZWN0U291bmQzREJ1ZmZlckltcGwqIGRzM2RiOwogICAgRFdPUkQgICAgICAgICAgICAgICAgICAgICBwbGF5ZmxhZ3Msc3RhdGUsbGVhZGluOwogICAgRFdPUkQgICAgICAgICAgICAgICAgICAgICBwbGF5cG9zLHN0YXJ0cG9zLHdyaXRlbGVhZCxidWZsZW47CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgIG5BdmdCeXRlc1BlclNlYzsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgICAgZnJlcTsKICAgIERTVk9MVU1FUEFOICAgICAgICAgICAgICAgdm9scGFuOwogICAgSURpcmVjdFNvdW5kQnVmZmVySW1wbCogICBwYXJlbnQ7ICAgICAgICAgLyogZm9yIGR1cGxpY2F0ZXMgKi8KICAgIElEaXJlY3RTb3VuZEltcGwqICAgICAgICAgZHNvdW5kOwogICAgRFNCVUZGRVJERVNDICAgICAgICAgICAgICBkc2JkOwogICAgTFBEU0JQT1NJVElPTk5PVElGWSAgICAgICBub3RpZmllczsKICAgIGludCAgICAgICAgICAgICAgICAgICAgICAgbnJvZm5vdGlmaWVzOwogICAgQ1JJVElDQUxfU0VDVElPTiAgICAgICAgICBsb2NrOwogICAgLyogdXNlZCBmb3IgZnJlcXVlbmN5IGNvbnZlcnNpb24gKFBlcmZlY3RQaXRjaCkgKi8KICAgIFVMT05HICAgICAgICAgICAgICAgICAgICAgZnJlcUFkanVzdCwgZnJlcUFjYzsKICAgIC8qIHVzZWQgZm9yIGludGVsbGlnZW50ICh3ZWxsLCBzb3J0IG9mKSBwcmVidWZmZXJpbmcgKi8KICAgIERXT1JEICAgICAgICAgICAgICAgICAgICAgcHJvYmFibHlfdmFsaWRfdG87CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgIHByaW1hcnlfbWl4cG9zLCBidWZfbWl4cG9zOwogICAgQk9PTCAgICAgICAgICAgICAgICAgICAgICBuZWVkX3JlbWl4Owp9OwoKI2RlZmluZSBTVEFURV9TVE9QUEVEICAwCiNkZWZpbmUgU1RBVEVfU1RBUlRJTkcgMQojZGVmaW5lIFNUQVRFX1BMQVlJTkcgIDIKI2RlZmluZSBTVEFURV9TVE9QUElORyAzCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdFNvdW5kTm90aWZ5IGltcGxlbWVudGF0aW9uIHN0cnVjdHVyZQogKi8Kc3RydWN0IElEaXJlY3RTb3VuZE5vdGlmeUltcGwKewogICAgLyogSVVua25vd24gZmllbGRzICovCiAgICBJQ09NX1ZGSUVMRChJRGlyZWN0U291bmROb3RpZnkpOwogICAgRFdPUkQgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmOwogICAgLyogSURpcmVjdFNvdW5kTm90aWZ5SW1wbCBmaWVsZHMgKi8KICAgIElEaXJlY3RTb3VuZEJ1ZmZlckltcGwqIGRzYjsKfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgSURpcmVjdFNvdW5kM0RMaXN0ZW5lciBpbXBsZW1lbnRhdGlvbiBzdHJ1Y3R1cmUKICovCnN0cnVjdCBJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbAp7CiAgICAvKiBJVW5rbm93biBmaWVsZHMgKi8KICAgIElDT01fVkZJRUxEKElEaXJlY3RTb3VuZDNETGlzdGVuZXIpOwogICAgRFdPUkQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZjsKICAgIC8qIElEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsIGZpZWxkcyAqLwogICAgSURpcmVjdFNvdW5kQnVmZmVySW1wbCogZHNiOwogICAgRFMzRExJU1RFTkVSICAgICAgICAgICAgZHMzZGw7CiAgICBDUklUSUNBTF9TRUNUSU9OICAgICAgICBsb2NrOyAgIAp9OwoKc3RydWN0IElLc1Byb3BlcnR5U2V0SW1wbCAKewogICAgLyogSVVua25vd24gZmllbGRzICovCiAgICBJQ09NX1ZGSUVMRChJS3NQcm9wZXJ0eVNldCk7CiAgICBEV09SRAkJCXJlZjsKICAgIC8qIElLc1Byb3BlcnR5U2V0SW1wbCBmaWVsZHMgKi8KICAgIElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbAkqZHMzZGI7CS8qIGJhY2twdHIsIG5vIHJlZiAqLwp9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3RTb3VuZDNEQnVmZmVyIGltcGxlbWVudGF0aW9uIHN0cnVjdHVyZQogKi8Kc3RydWN0IElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbAp7CiAgICAvKiBJVW5rbm93biBmaWVsZHMgKi8KICAgIElDT01fVkZJRUxEKElEaXJlY3RTb3VuZDNEQnVmZmVyKTsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmOwogICAgLyogSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsIGZpZWxkcyAqLwogICAgSURpcmVjdFNvdW5kQnVmZmVySW1wbCogZHNiOwogICAgRFMzREJVRkZFUiAgICAgICAgICAgICAgZHMzZGI7CiAgICBMUEJZVEUgICAgICAgICAgICAgICAgICBidWZmZXI7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICBidWZsZW47CiAgICBDUklUSUNBTF9TRUNUSU9OICAgICAgICBsb2NrOwogICAgSUtzUHJvcGVydHlTZXRJbXBsKiAgICAgaWtzOwp9OwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0U291bmRDYXB0dXJlIGltcGxlbWVudGF0aW9uIHN0cnVjdHVyZQogKi8Kc3RydWN0IElEaXJlY3RTb3VuZENhcHR1cmVJbXBsCnsKICAgIC8qIElVbmtub3duIGZpZWxkcyAqLwogICAgSUNPTV9WRklFTEQoSURpcmVjdFNvdW5kQ2FwdHVyZSk7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZjsKCiAgICAvKiBJRGlyZWN0U291bmRDYXB0dXJlSW1wbCBmaWVsZHMgKi8KICAgIENSSVRJQ0FMX1NFQ1RJT04gICAgICAgIGxvY2s7Cn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdFNvdW5kQ2FwdHVyZSBpbXBsZW1lbnRhdGlvbiBzdHJ1Y3R1cmUKICovCnN0cnVjdCBJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbAp7CiAgICAvKiBJVW5rbm93biBmaWVsZHMgKi8KICAgIElDT01fVkZJRUxEKElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXIpOwogICAgRFdPUkQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWY7CgogICAgLyogSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGwgZmllbGRzICovCiAgICBDUklUSUNBTF9TRUNUSU9OICAgICAgICBsb2NrOwp9OwoKCi8qICNkZWZpbmUgVVNFX0RTT1VORDNEIDEgKi8KCiNkZWZpbmUgRFNPVU5EX0ZSRVFTSElGVCAoMTQpCgpzdGF0aWMgSURpcmVjdFNvdW5kSW1wbCoJZHNvdW5kID0gTlVMTDsKCnN0YXRpYyBJRGlyZWN0U291bmRCdWZmZXJJbXBsKglwcmltYXJ5YnVmID0gTlVMTDsKCnN0YXRpYyB2b2lkIERTT1VORF9DaGVja0V2ZW50KElEaXJlY3RTb3VuZEJ1ZmZlckltcGwgKmRzYiwgaW50IGxlbik7CnN0YXRpYyB2b2lkIERTT1VORF9NaXhDYW5jZWxBdChJRGlyZWN0U291bmRCdWZmZXJJbXBsICpkc2IsIERXT1JEIGJ1Zl93cml0ZXBvcyk7CgpzdGF0aWMgdm9pZCBEU09VTkRfV2F2ZVF1ZXVlKElEaXJlY3RTb3VuZEltcGwgKmRzb3VuZCwgRFdPUkQgbWl4cSk7CnN0YXRpYyB2b2lkIERTT1VORF9QZXJmb3JtTWl4KHZvaWQpOwpzdGF0aWMgdm9pZCBDQUxMQkFDSyBEU09VTkRfY2FsbGJhY2soSFdBVkVPVVQgaHdvLCBVSU5UIG1zZywgRFdPUkQgZHdVc2VyLCBEV09SRCBkdzEsIERXT1JEIGR3Mik7CgpzdGF0aWMgSFJFU1VMVCBEU09VTkRfQ3JlYXRlRGlyZWN0U291bmRDYXB0dXJlKCBMUFZPSUQqIHBwb2JqICk7CnN0YXRpYyBIUkVTVUxUIERTT1VORF9DcmVhdGVEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXIoIExQQ0RTQ0JVRkZFUkRFU0MgbHBjRFNDQnVmZmVyRGVzYywgTFBWT0lEKiBwcG9iaiApOwoKc3RhdGljIElDT01fVlRBQkxFKElEaXJlY3RTb3VuZENhcHR1cmUpIGRzY3Z0OwpzdGF0aWMgSUNPTV9WVEFCTEUoSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlcikgZHNjYnZ0OwoKc3RhdGljIEhSRVNVTFQgbW1FcnIoVUlOVCBlcnIpCnsKCXN3aXRjaChlcnIpIHsKCWNhc2UgTU1TWVNFUlJfTk9FUlJPUjoKCQlyZXR1cm4gRFNfT0s7CgljYXNlIE1NU1lTRVJSX0FMTE9DQVRFRDoKCQlyZXR1cm4gRFNFUlJfQUxMT0NBVEVEOwoJY2FzZSBNTVNZU0VSUl9JTlZBTEhBTkRMRToKCQlyZXR1cm4gRFNFUlJfR0VORVJJQzsgLyogRklYTUUgKi8KCWNhc2UgTU1TWVNFUlJfTk9EUklWRVI6CgkJcmV0dXJuIERTRVJSX05PRFJJVkVSOwoJY2FzZSBNTVNZU0VSUl9OT01FTToKCQlyZXR1cm4gRFNFUlJfT1VUT0ZNRU1PUlk7CgljYXNlIE1NU1lTRVJSX0lOVkFMUEFSQU06CgkJcmV0dXJuIERTRVJSX0lOVkFMSURQQVJBTTsKCWRlZmF1bHQ6CgkJRklYTUUoIlVua25vd24gTU1TWVMgZXJyb3IgJWRcbiIsZXJyKTsKCQlyZXR1cm4gRFNFUlJfR0VORVJJQzsKCX0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEaXJlY3RTb3VuZEVudW1lcmF0ZUEgW0RTT1VORC4yXSAgCiAqCiAqIEVudW1lcmF0ZSBhbGwgRGlyZWN0U291bmQgZHJpdmVycyBpbnN0YWxsZWQgaW4gdGhlIHN5c3RlbQogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IERTX09LCiAqICAgIEZhaWx1cmU6IERTRVJSX0lOVkFMSURQQVJBTQogKi8KSFJFU1VMVCBXSU5BUEkgRGlyZWN0U291bmRFbnVtZXJhdGVBKAoJTFBEU0VOVU1DQUxMQkFDS0EgbHBEU0VudW1DYWxsYmFjaywKCUxQVk9JRCBscENvbnRleHQpCnsKCVRSQUNFKCJscERTRW51bUNhbGxiYWNrID0gJXAsIGxwQ29udGV4dCA9ICVwXG4iLCAKCQlscERTRW51bUNhbGxiYWNrLCBscENvbnRleHQpOwoKI2lmZGVmIEhBVkVfT1NTCglpZiAobHBEU0VudW1DYWxsYmFjayAhPSBOVUxMKQoJCWxwRFNFbnVtQ2FsbGJhY2soTlVMTCwiV0lORSBEaXJlY3RTb3VuZCB1c2luZyBPcGVuIFNvdW5kIFN5c3RlbSIsCgkJICAgICJzb3VuZCIsbHBDb250ZXh0KTsKI2VuZGlmCgoJcmV0dXJuIERTX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERpcmVjdFNvdW5kRW51bWVyYXRlVyBbRFNPVU5ELjNdICAKICoKICogRW51bWVyYXRlIGFsbCBEaXJlY3RTb3VuZCBkcml2ZXJzIGluc3RhbGxlZCBpbiB0aGUgc3lzdGVtCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRFNfT0sKICogICAgRmFpbHVyZTogRFNFUlJfSU5WQUxJRFBBUkFNCiAqLwpIUkVTVUxUIFdJTkFQSSBEaXJlY3RTb3VuZEVudW1lcmF0ZVcoCglMUERTRU5VTUNBTExCQUNLVyBscERTRW51bUNhbGxiYWNrLCAKCUxQVk9JRCBscENvbnRleHQgKQp7CiAgICAgICAgRklYTUUoImxwRFNFbnVtQ2FsbGJhY2sgPSAlcCwgbHBDb250ZXh0ID0gJXA6IHN0dWJcbiIsIAogICAgICAgICAgICAgICAgbHBEU0VudW1DYWxsYmFjaywgbHBDb250ZXh0KTsKCiAgICAgICAgcmV0dXJuIERTX09LOwp9CgoKc3RhdGljIHZvaWQgX2R1bXBfRFNCQ0FQUyhEV09SRCB4bWFzaykgewoJc3RydWN0IHsKCQlEV09SRAltYXNrOwoJCWNoYXIJKm5hbWU7Cgl9IGZsYWdzW10gPSB7CiNkZWZpbmUgRkUoeCkgeyB4LCAjeCB9LAoJCUZFKERTQkNBUFNfUFJJTUFSWUJVRkZFUikKCQlGRShEU0JDQVBTX1NUQVRJQykKCQlGRShEU0JDQVBTX0xPQ0hBUkRXQVJFKQoJCUZFKERTQkNBUFNfTE9DU09GVFdBUkUpCgkJRkUoRFNCQ0FQU19DVFJMM0QpCgkJRkUoRFNCQ0FQU19DVFJMRlJFUVVFTkNZKQoJCUZFKERTQkNBUFNfQ1RSTFBBTikKCQlGRShEU0JDQVBTX0NUUkxWT0xVTUUpCgkJRkUoRFNCQ0FQU19DVFJMUE9TSVRJT05OT1RJRlkpCgkJRkUoRFNCQ0FQU19DVFJMREVGQVVMVCkKCQlGRShEU0JDQVBTX0NUUkxBTEwpCgkJRkUoRFNCQ0FQU19TVElDS1lGT0NVUykKCQlGRShEU0JDQVBTX0dMT0JBTEZPQ1VTKQoJCUZFKERTQkNBUFNfR0VUQ1VSUkVOVFBPU0lUSU9OMikKCQlGRShEU0JDQVBTX01VVEUzREFUTUFYRElTVEFOQ0UpCiN1bmRlZiBGRQoJfTsKCWludAlpOwoKCWZvciAoaT0wO2k8c2l6ZW9mKGZsYWdzKS9zaXplb2YoZmxhZ3NbMF0pO2krKykKCQlpZiAoKGZsYWdzW2ldLm1hc2sgJiB4bWFzaykgPT0gZmxhZ3NbaV0ubWFzaykKCQkJRFBSSU5URigiJXMgIixmbGFnc1tpXS5uYW1lKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgIElLc1Byb3BlcnR5U2V0CiAqLwoKLyogSVVua25vd24gbWV0aG9kcyAqLwojaWZkZWYgVVNFX0RTT1VORDNECnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJS3NQcm9wZXJ0eVNldEltcGxfUXVlcnlJbnRlcmZhY2UoCglMUEtTUFJPUEVSVFlTRVQgaWZhY2UsIFJFRklJRCByaWlkLCBMUFZPSUQgKnBwb2JqCikgewoJSUNPTV9USElTKElLc1Byb3BlcnR5U2V0SW1wbCxpZmFjZSk7CgoJRklYTUUoIiglcCwlcywlcCksIHN0dWIhXG4iLFRoaXMsZGVidWdzdHJfZ3VpZChyaWlkKSxwcG9iaik7CglyZXR1cm4gRV9GQUlMOwp9CiNlbmRpZgoKI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgVUxPTkcgV0lOQVBJIElLc1Byb3BlcnR5U2V0SW1wbF9BZGRSZWYoTFBLU1BST1BFUlRZU0VUIGlmYWNlKSB7CglJQ09NX1RISVMoSUtzUHJvcGVydHlTZXRJbXBsLGlmYWNlKTsKCglUaGlzLT5yZWYrKzsKCXJldHVybiBUaGlzLT5yZWY7Cn0KI2VuZGlmCgojaWZkZWYgVVNFX0RTT1VORDNECnN0YXRpYyBVTE9ORyBXSU5BUEkgSUtzUHJvcGVydHlTZXRJbXBsX1JlbGVhc2UoTFBLU1BST1BFUlRZU0VUIGlmYWNlKSB7CglJQ09NX1RISVMoSUtzUHJvcGVydHlTZXRJbXBsLGlmYWNlKTsKCglUaGlzLT5yZWYtLTsKCXJldHVybiBUaGlzLT5yZWY7Cn0KI2VuZGlmCgojaWZkZWYgVVNFX0RTT1VORDNECnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJS3NQcm9wZXJ0eVNldEltcGxfR2V0KExQS1NQUk9QRVJUWVNFVCBpZmFjZSwKCVJFRkdVSUQgZ3VpZFByb3BTZXQsIFVMT05HIGR3UHJvcElELAoJTFBWT0lEIHBJbnN0YW5jZURhdGEsIFVMT05HIGNiSW5zdGFuY2VEYXRhLAoJTFBWT0lEIHBQcm9wRGF0YSwgVUxPTkcgY2JQcm9wRGF0YSwKCVBVTE9ORyBwY2JSZXR1cm5lZAopIHsKCUlDT01fVEhJUyhJS3NQcm9wZXJ0eVNldEltcGwsaWZhY2UpOwoKCUZJWE1FKCIoJXAsJXMsJWxkLCVwLCVsZCwlcCwlbGQsJXApLCBzdHViIVxuIixUaGlzLGRlYnVnc3RyX2d1aWQoZ3VpZFByb3BTZXQpLGR3UHJvcElELHBJbnN0YW5jZURhdGEsY2JJbnN0YW5jZURhdGEscFByb3BEYXRhLGNiUHJvcERhdGEscGNiUmV0dXJuZWQpOwoJcmV0dXJuIEVfUFJPUF9JRF9VTlNVUFBPUlRFRDsKfQojZW5kaWYKCiNpZmRlZiBVU0VfRFNPVU5EM0QKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElLc1Byb3BlcnR5U2V0SW1wbF9TZXQoTFBLU1BST1BFUlRZU0VUIGlmYWNlLAoJUkVGR1VJRCBndWlkUHJvcFNldCwgVUxPTkcgZHdQcm9wSUQsCglMUFZPSUQgcEluc3RhbmNlRGF0YSwgVUxPTkcgY2JJbnN0YW5jZURhdGEsCglMUFZPSUQgcFByb3BEYXRhLCBVTE9ORyBjYlByb3BEYXRhCikgewoJSUNPTV9USElTKElLc1Byb3BlcnR5U2V0SW1wbCxpZmFjZSk7CgoJRklYTUUoIiglcCwlcywlbGQsJXAsJWxkLCVwLCVsZCksIHN0dWIhXG4iLFRoaXMsZGVidWdzdHJfZ3VpZChndWlkUHJvcFNldCksZHdQcm9wSUQscEluc3RhbmNlRGF0YSxjYkluc3RhbmNlRGF0YSxwUHJvcERhdGEsY2JQcm9wRGF0YSk7CglyZXR1cm4gRV9QUk9QX0lEX1VOU1VQUE9SVEVEOwp9CiNlbmRpZgoKI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUtzUHJvcGVydHlTZXRJbXBsX1F1ZXJ5U3VwcG9ydChMUEtTUFJPUEVSVFlTRVQgaWZhY2UsCglSRUZHVUlEIGd1aWRQcm9wU2V0LCBVTE9ORyBkd1Byb3BJRCwgUFVMT05HIHBUeXBlU3VwcG9ydAopIHsKCUlDT01fVEhJUyhJS3NQcm9wZXJ0eVNldEltcGwsaWZhY2UpOwoKCUZJWE1FKCIoJXAsJXMsJWxkLCVwKSwgc3R1YiFcbiIsVGhpcyxkZWJ1Z3N0cl9ndWlkKGd1aWRQcm9wU2V0KSxkd1Byb3BJRCxwVHlwZVN1cHBvcnQpOwoJcmV0dXJuIEVfUFJPUF9JRF9VTlNVUFBPUlRFRDsKfQojZW5kaWYKCiNpZmRlZiBVU0VfRFNPVU5EM0QKc3RhdGljIElDT01fVlRBQkxFKElLc1Byb3BlcnR5U2V0KSBpa3N2dCA9IHsKCUlDT01fTVNWVEFCTEVfQ09NUEFUX0R1bW15UlRUSVZBTFVFCglJS3NQcm9wZXJ0eVNldEltcGxfUXVlcnlJbnRlcmZhY2UsCglJS3NQcm9wZXJ0eVNldEltcGxfQWRkUmVmLAoJSUtzUHJvcGVydHlTZXRJbXBsX1JlbGVhc2UsCglJS3NQcm9wZXJ0eVNldEltcGxfR2V0LAoJSUtzUHJvcGVydHlTZXRJbXBsX1NldCwKCUlLc1Byb3BlcnR5U2V0SW1wbF9RdWVyeVN1cHBvcnQKfTsKI2VuZGlmCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgSURpcmVjdFNvdW5kM0RCdWZmZXIKICovCgovKiBJVW5rbm93biBtZXRob2RzICovCiNpZmRlZiBVU0VfRFNPVU5EM0QKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9RdWVyeUludGVyZmFjZSgKCUxQRElSRUNUU09VTkQzREJVRkZFUiBpZmFjZSwgUkVGSUlEIHJpaWQsIExQVk9JRCAqcHBvYmopCnsKCUlDT01fVEhJUyhJRGlyZWN0U291bmQzREJ1ZmZlckltcGwsaWZhY2UpOwoKCWlmICggSXNFcXVhbEdVSUQoICZJSURfSUtzUHJvcGVydHlTZXQsIHJpaWQgKSApIHsKCSAgICBJRGlyZWN0U291bmQzREJ1ZmZlcl9BZGRSZWYoaWZhY2UpOwoJICAgICpwcG9iaiA9IFRoaXMtPmlrczsKCSAgICByZXR1cm4gU19PSzsKCX0KCglGSVhNRSgiKCVwLCVzLCVwKSwgbm8gc3VjaCBpbnRlcmZhY2UuXG4iLFRoaXMsZGVidWdzdHJfZ3VpZChyaWlkKSxwcG9iaik7CglyZXR1cm4gRV9GQUlMOwp9CiNlbmRpZgoKI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgVUxPTkcgV0lOQVBJIElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9BZGRSZWYoTFBESVJFQ1RTT1VORDNEQlVGRkVSIGlmYWNlKQp7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsLGlmYWNlKTsKCVRoaXMtPnJlZisrOwoJcmV0dXJuIFRoaXMtPnJlZjsKfQojZW5kaWYKCiNpZmRlZiBVU0VfRFNPVU5EM0QKc3RhdGljIFVMT05HIFdJTkFQSSBJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfUmVsZWFzZShMUERJUkVDVFNPVU5EM0RCVUZGRVIgaWZhY2UpCnsKCUlDT01fVEhJUyhJRGlyZWN0U291bmQzREJ1ZmZlckltcGwsaWZhY2UpOwoKCVRSQUNFKCIoJXApIHJlZiB3YXMgJWxkXG4iLCBUaGlzLCBUaGlzLT5yZWYpOwoKCWlmKC0tVGhpcy0+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+aHdvKSk7CglyZXR1cm4gZXJyOwp9CgpzdGF0aWMgSFJFU1VMVCBEU09VTkRfUHJpbWFyeVN0b3AoSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiKQp7CglIUkVTVUxUIGVyciA9IERTX09LOwoJaWYgKGRzYi0+aHdidWYpIHsKCQllcnIgPSBJRHNEcml2ZXJCdWZmZXJfU3RvcChkc2ItPmh3YnVmKTsKCQlpZiAoZXJyID09IERTRVJSX0JVRkZFUkxPU1QpIHsKCQkJLyogV2luZS1vbmx5OiB0aGUgZHJpdmVyIHdhbnRzIHVzIHRvIHJlb3BlbiB0aGUgZGV2aWNlICovCgkJCS8qIEZJWE1FOiBjaGVjayBmb3IgZXJyb3JzICovCgkJCUlEc0RyaXZlckJ1ZmZlcl9SZWxlYXNlKHByaW1hcnlidWYtPmh3YnVmKTsKCQkJd2F2ZU91dENsb3NlKGRzYi0+ZHNvdW5kLT5od28pOwoJCQlkc2ItPmRzb3VuZC0+aHdvID0gMDsKCQkJd2F2ZU91dE9wZW4oJihkc2ItPmRzb3VuZC0+aHdvKSwgZHNiLT5kc291bmQtPmRydmRlc2MuZG5EZXZOb2RlLAoJCQkJICAgICYocHJpbWFyeWJ1Zi0+d2Z4KSwgKERXT1JEKURTT1VORF9jYWxsYmFjaywgKERXT1JEKWRzYi0+ZHNvdW5kLAoJCQkJICAgIENBTExCQUNLX0ZVTkNUSU9OIHwgV0FWRV9ESVJFQ1RTT1VORCk7CgkJCWVyciA9IElEc0RyaXZlcl9DcmVhdGVTb3VuZEJ1ZmZlcihkc2ItPmRzb3VuZC0+ZHJpdmVyLCYoZHNiLT53ZngpLGRzYi0+ZHNiZC5kd0ZsYWdzLDAsCgkJCQkJCQkgICYoZHNiLT5idWZsZW4pLCYoZHNiLT5idWZmZXIpLAoJCQkJCQkJICAoTFBWT0lEKSYoZHNiLT5od2J1ZikpOwoJCX0KCX0KCWVsc2UKCQllcnIgPSBtbUVycih3YXZlT3V0UGF1c2UoZHNiLT5kc291bmQtPmh3bykpOwoJcmV0dXJuIGVycjsKfQoKLyogVGhpcyBzZXRzIHRoaXMgZm9ybWF0IGZvciB0aGUgPGVtPlByaW1hcnkgQnVmZmVyIE9ubHk8L2VtPiAqLwovKiBTZWUgZmlsZTovLy9jZHJvbS9zZGs1Mi9kb2NzL3dvcmRkb2MvZHNvdW5kLmRvYyBwYWdlIDEyMCAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kQnVmZmVySW1wbF9TZXRGb3JtYXQoCglMUERJUkVDVFNPVU5EQlVGRkVSIGlmYWNlLExQV0FWRUZPUk1BVEVYIHdmZXgKKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQnVmZmVySW1wbCxpZmFjZSk7CglJRGlyZWN0U291bmRCdWZmZXJJbXBsKiogZHNiOwoJSFJFU1VMVCBlcnIgPSBEU19PSzsKCWludAkJCWk7CgoJLyogTGV0J3MgYmUgcGVkYW50aWMhICovCglpZiAoKHdmZXggPT0gTlVMTCkgfHwKCSAgICAod2ZleC0+d0Zvcm1hdFRhZyAhPSBXQVZFX0ZPUk1BVF9QQ00pIHx8CgkgICAgKHdmZXgtPm5DaGFubmVscyA8IDEpIHx8ICh3ZmV4LT5uQ2hhbm5lbHMgPiAyKSB8fAoJICAgICh3ZmV4LT5uU2FtcGxlc1BlclNlYyA8IDEpIHx8CgkgICAgKHdmZXgtPm5CbG9ja0FsaWduIDwgMSkgfHwgKHdmZXgtPm5DaGFubmVscyA+IDQpIHx8CgkgICAgKCh3ZmV4LT53Qml0c1BlclNhbXBsZSAhPSA4KSAmJiAod2ZleC0+d0JpdHNQZXJTYW1wbGUgIT0gMTYpKSkgewoJCVRSQUNFKCJmYWlsZWQgcGVkYW50aWMgY2hlY2shXG4iKTsKCQlyZXR1cm4gRFNFUlJfSU5WQUxJRFBBUkFNOwoJfQoKCS8qICoqKiogKi8KCUVudGVyQ3JpdGljYWxTZWN0aW9uKCYoVGhpcy0+ZHNvdW5kLT5sb2NrKSk7CgoJaWYgKHByaW1hcnlidWYtPndmeC5uU2FtcGxlc1BlclNlYyAhPSB3ZmV4LT5uU2FtcGxlc1BlclNlYykgewoJCWRzYiA9IGRzb3VuZC0+YnVmZmVyczsKCQlmb3IgKGkgPSAwOyBpIDwgZHNvdW5kLT5ucm9mYnVmZmVyczsgaSsrLCBkc2IrKykgewoJCQkvKiAqKioqICovCgkJCUVudGVyQ3JpdGljYWxTZWN0aW9uKCYoKCpkc2IpLT5sb2NrKSk7CgoJCQkoKmRzYiktPmZyZXFBZGp1c3QgPSAoKCpkc2IpLT5mcmVxIDw8IERTT1VORF9GUkVRU0hJRlQpIC8KCQkJCXdmZXgtPm5TYW1wbGVzUGVyU2VjOwoKCQkJTGVhdmVDcml0aWNhbFNlY3Rpb24oJigoKmRzYiktPmxvY2spKTsKCQkJLyogKioqKiAqLwoJCX0KCX0KCgltZW1jcHkoJihwcmltYXJ5YnVmLT53ZngpLCB3ZmV4LCBzaXplb2YocHJpbWFyeWJ1Zi0+d2Z4KSk7CgoJVFJBQ0UoIihmb3JtYXR0YWc9MHglMDR4LGNoYW5zPSVkLHNhbXBsZXJhdGU9JWxkLCIKCQkgICAiYnl0ZXNwZXJzZWM9JWxkLGJsb2NrYWxpZ249JWQsYml0c3BlcnNhbXA9JWQsY2JTaXplPSVkKVxuIiwKCQkgICB3ZmV4LT53Rm9ybWF0VGFnLCB3ZmV4LT5uQ2hhbm5lbHMsIHdmZXgtPm5TYW1wbGVzUGVyU2VjLAoJCSAgIHdmZXgtPm5BdmdCeXRlc1BlclNlYywgd2ZleC0+bkJsb2NrQWxpZ24sIAoJCSAgIHdmZXgtPndCaXRzUGVyU2FtcGxlLCB3ZmV4LT5jYlNpemUpOwoKCXByaW1hcnlidWYtPndmeC5uQXZnQnl0ZXNQZXJTZWMgPQoJCVRoaXMtPndmeC5uU2FtcGxlc1BlclNlYyAqIFRoaXMtPndmeC5uQmxvY2tBbGlnbjsKCglpZiAocHJpbWFyeWJ1Zi0+ZHNvdW5kLT5kcnZkZXNjLmR3RmxhZ3MgJiBEU0RERVNDX0RPTU1TWVNURU1TRVRGT1JNQVQpIHsKCQkvKiBGSVhNRTogY2hlY2sgZm9yIGVycm9ycyAqLwoJCURTT1VORF9QcmltYXJ5Q2xvc2UocHJpbWFyeWJ1Zik7CgkJd2F2ZU91dENsb3NlKFRoaXMtPmRzb3VuZC0+aHdvKTsKCQlUaGlzLT5kc291bmQtPmh3byA9IDA7CiAgICAgICAgICAgICAgICB3YXZlT3V0T3BlbigmKFRoaXMtPmRzb3VuZC0+aHdvKSwgVGhpcy0+ZHNvdW5kLT5kcnZkZXNjLmRuRGV2Tm9kZSwKCQkJICAgICYocHJpbWFyeWJ1Zi0+d2Z4KSwgKERXT1JEKURTT1VORF9jYWxsYmFjaywgKERXT1JEKVRoaXMtPmRzb3VuZCwKCQkJICAgIENBTExCQUNLX0ZVTkNUSU9OIHwgV0FWRV9ESVJFQ1RTT1VORCk7CgkJRFNPVU5EX1ByaW1hcnlPcGVuKHByaW1hcnlidWYpOwoJfQoJaWYgKHByaW1hcnlidWYtPmh3YnVmKSB7CgkJZXJyID0gSURzRHJpdmVyQnVmZmVyX1NldEZvcm1hdChwcmltYXJ5YnVmLT5od2J1ZiwgJihwcmltYXJ5YnVmLT53ZngpKTsKCQlpZiAoZXJyID09IERTRVJSX0JVRkZFUkxPU1QpIHsKCQkJLyogV2luZS1vbmx5OiB0aGUgZHJpdmVyIHdhbnRzIHVzIHRvIHJlY3JlYXRlIHRoZSBIVyBidWZmZXIgKi8KCQkJSURzRHJpdmVyQnVmZmVyX1JlbGVhc2UocHJpbWFyeWJ1Zi0+aHdidWYpOwoJCQllcnIgPSBJRHNEcml2ZXJfQ3JlYXRlU291bmRCdWZmZXIocHJpbWFyeWJ1Zi0+ZHNvdW5kLT5kcml2ZXIsJihwcmltYXJ5YnVmLT53ZngpLHByaW1hcnlidWYtPmRzYmQuZHdGbGFncywwLAoJCQkJCQkJICAmKHByaW1hcnlidWYtPmJ1ZmxlbiksJihwcmltYXJ5YnVmLT5idWZmZXIpLAoJCQkJCQkJICAoTFBWT0lEKSYocHJpbWFyeWJ1Zi0+aHdidWYpKTsKCQkJaWYgKHByaW1hcnlidWYtPnN0YXRlID09IFNUQVRFX1BMQVlJTkcpIHByaW1hcnlidWYtPnN0YXRlID0gU1RBVEVfU1RBUlRJTkc7CgkJCWVsc2UgaWYgKHByaW1hcnlidWYtPnN0YXRlID09IFNUQVRFX1NUT1BQSU5HKSBwcmltYXJ5YnVmLT5zdGF0ZSA9IFNUQVRFX1NUT1BQRUQ7CgkJfQoJfQoJRFNPVU5EX1JlY2FsY0Zvcm1hdChwcmltYXJ5YnVmKTsKCglMZWF2ZUNyaXRpY2FsU2VjdGlvbigmKFRoaXMtPmRzb3VuZC0+bG9jaykpOwoJLyogKioqKiAqLwoKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZEJ1ZmZlckltcGxfU2V0Vm9sdW1lKAoJTFBESVJFQ1RTT1VOREJVRkZFUiBpZmFjZSxMT05HIHZvbAopIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRCdWZmZXJJbXBsLGlmYWNlKTsKCglUUkFDRSgiKCVwLCVsZClcbiIsVGhpcyx2b2wpOwoKCS8qIEknbSBub3Qgc3VyZSBpZiB3ZSBuZWVkIHRoaXMgZm9yIHByaW1hcnkgYnVmZmVyICovCglpZiAoIShUaGlzLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX0NUUkxWT0xVTUUpKQoJCXJldHVybiBEU0VSUl9DT05UUk9MVU5BVkFJTDsKCglpZiAoKHZvbCA+IERTQlZPTFVNRV9NQVgpIHx8ICh2b2wgPCBEU0JWT0xVTUVfTUlOKSkKCQlyZXR1cm4gRFNFUlJfSU5WQUxJRFBBUkFNOwoKCS8qICoqKiogKi8KCUVudGVyQ3JpdGljYWxTZWN0aW9uKCYoVGhpcy0+bG9jaykpOwoKCVRoaXMtPnZvbHBhbi5sVm9sdW1lID0gdm9sOwoKCURTT1VORF9SZWNhbGNWb2xQYW4oJihUaGlzLT52b2xwYW4pKTsKCglpZiAoVGhpcy0+aHdidWYpIHsKCQlJRHNEcml2ZXJCdWZmZXJfU2V0Vm9sdW1lUGFuKFRoaXMtPmh3YnVmLCAmKFRoaXMtPnZvbHBhbikpOwoJfQoJZWxzZSBpZiAoVGhpcy0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19QUklNQVJZQlVGRkVSKSB7CiNpZiAwIC8qIHNob3VsZCB3ZSByZWFsbHkgZG8gdGhpcz8gKi8KCQkvKiB0aGUgRFMgdm9sdW1lIHJhbmdlcyBmcm9tIDAgKG1heCwgMGRCIGF0dGVudWF0aW9uKSB0byAtMTAwMDAgKG1pbiwgMTAwZEIgYXR0ZW51YXRpb24pICovCgkJLyogdGhlIE1NIHZvbHVtZSByYW5nZXMgZnJvbSAwIHRvIDB4ZmZmZiBpbiBhbiB1bnNwZWNpZmllZCBsb2dhcml0aG1pYyBzY2FsZSAqLwoJCVdPUkQgY3ZvbCA9IDB4ZmZmZiArIHZvbCo2ICsgdm9sLzI7CgkJRFdPUkQgdm9sID0gY3ZvbCB8ICgoRFdPUkQpY3ZvbCA8PCAxNikKCQl3YXZlT3V0U2V0Vm9sdW1lKFRoaXMtPmRzb3VuZC0+aHdvLCB2b2wpOwojZW5kaWYKCX0KCglMZWF2ZUNyaXRpY2FsU2VjdGlvbigmKFRoaXMtPmxvY2spKTsKCS8qICoqKiogKi8KCglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmRCdWZmZXJJbXBsX0dldFZvbHVtZSgKCUxQRElSRUNUU09VTkRCVUZGRVIgaWZhY2UsTFBMT05HIHZvbAopIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRCdWZmZXJJbXBsLGlmYWNlKTsKCVRSQUNFKCIoJXAsJXApXG4iLFRoaXMsdm9sKTsKCglpZiAodm9sID09IE5VTEwpCgkJcmV0dXJuIERTRVJSX0lOVkFMSURQQVJBTTsKCgkqdm9sID0gVGhpcy0+dm9scGFuLmxWb2x1bWU7CglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmRCdWZmZXJJbXBsX1NldEZyZXF1ZW5jeSgKCUxQRElSRUNUU09VTkRCVUZGRVIgaWZhY2UsRFdPUkQgZnJlcQopIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRCdWZmZXJJbXBsLGlmYWNlKTsKCVRSQUNFKCIoJXAsJWxkKVxuIixUaGlzLGZyZXEpOwoKCS8qIFlvdSBjYW5ub3Qgc2V0IHRoZSBmcmVxdWVuY3kgb2YgdGhlIHByaW1hcnkgYnVmZmVyICovCglpZiAoIShUaGlzLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX0NUUkxGUkVRVUVOQ1kpIHx8CgkgICAgKFRoaXMtPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfUFJJTUFSWUJVRkZFUikpCgkJcmV0dXJuIERTRVJSX0NPTlRST0xVTkFWQUlMOwoKCWlmICghZnJlcSkgZnJlcSA9IFRoaXMtPndmeC5uU2FtcGxlc1BlclNlYzsKCglpZiAoKGZyZXEgPCBEU0JGUkVRVUVOQ1lfTUlOKSB8fCAoZnJlcSA+IERTQkZSRVFVRU5DWV9NQVgpKQoJCXJldHVybiBEU0VSUl9JTlZBTElEUEFSQU07CgoJLyogKioqKiAqLwoJRW50ZXJDcml0aWNhbFNlY3Rpb24oJihUaGlzLT5sb2NrKSk7CgoJVGhpcy0+ZnJlcSA9IGZyZXE7CglUaGlzLT5mcmVxQWRqdXN0ID0gKGZyZXEgPDwgRFNPVU5EX0ZSRVFTSElGVCkgLyBwcmltYXJ5YnVmLT53ZngublNhbXBsZXNQZXJTZWM7CglUaGlzLT5uQXZnQnl0ZXNQZXJTZWMgPSBmcmVxICogVGhpcy0+d2Z4Lm5CbG9ja0FsaWduOwoJRFNPVU5EX1JlY2FsY0Zvcm1hdChUaGlzKTsKCglMZWF2ZUNyaXRpY2FsU2VjdGlvbigmKFRoaXMtPmxvY2spKTsKCS8qICoqKiogKi8KCglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmRCdWZmZXJJbXBsX1BsYXkoCglMUERJUkVDVFNPVU5EQlVGRkVSIGlmYWNlLERXT1JEIHJlc2VydmVkMSxEV09SRCByZXNlcnZlZDIsRFdPUkQgZmxhZ3MKKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQnVmZmVySW1wbCxpZmFjZSk7CglUUkFDRSgiKCVwLCUwOGx4LCUwOGx4LCUwOGx4KVxuIiwKCQlUaGlzLHJlc2VydmVkMSxyZXNlcnZlZDIsZmxhZ3MKCSk7CgoJLyogKioqKiAqLwoJRW50ZXJDcml0aWNhbFNlY3Rpb24oJihUaGlzLT5sb2NrKSk7CgoJVGhpcy0+cGxheWZsYWdzID0gZmxhZ3M7CglpZiAoVGhpcy0+c3RhdGUgPT0gU1RBVEVfU1RPUFBFRCkgewoJCVRoaXMtPmxlYWRpbiA9IFRSVUU7CgkJVGhpcy0+c3RhcnRwb3MgPSBUaGlzLT5idWZfbWl4cG9zOwoJCVRoaXMtPnN0YXRlID0gU1RBVEVfU1RBUlRJTkc7Cgl9IGVsc2UgaWYgKFRoaXMtPnN0YXRlID09IFNUQVRFX1NUT1BQSU5HKQoJCVRoaXMtPnN0YXRlID0gU1RBVEVfUExBWUlORzsKCWlmICghKFRoaXMtPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfUFJJTUFSWUJVRkZFUikgJiYgVGhpcy0+aHdidWYpIHsKCQlJRHNEcml2ZXJCdWZmZXJfUGxheShUaGlzLT5od2J1ZiwgMCwgMCwgVGhpcy0+cGxheWZsYWdzKTsKCQlUaGlzLT5zdGF0ZSA9IFNUQVRFX1BMQVlJTkc7Cgl9CgoJTGVhdmVDcml0aWNhbFNlY3Rpb24oJihUaGlzLT5sb2NrKSk7CgkvKiAqKioqICovCgoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kQnVmZmVySW1wbF9TdG9wKExQRElSRUNUU09VTkRCVUZGRVIgaWZhY2UpCnsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRCdWZmZXJJbXBsLGlmYWNlKTsKCVRSQUNFKCIoJXApXG4iLFRoaXMpOwoKCS8qICoqKiogKi8KCUVudGVyQ3JpdGljYWxTZWN0aW9uKCYoVGhpcy0+bG9jaykpOwoKCWlmIChUaGlzLT5zdGF0ZSA9PSBTVEFURV9QTEFZSU5HKQoJCVRoaXMtPnN0YXRlID0gU1RBVEVfU1RPUFBJTkc7CgllbHNlIGlmIChUaGlzLT5zdGF0ZSA9PSBTVEFURV9TVEFSVElORykKCQlUaGlzLT5zdGF0ZSA9IFNUQVRFX1NUT1BQRUQ7CglpZiAoIShUaGlzLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX1BSSU1BUllCVUZGRVIpICYmIFRoaXMtPmh3YnVmKSB7CgkJSURzRHJpdmVyQnVmZmVyX1N0b3AoVGhpcy0+aHdidWYpOwoJCVRoaXMtPnN0YXRlID0gU1RBVEVfU1RPUFBFRDsKCX0KCURTT1VORF9DaGVja0V2ZW50KFRoaXMsIDApOwoKCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCYoVGhpcy0+bG9jaykpOwoJLyogKioqKiAqLwoKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIERXT1JEIFdJTkFQSSBJRGlyZWN0U291bmRCdWZmZXJJbXBsX0FkZFJlZihMUERJUkVDVFNPVU5EQlVGRkVSIGlmYWNlKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQnVmZmVySW1wbCxpZmFjZSk7CglEV09SRCByZWY7CgoJVFJBQ0UoIiglcCkgcmVmIHdhcyAlbGQsIHRocmVhZCBpcyAlbHhcbiIsVGhpcywgVGhpcy0+cmVmLCBHZXRDdXJyZW50VGhyZWFkSWQoKSk7CgoJcmVmID0gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJihUaGlzLT5yZWYpKTsKCWlmICghcmVmKSB7CgkJRklYTUUoInRocmVhZC1zYWZldHkgYWxlcnQhIEFkZFJlZi1pbmcgd2l0aCBhIHplcm8gcmVmY291bnQhXG4iKTsKCX0KCXJldHVybiByZWY7Cn0Kc3RhdGljIERXT1JEIFdJTkFQSSBJRGlyZWN0U291bmRCdWZmZXJJbXBsX1JlbGVhc2UoTFBESVJFQ1RTT1VOREJVRkZFUiBpZmFjZSkgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwsaWZhY2UpOwoJaW50CWk7CglEV09SRCByZWY7CgoJVFJBQ0UoIiglcCkgcmVmIHdhcyAlbGQsIHRocmVhZCBpcyAlbHhcbiIsVGhpcywgVGhpcy0+cmVmLCBHZXRDdXJyZW50VGhyZWFkSWQoKSk7CgoJcmVmID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJihUaGlzLT5yZWYpKTsKCWlmIChyZWYpIHJldHVybiByZWY7CgoJRW50ZXJDcml0aWNhbFNlY3Rpb24oJihUaGlzLT5kc291bmQtPmxvY2spKTsKCWZvciAoaT0wO2k8VGhpcy0+ZHNvdW5kLT5ucm9mYnVmZmVycztpKyspCgkJaWYgKFRoaXMtPmRzb3VuZC0+YnVmZmVyc1tpXSA9PSBUaGlzKQoJCQlicmVhazsKCglpZiAoaSA8IFRoaXMtPmRzb3VuZC0+bnJvZmJ1ZmZlcnMpIHsKCQkvKiBQdXQgdGhlIGxhc3QgYnVmZmVyIG9mIHRoZSBsaXN0IGluIHRoZSAobm93IGVtcHR5KSBwb3NpdGlvbiAqLwoJCVRoaXMtPmRzb3VuZC0+YnVmZmVyc1tpXSA9IFRoaXMtPmRzb3VuZC0+YnVmZmVyc1tUaGlzLT5kc291bmQtPm5yb2ZidWZmZXJzIC0gMV07CgkJVGhpcy0+ZHNvdW5kLT5ucm9mYnVmZmVycy0tOwoJCVRoaXMtPmRzb3VuZC0+YnVmZmVycyA9IEhlYXBSZUFsbG9jKEdldFByb2Nlc3NIZWFwKCksMCxUaGlzLT5kc291bmQtPmJ1ZmZlcnMsc2l6ZW9mKExQRElSRUNUU09VTkRCVUZGRVIpKlRoaXMtPmRzb3VuZC0+bnJvZmJ1ZmZlcnMpOwoJCVRSQUNFKCJidWZmZXIgY291bnQgaXMgbm93ICVkXG4iLCBUaGlzLT5kc291bmQtPm5yb2ZidWZmZXJzKTsKCQlJRGlyZWN0U291bmRfUmVsZWFzZSgoTFBESVJFQ1RTT1VORClUaGlzLT5kc291bmQpOwoJfQoJTGVhdmVDcml0aWNhbFNlY3Rpb24oJihUaGlzLT5kc291bmQtPmxvY2spKTsKCglEZWxldGVDcml0aWNhbFNlY3Rpb24oJihUaGlzLT5sb2NrKSk7CglpZiAoVGhpcy0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19QUklNQVJZQlVGRkVSKQoJCURTT1VORF9QcmltYXJ5Q2xvc2UoVGhpcyk7CglpZiAoVGhpcy0+aHdidWYpIHsKCQlJRHNEcml2ZXJCdWZmZXJfUmVsZWFzZShUaGlzLT5od2J1Zik7Cgl9CglpZiAoVGhpcy0+ZHMzZGIpCgkJSURpcmVjdFNvdW5kM0RCdWZmZXJfUmVsZWFzZSgoTFBESVJFQ1RTT1VORDNEQlVGRkVSKVRoaXMtPmRzM2RiKTsKCWlmIChUaGlzLT5wYXJlbnQpCgkJLyogdGhpcyBpcyBhIGR1cGxpY2F0ZSBidWZmZXIgKi8KCQlJRGlyZWN0U291bmRCdWZmZXJfUmVsZWFzZSgoTFBESVJFQ1RTT1VOREJVRkZFUilUaGlzLT5wYXJlbnQpOwoJZWxzZQoJCS8qIHRoaXMgaXMgYSB0b3BsZXZlbCBidWZmZXIgKi8KCQlIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsVGhpcy0+YnVmZmVyKTsKCglIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsVGhpcyk7CgkKCWlmIChUaGlzID09IHByaW1hcnlidWYpCgkJcHJpbWFyeWJ1ZiA9IE5VTEw7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBEV09SRCBEU09VTkRfQ2FsY1BsYXlQb3NpdGlvbihJRGlyZWN0U291bmRCdWZmZXJJbXBsICpUaGlzLAoJCQkJICAgICBEV09SRCBzdGF0ZSwgRFdPUkQgcHBsYXksIERXT1JEIHB3cml0ZSwgRFdPUkQgcG1peCwgRFdPUkQgYm1peCkKewoJRFdPUkQgYnBsYXk7CgoJVFJBQ0UoInByaW1hcnkgcGxheXBvcz0lbGQsIG1peHBvcz0lbGRcbiIsIHBwbGF5LCBwbWl4KTsKCVRSQUNFKCJ0aGlzIG1peHBvcz0lbGQsIHRpbWU9JWxkXG4iLCBibWl4LCBHZXRUaWNrQ291bnQoKSk7CgoJLyogdGhlIGFjdHVhbCBwcmltYXJ5IHBsYXkgcG9zaXRpb24gKHBwbGF5KSBpcyBhbHdheXMgYmVoaW5kIGxhc3QgbWl4ZWQgKHBtaXgpLAoJICogdW5sZXNzIHRoZSBjb21wdXRlciBpcyB0b28gc2xvdyBvciBzb21ldGhpbmcgKi8KCS8qIHdlIG5lZWQgdG8ga25vdyBob3cgZmFyIGF3YXkgd2UgYXJlIGZyb20gdGhlcmUgKi8KI2lmIDAgLyogd2UnbGwgbmV2ZXIgZmlsbCB0aGUgcHJpbWFyeSBlbnRpcmVseSAqLwoJaWYgKHBtaXggPT0gcHBsYXkpIHsKCQlpZiAoKHN0YXRlID09IFNUQVRFX1BMQVlJTkcpIHx8IChzdGF0ZSA9PSBTVEFURV9TVE9QUElORykpIHsKCQkJLyogd293LCB0aGUgc29mdHdhcmUgbWl4ZXIgaXMgcmVhbGx5IGRvaW5nIHdlbGwsCgkJCSAqIHNlZW1zIHRoZSBlbnRpcmUgcHJpbWFyeSBidWZmZXIgaXMgZmlsbGVkISAqLwoJCQlwbWl4ICs9IHByaW1hcnlidWYtPmJ1ZmxlbjsKCQl9CgkJLyogZWxzZTogdGhlIHByaW1hcnkgYnVmZmVyIGlzIG5vdCBwbGF5aW5nLCBzbyBwcm9iYWJseSBlbXB0eSAqLwoJfQojZW5kaWYKCWlmIChwbWl4IDwgcHBsYXkpIHBtaXggKz0gcHJpbWFyeWJ1Zi0+YnVmbGVuOyAvKiB3cmFwYXJvdW5kICovCglwbWl4IC09IHBwbGF5OwoJLyogZGV0ZWN0IGJ1ZmZlciB1bmRlcnJ1biAqLwoJaWYgKHB3cml0ZSA8IHBwbGF5KSBwd3JpdGUgKz0gcHJpbWFyeWJ1Zi0+YnVmbGVuOyAvKiB3cmFwYXJvdW5kICovCglwd3JpdGUgLT0gcHBsYXk7CglpZiAocG1peCA+IChEU19TTkRfUVVFVUVfTUFYICogcHJpbWFyeWJ1Zi0+ZHNvdW5kLT5mcmFnbGVuICsgcHdyaXRlICsgcHJpbWFyeWJ1Zi0+d3JpdGVsZWFkKSkgewoJCVdBUk4oImRldGVjdGVkIGFuIHVuZGVycnVuOiBwcmltYXJ5IHF1ZXVlIHdhcyAlbGRcbiIscG1peCk7CgkJcG1peCA9IDA7Cgl9CgkvKiBkaXZpZGUgdGhlIG9mZnNldCBieSBpdHMgc2FtcGxlIHNpemUgKi8KCXBtaXggLz0gcHJpbWFyeWJ1Zi0+d2Z4Lm5CbG9ja0FsaWduOwoJVFJBQ0UoInByaW1hcnkgYmFjay1zYW1wbGVzPSVsZFxuIixwbWl4KTsKCS8qIGFkanVzdCBmb3Igb3VyIGZyZXF1ZW5jeSAqLwoJcG1peCA9IChwbWl4ICogVGhpcy0+ZnJlcUFkanVzdCkgPj4gRFNPVU5EX0ZSRVFTSElGVDsKCS8qIG11bHRpcGx5IGJ5IG91ciBvd24gc2FtcGxlIHNpemUgKi8KCXBtaXggKj0gVGhpcy0+d2Z4Lm5CbG9ja0FsaWduOwoJVFJBQ0UoInRoaXMgYmFjay1vZmZzZXQ9JWxkXG4iLCBwbWl4KTsKCS8qIHN1YnRyYWN0IGZyb20gb3VyIGxhc3QgbWl4ZWQgcG9zaXRpb24gKi8KCWJwbGF5ID0gYm1peDsKCXdoaWxlIChicGxheSA8IHBtaXgpIGJwbGF5ICs9IFRoaXMtPmJ1ZmxlbjsgLyogd3JhcGFyb3VuZCAqLwoJYnBsYXkgLT0gcG1peDsKCWlmIChUaGlzLT5sZWFkaW4gJiYgKChicGxheSA8IFRoaXMtPnN0YXJ0cG9zKSB8fCAoYnBsYXkgPiBibWl4KSkpIHsKCQkvKiBzZWVtcyB3ZSBoYXZlbid0IHN0YXJ0ZWQgcGxheWluZyB5ZXQgKi8KCQlUUkFDRSgidGhpcyBzdGlsbCBpbiBsZWFkLWluIHBoYXNlXG4iKTsKCQlicGxheSA9IFRoaXMtPnN0YXJ0cG9zOwoJfQoJLyogcmV0dXJuIHRoZSByZXN1bHQgKi8KCXJldHVybiBicGxheTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZEJ1ZmZlckltcGxfR2V0Q3VycmVudFBvc2l0aW9uKAoJTFBESVJFQ1RTT1VOREJVRkZFUiBpZmFjZSxMUERXT1JEIHBsYXlwb3MsTFBEV09SRCB3cml0ZXBvcwopIHsKCUhSRVNVTFQJaHJlczsgCglJQ09NX1RISVMoSURpcmVjdFNvdW5kQnVmZmVySW1wbCxpZmFjZSk7CglUUkFDRSgiKCVwLCVwLCVwKVxuIixUaGlzLHBsYXlwb3Msd3JpdGVwb3MpOwoJaWYgKFRoaXMtPmh3YnVmKSB7CgkJaHJlcz1JRHNEcml2ZXJCdWZmZXJfR2V0UG9zaXRpb24oVGhpcy0+aHdidWYscGxheXBvcyx3cml0ZXBvcyk7CgkJaWYgKGhyZXMpCgkJICAgIHJldHVybiBocmVzOwoJfQoJZWxzZSBpZiAoVGhpcy0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19QUklNQVJZQlVGRkVSKSB7CgkJaWYgKHBsYXlwb3MpIHsKCQkJTU1USU1FIG10aW1lOwoJCQltdGltZS53VHlwZSA9IFRJTUVfQllURVM7CgkJCXdhdmVPdXRHZXRQb3NpdGlvbihUaGlzLT5kc291bmQtPmh3bywgJm10aW1lLCBzaXplb2YobXRpbWUpKTsKCQkJbXRpbWUudS5jYiA9IG10aW1lLnUuY2IgJSBUaGlzLT5idWZsZW47CgkJCSpwbGF5cG9zID0gbXRpbWUudS5jYjsKCQl9CgkJaWYgKHdyaXRlcG9zKSB7CgkJCS8qIHRoZSB3cml0ZXBvcyBzaG91bGQgb25seSBiZSB1c2VkIGJ5IGFwcHMgd2l0aCBXUklURVBSSU1BUlkgcHJpb3JpdHksCgkJCSAqIGluIHdoaWNoIGNhc2Ugb3VyIHNvZnR3YXJlIG1peGVyIGlzIGRpc2FibGVkIGFueXdheSAqLwoJCQkqd3JpdGVwb3MgPSAoVGhpcy0+ZHNvdW5kLT5wd3BsYXkgKyBEU19IRUxfTUFSR0lOKSAqIFRoaXMtPmRzb3VuZC0+ZnJhZ2xlbjsKCQkJd2hpbGUgKCp3cml0ZXBvcyA+PSBUaGlzLT5idWZsZW4pCgkJCQkqd3JpdGVwb3MgLT0gVGhpcy0+YnVmbGVuOwoJCX0KCX0gZWxzZSB7CgkJaWYgKHBsYXlwb3MgJiYgKFRoaXMtPnN0YXRlICE9IFNUQVRFX1BMQVlJTkcpKSB7CgkJCS8qIHdlIGhhdmVuJ3QgYmVlbiBtZXJnZWQgaW50byB0aGUgcHJpbWFyeSBidWZmZXIgKHlldCkgKi8KCQkJKnBsYXlwb3MgPSBUaGlzLT5idWZfbWl4cG9zOwoJCX0KCQllbHNlIGlmIChwbGF5cG9zKSB7CgkJCURXT1JEIHBwbGF5LCBwd3JpdGUsIGxwbGF5LCBzcGxheSwgcHN0YXRlOwoJCQkvKiBsZXQncyBnZXQgdGhpcyBleGFjdDsgZmlyc3QsIHJlY3Vyc2l2ZWx5IGNhbGwgR2V0UG9zaXRpb24gb24gdGhlIHByaW1hcnkgKi8KCQkJRW50ZXJDcml0aWNhbFNlY3Rpb24oJihwcmltYXJ5YnVmLT5sb2NrKSk7CgkJCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGxfR2V0Q3VycmVudFBvc2l0aW9uKChMUERJUkVDVFNPVU5EQlVGRkVSKXByaW1hcnlidWYsICZwcGxheSwgJnB3cml0ZSk7CgkJCS8qIGRldGVjdCBIRUwgbW9kZSB1bmRlcnJ1biAqLwoJCQlwc3RhdGUgPSBwcmltYXJ5YnVmLT5zdGF0ZTsKCQkJaWYgKCEocHJpbWFyeWJ1Zi0+aHdidWYgfHwgcHJpbWFyeWJ1Zi0+ZHNvdW5kLT5wd3F1ZXVlKSkgewoJCQkJVFJBQ0UoImRldGVjdGVkIGFuIHVuZGVycnVuXG4iKTsKCQkJCS8qIHBwbGF5ID0gPyAqLwoJCQkJaWYgKHBzdGF0ZSA9PSBTVEFURV9QTEFZSU5HKQoJCQkJCXBzdGF0ZSA9IFNUQVRFX1NUQVJUSU5HOwoJCQkJZWxzZSBpZiAocHN0YXRlID09IFNUQVRFX1NUT1BQSU5HKQoJCQkJCXBzdGF0ZSA9IFNUQVRFX1NUT1BQRUQ7CgkJCX0KCQkJLyogZ2V0IGRhdGEgZm9yIG91cnNlbHZlcyB3aGlsZSB3ZSBzdGlsbCBoYXZlIHRoZSBsb2NrICovCgkJCXBzdGF0ZSAmPSBUaGlzLT5zdGF0ZTsKCQkJbHBsYXkgPSBUaGlzLT5wcmltYXJ5X21peHBvczsKCQkJc3BsYXkgPSBUaGlzLT5idWZfbWl4cG9zOwoJCQlpZiAoKFRoaXMtPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfR0VUQ1VSUkVOVFBPU0lUSU9OMikgfHwgcHJpbWFyeWJ1Zi0+aHdidWYpIHsKCQkJCS8qIGNhbGN1bGF0ZSBwbGF5IHBvc2l0aW9uIHVzaW5nIHRoaXMgKi8KCQkJCSpwbGF5cG9zID0gRFNPVU5EX0NhbGNQbGF5UG9zaXRpb24oVGhpcywgcHN0YXRlLCBwcGxheSwgcHdyaXRlLCBscGxheSwgc3BsYXkpOwoJCQl9IGVsc2UgewoJCQkJLyogKHVubGVzcyB0aGUgYXBwIGlzbid0IHVzaW5nIEdFVENVUlJFTlRQT1NJVElPTjIpICovCgkJCQkvKiBkb24ndCBrbm93IGV4YWN0bHkgaG93IHRoaXMgc2hvdWxkIGJlIGhhbmRsZWQuLi4KCQkJCSAqIHRoZSBkb2NzIHNheXMgdGhhdCBwbGF5IGN1cnNvciBpcyByZXBvcnRlZCBhcyBkaXJlY3RseQoJCQkJICogYmVoaW5kIHdyaXRlIGN1cnNvciwgaG1tLi4uICovCgkJCQkvKiBsZXQncyBqdXN0IGRvIHdoYXQgbWlnaHQgd29yayBmb3IgSGFsZi1MaWZlICovCgkJCQlEV09SRCB3cDsKCQkJCXdwID0gKFRoaXMtPmRzb3VuZC0+cHdwbGF5ICsgRFNfSEVMX01BUkdJTikgKiBUaGlzLT5kc291bmQtPmZyYWdsZW47CgkJCQl3aGlsZSAod3AgPj0gcHJpbWFyeWJ1Zi0+YnVmbGVuKQoJCQkJCXdwIC09IHByaW1hcnlidWYtPmJ1ZmxlbjsKCQkJCSpwbGF5cG9zID0gRFNPVU5EX0NhbGNQbGF5UG9zaXRpb24oVGhpcywgcHN0YXRlLCB3cCwgcHdyaXRlLCBscGxheSwgc3BsYXkpOwoJCQl9CgkJCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCYocHJpbWFyeWJ1Zi0+bG9jaykpOwoJCX0KCQlpZiAod3JpdGVwb3MpICp3cml0ZXBvcyA9IFRoaXMtPmJ1Zl9taXhwb3M7Cgl9CglpZiAod3JpdGVwb3MpIHsKCQlpZiAoVGhpcy0+c3RhdGUgIT0gU1RBVEVfU1RPUFBFRCkKCQkJLyogYXBwbHkgdGhlIGRvY3VtZW50ZWQgMTBtcyBsZWFkIHRvIHdyaXRlcG9zICovCgkJCSp3cml0ZXBvcyArPSBUaGlzLT53cml0ZWxlYWQ7CgkJd2hpbGUgKCp3cml0ZXBvcyA+PSBUaGlzLT5idWZsZW4pICp3cml0ZXBvcyAtPSBUaGlzLT5idWZsZW47Cgl9CglUUkFDRSgicGxheXBvcyA9ICVsZCwgd3JpdGVwb3MgPSAlbGQgKCVwLCB0aW1lPSVsZClcbiIsIHBsYXlwb3M/KnBsYXlwb3M6MCwgd3JpdGVwb3M/KndyaXRlcG9zOjAsIFRoaXMsIEdldFRpY2tDb3VudCgpKTsKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZEJ1ZmZlckltcGxfR2V0U3RhdHVzKAoJTFBESVJFQ1RTT1VOREJVRkZFUiBpZmFjZSxMUERXT1JEIHN0YXR1cwopIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRCdWZmZXJJbXBsLGlmYWNlKTsKCVRSQUNFKCIoJXAsJXApLCB0aHJlYWQgaXMgJWx4XG4iLFRoaXMsc3RhdHVzLEdldEN1cnJlbnRUaHJlYWRJZCgpKTsKCglpZiAoc3RhdHVzID09IE5VTEwpCgkJcmV0dXJuIERTRVJSX0lOVkFMSURQQVJBTTsKCgkqc3RhdHVzID0gMDsKCWlmICgoVGhpcy0+c3RhdGUgPT0gU1RBVEVfU1RBUlRJTkcpIHx8IChUaGlzLT5zdGF0ZSA9PSBTVEFURV9QTEFZSU5HKSkgewoJCSpzdGF0dXMgfD0gRFNCU1RBVFVTX1BMQVlJTkc7CgkJaWYgKFRoaXMtPnBsYXlmbGFncyAmIERTQlBMQVlfTE9PUElORykKCQkJKnN0YXR1cyB8PSBEU0JTVEFUVVNfTE9PUElORzsKCX0KCglUUkFDRSgic3RhdHVzPSVseFxuIiwgKnN0YXR1cyk7CglyZXR1cm4gRFNfT0s7Cn0KCgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kQnVmZmVySW1wbF9HZXRGb3JtYXQoCglMUERJUkVDVFNPVU5EQlVGRkVSIGlmYWNlLExQV0FWRUZPUk1BVEVYIGxwd2YsRFdPUkQgd2ZzaXplLExQRFdPUkQgd2Z3cml0dGVuCikgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwsaWZhY2UpOwoJVFJBQ0UoIiglcCwlcCwlbGQsJXApXG4iLFRoaXMsbHB3Zix3ZnNpemUsd2Z3cml0dGVuKTsKCglpZiAod2ZzaXplPnNpemVvZihUaGlzLT53ZngpKQoJCXdmc2l6ZSA9IHNpemVvZihUaGlzLT53ZngpOwoJaWYgKGxwd2YpIHsJLyogTlVMTCBpcyB2YWxpZCAqLwoJCW1lbWNweShscHdmLCYoVGhpcy0+d2Z4KSx3ZnNpemUpOwoJCWlmICh3ZndyaXR0ZW4pCgkJCSp3ZndyaXR0ZW4gPSB3ZnNpemU7Cgl9IGVsc2UKCQlpZiAod2Z3cml0dGVuKQoJCQkqd2Z3cml0dGVuID0gc2l6ZW9mKFRoaXMtPndmeCk7CgkJZWxzZQoJCQlyZXR1cm4gRFNFUlJfSU5WQUxJRFBBUkFNOwoKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZEJ1ZmZlckltcGxfTG9jaygKCUxQRElSRUNUU09VTkRCVUZGRVIgaWZhY2UsRFdPUkQgd3JpdGVjdXJzb3IsRFdPUkQgd3JpdGVieXRlcyxMUFZPSUQgbHBscGF1ZGlvcHRyMSxMUERXT1JEIGF1ZGlvYnl0ZXMxLExQVk9JRCBscGxwYXVkaW9wdHIyLExQRFdPUkQgYXVkaW9ieXRlczIsRFdPUkQgZmxhZ3MKKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQnVmZmVySW1wbCxpZmFjZSk7CglEV09SRCBjYXBmOwoKCVRSQUNFKCIoJXAsJWxkLCVsZCwlcCwlcCwlcCwlcCwweCUwOGx4KSBhdCAlbGRcbiIsCgkJVGhpcywKCQl3cml0ZWN1cnNvciwKCQl3cml0ZWJ5dGVzLAoJCWxwbHBhdWRpb3B0cjEsCgkJYXVkaW9ieXRlczEsCgkJbHBscGF1ZGlvcHRyMiwKCQlhdWRpb2J5dGVzMiwKCQlmbGFncywKCQlHZXRUaWNrQ291bnQoKQoJKTsKCglpZiAoZmxhZ3MgJiBEU0JMT0NLX0ZST01XUklURUNVUlNPUikgewoJCURXT1JEIHdyaXRlcG9zOwoJCS8qIEdldEN1cnJlbnRQb3NpdGlvbiBkb2VzIHRvbyBtdWNoIG1hZ2ljIHRvIGR1cGxpY2F0ZSBoZXJlICovCgkJSURpcmVjdFNvdW5kQnVmZmVySW1wbF9HZXRDdXJyZW50UG9zaXRpb24oaWZhY2UsIE5VTEwsICZ3cml0ZXBvcyk7CgkJd3JpdGVjdXJzb3IgKz0gd3JpdGVwb3M7Cgl9CglpZiAoZmxhZ3MgJiBEU0JMT0NLX0VOVElSRUJVRkZFUikKCQl3cml0ZWJ5dGVzID0gVGhpcy0+YnVmbGVuOwoJaWYgKHdyaXRlYnl0ZXMgPiBUaGlzLT5idWZsZW4pCgkJd3JpdGVieXRlcyA9IFRoaXMtPmJ1ZmxlbjsKCglhc3NlcnQoYXVkaW9ieXRlczEhPWF1ZGlvYnl0ZXMyKTsKCWFzc2VydChscGxwYXVkaW9wdHIxIT1scGxwYXVkaW9wdHIyKTsKCglpZiAoKHdyaXRlYnl0ZXMgPT0gVGhpcy0+YnVmbGVuKSAmJgoJICAgICgoVGhpcy0+c3RhdGUgPT0gU1RBVEVfU1RBUlRJTkcpIHx8CgkgICAgIChUaGlzLT5zdGF0ZSA9PSBTVEFURV9QTEFZSU5HKSkpCgkJLyogc29tZSBnYW1lcywgbGlrZSBIYWxmLUxpZmUsIHRyeSB0byBiZSBjbGV2ZXIgKG5vdCkgYW5kCgkJICoga2VlcCBvbmUgc2Vjb25kYXJ5IGJ1ZmZlciwgYW5kIG1peCBzb3VuZHMgaW50byBpdCBpdHNlbGYsCgkJICogbG9ja2luZyB0aGUgZW50aXJlIGJ1ZmZlciBldmVyeSB0aW1lLi4uIHNvIHdlIGNhbiBqdXN0IGZvcmdldAoJCSAqIGFib3V0IHRyYWNraW5nIHRoZSBsYXN0LXdyaXR0ZW4tdG8tcG9zaXRpb24uLi4gKi8KCQlUaGlzLT5wcm9iYWJseV92YWxpZF90byA9IChEV09SRCktMTsKCWVsc2UKCQlUaGlzLT5wcm9iYWJseV92YWxpZF90byA9IHdyaXRlY3Vyc29yOwoKCWlmIChUaGlzLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX1BSSU1BUllCVUZGRVIpCgkJY2FwZiA9IERTRERFU0NfRE9OVE5FRURQUklNQVJZTE9DSzsKCWVsc2UKCQljYXBmID0gRFNEREVTQ19ET05UTkVFRFNFQ09OREFSWUxPQ0s7CglpZiAoIShUaGlzLT5kc291bmQtPmRydmRlc2MuZHdGbGFncyAmIGNhcGYpICYmIFRoaXMtPmh3YnVmKSB7CgkJSURzRHJpdmVyQnVmZmVyX0xvY2soVGhpcy0+aHdidWYsCgkJCQkgICAgIGxwbHBhdWRpb3B0cjEsIGF1ZGlvYnl0ZXMxLAoJCQkJICAgICBscGxwYXVkaW9wdHIyLCBhdWRpb2J5dGVzMiwKCQkJCSAgICAgd3JpdGVjdXJzb3IsIHdyaXRlYnl0ZXMsCgkJCQkgICAgIDApOwoJfQoJZWxzZSB7CgkJQk9PTCByZW1peCA9IEZBTFNFOwoJCWlmICh3cml0ZWN1cnNvcit3cml0ZWJ5dGVzIDw9IFRoaXMtPmJ1ZmxlbikgewoJCQkqKExQQllURSopbHBscGF1ZGlvcHRyMSA9IFRoaXMtPmJ1ZmZlcit3cml0ZWN1cnNvcjsKCQkJKmF1ZGlvYnl0ZXMxID0gd3JpdGVieXRlczsKCQkJaWYgKGxwbHBhdWRpb3B0cjIpCgkJCQkqKExQQllURSopbHBscGF1ZGlvcHRyMiA9IE5VTEw7CgkJCWlmIChhdWRpb2J5dGVzMikKCQkJCSphdWRpb2J5dGVzMiA9IDA7CgkJCVRSQUNFKCItPiVsZC4wXG4iLHdyaXRlYnl0ZXMpOwoJCX0gZWxzZSB7CgkJCSooTFBCWVRFKilscGxwYXVkaW9wdHIxID0gVGhpcy0+YnVmZmVyK3dyaXRlY3Vyc29yOwoJCQkqYXVkaW9ieXRlczEgPSBUaGlzLT5idWZsZW4td3JpdGVjdXJzb3I7CgkJCWlmIChscGxwYXVkaW9wdHIyKQoJCQkJKihMUEJZVEUqKWxwbHBhdWRpb3B0cjIgPSBUaGlzLT5idWZmZXI7CgkJCWlmIChhdWRpb2J5dGVzMikKCQkJCSphdWRpb2J5dGVzMiA9IHdyaXRlYnl0ZXMtKFRoaXMtPmJ1Zmxlbi13cml0ZWN1cnNvcik7CgkJCVRSQUNFKCItPiVsZC4lbGRcbiIsKmF1ZGlvYnl0ZXMxLGF1ZGlvYnl0ZXMyPyphdWRpb2J5dGVzMjowKTsKCQl9CgkJLyogaWYgdGhlIHNlZ21lbnQgYmV0d2VlbiBwbGF5cG9zIGFuZCBidWZfbWl4cG9zIGlzIHRvdWNoZWQsCgkJICogd2UgbmVlZCB0byBjYW5jZWwgc29tZSBtaXhpbmcgKi8KCQlpZiAoVGhpcy0+YnVmX21peHBvcyA+PSBUaGlzLT5wbGF5cG9zKSB7CgkJCWlmIChUaGlzLT5idWZfbWl4cG9zID4gd3JpdGVjdXJzb3IgJiYKCQkJICAgIFRoaXMtPnBsYXlwb3MgPD0gd3JpdGVjdXJzb3Ird3JpdGVieXRlcykKCQkJCXJlbWl4ID0gVFJVRTsKCQl9CgkJZWxzZSB7CgkJCWlmIChUaGlzLT5idWZfbWl4cG9zID4gd3JpdGVjdXJzb3IgfHwKCQkJICAgIFRoaXMtPnBsYXlwb3MgPD0gd3JpdGVjdXJzb3Ird3JpdGVieXRlcykKCQkJCXJlbWl4ID0gVFJVRTsKCQl9CgkJaWYgKHJlbWl4KSB7CgkJCVRSQUNFKCJsb2NraW5nIHByZWJ1ZmZlcmVkIHJlZ2lvbiwgb3VjaFxuIik7CgkJCURTT1VORF9NaXhDYW5jZWxBdChUaGlzLCB3cml0ZWN1cnNvcik7CgkJfQoJfQoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kQnVmZmVySW1wbF9TZXRDdXJyZW50UG9zaXRpb24oCglMUERJUkVDVFNPVU5EQlVGRkVSIGlmYWNlLERXT1JEIG5ld3BvcwopIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRCdWZmZXJJbXBsLGlmYWNlKTsKCVRSQUNFKCIoJXAsJWxkKVxuIixUaGlzLG5ld3Bvcyk7CgoJLyogKioqKiAqLwoJRW50ZXJDcml0aWNhbFNlY3Rpb24oJihUaGlzLT5sb2NrKSk7CgoJVGhpcy0+YnVmX21peHBvcyA9IG5ld3BvczsKCWlmIChUaGlzLT5od2J1ZikKCQlJRHNEcml2ZXJCdWZmZXJfU2V0UG9zaXRpb24oVGhpcy0+aHdidWYsIFRoaXMtPmJ1Zl9taXhwb3MpOwoKCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCYoVGhpcy0+bG9jaykpOwoJLyogKioqKiAqLwoKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZEJ1ZmZlckltcGxfU2V0UGFuKAoJTFBESVJFQ1RTT1VOREJVRkZFUiBpZmFjZSxMT05HIHBhbgopIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRCdWZmZXJJbXBsLGlmYWNlKTsKCglUUkFDRSgiKCVwLCVsZClcbiIsVGhpcyxwYW4pOwoKCWlmICgocGFuID4gRFNCUEFOX1JJR0hUKSB8fCAocGFuIDwgRFNCUEFOX0xFRlQpKQoJCXJldHVybiBEU0VSUl9JTlZBTElEUEFSQU07CgoJLyogWW91IGNhbm5vdCBzZXQgdGhlIHBhbiBvZiB0aGUgcHJpbWFyeSBidWZmZXIgKi8KCS8qIGFuZCB5b3UgY2Fubm90IHVzZSBib3RoIHBhbiBhbmQgM0QgY29udHJvbHMgKi8KCWlmICghKFRoaXMtPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfQ1RSTFBBTikgfHwKCSAgICAoVGhpcy0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19DVFJMM0QpIHx8CgkgICAgKFRoaXMtPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfUFJJTUFSWUJVRkZFUikpCgkJcmV0dXJuIERTRVJSX0NPTlRST0xVTkFWQUlMOwoKCS8qICoqKiogKi8KCUVudGVyQ3JpdGljYWxTZWN0aW9uKCYoVGhpcy0+bG9jaykpOwoKCVRoaXMtPnZvbHBhbi5sUGFuID0gcGFuOwoKCURTT1VORF9SZWNhbGNWb2xQYW4oJihUaGlzLT52b2xwYW4pKTsKCglpZiAoVGhpcy0+aHdidWYpIHsKCQlJRHNEcml2ZXJCdWZmZXJfU2V0Vm9sdW1lUGFuKFRoaXMtPmh3YnVmLCAmKFRoaXMtPnZvbHBhbikpOwoJfQoKCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCYoVGhpcy0+bG9jaykpOwoJLyogKioqKiAqLwoKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZEJ1ZmZlckltcGxfR2V0UGFuKAoJTFBESVJFQ1RTT1VOREJVRkZFUiBpZmFjZSxMUExPTkcgcGFuCikgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwsaWZhY2UpOwoJVFJBQ0UoIiglcCwlcClcbiIsVGhpcyxwYW4pOwoKCWlmIChwYW4gPT0gTlVMTCkKCQlyZXR1cm4gRFNFUlJfSU5WQUxJRFBBUkFNOwoKCSpwYW4gPSBUaGlzLT52b2xwYW4ubFBhbjsKCglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmRCdWZmZXJJbXBsX1VubG9jaygKCUxQRElSRUNUU09VTkRCVUZGRVIgaWZhY2UsTFBWT0lEIHAxLERXT1JEIHgxLExQVk9JRCBwMixEV09SRCB4MgopIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRCdWZmZXJJbXBsLGlmYWNlKTsKCURXT1JEIGNhcGYsIHByb2JhYmx5X3ZhbGlkX3RvOwoKCVRSQUNFKCIoJXAsJXAsJWxkLCVwLCVsZCk6c3R1YlxuIiwgVGhpcyxwMSx4MSxwMix4Mik7CgojaWYgMAoJLyogUHJlcHJvY2VzcyAzRCBidWZmZXJzLi4uICovCgoJLyogVGhpcyBpcyBoaWdobHkgZXhwZXJpbWVudGFsIGFuZCBsaWFibGUgdG8gYnJlYWsgdGhpbmdzICovCglpZiAoVGhpcy0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19DVFJMM0QpCgkJRFNPVU5EX0NyZWF0ZTNEQnVmZmVyKFRoaXMpOwojZW5kaWYKCglpZiAoVGhpcy0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19QUklNQVJZQlVGRkVSKQoJCWNhcGYgPSBEU0RERVNDX0RPTlRORUVEUFJJTUFSWUxPQ0s7CgllbHNlCgkJY2FwZiA9IERTRERFU0NfRE9OVE5FRURTRUNPTkRBUllMT0NLOwoJaWYgKCEoVGhpcy0+ZHNvdW5kLT5kcnZkZXNjLmR3RmxhZ3MgJiBjYXBmKSAmJiBUaGlzLT5od2J1ZikgewoJCUlEc0RyaXZlckJ1ZmZlcl9VbmxvY2soVGhpcy0+aHdidWYsIHAxLCB4MSwgcDIsIHgyKTsKCX0KCglpZiAocDIpIHByb2JhYmx5X3ZhbGlkX3RvID0gKCgoTFBCWVRFKXAyKS1UaGlzLT5idWZmZXIpICsgeDI7CgllbHNlIHByb2JhYmx5X3ZhbGlkX3RvID0gKCgoTFBCWVRFKXAxKS1UaGlzLT5idWZmZXIpICsgeDE7Cgl3aGlsZSAocHJvYmFibHlfdmFsaWRfdG8gPj0gVGhpcy0+YnVmbGVuKQoJCXByb2JhYmx5X3ZhbGlkX3RvIC09IFRoaXMtPmJ1ZmxlbjsKCWlmICgocHJvYmFibHlfdmFsaWRfdG8gPT0gMCkgJiYgKCh4MSt4MikgPT0gVGhpcy0+YnVmbGVuKSAmJgoJICAgICgoVGhpcy0+c3RhdGUgPT0gU1RBVEVfU1RBUlRJTkcpIHx8CgkgICAgIChUaGlzLT5zdGF0ZSA9PSBTVEFURV9QTEFZSU5HKSkpCgkJLyogc2VlIElEaXJlY3RTb3VuZEJ1ZmZlckltcGxfTG9jayAqLwoJCXByb2JhYmx5X3ZhbGlkX3RvID0gKERXT1JEKS0xOwoJVGhpcy0+cHJvYmFibHlfdmFsaWRfdG8gPSBwcm9iYWJseV92YWxpZF90bzsKCglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmRCdWZmZXJJbXBsX1Jlc3RvcmUoCglMUERJUkVDVFNPVU5EQlVGRkVSIGlmYWNlCikgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwsaWZhY2UpOwoJRklYTUUoIiglcCk6c3R1YlxuIixUaGlzKTsKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZEJ1ZmZlckltcGxfR2V0RnJlcXVlbmN5KAoJTFBESVJFQ1RTT1VOREJVRkZFUiBpZmFjZSxMUERXT1JEIGZyZXEKKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQnVmZmVySW1wbCxpZmFjZSk7CglUUkFDRSgiKCVwLCVwKVxuIixUaGlzLGZyZXEpOwoKCWlmIChmcmVxID09IE5VTEwpCgkJcmV0dXJuIERTRVJSX0lOVkFMSURQQVJBTTsKCgkqZnJlcSA9IFRoaXMtPmZyZXE7CglUUkFDRSgiLT4gJWxkXG4iLCAqZnJlcSk7CgoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kQnVmZmVySW1wbF9Jbml0aWFsaXplKAoJTFBESVJFQ1RTT1VOREJVRkZFUiBpZmFjZSxMUERJUkVDVFNPVU5EIGRzb3VuZCxMUERTQlVGRkVSREVTQyBkYnNkCikgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwsaWZhY2UpOwoJRklYTUUoIiglcCwlcCwlcCk6c3R1YlxuIixUaGlzLGRzb3VuZCxkYnNkKTsKCURQUklOVEYoIlJlLUluaXQhISFcbiIpOwoJcmV0dXJuIERTRVJSX0FMUkVBRFlJTklUSUFMSVpFRDsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZEJ1ZmZlckltcGxfR2V0Q2FwcygKCUxQRElSRUNUU09VTkRCVUZGRVIgaWZhY2UsTFBEU0JDQVBTIGNhcHMKKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQnVmZmVySW1wbCxpZmFjZSk7CiAgCVRSQUNFKCIoJXApLT4oJXApXG4iLFRoaXMsY2Fwcyk7CiAgCglpZiAoY2FwcyA9PSBOVUxMKQoJCXJldHVybiBEU0VSUl9JTlZBTElEUEFSQU07CgoJLyogSSB0aGluayB3ZSBzaG91bGQgY2hlY2sgdGhpcyB2YWx1ZSwgbm90IHNldCBpdC4gU2VlICovCgkvKiBJbnNpZGUgRGlyZWN0WCwgcDIxNS4gVGhhdCBzaG91bGQgYXBwbHkgaGVyZSwgdG9vLiAqLwoJY2Fwcy0+ZHdTaXplID0gc2l6ZW9mKCpjYXBzKTsKCgljYXBzLT5kd0ZsYWdzID0gVGhpcy0+ZHNiZC5kd0ZsYWdzOwoJaWYgKFRoaXMtPmh3YnVmKSBjYXBzLT5kd0ZsYWdzIHw9IERTQkNBUFNfTE9DSEFSRFdBUkU7CgllbHNlIGNhcHMtPmR3RmxhZ3MgfD0gRFNCQ0FQU19MT0NTT0ZUV0FSRTsKCgljYXBzLT5kd0J1ZmZlckJ5dGVzID0gVGhpcy0+YnVmbGVuOwoKCS8qIFRoaXMgdmFsdWUgcmVwcmVzZW50cyB0aGUgc3BlZWQgb2YgdGhlICJ1bmxvY2siIGNvbW1hbmQuCgkgICBBcyB1bmxvY2sgaXMgcXVpdGUgZmFzdCAoaXQgZG9lcyBub3QgZG8gYW55dGhpbmcpLCBJIHB1dAoJICAgNDA5NiBrby9zID0gNCBNbyAvIHMgKi8KCS8qIEZJWE1FOiBod2J1ZiBzcGVlZCAqLwoJY2Fwcy0+ZHdVbmxvY2tUcmFuc2ZlclJhdGUgPSA0MDk2OwoJY2Fwcy0+ZHdQbGF5Q3B1T3ZlcmhlYWQgPSAwOwoKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZEJ1ZmZlckltcGxfUXVlcnlJbnRlcmZhY2UoCglMUERJUkVDVFNPVU5EQlVGRkVSIGlmYWNlLFJFRklJRCByaWlkLExQVk9JRCAqcHBvYmoKKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQnVmZmVySW1wbCxpZmFjZSk7CgoJVFJBQ0UoIiglcCwlcywlcClcbiIsVGhpcyxkZWJ1Z3N0cl9ndWlkKHJpaWQpLHBwb2JqKTsKCglpZiAoIElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3RTb3VuZE5vdGlmeSwgcmlpZCApICkgewoJCUlEaXJlY3RTb3VuZE5vdGlmeUltcGwJKmRzbjsKCgkJZHNuID0gKElEaXJlY3RTb3VuZE5vdGlmeUltcGwqKUhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLDAsc2l6ZW9mKCpkc24pKTsKCQlkc24tPnJlZiA9IDE7CgkJZHNuLT5kc2IgPSBUaGlzOwoJCUlEaXJlY3RTb3VuZEJ1ZmZlcl9BZGRSZWYoaWZhY2UpOwoJCUlDT01fVlRCTChkc24pID0gJmRzbnZ0OwoJCSpwcG9iaiA9IChMUFZPSUQpZHNuOwoJCXJldHVybiBTX09LOwoJfQoKI2lmZGVmIFVTRV9EU09VTkQzRAoJaWYgKCBJc0VxdWFsR1VJRCggJklJRF9JRGlyZWN0U291bmQzREJ1ZmZlciwgcmlpZCApICkgewogICAgICAgICAgICAgICAgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsICAgICAgICAqZHMzZGI7CgoJCSpwcG9iaiA9IFRoaXMtPmRzM2RiOwoJCWlmICgqcHBvYmopIHsKCQkJSURpcmVjdFNvdW5kM0RCdWZmZXJfQWRkUmVmKChMUERJUkVDVFNPVU5EM0RCVUZGRVIpVGhpcy0+ZHMzZGIpOwoJCQlyZXR1cm4gU19PSzsKCQl9CgogICAgICAgICAgICAgICAgZHMzZGIgPSAoSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsKilIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwKICAgICAgICAgICAgICAgICAgICAgICAgMCxzaXplb2YoKmRzM2RiKSk7CiAgICAgICAgICAgICAgICBkczNkYi0+cmVmID0gMTsKICAgICAgICAgICAgICAgIGRzM2RiLT5kc2IgPSBUaGlzOwogICAgICAgICAgICAgICAgSUNPTV9WVEJMKGRzM2RiKSA9ICZkczNkYnZ0OwoJCUluaXRpYWxpemVDcml0aWNhbFNlY3Rpb24oJmRzM2RiLT5sb2NrKTsKCgkJSURpcmVjdFNvdW5kQnVmZmVyX0FkZFJlZihpZmFjZSk7CgogICAgICAgICAgICAgICAgZHMzZGItPmRzM2RiLmR3U2l6ZSA9IHNpemVvZihEUzNEQlVGRkVSKTsKICAgICAgICAgICAgICAgIGRzM2RiLT5kczNkYi52UG9zaXRpb24udTEueCA9IDAuMDsKICAgICAgICAgICAgICAgIGRzM2RiLT5kczNkYi52UG9zaXRpb24udTIueSA9IDAuMDsKICAgICAgICAgICAgICAgIGRzM2RiLT5kczNkYi52UG9zaXRpb24udTMueiA9IDAuMDsKICAgICAgICAgICAgICAgIGRzM2RiLT5kczNkYi52VmVsb2NpdHkudTEueCA9IDAuMDsKICAgICAgICAgICAgICAgIGRzM2RiLT5kczNkYi52VmVsb2NpdHkudTIueSA9IDAuMDsKICAgICAgICAgICAgICAgIGRzM2RiLT5kczNkYi52VmVsb2NpdHkudTMueiA9IDAuMDsKICAgICAgICAgICAgICAgIGRzM2RiLT5kczNkYi5kd0luc2lkZUNvbmVBbmdsZSA9IERTM0RfREVGQVVMVENPTkVBTkdMRTsKICAgICAgICAgICAgICAgIGRzM2RiLT5kczNkYi5kd091dHNpZGVDb25lQW5nbGUgPSBEUzNEX0RFRkFVTFRDT05FQU5HTEU7CiAgICAgICAgICAgICAgICBkczNkYi0+ZHMzZGIudkNvbmVPcmllbnRhdGlvbi51MS54ID0gMC4wOwogICAgICAgICAgICAgICAgZHMzZGItPmRzM2RiLnZDb25lT3JpZW50YXRpb24udTIueSA9IDAuMDsKICAgICAgICAgICAgICAgIGRzM2RiLT5kczNkYi52Q29uZU9yaWVudGF0aW9uLnUzLnogPSAwLjA7CiAgICAgICAgICAgICAgICBkczNkYi0+ZHMzZGIubENvbmVPdXRzaWRlVm9sdW1lID0gRFMzRF9ERUZBVUxUQ09ORU9VVFNJREVWT0xVTUU7ICAgICAgICAgICAgICAgIGRzM2RiLT5kczNkYi5mbE1pbkRpc3RhbmNlID0gRFMzRF9ERUZBVUxUTUlORElTVEFOQ0U7CiAgICAgICAgICAgICAgICBkczNkYi0+ZHMzZGIuZmxNYXhEaXN0YW5jZSA9IERTM0RfREVGQVVMVE1BWERJU1RBTkNFOwogICAgICAgICAgICAgICAgZHMzZGItPmRzM2RiLmR3TW9kZSA9IERTM0RNT0RFX05PUk1BTDsKICAgICAgICAgICAgICAgIGRzM2RiLT5idWZsZW4gPSAoVGhpcy0+YnVmbGVuICogcHJpbWFyeWJ1Zi0+d2Z4Lm5CbG9ja0FsaWduKSAvCiAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPndmeC5uQmxvY2tBbGlnbjsKICAgICAgICAgICAgICAgIGRzM2RiLT5idWZmZXIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZHMzZGItPmJ1Zmxlbik7CiAgICAgICAgICAgICAgICBpZiAoZHMzZGItPmJ1ZmZlciA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGRzM2RiLT5idWZsZW4gPSAwOwogICAgICAgICAgICAgICAgICAgICAgICBkczNkYi0+ZHMzZGIuZHdNb2RlID0gRFMzRE1PREVfRElTQUJMRTsKICAgICAgICAgICAgICAgIH0KCgkJZHMzZGItPmlrcyA9IChJS3NQcm9wZXJ0eVNldEltcGwqKUhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLDAsc2l6ZW9mKCooZHMzZGItPmlrcykpKTsKCQlkczNkYi0+aWtzLT5yZWYgPSAxOwoJCWRzM2RiLT5pa3MtPmRzM2RiID0gZHMzZGI7CgkJSUNPTV9WVEJMKGRzM2RiLT5pa3MpID0gJmlrc3Z0OwoKCQlyZXR1cm4gU19PSzsKCX0KI2Vsc2UKCWlmICggSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdFNvdW5kM0RCdWZmZXIsIHJpaWQgKSApIHsKCQlGSVhNRSgiJXM6IEkga25vdyBhYm91dCB0aGlzIEdVSUQsIGJ1dCBkb24ndCBzdXBwb3J0IGl0IHlldFxuIiwKCQkgICAgICBkZWJ1Z3N0cl9ndWlkKCByaWlkICkpOwoJCSpwcG9iaiA9IE5VTEw7CgkJcmV0dXJuIEVfRkFJTDsKCX0KI2VuZGlmCgojaWYgVVNFX0RTT1VORDNECiAgICAgICAgaWYgKCBJc0VxdWFsR1VJRCggJklJRF9JRGlyZWN0U291bmQzRExpc3RlbmVyLCByaWlkICkgKSB7CgkJSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGwqIGRzbDsKCgkJaWYgKFRoaXMtPmRzb3VuZC0+bGlzdGVuZXIpIHsKCQkJKnBwb2JqID0gVGhpcy0+ZHNvdW5kLT5saXN0ZW5lcjsKICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdFNvdW5kM0RMaXN0ZW5lcl9BZGRSZWYoKExQRElSRUNUU09VTkQzRExJU1RFTkVSKVRoaXMtPmRzb3VuZC0+bGlzdGVuZXIpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRFNfT0s7CgkJfQoKCQlkc2wgPSAoSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGwqKUhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLDAsc2l6ZW9mKCpkc2wpKTsKCQlkc2wtPnJlZiA9IDE7CgkJSUNPTV9WVEJMKGRzbCkgPSAmZHMzZGx2dDsKCQkqcHBvYmogPSAoTFBWT0lEKWRzbDsKCiAgICAgICAgICAgICAgICBkc2wtPmRzM2RsLmR3U2l6ZSA9IHNpemVvZihEUzNETElTVEVORVIpOwogICAgICAgICAgICAgICAgZHNsLT5kczNkbC52UG9zaXRpb24udTEueCA9IDAuMDsKICAgICAgICAgICAgICAgIGRzbC0+ZHMzZGwudlBvc2l0aW9uLnUyLnkgPSAwLjA7CiAgICAgICAgICAgICAgICBkc2wtPmRzM2RsLnZQb3NpdGlvbi51My56ID0gMC4wOwogICAgICAgICAgICAgICAgZHNsLT5kczNkbC52VmVsb2NpdHkudTEueCA9IDAuMDsKICAgICAgICAgICAgICAgIGRzbC0+ZHMzZGwudlZlbG9jaXR5LnUyLnkgPSAwLjA7CiAgICAgICAgICAgICAgICBkc2wtPmRzM2RsLnZWZWxvY2l0eS51My56ID0gMC4wOwogICAgICAgICAgICAgICAgZHNsLT5kczNkbC52T3JpZW50RnJvbnQudTEueCA9IDAuMDsKICAgICAgICAgICAgICAgIGRzbC0+ZHMzZGwudk9yaWVudEZyb250LnUyLnkgPSAwLjA7CiAgICAgICAgICAgICAgICBkc2wtPmRzM2RsLnZPcmllbnRGcm9udC51My56ID0gMS4wOwogICAgICAgICAgICAgICAgZHNsLT5kczNkbC52T3JpZW50VG9wLnUxLnggPSAwLjA7CiAgICAgICAgICAgICAgICBkc2wtPmRzM2RsLnZPcmllbnRUb3AudTIueSA9IDEuMDsKICAgICAgICAgICAgICAgIGRzbC0+ZHMzZGwudk9yaWVudFRvcC51My56ID0gMC4wOwogICAgICAgICAgICAgICAgZHNsLT5kczNkbC5mbERpc3RhbmNlRmFjdG9yID0gRFMzRF9ERUZBVUxURElTVEFOQ0VGQUNUT1I7CiAgICAgICAgICAgICAgICBkc2wtPmRzM2RsLmZsUm9sbG9mZkZhY3RvciA9IERTM0RfREVGQVVMVFJPTExPRkZGQUNUT1I7CgoJCUluaXRpYWxpemVDcml0aWNhbFNlY3Rpb24oJmRzbC0+bG9jayk7CgoJCWRzbC0+ZHNiID0gVGhpczsKCQlJRGlyZWN0U291bmRCdWZmZXJfQWRkUmVmKGlmYWNlKTsKCgkJVGhpcy0+ZHNvdW5kLT5saXN0ZW5lciA9IGRzbDsKCQlJRGlyZWN0U291bmQzRExpc3RlbmVyX0FkZFJlZigoTFBESVJFQ1RTT1VORDNETElTVEVORVIpZHNsKTsKCgkJcmV0dXJuIFNfT0s7Cgl9CiNlbHNlCglpZiAoIElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3RTb3VuZDNETGlzdGVuZXIsIHJpaWQgKSApIHsKCQlGSVhNRSgiJXM6IEkga25vdyBhYm91dCB0aGlzIEdVSUQsIGJ1dCBkb24ndCBzdXBwb3J0IGl0IHlldFxuIiwKCQkgICAgICBkZWJ1Z3N0cl9ndWlkKCByaWlkICkpOwoJCSpwcG9iaiA9IE5VTEw7CgkJcmV0dXJuIEVfRkFJTDsKCX0KI2VuZGlmCgoJRklYTUUoICJVbmtub3duIEdVSUQgJXNcbiIsIGRlYnVnc3RyX2d1aWQoIHJpaWQgKSApOwoKCSpwcG9iaiA9IE5VTEw7CgoJcmV0dXJuIEVfRkFJTDsKfQoKc3RhdGljIElDT01fVlRBQkxFKElEaXJlY3RTb3VuZEJ1ZmZlcikgZHNidnQgPSAKewoJSUNPTV9NU1ZUQUJMRV9DT01QQVRfRHVtbXlSVFRJVkFMVUUKCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGxfUXVlcnlJbnRlcmZhY2UsCglJRGlyZWN0U291bmRCdWZmZXJJbXBsX0FkZFJlZiwKCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGxfUmVsZWFzZSwKCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGxfR2V0Q2FwcywKCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGxfR2V0Q3VycmVudFBvc2l0aW9uLAoJSURpcmVjdFNvdW5kQnVmZmVySW1wbF9HZXRGb3JtYXQsCglJRGlyZWN0U291bmRCdWZmZXJJbXBsX0dldFZvbHVtZSwKCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGxfR2V0UGFuLAogICAgICAgIElEaXJlY3RTb3VuZEJ1ZmZlckltcGxfR2V0RnJlcXVlbmN5LAoJSURpcmVjdFNvdW5kQnVmZmVySW1wbF9HZXRTdGF0dXMsCglJRGlyZWN0U291bmRCdWZmZXJJbXBsX0luaXRpYWxpemUsCglJRGlyZWN0U291bmRCdWZmZXJJbXBsX0xvY2ssCglJRGlyZWN0U291bmRCdWZmZXJJbXBsX1BsYXksCglJRGlyZWN0U291bmRCdWZmZXJJbXBsX1NldEN1cnJlbnRQb3NpdGlvbiwKCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGxfU2V0Rm9ybWF0LAoJSURpcmVjdFNvdW5kQnVmZmVySW1wbF9TZXRWb2x1bWUsCglJRGlyZWN0U291bmRCdWZmZXJJbXBsX1NldFBhbiwKCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGxfU2V0RnJlcXVlbmN5LAoJSURpcmVjdFNvdW5kQnVmZmVySW1wbF9TdG9wLAoJSURpcmVjdFNvdW5kQnVmZmVySW1wbF9VbmxvY2ssCglJRGlyZWN0U291bmRCdWZmZXJJbXBsX1Jlc3RvcmUKfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlJRGlyZWN0U291bmQKICovCgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kSW1wbF9TZXRDb29wZXJhdGl2ZUxldmVsKAoJTFBESVJFQ1RTT1VORCBpZmFjZSxIV05EIGh3bmQsRFdPUkQgbGV2ZWwKKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kSW1wbCxpZmFjZSk7CgoJRklYTUUoIiglcCwlMDhseCwlbGQpOnN0dWJcbiIsVGhpcywoRFdPUkQpaHduZCxsZXZlbCk7CgoJVGhpcy0+cHJpb2xldmVsID0gbGV2ZWw7CgoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kSW1wbF9DcmVhdGVTb3VuZEJ1ZmZlcigKCUxQRElSRUNUU09VTkQgaWZhY2UsTFBEU0JVRkZFUkRFU0MgZHNiZCxMUExQRElSRUNUU09VTkRCVUZGRVIgcHBkc2IsTFBVTktOT1dOIGxwdW5rCikgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEltcGwsaWZhY2UpOwoJSURpcmVjdFNvdW5kQnVmZmVySW1wbCoqIGlwcGRzYj0oSURpcmVjdFNvdW5kQnVmZmVySW1wbCoqKXBwZHNiOwoJTFBXQVZFRk9STUFURVgJd2ZleDsKCUhSRVNVTFQgZXJyID0gRFNfT0s7CgoJVFJBQ0UoIiglcCwlcCwlcCwlcClcbiIsVGhpcyxkc2JkLGlwcGRzYixscHVuayk7CgkKCWlmICgoVGhpcyA9PSBOVUxMKSB8fCAoZHNiZCA9PSBOVUxMKSB8fCAoaXBwZHNiID09IE5VTEwpKQoJCXJldHVybiBEU0VSUl9JTlZBTElEUEFSQU07CgkKCWlmIChUUkFDRV9PTihkc291bmQpKSB7CgkJVFJBQ0UoIihzdHJ1Y3RzaXplPSVsZClcbiIsZHNiZC0+ZHdTaXplKTsKCQlUUkFDRSgiKGZsYWdzPTB4JTA4bHg6XG4iLGRzYmQtPmR3RmxhZ3MpOwoJCV9kdW1wX0RTQkNBUFMoZHNiZC0+ZHdGbGFncyk7CgkJRFBSSU5URigiKVxuIik7CgkJVFJBQ0UoIihidWZmZXJieXRlcz0lbGQpXG4iLGRzYmQtPmR3QnVmZmVyQnl0ZXMpOwoJCVRSQUNFKCIobHB3ZnhGb3JtYXQ9JXApXG4iLGRzYmQtPmxwd2Z4Rm9ybWF0KTsKCX0KCgl3ZmV4ID0gZHNiZC0+bHB3ZnhGb3JtYXQ7CgoJaWYgKHdmZXgpCgkJVFJBQ0UoIihmb3JtYXR0YWc9MHglMDR4LGNoYW5zPSVkLHNhbXBsZXJhdGU9JWxkLCIKCQkgICAiYnl0ZXNwZXJzZWM9JWxkLGJsb2NrYWxpZ249JWQsYml0c3BlcnNhbXA9JWQsY2JTaXplPSVkKVxuIiwKCQkgICB3ZmV4LT53Rm9ybWF0VGFnLCB3ZmV4LT5uQ2hhbm5lbHMsIHdmZXgtPm5TYW1wbGVzUGVyU2VjLAoJCSAgIHdmZXgtPm5BdmdCeXRlc1BlclNlYywgd2ZleC0+bkJsb2NrQWxpZ24sIAoJCSAgIHdmZXgtPndCaXRzUGVyU2FtcGxlLCB3ZmV4LT5jYlNpemUpOwoKCWlmIChkc2JkLT5kd0ZsYWdzICYgRFNCQ0FQU19QUklNQVJZQlVGRkVSKSB7CgkJaWYgKHByaW1hcnlidWYpIHsKCQkJSURpcmVjdFNvdW5kQnVmZmVyX0FkZFJlZigoTFBESVJFQ1RTT1VOREJVRkZFUilwcmltYXJ5YnVmKTsKCQkJKmlwcGRzYiA9IHByaW1hcnlidWY7CgkJCXByaW1hcnlidWYtPmRzYmQuZHdGbGFncyA9IGRzYmQtPmR3RmxhZ3M7CgkJCXJldHVybiBEU19PSzsKCQl9IC8qIEVsc2UgY3JlYXRlIHByaW1hcnkgYnVmZmVyICovCgl9IGVsc2UgewoJCWlmIChkc2JkLT5kd0J1ZmZlckJ5dGVzIDwgRFNCU0laRV9NSU4gfHwgZHNiZC0+ZHdCdWZmZXJCeXRlcyA+IERTQlNJWkVfTUFYKSB7CgkJCUVSUigiaW52YWxpZCBzb3VuZCBidWZmZXIgc2l6ZSAlbGRcbiIsIGRzYmQtPmR3QnVmZmVyQnl0ZXMpOwoJCQlyZXR1cm4gRFNFUlJfSU5WQUxJRFBBUkFNOyAvKiBGSVhNRTogd2hpY2ggZXJyb3I/ICovCgkJfQoJfQoKCSppcHBkc2IgPSAoSURpcmVjdFNvdW5kQnVmZmVySW1wbCopSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksSEVBUF9aRVJPX01FTU9SWSxzaXplb2YoSURpcmVjdFNvdW5kQnVmZmVySW1wbCkpOwoJaWYgKCppcHBkc2IgPT0gTlVMTCkKCQlyZXR1cm4gRFNFUlJfT1VUT0ZNRU1PUlk7CglJQ09NX1ZUQkwoKmlwcGRzYikgPSAmZHNidnQ7CgkoKmlwcGRzYiktPnJlZiA9IDE7CgkoKmlwcGRzYiktPmRzb3VuZCA9IFRoaXM7CgkoKmlwcGRzYiktPnBhcmVudCA9IE5VTEw7CgkoKmlwcGRzYiktPmJ1ZmZlciA9IE5VTEw7CgoJbWVtY3B5KCYoKCppcHBkc2IpLT5kc2JkKSxkc2JkLHNpemVvZigqZHNiZCkpOwoJaWYgKGRzYmQtPmxwd2Z4Rm9ybWF0KQoJCW1lbWNweSgmKCgqaXBwZHNiKS0+d2Z4KSwgZHNiZC0+bHB3ZnhGb3JtYXQsIHNpemVvZigoKmlwcGRzYiktPndmeCkpOwoKCVRSQUNFKCJDcmVhdGVkIGJ1ZmZlciBhdCAlcFxuIiwgKmlwcGRzYik7CgoJaWYgKGRzYmQtPmR3RmxhZ3MgJiBEU0JDQVBTX1BSSU1BUllCVUZGRVIpIHsKCQkoKmlwcGRzYiktPmJ1ZmxlbiA9IGRzb3VuZC0+d2Z4Lm5BdmdCeXRlc1BlclNlYzsKCQkoKmlwcGRzYiktPmZyZXEgPSBkc291bmQtPndmeC5uU2FtcGxlc1BlclNlYzsKCgkJLyogRklYTUU6IHZlcmlmeSB0aGF0IGhhcmR3YXJlIGNhcGFiaWxpdGllcyAoRFNDQVBTX1BSSU1BUlkgZmxhZ3MpIG1hdGNoICovCgoJCWlmIChUaGlzLT5kcml2ZXIpIHsKCQkJZXJyID0gSURzRHJpdmVyX0NyZWF0ZVNvdW5kQnVmZmVyKFRoaXMtPmRyaXZlcix3ZmV4LGRzYmQtPmR3RmxhZ3MsMCwKCQkJCQkJCSAgJigoKmlwcGRzYiktPmJ1ZmxlbiksJigoKmlwcGRzYiktPmJ1ZmZlciksCgkJCQkJCQkgIChMUFZPSUQqKSYoKCppcHBkc2IpLT5od2J1ZikpOwoJCX0KCQlpZiAoZXJyID09IERTX09LKQoJCQllcnIgPSBEU09VTkRfUHJpbWFyeU9wZW4oKmlwcGRzYik7Cgl9IGVsc2UgewoJCURXT1JEIGNhcGYgPSAwOwoJCWludCB1c2VfaHc7CgoJCSgqaXBwZHNiKS0+YnVmbGVuID0gZHNiZC0+ZHdCdWZmZXJCeXRlczsKCQkoKmlwcGRzYiktPmZyZXEgPSBkc2JkLT5scHdmeEZvcm1hdC0+blNhbXBsZXNQZXJTZWM7CgoJCS8qIENoZWNrIG5lY2Vzc2FyeSBoYXJkd2FyZSBtaXhpbmcgY2FwYWJpbGl0aWVzICovCgkJaWYgKHdmZXgtPm5DaGFubmVscz09MikgY2FwZiB8PSBEU0NBUFNfU0VDT05EQVJZU1RFUkVPOwoJCWVsc2UgY2FwZiB8PSBEU0NBUFNfU0VDT05EQVJZTU9OTzsKCQlpZiAod2ZleC0+d0JpdHNQZXJTYW1wbGU9PTE2KSBjYXBmIHw9IERTQ0FQU19TRUNPTkRBUlkxNkJJVDsKCQllbHNlIGNhcGYgfD0gRFNDQVBTX1NFQ09OREFSWThCSVQ7CgkJdXNlX2h3ID0gKFRoaXMtPmRydmNhcHMuZHdGbGFncyAmIGNhcGYpID09IGNhcGY7CgoJCS8qIEZJWE1FOiBjaGVjayBoYXJkd2FyZSBzYW1wbGUgcmF0ZSBtaXhpbmcgY2FwYWJpbGl0aWVzICovCgkJLyogRklYTUU6IGNoZWNrIGFwcCBoaW50cyBmb3Igc29mdHdhcmUvaGFyZHdhcmUgYnVmZmVyIChTVEFUSUMsIExPQ0hBUkRXQVJFLCBldGMpICovCgkJLyogRklYTUU6IGNoZWNrIHdoZXRoZXIgYW55IGhhcmR3YXJlIGJ1ZmZlcnMgYXJlIGxlZnQgKi8KCQkvKiBGSVhNRTogaGFuZGxlIERTREhFQVBfQ1JFQVRFSEVBUCBmb3IgaGFyZHdhcmUgYnVmZmVycyAqLwoKCQkvKiBBbGxvY2F0ZSBzeXN0ZW0gbWVtb3J5IGlmIGFwcGxpY2FibGUgKi8KCQlpZiAoKFRoaXMtPmRydmRlc2MuZHdGbGFncyAmIERTRERFU0NfVVNFU1lTVEVNTUVNT1JZKSB8fCAhdXNlX2h3KSB7CgkJCSgqaXBwZHNiKS0+YnVmZmVyID0gKExQQllURSlIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwwLCgqaXBwZHNiKS0+YnVmbGVuKTsKCQkJaWYgKCgqaXBwZHNiKS0+YnVmZmVyID09IE5VTEwpCgkJCQllcnIgPSBEU0VSUl9PVVRPRk1FTU9SWTsKCQl9CgoJCS8qIEFsbG9jYXRlIHRoZSBoYXJkd2FyZSBidWZmZXIgKi8KCQlpZiAodXNlX2h3ICYmIChlcnIgPT0gRFNfT0spKSB7CgkJCWVyciA9IElEc0RyaXZlcl9DcmVhdGVTb3VuZEJ1ZmZlcihUaGlzLT5kcml2ZXIsd2ZleCxkc2JkLT5kd0ZsYWdzLDAsCgkJCQkJCQkgICYoKCppcHBkc2IpLT5idWZsZW4pLCYoKCppcHBkc2IpLT5idWZmZXIpLAoJCQkJCQkJICAoTFBWT0lEKikmKCgqaXBwZHNiKS0+aHdidWYpKTsKCQl9Cgl9CgoJaWYgKGVyciAhPSBEU19PSykgewoJCWlmICgoKmlwcGRzYiktPmJ1ZmZlcikKCQkJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLCgqaXBwZHNiKS0+YnVmZmVyKTsKCQlIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsKCppcHBkc2IpKTsKCQkqaXBwZHNiID0gTlVMTDsKCQlyZXR1cm4gZXJyOwoJfQoJLyogY2FsY3VsYXRlIGZyYWdtZW50IHNpemUgYW5kIHdyaXRlIGxlYWQgKi8KCURTT1VORF9SZWNhbGNGb3JtYXQoKmlwcGRzYik7CgoJLyogSXQncyBub3QgbmVjZXNzYXJ5IHRvIGluaXRpYWxpemUgdmFsdWVzIHRvIHplcm8gc2luY2UgKi8KCS8qIHdlIGFsbG9jYXRlZCB0aGlzIHN0cnVjdHVyZSB3aXRoIEhFQVBfWkVST19NRU1PUlkuLi4gKi8KCSgqaXBwZHNiKS0+cGxheXBvcyA9IDA7CgkoKmlwcGRzYiktPmJ1Zl9taXhwb3MgPSAwOwoJKCppcHBkc2IpLT5zdGF0ZSA9IFNUQVRFX1NUT1BQRUQ7CglEU09VTkRfUmVjYWxjVm9sUGFuKCYoKCppcHBkc2IpLT52b2xwYW4pKTsKCglpZiAoIShkc2JkLT5kd0ZsYWdzICYgRFNCQ0FQU19QUklNQVJZQlVGRkVSKSkgewoJCSgqaXBwZHNiKS0+ZnJlcUFkanVzdCA9ICgoKmlwcGRzYiktPmZyZXEgPDwgRFNPVU5EX0ZSRVFTSElGVCkgLwoJCQlwcmltYXJ5YnVmLT53ZngublNhbXBsZXNQZXJTZWM7CgkJKCppcHBkc2IpLT5uQXZnQnl0ZXNQZXJTZWMgPSAoKmlwcGRzYiktPmZyZXEgKgoJCQlkc2JkLT5scHdmeEZvcm1hdC0+bkJsb2NrQWxpZ247Cgl9CgoJRW50ZXJDcml0aWNhbFNlY3Rpb24oJihUaGlzLT5sb2NrKSk7CgkvKiByZWdpc3RlciBidWZmZXIgKi8KCWlmICghKGRzYmQtPmR3RmxhZ3MgJiBEU0JDQVBTX1BSSU1BUllCVUZGRVIpKSB7CgkJSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqKm5ld2J1ZmZlcnMgPSAoSURpcmVjdFNvdW5kQnVmZmVySW1wbCoqKUhlYXBSZUFsbG9jKEdldFByb2Nlc3NIZWFwKCksMCxUaGlzLT5idWZmZXJzLHNpemVvZihJRGlyZWN0U291bmRCdWZmZXJJbXBsKikqKFRoaXMtPm5yb2ZidWZmZXJzKzEpKTsKCQlpZiAobmV3YnVmZmVycykgewoJCQlUaGlzLT5idWZmZXJzID0gbmV3YnVmZmVyczsKCQkJVGhpcy0+YnVmZmVyc1tUaGlzLT5ucm9mYnVmZmVyc10gPSAqaXBwZHNiOwoJCQlUaGlzLT5ucm9mYnVmZmVycysrOwoJCQlUUkFDRSgiYnVmZmVyIGNvdW50IGlzIG5vdyAlZFxuIiwgVGhpcy0+bnJvZmJ1ZmZlcnMpOwoJCX0gZWxzZSB7CgkJCUVSUigib3V0IG9mIG1lbW9yeSBmb3IgYnVmZmVyIGxpc3QhIEN1cnJlbnQgYnVmZmVyIGNvdW50IGlzICVkXG4iLCBUaGlzLT5ucm9mYnVmZmVycyk7CgkJCWVyciA9IERTRVJSX09VVE9GTUVNT1JZOwoJCX0KCX0KCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCYoVGhpcy0+bG9jaykpOwoKCUlEaXJlY3RTb3VuZF9BZGRSZWYoaWZhY2UpOwoKCUluaXRpYWxpemVDcml0aWNhbFNlY3Rpb24oJigoKmlwcGRzYiktPmxvY2spKTsKCglpZiAoZXJyICE9IERTX09LKSB7CgkJLyogb29wcy4uLiAqLwoJCUlEaXJlY3RTb3VuZEJ1ZmZlcl9SZWxlYXNlKCpwcGRzYik7CgkJKmlwcGRzYiA9IE5VTEw7CgkJcmV0dXJuIGVycjsKCX0KCQojaWZkZWYgVVNFX0RTT1VORDNECglpZiAoZHNiZC0+ZHdGbGFncyAmIERTQkNBUFNfQ1RSTDNEKSB7CgkJSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsCSpkczNkYjsKCgkJZHMzZGIgPSAoSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsKilIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwKCQkJMCxzaXplb2YoKmRzM2RiKSk7CgkJSUNPTV9WVEJMKGRzM2RiKSA9ICZkczNkYnZ0OwoJCWRzM2RiLT5yZWYgPSAxOwoJCSgqaXBwZHNiKS0+ZHMzZGIgPSBkczNkYjsKCgkJZHMzZGItPmRzYiA9ICgqaXBwZHNiKTsKCQlJRGlyZWN0U291bmRCdWZmZXJJbXBsX0FkZFJlZigoTFBESVJFQ1RTT1VOREJVRkZFUikoKmlwcGRzYikpOwoKCQlJbml0aWFsaXplQ3JpdGljYWxTZWN0aW9uKCZkczNkYi0+bG9jayk7CgoJCWRzM2RiLT5kczNkYi5kd1NpemUgPSBzaXplb2YoRFMzREJVRkZFUik7CgkJZHMzZGItPmRzM2RiLnZQb3NpdGlvbi51MS54ID0gMC4wOwoJCWRzM2RiLT5kczNkYi52UG9zaXRpb24udTIueSA9IDAuMDsKCQlkczNkYi0+ZHMzZGIudlBvc2l0aW9uLnUzLnogPSAwLjA7CgkJZHMzZGItPmRzM2RiLnZWZWxvY2l0eS51MS54ID0gMC4wOwoJCWRzM2RiLT5kczNkYi52VmVsb2NpdHkudTIueSA9IDAuMDsKCQlkczNkYi0+ZHMzZGIudlZlbG9jaXR5LnUzLnogPSAwLjA7CgkJZHMzZGItPmRzM2RiLmR3SW5zaWRlQ29uZUFuZ2xlID0gRFMzRF9ERUZBVUxUQ09ORUFOR0xFOwoJCWRzM2RiLT5kczNkYi5kd091dHNpZGVDb25lQW5nbGUgPSBEUzNEX0RFRkFVTFRDT05FQU5HTEU7CgkJZHMzZGItPmRzM2RiLnZDb25lT3JpZW50YXRpb24udTEueCA9IDAuMDsKCQlkczNkYi0+ZHMzZGIudkNvbmVPcmllbnRhdGlvbi51Mi55ID0gMC4wOwoJCWRzM2RiLT5kczNkYi52Q29uZU9yaWVudGF0aW9uLnUzLnogPSAwLjA7CgkJZHMzZGItPmRzM2RiLmxDb25lT3V0c2lkZVZvbHVtZSA9IERTM0RfREVGQVVMVENPTkVPVVRTSURFVk9MVU1FOwoJCWRzM2RiLT5kczNkYi5mbE1pbkRpc3RhbmNlID0gRFMzRF9ERUZBVUxUTUlORElTVEFOQ0U7CgkJZHMzZGItPmRzM2RiLmZsTWF4RGlzdGFuY2UgPSBEUzNEX0RFRkFVTFRNQVhESVNUQU5DRTsKCQlkczNkYi0+ZHMzZGIuZHdNb2RlID0gRFMzRE1PREVfTk9STUFMOwoJCWRzM2RiLT5idWZsZW4gPSAoKCppcHBkc2IpLT5idWZsZW4gKiBwcmltYXJ5YnVmLT53ZngubkJsb2NrQWxpZ24pIC8KCQkJKCppcHBkc2IpLT53ZngubkJsb2NrQWxpZ247CgkJZHMzZGItPmJ1ZmZlciA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBkczNkYi0+YnVmbGVuKTsKCQlpZiAoZHMzZGItPmJ1ZmZlciA9PSBOVUxMKSB7CgkJCWRzM2RiLT5idWZsZW4gPSAwOwoJCQlkczNkYi0+ZHMzZGIuZHdNb2RlID0gRFMzRE1PREVfRElTQUJMRTsKCQl9CgkJZHMzZGItPmlrcyA9IChJS3NQcm9wZXJ0eVNldEltcGwqKUhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLDAsc2l6ZW9mKCooZHMzZGItPmlrcykpKTsKCQlkczNkYi0+aWtzLT5yZWYgPSAxOwoJCWRzM2RiLT5pa3MtPmRzM2RiID0gZHMzZGI7CgkJSUNPTV9WVEJMKGRzM2RiLT5pa3MpID0gJmlrc3Z0OwoKCX0KI2VuZGlmCglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmRJbXBsX0R1cGxpY2F0ZVNvdW5kQnVmZmVyKAoJTFBESVJFQ1RTT1VORCBpZmFjZSxMUERJUkVDVFNPVU5EQlVGRkVSIHBkc2IsTFBMUERJUkVDVFNPVU5EQlVGRkVSIHBwZHNiCikgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEltcGwsaWZhY2UpOwoJSURpcmVjdFNvdW5kQnVmZmVySW1wbCogaXBkc2I9KElEaXJlY3RTb3VuZEJ1ZmZlckltcGwqKXBkc2I7CglJRGlyZWN0U291bmRCdWZmZXJJbXBsKiogaXBwZHNiPShJRGlyZWN0U291bmRCdWZmZXJJbXBsKiopcHBkc2I7CglUUkFDRSgiKCVwLCVwLCVwKVxuIixUaGlzLGlwZHNiLGlwcGRzYik7CgoJaWYgKGlwZHNiLT5od2J1ZikgewoJCUZJWE1FKCJuZWVkIHRvIGR1cGxpY2F0ZSBoYXJkd2FyZSBidWZmZXJcbiIpOwoJfQoKCSppcHBkc2IgPSAoSURpcmVjdFNvdW5kQnVmZmVySW1wbCopSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksSEVBUF9aRVJPX01FTU9SWSxzaXplb2YoSURpcmVjdFNvdW5kQnVmZmVySW1wbCkpOwoKCUlEaXJlY3RTb3VuZEJ1ZmZlcl9BZGRSZWYocGRzYik7CgltZW1jcHkoKmlwcGRzYiwgaXBkc2IsIHNpemVvZihJRGlyZWN0U291bmRCdWZmZXJJbXBsKSk7CgkoKmlwcGRzYiktPnJlZiA9IDE7CgkoKmlwcGRzYiktPnN0YXRlID0gU1RBVEVfU1RPUFBFRDsKCSgqaXBwZHNiKS0+cGxheXBvcyA9IDA7CgkoKmlwcGRzYiktPmJ1Zl9taXhwb3MgPSAwOwoJKCppcHBkc2IpLT5kc291bmQgPSBUaGlzOwoJKCppcHBkc2IpLT5wYXJlbnQgPSBpcGRzYjsKCW1lbWNweSgmKCgqaXBwZHNiKS0+d2Z4KSwgJihpcGRzYi0+d2Z4KSwgc2l6ZW9mKCgqaXBwZHNiKS0+d2Z4KSk7CglJbml0aWFsaXplQ3JpdGljYWxTZWN0aW9uKCYoKmlwcGRzYiktPmxvY2spOwoJLyogcmVnaXN0ZXIgYnVmZmVyICovCglFbnRlckNyaXRpY2FsU2VjdGlvbigmKFRoaXMtPmxvY2spKTsKCXsKCQlJRGlyZWN0U291bmRCdWZmZXJJbXBsICoqbmV3YnVmZmVycyA9IChJRGlyZWN0U291bmRCdWZmZXJJbXBsKiopSGVhcFJlQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwwLFRoaXMtPmJ1ZmZlcnMsc2l6ZW9mKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwqKikqKFRoaXMtPm5yb2ZidWZmZXJzKzEpKTsKCQlpZiAobmV3YnVmZmVycykgewoJCQlUaGlzLT5idWZmZXJzID0gbmV3YnVmZmVyczsKCQkJVGhpcy0+YnVmZmVyc1tUaGlzLT5ucm9mYnVmZmVyc10gPSAqaXBwZHNiOwoJCQlUaGlzLT5ucm9mYnVmZmVycysrOwoJCQlUUkFDRSgiYnVmZmVyIGNvdW50IGlzIG5vdyAlZFxuIiwgVGhpcy0+bnJvZmJ1ZmZlcnMpOwoJCX0gZWxzZSB7CgkJCUVSUigib3V0IG9mIG1lbW9yeSBmb3IgYnVmZmVyIGxpc3QhIEN1cnJlbnQgYnVmZmVyIGNvdW50IGlzICVkXG4iLCBUaGlzLT5ucm9mYnVmZmVycyk7CgkJCS8qIEZJWE1FOiByZWxlYXNlIGJ1ZmZlciAqLwoJCX0KCX0KCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCYoVGhpcy0+bG9jaykpOwoJSURpcmVjdFNvdW5kX0FkZFJlZihpZmFjZSk7CglyZXR1cm4gRFNfT0s7Cn0KCgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kSW1wbF9HZXRDYXBzKExQRElSRUNUU09VTkQgaWZhY2UsTFBEU0NBUFMgY2FwcykgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEltcGwsaWZhY2UpOwoJVFJBQ0UoIiglcCwlcClcbiIsVGhpcyxjYXBzKTsKCVRSQUNFKCIoZmxhZ3M9MHglMDhseClcbiIsY2Fwcy0+ZHdGbGFncyk7CgoJaWYgKGNhcHMgPT0gTlVMTCkKCQlyZXR1cm4gRFNFUlJfSU5WQUxJRFBBUkFNOwoKCS8qIFdlIHNob3VsZCBjaGVjayB0aGlzIHZhbHVlLCBub3Qgc2V0IGl0LiBTZWUgSW5zaWRlIERpcmVjdFgsIHAyMTUuICovCgljYXBzLT5kd1NpemUgPSBzaXplb2YoKmNhcHMpOwoKCWNhcHMtPmR3RmxhZ3MgPSBUaGlzLT5kcnZjYXBzLmR3RmxhZ3M7CgoJLyogRklYTUU6IGNvcHkgY2FwcyBmcm9tIFRoaXMtPmRydmNhcHMgKi8KCWNhcHMtPmR3TWluU2Vjb25kYXJ5U2FtcGxlUmF0ZQkJPSBEU0JGUkVRVUVOQ1lfTUlOOwoJY2Fwcy0+ZHdNYXhTZWNvbmRhcnlTYW1wbGVSYXRlCQk9IERTQkZSRVFVRU5DWV9NQVg7CgoJY2Fwcy0+ZHdQcmltYXJ5QnVmZmVycwkJCT0gMTsKCgljYXBzLT5kd01heEh3TWl4aW5nQWxsQnVmZmVycwkJPSAwOwoJY2Fwcy0+ZHdNYXhId01peGluZ1N0YXRpY0J1ZmZlcnMJPSAwOwoJY2Fwcy0+ZHdNYXhId01peGluZ1N0cmVhbWluZ0J1ZmZlcnMJPSAwOwoKCWNhcHMtPmR3RnJlZUh3TWl4aW5nQWxsQnVmZmVycwkJPSAwOwoJY2Fwcy0+ZHdGcmVlSHdNaXhpbmdTdGF0aWNCdWZmZXJzCT0gMDsKCWNhcHMtPmR3RnJlZUh3TWl4aW5nU3RyZWFtaW5nQnVmZmVycwk9IDA7CgoJY2Fwcy0+ZHdNYXhIdzNEQWxsQnVmZmVycwkJPSAwOwoJY2Fwcy0+ZHdNYXhIdzNEU3RhdGljQnVmZmVycwkJPSAwOwoJY2Fwcy0+ZHdNYXhIdzNEU3RyZWFtaW5nQnVmZmVycwkJPSAwOwoKCWNhcHMtPmR3RnJlZUh3M0RBbGxCdWZmZXJzCQk9IDA7CgljYXBzLT5kd0ZyZWVIdzNEU3RhdGljQnVmZmVycwkJPSAwOwoJY2Fwcy0+ZHdGcmVlSHczRFN0cmVhbWluZ0J1ZmZlcnMJPSAwOwoKCWNhcHMtPmR3VG90YWxId01lbUJ5dGVzCQkJPSAwOwoKCWNhcHMtPmR3RnJlZUh3TWVtQnl0ZXMJCQk9IDA7CgoJY2Fwcy0+ZHdNYXhDb250aWdGcmVlSHdNZW1CeXRlcwkJPSAwOwoKCWNhcHMtPmR3VW5sb2NrVHJhbnNmZXJSYXRlSHdCdWZmZXJzCT0gNDA5NjsJLyogQnV0IHdlIGhhdmUgbm9uZS4uLiAqLwoKCWNhcHMtPmR3UGxheUNwdU92ZXJoZWFkU3dCdWZmZXJzCT0gMTsJLyogMSUgKi8KCglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSURpcmVjdFNvdW5kSW1wbF9BZGRSZWYoTFBESVJFQ1RTT1VORCBpZmFjZSkgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEltcGwsaWZhY2UpOwoJcmV0dXJuICsrKFRoaXMtPnJlZik7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSURpcmVjdFNvdW5kSW1wbF9SZWxlYXNlKExQRElSRUNUU09VTkQgaWZhY2UpIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRJbXBsLGlmYWNlKTsKCVRSQUNFKCIoJXApLCByZWYgd2FzICVsZFxuIixUaGlzLFRoaXMtPnJlZik7CglpZiAoIS0tKFRoaXMtPnJlZikpIHsKCQlVSU5UIGk7CgoJCXRpbWVLaWxsRXZlbnQoVGhpcy0+dGltZXJJRCk7CgkJdGltZUVuZFBlcmlvZChEU19USU1FX1JFUyk7CgoJCWlmIChwcmltYXJ5YnVmKQoJCQlJRGlyZWN0U291bmRCdWZmZXJfUmVsZWFzZSgoTFBESVJFQ1RTT1VOREJVRkZFUilwcmltYXJ5YnVmKTsKCgkJaWYgKFRoaXMtPmJ1ZmZlcnMpIHsKCQkJZm9yKCBpPTA7aTxUaGlzLT5ucm9mYnVmZmVycztpKyspCQoJCQkJSURpcmVjdFNvdW5kQnVmZmVyX1JlbGVhc2UoKExQRElSRUNUU09VTkRCVUZGRVIpVGhpcy0+YnVmZmVyc1tpXSk7CgkJfQoKCQlpZiAoVGhpcy0+cHJpbWFyeSkKCQkJSURpcmVjdFNvdW5kQnVmZmVyX1JlbGVhc2UoKExQRElSRUNUU09VTkRCVUZGRVIpVGhpcy0+cHJpbWFyeSk7CgoJCURlbGV0ZUNyaXRpY2FsU2VjdGlvbigmVGhpcy0+bG9jayk7CgkJaWYgKFRoaXMtPmRyaXZlcikgewoJCQlJRHNEcml2ZXJfQ2xvc2UoVGhpcy0+ZHJpdmVyKTsKCQl9IGVsc2UgewoJCQl1bnNpZ25lZCBjOwoJCQlmb3IgKGM9MDsgYzxEU19IRUxfRlJBR1M7IGMrKykKCQkJCUhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCxUaGlzLT5wd2F2ZVtjXSk7CgkJfQoJCWlmIChUaGlzLT5kcnZkZXNjLmR3RmxhZ3MgJiBEU0RERVNDX0RPTU1TWVNURU1PUEVOKSB7CgkJCXdhdmVPdXRDbG9zZShUaGlzLT5od28pOwoJCX0KCQlpZiAoVGhpcy0+ZHJpdmVyKQoJCQlJRHNEcml2ZXJfUmVsZWFzZShUaGlzLT5kcml2ZXIpOwoKCQlIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsVGhpcyk7CgkJZHNvdW5kID0gTlVMTDsKCQlyZXR1cm4gMDsKCX0KCXJldHVybiBUaGlzLT5yZWY7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmRJbXBsX1NldFNwZWFrZXJDb25maWcoCglMUERJUkVDVFNPVU5EIGlmYWNlLERXT1JEIGNvbmZpZwopIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRJbXBsLGlmYWNlKTsKCUZJWE1FKCIoJXAsMHglMDhseCk6c3R1YlxuIixUaGlzLGNvbmZpZyk7CglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmRJbXBsX1F1ZXJ5SW50ZXJmYWNlKAoJTFBESVJFQ1RTT1VORCBpZmFjZSxSRUZJSUQgcmlpZCxMUFZPSUQgKnBwb2JqCikgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEltcGwsaWZhY2UpOwoKCWlmICggSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdFNvdW5kM0RMaXN0ZW5lciwgcmlpZCApICkgewoKCQlpZiAoVGhpcy0+bGlzdGVuZXIpIHsKCQkJKnBwb2JqID0gVGhpcy0+bGlzdGVuZXI7CgkJCUlEaXJlY3RTb3VuZDNETGlzdGVuZXJfQWRkUmVmKChMUERJUkVDVFNPVU5EM0RMSVNURU5FUilUaGlzLT5saXN0ZW5lcik7CgkJCXJldHVybiBEU19PSzsKCQl9CgoJCVRoaXMtPmxpc3RlbmVyID0gKElEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsKilIZWFwQWxsb2MoCgkJCUdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZigqKFRoaXMtPmxpc3RlbmVyKSkpOwoJCVRoaXMtPmxpc3RlbmVyLT5yZWYgPSAxOwoJCUlDT01fVlRCTChUaGlzLT5saXN0ZW5lcikgPSAmZHMzZGx2dDsKCQkqcHBvYmogPSAoTFBWT0lEKVRoaXMtPmxpc3RlbmVyOwoJCUlEaXJlY3RTb3VuZDNETGlzdGVuZXJfQWRkUmVmKChMUERJUkVDVFNPVU5EM0RMSVNURU5FUikqcHBvYmopOwkKCgkJVGhpcy0+bGlzdGVuZXItPmRzYiA9IE5VTEw7IAoKCQlUaGlzLT5saXN0ZW5lci0+ZHMzZGwuZHdTaXplID0gc2l6ZW9mKERTM0RMSVNURU5FUik7CgkJVGhpcy0+bGlzdGVuZXItPmRzM2RsLnZQb3NpdGlvbi51MS54ID0gMC4wOwoJCVRoaXMtPmxpc3RlbmVyLT5kczNkbC52UG9zaXRpb24udTIueSA9IDAuMDsKCQlUaGlzLT5saXN0ZW5lci0+ZHMzZGwudlBvc2l0aW9uLnUzLnogPSAwLjA7CgkJVGhpcy0+bGlzdGVuZXItPmRzM2RsLnZWZWxvY2l0eS51MS54ID0gMC4wOwoJCVRoaXMtPmxpc3RlbmVyLT5kczNkbC52VmVsb2NpdHkudTIueSA9IDAuMDsKCQlUaGlzLT5saXN0ZW5lci0+ZHMzZGwudlZlbG9jaXR5LnUzLnogPSAwLjA7CgkJVGhpcy0+bGlzdGVuZXItPmRzM2RsLnZPcmllbnRGcm9udC51MS54ID0gMC4wOwoJCVRoaXMtPmxpc3RlbmVyLT5kczNkbC52T3JpZW50RnJvbnQudTIueSA9IDAuMDsKCQlUaGlzLT5saXN0ZW5lci0+ZHMzZGwudk9yaWVudEZyb250LnUzLnogPSAxLjA7CgkJVGhpcy0+bGlzdGVuZXItPmRzM2RsLnZPcmllbnRUb3AudTEueCA9IDAuMDsKCQlUaGlzLT5saXN0ZW5lci0+ZHMzZGwudk9yaWVudFRvcC51Mi55ID0gMS4wOwoJCVRoaXMtPmxpc3RlbmVyLT5kczNkbC52T3JpZW50VG9wLnUzLnogPSAwLjA7CgkJVGhpcy0+bGlzdGVuZXItPmRzM2RsLmZsRGlzdGFuY2VGYWN0b3IgPSBEUzNEX0RFRkFVTFRESVNUQU5DRUZBQ1RPUjsKCQlUaGlzLT5saXN0ZW5lci0+ZHMzZGwuZmxSb2xsb2ZmRmFjdG9yID0gRFMzRF9ERUZBVUxUUk9MTE9GRkZBQ1RPUjsKCQlUaGlzLT5saXN0ZW5lci0+ZHMzZGwuZmxEb3BwbGVyRmFjdG9yID0gRFMzRF9ERUZBVUxURE9QUExFUkZBQ1RPUjsKCgkJSW5pdGlhbGl6ZUNyaXRpY2FsU2VjdGlvbigmVGhpcy0+bGlzdGVuZXItPmxvY2spOwoKCQlyZXR1cm4gRFNfT0s7Cgl9CgoJRklYTUUoIiglcCwlcywlcClcbiIsVGhpcyxkZWJ1Z3N0cl9ndWlkKHJpaWQpLHBwb2JqKTsKCXJldHVybiBFX0ZBSUw7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmRJbXBsX0NvbXBhY3QoCglMUERJUkVDVFNPVU5EIGlmYWNlKQp7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kSW1wbCxpZmFjZSk7CglUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmRJbXBsX0dldFNwZWFrZXJDb25maWcoCglMUERJUkVDVFNPVU5EIGlmYWNlLAoJTFBEV09SRCBscGR3U3BlYWtlckNvbmZpZykKewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEltcGwsaWZhY2UpOwoJVFJBQ0UoIiglcCwgJXApXG4iLCBUaGlzLCBscGR3U3BlYWtlckNvbmZpZyk7CgkqbHBkd1NwZWFrZXJDb25maWcgPSBEU1NQRUFLRVJfU1RFUkVPIHwgKERTU1BFQUtFUl9HRU9NRVRSWV9OQVJST1cgPDwgMTYpOwoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kSW1wbF9Jbml0aWFsaXplKAoJTFBESVJFQ1RTT1VORCBpZmFjZSwKCUxQQ0dVSUQgbHBjR3VpZCkKewoJSUNPTV9USElTKElEaXJlY3RTb3VuZEltcGwsaWZhY2UpOwoJVFJBQ0UoIiglcCwgJXApXG4iLCBUaGlzLCBscGNHdWlkKTsKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIElDT01fVlRBQkxFKElEaXJlY3RTb3VuZCkgZHN2dCA9IAp7CglJQ09NX01TVlRBQkxFX0NPTVBBVF9EdW1teVJUVElWQUxVRQoJSURpcmVjdFNvdW5kSW1wbF9RdWVyeUludGVyZmFjZSwKCUlEaXJlY3RTb3VuZEltcGxfQWRkUmVmLAoJSURpcmVjdFNvdW5kSW1wbF9SZWxlYXNlLAoJSURpcmVjdFNvdW5kSW1wbF9DcmVhdGVTb3VuZEJ1ZmZlciwKCUlEaXJlY3RTb3VuZEltcGxfR2V0Q2FwcywKCUlEaXJlY3RTb3VuZEltcGxfRHVwbGljYXRlU291bmRCdWZmZXIsCglJRGlyZWN0U291bmRJbXBsX1NldENvb3BlcmF0aXZlTGV2ZWwsCglJRGlyZWN0U291bmRJbXBsX0NvbXBhY3QsCglJRGlyZWN0U291bmRJbXBsX0dldFNwZWFrZXJDb25maWcsCglJRGlyZWN0U291bmRJbXBsX1NldFNwZWFrZXJDb25maWcsCglJRGlyZWN0U291bmRJbXBsX0luaXRpYWxpemUKfTsKCgpzdGF0aWMgdm9pZCBEU09VTkRfQ2hlY2tFdmVudChJRGlyZWN0U291bmRCdWZmZXJJbXBsICpkc2IsIGludCBsZW4pCnsKCWludAkJCWk7CglEV09SRAkJCW9mZnNldDsKCUxQRFNCUE9TSVRJT05OT1RJRlkJZXZlbnQ7CgoJaWYgKGRzYi0+bnJvZm5vdGlmaWVzID09IDApCgkJcmV0dXJuOwoKCVRSQUNFKCIoJXApIGJ1ZmxlbiA9ICVsZCwgcGxheXBvcyA9ICVsZCwgbGVuID0gJWRcbiIsCgkJZHNiLCBkc2ItPmJ1ZmxlbiwgZHNiLT5wbGF5cG9zLCBsZW4pOwoJZm9yIChpID0gMDsgaSA8IGRzYi0+bnJvZm5vdGlmaWVzIDsgaSsrKSB7CgkJZXZlbnQgPSBkc2ItPm5vdGlmaWVzICsgaTsKCQlvZmZzZXQgPSBldmVudC0+ZHdPZmZzZXQ7CgkJVFJBQ0UoImNoZWNraW5nICVkLCBwb3NpdGlvbiAlbGQsIGV2ZW50ID0gJWRcbiIsCgkJCWksIG9mZnNldCwgZXZlbnQtPmhFdmVudE5vdGlmeSk7CgkJLyogRFNCUE5fT0ZGU0VUU1RPUCBoYXMgdG8gYmUgdGhlIGxhc3QgZWxlbWVudC4gU28gdGhpcyBpcyAqLwoJCS8qIE9LLiBbSW5zaWRlIERpcmVjdFgsIHAyNzRdICovCgkJLyogICovCgkJLyogVGhpcyBhbHNvIG1lYW5zIHdlIGNhbid0IHNvcnQgdGhlIGVudHJpZXMgYnkgb2Zmc2V0LCAqLwoJCS8qIGJlY2F1c2UgRFNCUE5fT0ZGU0VUU1RPUCA9PSAtMSAqLwoJCWlmIChvZmZzZXQgPT0gRFNCUE5fT0ZGU0VUU1RPUCkgewoJCQlpZiAoZHNiLT5zdGF0ZSA9PSBTVEFURV9TVE9QUEVEKSB7CgkJCQlTZXRFdmVudChldmVudC0+aEV2ZW50Tm90aWZ5KTsKCQkJCVRSQUNFKCJzaWduYWxsZWQgZXZlbnQgJWQgKCVkKVxuIiwgZXZlbnQtPmhFdmVudE5vdGlmeSwgaSk7CgkJCQlyZXR1cm47CgkJCX0gZWxzZQoJCQkJcmV0dXJuOwoJCX0KCQlpZiAoKGRzYi0+cGxheXBvcyArIGxlbikgPj0gZHNiLT5idWZsZW4pIHsKCQkJaWYgKChvZmZzZXQgPCAoKGRzYi0+cGxheXBvcyArIGxlbikgJSBkc2ItPmJ1ZmxlbikpIHx8CgkJCSAgICAob2Zmc2V0ID49IGRzYi0+cGxheXBvcykpIHsKCQkJCVRSQUNFKCJzaWduYWxsZWQgZXZlbnQgJWQgKCVkKVxuIiwgZXZlbnQtPmhFdmVudE5vdGlmeSwgaSk7CgkJCQlTZXRFdmVudChldmVudC0+aEV2ZW50Tm90aWZ5KTsKCQkJfQoJCX0gZWxzZSB7CgkJCWlmICgob2Zmc2V0ID49IGRzYi0+cGxheXBvcykgJiYgKG9mZnNldCA8IChkc2ItPnBsYXlwb3MgKyBsZW4pKSkgewoJCQkJVFJBQ0UoInNpZ25hbGxlZCBldmVudCAlZCAoJWQpXG4iLCBldmVudC0+aEV2ZW50Tm90aWZ5LCBpKTsKCQkJCVNldEV2ZW50KGV2ZW50LT5oRXZlbnROb3RpZnkpOwoJCQl9CgkJfQoJfQp9CgovKiBXQVYgZm9ybWF0IGluZm8gY2FuIGJlIGZvdW5kIGF0OiAqLwovKiAqLwovKglodHRwOi8vd3d3LmN3aS5ubC9mdHAvYXVkaW8vQXVkaW9Gb3JtYXRzLnBhcnQyICovCi8qCWZ0cDovL2Z0cC5jd2kubmwvcHViL2F1ZGlvL1JJRkYtZm9ybWF0ICovCi8qICovCi8qIEltcG9ydCBwb2ludHMgdG8gcmVtZW1iZXI6ICovCi8qICovCi8qCTgtYml0IFdBViBpcyB1bnNpZ25lZCAqLwovKgkxNi1iaXQgV0FWIGlzIHNpZ25lZCAqLwoKc3RhdGljIGlubGluZSBJTlQxNiBjdnRVOHRvUzE2KEJZVEUgYnl0ZSkKewoJSU5UMTYJcyA9IChieXRlIC0gMTI4KSA8PCA4OwoKCXJldHVybiBzOwp9CgpzdGF0aWMgaW5saW5lIEJZVEUgY3Z0UzE2dG9VOChJTlQxNiB3b3JkKQp7CglCWVRFCWIgPSAod29yZCArIDMyNzY4KSA+PiA4OwoJCglyZXR1cm4gYjsKfQoKCi8qIFdlIHNob3VsZCBiZSBhYmxlIHRvIG9wdGltaXplIHRoZXNlIHR3byBpbmxpbmUgZnVuY3Rpb25zICovCi8qIHNvIHRoYXQgd2UgYXJlbid0IGRvaW5nIDgtPjE2LT44IGNvbnZlcnNpb25zIHdoZW4gaXQgaXMgKi8KLyogbm90IG5lY2Vzc2FyeS4gQnV0IHRoaXMgaXMgc3RpbGwgYSBXSVAuIE9wdGltaXplIGxhdGVyLiAqLwpzdGF0aWMgaW5saW5lIHZvaWQgZ2V0X2ZpZWxkcyhjb25zdCBJRGlyZWN0U291bmRCdWZmZXJJbXBsICpkc2IsIEJZVEUgKmJ1ZiwgSU5UICpmbCwgSU5UICpmcikKewoJSU5UMTYJKmJ1ZnMgPSAoSU5UMTYgKikgYnVmOwoKCS8qIFRSQUNFKCIoJXApXG4iLCBidWYpOyAqLwoJaWYgKChkc2ItPndmeC53Qml0c1BlclNhbXBsZSA9PSA4KSAmJiBkc2ItPndmeC5uQ2hhbm5lbHMgPT0gMikgewoJCSpmbCA9IGN2dFU4dG9TMTYoKmJ1Zik7CgkJKmZyID0gY3Z0VTh0b1MxNigqKGJ1ZiArIDEpKTsKCQlyZXR1cm47Cgl9CgoJaWYgKChkc2ItPndmeC53Qml0c1BlclNhbXBsZSA9PSAxNikgJiYgZHNiLT53ZngubkNoYW5uZWxzID09IDIpIHsKCQkqZmwgPSAqYnVmczsKCQkqZnIgPSAqKGJ1ZnMgKyAxKTsKCQlyZXR1cm47Cgl9CgoJaWYgKChkc2ItPndmeC53Qml0c1BlclNhbXBsZSA9PSA4KSAmJiBkc2ItPndmeC5uQ2hhbm5lbHMgPT0gMSkgewoJCSpmbCA9IGN2dFU4dG9TMTYoKmJ1Zik7CgkJKmZyID0gKmZsOwoJCXJldHVybjsKCX0KCglpZiAoKGRzYi0+d2Z4LndCaXRzUGVyU2FtcGxlID09IDE2KSAmJiBkc2ItPndmeC5uQ2hhbm5lbHMgPT0gMSkgewoJCSpmbCA9ICpidWZzOwoJCSpmciA9ICpidWZzOwoJCXJldHVybjsKCX0KCglGSVhNRSgiZ2V0X2ZpZWxkcyBmb3VuZCBhbiB1bnN1cHBvcnRlZCBjb25maWd1cmF0aW9uXG4iKTsKCXJldHVybjsKfQoKc3RhdGljIGlubGluZSB2b2lkIHNldF9maWVsZHMoQllURSAqYnVmLCBJTlQgZmwsIElOVCBmcikKewoJSU5UMTYgKmJ1ZnMgPSAoSU5UMTYgKikgYnVmOwoKCWlmICgocHJpbWFyeWJ1Zi0+d2Z4LndCaXRzUGVyU2FtcGxlID09IDgpICYmIChwcmltYXJ5YnVmLT53ZngubkNoYW5uZWxzID09IDIpKSB7CgkJKmJ1ZiA9IGN2dFMxNnRvVTgoZmwpOwoJCSooYnVmICsgMSkgPSBjdnRTMTZ0b1U4KGZyKTsKCQlyZXR1cm47Cgl9CgoJaWYgKChwcmltYXJ5YnVmLT53Zngud0JpdHNQZXJTYW1wbGUgPT0gMTYpICYmIChwcmltYXJ5YnVmLT53ZngubkNoYW5uZWxzID09IDIpKSB7CgkJKmJ1ZnMgPSBmbDsKCQkqKGJ1ZnMgKyAxKSA9IGZyOwoJCXJldHVybjsKCX0KCglpZiAoKHByaW1hcnlidWYtPndmeC53Qml0c1BlclNhbXBsZSA9PSA4KSAmJiAocHJpbWFyeWJ1Zi0+d2Z4Lm5DaGFubmVscyA9PSAxKSkgewoJCSpidWYgPSBjdnRTMTZ0b1U4KChmbCArIGZyKSA+PiAxKTsKCQlyZXR1cm47Cgl9CgoJaWYgKChwcmltYXJ5YnVmLT53Zngud0JpdHNQZXJTYW1wbGUgPT0gMTYpICYmIChwcmltYXJ5YnVmLT53ZngubkNoYW5uZWxzID09IDEpKSB7CgkJKmJ1ZnMgPSAoZmwgKyBmcikgPj4gMTsKCQlyZXR1cm47Cgl9CglGSVhNRSgic2V0X2ZpZWxkcyBmb3VuZCBhbiB1bnN1cHBvcnRlZCBjb25maWd1cmF0aW9uXG4iKTsKCXJldHVybjsKfQoKLyogTm93IHdpdGggUGVyZmVjdFBpdGNoICh0bSkgdGVjaG5vbG9neSAqLwpzdGF0aWMgSU5UIERTT1VORF9NaXhlck5vcm0oSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiLCBCWVRFICpidWYsIElOVCBsZW4pCnsKCUlOVAlpLCBzaXplLCBpcG9zLCBpbGVuLCBmaWVsZEwsIGZpZWxkUjsKCUJZVEUJKmlicCwgKm9icDsKCUlOVAlpQWR2YW5jZSA9IGRzYi0+d2Z4Lm5CbG9ja0FsaWduOwoJSU5UCW9BZHZhbmNlID0gcHJpbWFyeWJ1Zi0+d2Z4Lm5CbG9ja0FsaWduOwoKCWlicCA9IGRzYi0+YnVmZmVyICsgZHNiLT5idWZfbWl4cG9zOwoJb2JwID0gYnVmOwoKCVRSQUNFKCIoJXAsICVwLCAlcCksIGJ1Zl9taXhwb3M9JWxkXG4iLCBkc2IsIGlicCwgb2JwLCBkc2ItPmJ1Zl9taXhwb3MpOwoJLyogQ2hlY2sgZm9yIHRoZSBiZXN0IGNhc2UgKi8KCWlmICgoZHNiLT5mcmVxID09IHByaW1hcnlidWYtPndmeC5uU2FtcGxlc1BlclNlYykgJiYKCSAgICAoZHNiLT53Zngud0JpdHNQZXJTYW1wbGUgPT0gcHJpbWFyeWJ1Zi0+d2Z4LndCaXRzUGVyU2FtcGxlKSAmJgoJICAgIChkc2ItPndmeC5uQ2hhbm5lbHMgPT0gcHJpbWFyeWJ1Zi0+d2Z4Lm5DaGFubmVscykpIHsKCSAgICAgICAgRFdPUkQgYnl0ZXNsZWZ0ID0gZHNiLT5idWZsZW4gLSBkc2ItPmJ1Zl9taXhwb3M7CgkJVFJBQ0UoIiglcCkgQmVzdCBjYXNlXG4iLCBkc2IpOwoJICAgIAlpZiAobGVuIDw9IGJ5dGVzbGVmdCApCgkJCW1lbWNweShvYnAsIGlicCwgbGVuKTsKCQllbHNlIHsgLyogd3JhcCAqLwoJCQltZW1jcHkob2JwLCBpYnAsIGJ5dGVzbGVmdCApOwoJCQltZW1jcHkob2JwICsgYnl0ZXNsZWZ0LCBkc2ItPmJ1ZmZlciwgbGVuIC0gYnl0ZXNsZWZ0KTsKCQl9CgkJcmV0dXJuIGxlbjsKCX0KCQoJLyogQ2hlY2sgZm9yIHNhbWUgc2FtcGxlIHJhdGUgKi8KCWlmIChkc2ItPmZyZXEgPT0gcHJpbWFyeWJ1Zi0+d2Z4Lm5TYW1wbGVzUGVyU2VjKSB7CgkJVFJBQ0UoIiglcCkgU2FtZSBzYW1wbGUgcmF0ZSAlbGQgPSBwcmltYXJ5ICVsZFxuIiwgZHNiLAoJCQlkc2ItPmZyZXEsIHByaW1hcnlidWYtPndmeC5uU2FtcGxlc1BlclNlYyk7CgkJaWxlbiA9IDA7CgkJZm9yIChpID0gMDsgaSA8IGxlbjsgaSArPSBvQWR2YW5jZSkgewoJCQlnZXRfZmllbGRzKGRzYiwgaWJwLCAmZmllbGRMLCAmZmllbGRSKTsKCQkJaWJwICs9IGlBZHZhbmNlOwoJCQlpbGVuICs9IGlBZHZhbmNlOwoJCQlzZXRfZmllbGRzKG9icCwgZmllbGRMLCBmaWVsZFIpOwoJCQlvYnAgKz0gb0FkdmFuY2U7CgkJCWlmIChpYnAgPj0gKEJZVEUgKikoZHNiLT5idWZmZXIgKyBkc2ItPmJ1ZmxlbikpCgkJCQlpYnAgPSBkc2ItPmJ1ZmZlcjsJLyogd3JhcCAqLwoJCX0KCQlyZXR1cm4gKGlsZW4pOwkKCX0KCgkvKiBNaXggaW4gZGlmZmVyZW50IHNhbXBsZSByYXRlcyAqLwoJLyogKi8KCS8qIE5ldyBQZXJmZWN0UGl0Y2godG0pIFRlY2hub2xvZ3kgKGMpIDE5OTggUm9iIFJpZ2dzICovCgkvKiBQYXRlbnQgUGVuZGluZyA6LV0gKi8KCgkvKiBQYXRlbnQgZW5oYW5jZW1lbnRzIChjKSAyMDAwIE92ZSBL5XZlbiwKCSAqIFRyYW5zR2FtaW5nIFRlY2hub2xvZ2llcyBJbmMuICovCgoJRklYTUUoIiglcCkgQWRqdXN0aW5nIGZyZXF1ZW5jeTogJWxkIC0+ICVsZCAobmVlZCBvcHRpbWl6YXRpb24pXG4iLAoJCWRzYiwgZHNiLT5mcmVxLCBwcmltYXJ5YnVmLT53ZngublNhbXBsZXNQZXJTZWMpOwoKCXNpemUgPSBsZW4gLyBvQWR2YW5jZTsKCWlsZW4gPSAwOwoJaXBvcyA9IGRzYi0+YnVmX21peHBvczsKCWZvciAoaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKCQlnZXRfZmllbGRzKGRzYiwgKGRzYi0+YnVmZmVyICsgaXBvcyksICZmaWVsZEwsICZmaWVsZFIpOwoJCXNldF9maWVsZHMob2JwLCBmaWVsZEwsIGZpZWxkUik7CgkJb2JwICs9IG9BZHZhbmNlOwoKCQlkc2ItPmZyZXFBY2MgKz0gZHNiLT5mcmVxQWRqdXN0OwoJCWlmIChkc2ItPmZyZXFBY2MgPj0gKDE8PERTT1VORF9GUkVRU0hJRlQpKSB7CgkJCVVMT05HIGFkdiA9IChkc2ItPmZyZXFBY2M+PkRTT1VORF9GUkVRU0hJRlQpICogaUFkdmFuY2U7CgkJCWRzYi0+ZnJlcUFjYyAmPSAoMTw8RFNPVU5EX0ZSRVFTSElGVCktMTsKCQkJaXBvcyArPSBhZHY7IGlsZW4gKz0gYWR2OwoJCQl3aGlsZSAoaXBvcyA+PSBkc2ItPmJ1ZmxlbikKCQkJCWlwb3MgLT0gZHNiLT5idWZsZW47CgkJfQoJfQoJcmV0dXJuIGlsZW47Cn0KCnN0YXRpYyB2b2lkIERTT1VORF9NaXhlclZvbChJRGlyZWN0U291bmRCdWZmZXJJbXBsICpkc2IsIEJZVEUgKmJ1ZiwgSU5UIGxlbikKewoJSU5UCWksIGluYyA9IHByaW1hcnlidWYtPndmeC53Qml0c1BlclNhbXBsZSA+PiAzOwoJQllURQkqYnBjID0gYnVmOwoJSU5UMTYJKmJwcyA9IChJTlQxNiAqKSBidWY7CgkKCVRSQUNFKCIoJXApIGxlZnQgPSAlbHgsIHJpZ2h0ID0gJWx4XG4iLCBkc2IsCgkJZHNiLT52b2xwYW4uZHdUb3RhbExlZnRBbXBGYWN0b3IsIGRzYi0+dm9scGFuLmR3VG90YWxSaWdodEFtcEZhY3Rvcik7CglpZiAoKCEoZHNiLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX0NUUkxQQU4pIHx8IChkc2ItPnZvbHBhbi5sUGFuID09IDApKSAmJgoJICAgICghKGRzYi0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19DVFJMVk9MVU1FKSB8fCAoZHNiLT52b2xwYW4ubFZvbHVtZSA9PSAwKSkgJiYKCSAgICAhKGRzYi0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19DVFJMM0QpKQoJCXJldHVybjsJCS8qIE5vdGhpbmcgdG8gZG8gKi8KCgkvKiBJZiB3ZSBlbmQgdXAgd2l0aCBzb21lIGJvem8gY29kZXIgdXNpbmcgcGFubmluZyBvciAzRCBzb3VuZCAqLwoJLyogd2l0aCBhIG1vbm8gcHJpbWFyeSBidWZmZXIsIGl0IGNvdWxkIHNvdW5kIHZlcnkgd2VpcmQgdXNpbmcgKi8KCS8qIHRoaXMgbWV0aG9kLiBPaCB3ZWxsLCB0b3VnaCBwYXRvb3RpZXMuICovCgoJZm9yIChpID0gMDsgaSA8IGxlbjsgaSArPSBpbmMpIHsKCQlJTlQJdmFsOwoKCQlzd2l0Y2ggKGluYykgewoKCQljYXNlIDE6CgkJCS8qIDgtYml0IFdBViBpcyB1bnNpZ25lZCwgYnV0IHdlIG5lZWQgdG8gb3BlcmF0ZSAqLwoJCQkvKiBvbiBzaWduZWQgZGF0YSBmb3IgdGhpcyB0byB3b3JrIHByb3Blcmx5ICovCgkJCXZhbCA9ICpicGMgLSAxMjg7CgkJCXZhbCA9ICgodmFsICogKGkgJiBpbmMgPyBkc2ItPnZvbHBhbi5kd1RvdGFsUmlnaHRBbXBGYWN0b3IgOiBkc2ItPnZvbHBhbi5kd1RvdGFsTGVmdEFtcEZhY3RvcikpID4+IDE2KTsKCQkJKmJwYyA9IHZhbCArIDEyODsKCQkJYnBjKys7CgkJCWJyZWFrOwoJCWNhc2UgMjoKCQkJLyogMTYtYml0IFdBViBpcyBzaWduZWQgLS0gbXVjaCBiZXR0ZXIgKi8KCQkJdmFsID0gKmJwczsKCQkJdmFsID0gKCh2YWwgKiAoKGkgJiBpbmMpID8gZHNiLT52b2xwYW4uZHdUb3RhbFJpZ2h0QW1wRmFjdG9yIDogZHNiLT52b2xwYW4uZHdUb3RhbExlZnRBbXBGYWN0b3IpKSA+PiAxNik7CgkJCSpicHMgPSB2YWw7CgkJCWJwcysrOwoJCQlicmVhazsKCQlkZWZhdWx0OgoJCQkvKiBWZXJ5IHVnbHkhICovCgkJCUZJWE1FKCJNaXhlclZvbCBoYWQgYSBuYXN0eSBlcnJvclxuIik7CgkJfQoJfQkJCn0KCiNpZmRlZiBVU0VfRFNPVU5EM0QKc3RhdGljIHZvaWQgRFNPVU5EX01peGVyM0QoSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiLCBCWVRFICpidWYsIElOVCBsZW4pCnsKCUJZVEUJKmlicCwgKm9icDsKCURXT1JECWJ1ZmxlbiwgYnVmX21peHBvczsKCglidWZsZW4gPSBkc2ItPmRzM2RiLT5idWZsZW47CglidWZfbWl4cG9zID0gKGRzYi0+YnVmX21peHBvcyAqIHByaW1hcnlidWYtPndmeC5uQmxvY2tBbGlnbikgLyBkc2ItPndmeC5uQmxvY2tBbGlnbjsKCWlicCA9IGRzYi0+ZHMzZGItPmJ1ZmZlciArIGJ1Zl9taXhwb3M7CglvYnAgPSBidWY7CgoJaWYgKGJ1Zl9taXhwb3MgPiBidWZsZW4pIHsKCQlGSVhNRSgiTWFqb3IgYnJlYWthZ2VcbiIpOwoJCXJldHVybjsKCX0KCglpZiAobGVuIDw9IChidWZfbWl4cG9zICsgYnVmbGVuKSkKCQltZW1jcHkob2JwLCBpYnAsIGxlbik7CgllbHNlIHsgLyogd3JhcCAqLwoJCW1lbWNweShvYnAsIGlicCwgYnVmbGVuIC0gYnVmX21peHBvcyk7CgkJbWVtY3B5KG9icCArIChidWZsZW4gLSBidWZfbWl4cG9zKSwKCQkgICAgZHNiLT5idWZmZXIsCgkJICAgIGxlbiAtIChidWZsZW4gLSBidWZfbWl4cG9zKSk7Cgl9CglyZXR1cm47Cn0KI2VuZGlmCgpzdGF0aWMgdm9pZCAqdG1wX2J1ZmZlcjsKc3RhdGljIHNpemVfdCB0bXBfYnVmZmVyX2xlbiA9IDA7CgpzdGF0aWMgdm9pZCAqRFNPVU5EX3RtcGJ1ZmZlcihzaXplX3QgbGVuKQp7CiAgaWYgKGxlbj50bXBfYnVmZmVyX2xlbikgewogICAgdm9pZCAqbmV3X2J1ZmZlciA9IHJlYWxsb2ModG1wX2J1ZmZlciwgbGVuKTsKICAgIGlmIChuZXdfYnVmZmVyKSB7CiAgICAgIHRtcF9idWZmZXIgPSBuZXdfYnVmZmVyOwogICAgICB0bXBfYnVmZmVyX2xlbiA9IGxlbjsKICAgIH0KICAgIHJldHVybiBuZXdfYnVmZmVyOwogIH0KICByZXR1cm4gdG1wX2J1ZmZlcjsKfQoKc3RhdGljIERXT1JEIERTT1VORF9NaXhJbkJ1ZmZlcihJRGlyZWN0U291bmRCdWZmZXJJbXBsICpkc2IsIERXT1JEIHdyaXRlcG9zLCBEV09SRCBmcmFnbGVuKQp7CglJTlQJaSwgbGVuLCBpbGVuLCB0ZW1wLCBmaWVsZDsKCUlOVAlhZHZhbmNlID0gcHJpbWFyeWJ1Zi0+d2Z4LndCaXRzUGVyU2FtcGxlID4+IDM7CglCWVRFCSpidWYsICppYnVmLCAqb2J1ZjsKCUlOVDE2CSppYnVmcywgKm9idWZzOwoKCWxlbiA9IGZyYWdsZW47CglpZiAoIShkc2ItPnBsYXlmbGFncyAmIERTQlBMQVlfTE9PUElORykpIHsKCQl0ZW1wID0gTXVsRGl2KHByaW1hcnlidWYtPndmeC5uQXZnQnl0ZXNQZXJTZWMsIGRzYi0+YnVmbGVuLAoJCQlkc2ItPm5BdmdCeXRlc1BlclNlYykgLQoJCSAgICAgICBNdWxEaXYocHJpbWFyeWJ1Zi0+d2Z4Lm5BdmdCeXRlc1BlclNlYywgZHNiLT5idWZfbWl4cG9zLAoJCQlkc2ItPm5BdmdCeXRlc1BlclNlYyk7CgkJbGVuID0gKGxlbiA+IHRlbXApID8gdGVtcCA6IGxlbjsKCX0KCWxlbiAmPSB+MzsJCQkJLyogNCBieXRlIGFsaWdubWVudCAqLwoKCWlmIChsZW4gPT0gMCkgewoJCS8qIFRoaXMgc2hvdWxkIG9ubHkgaGFwcGVuIGlmIHdlIGFyZW4ndCBsb29waW5nIGFuZCB0ZW1wIDwgNCAqLwoKCQkvKiBXZSBza2lwIHRoZSByZW1haW5kZXIsIHNvIGNoZWNrIGZvciBwb3NzaWJsZSBldmVudHMgKi8KCQlEU09VTkRfQ2hlY2tFdmVudChkc2IsIGRzYi0+YnVmbGVuIC0gZHNiLT5idWZfbWl4cG9zKTsKCQkvKiBTdG9wICovCgkJZHNiLT5zdGF0ZSA9IFNUQVRFX1NUT1BQRUQ7CgkJZHNiLT5wbGF5cG9zID0gMDsKCQlkc2ItPmJ1Zl9taXhwb3MgPSAwOwoJCWRzYi0+bGVhZGluID0gRkFMU0U7CgkJLyogQ2hlY2sgZm9yIERTQlBOX09GRlNFVFNUT1AgKi8KCQlEU09VTkRfQ2hlY2tFdmVudChkc2IsIDApOwoJCXJldHVybiAwOwoJfQoKCS8qIEJlZW4gc2VlaW5nIHNlZ2ZhdWx0cyBpbiBtYWxsb2MoKSBmb3Igc29tZSByZWFzb24uLi4gKi8KCVRSQUNFKCJhbGxvY2F0aW5nIGJ1ZmZlciAoc2l6ZSA9ICVkKVxuIiwgbGVuKTsKCWlmICgoYnVmID0gaWJ1ZiA9IChCWVRFICopIERTT1VORF90bXBidWZmZXIobGVuKSkgPT0gTlVMTCkKCQlyZXR1cm4gMDsKCglUUkFDRSgiTWl4SW5CdWZmZXIgKCVwKSBsZW4gPSAlZCwgZGVzdCA9ICVsZFxuIiwgZHNiLCBsZW4sIHdyaXRlcG9zKTsKCglpbGVuID0gRFNPVU5EX01peGVyTm9ybShkc2IsIGlidWYsIGxlbik7CglpZiAoKGRzYi0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19DVFJMUEFOKSB8fAoJICAgIChkc2ItPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfQ1RSTFZPTFVNRSkpCgkJRFNPVU5EX01peGVyVm9sKGRzYiwgaWJ1ZiwgbGVuKTsKCglvYnVmID0gcHJpbWFyeWJ1Zi0+YnVmZmVyICsgd3JpdGVwb3M7Cglmb3IgKGkgPSAwOyBpIDwgbGVuOyBpICs9IGFkdmFuY2UpIHsKCQlvYnVmcyA9IChJTlQxNiAqKSBvYnVmOwoJCWlidWZzID0gKElOVDE2ICopIGlidWY7CgkJaWYgKHByaW1hcnlidWYtPndmeC53Qml0c1BlclNhbXBsZSA9PSA4KSB7CgkJCS8qIDgtYml0IFdBViBpcyB1bnNpZ25lZCAqLwoJCQlmaWVsZCA9ICgqaWJ1ZiAtIDEyOCk7CgkJCWZpZWxkICs9ICgqb2J1ZiAtIDEyOCk7CgkJCWZpZWxkID0gZmllbGQgPiAxMjcgPyAxMjcgOiBmaWVsZDsKCQkJZmllbGQgPSBmaWVsZCA8IC0xMjggPyAtMTI4IDogZmllbGQ7CgkJCSpvYnVmID0gZmllbGQgKyAxMjg7CgkJfSBlbHNlIHsKCQkJLyogMTYtYml0IFdBViBpcyBzaWduZWQgKi8KCQkJZmllbGQgPSAqaWJ1ZnM7CgkJCWZpZWxkICs9ICpvYnVmczsKCQkJZmllbGQgPSBmaWVsZCA+IDMyNzY3ID8gMzI3NjcgOiBmaWVsZDsKCQkJZmllbGQgPSBmaWVsZCA8IC0zMjc2OCA/IC0zMjc2OCA6IGZpZWxkOwoJCQkqb2J1ZnMgPSBmaWVsZDsKCQl9CgkJaWJ1ZiArPSBhZHZhbmNlOwoJCW9idWYgKz0gYWR2YW5jZTsKCQlpZiAob2J1ZiA+PSAoQllURSAqKShwcmltYXJ5YnVmLT5idWZmZXIgKyBwcmltYXJ5YnVmLT5idWZsZW4pKQoJCQlvYnVmID0gcHJpbWFyeWJ1Zi0+YnVmZmVyOwoJfQoJLyogZnJlZShidWYpOyAqLwoKCWlmIChkc2ItPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfQ1RSTFBPU0lUSU9OTk9USUZZKQoJCURTT1VORF9DaGVja0V2ZW50KGRzYiwgaWxlbik7CgoJaWYgKGRzYi0+bGVhZGluICYmIChkc2ItPnN0YXJ0cG9zID4gZHNiLT5idWZfbWl4cG9zKSAmJiAoZHNiLT5zdGFydHBvcyA8PSBkc2ItPmJ1Zl9taXhwb3MgKyBpbGVuKSkgewoJCS8qIEhBQ0suLi4gbGVhZGluIHNob3VsZCBiZSByZXNldCB3aGVuIHRoZSBQTEFZIHBvc2l0aW9uIHJlYWNoZXMgdGhlIHN0YXJ0cG9zLAoJCSAqIG5vdCB0aGUgTUlYIHBvc2l0aW9uLi4uIGJ1dCBpZiB0aGUgc291bmQgYnVmZmVyIGlzIGJpZ2dlciB0aGFuIG91ciBwcmVidWZmZXJpbmcKCQkgKiAod2hpY2ggbXVzdCBiZSB0aGUgY2FzZSBmb3IgdGhlIHN0cmVhbWluZyBidWZmZXJzIHRoYXQgbmVlZCB0aGlzIGhhY2sgYW55d2F5KQoJCSAqIHBsdXMgRFNfSEVMX01BUkdJTiBvciBlcXVpdmFsZW50LCB0aGVuIHRoaXMgb3VnaHQgdG8gd29yayBhbnl3YXkuICovCgkJZHNiLT5sZWFkaW4gPSBGQUxTRTsKCX0KCglkc2ItPmJ1Zl9taXhwb3MgKz0gaWxlbjsKCQoJaWYgKGRzYi0+YnVmX21peHBvcyA+PSBkc2ItPmJ1ZmxlbikgewoJCWlmICghKGRzYi0+cGxheWZsYWdzICYgRFNCUExBWV9MT09QSU5HKSkgewoJCQlkc2ItPnN0YXRlID0gU1RBVEVfU1RPUFBFRDsKCQkJZHNiLT5wbGF5cG9zID0gMDsKCQkJZHNiLT5idWZfbWl4cG9zID0gMDsKCQkJZHNiLT5sZWFkaW4gPSBGQUxTRTsKCQkJRFNPVU5EX0NoZWNrRXZlbnQoZHNiLCAwKTsJCS8qIEZvciBEU0JQTl9PRkZTRVRTVE9QICovCgkJfSBlbHNlIHsKCQkJLyogd3JhcCAqLwoJCQl3aGlsZSAoZHNiLT5idWZfbWl4cG9zID49IGRzYi0+YnVmbGVuKQoJCQkJZHNiLT5idWZfbWl4cG9zIC09IGRzYi0+YnVmbGVuOwoJCQlpZiAoZHNiLT5sZWFkaW4gJiYgKGRzYi0+c3RhcnRwb3MgPD0gZHNiLT5idWZfbWl4cG9zKSkKCQkJCWRzYi0+bGVhZGluID0gRkFMU0U7IC8qIEhBQ0s6IHNlZSBhYm92ZSAqLwoJCX0KCX0KCglyZXR1cm4gbGVuOwp9CgpzdGF0aWMgdm9pZCBEU09VTkRfUGhhc2VDYW5jZWwoSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiLCBEV09SRCB3cml0ZXBvcywgRFdPUkQgbGVuKQp7CglJTlQgICAgIGksIGlsZW4sIGZpZWxkOwoJSU5UICAgICBhZHZhbmNlID0gcHJpbWFyeWJ1Zi0+d2Z4LndCaXRzUGVyU2FtcGxlID4+IDM7CglCWVRFCSpidWYsICppYnVmLCAqb2J1ZjsKCUlOVDE2CSppYnVmcywgKm9idWZzOwoKCWxlbiAmPSB+MzsJCQkJLyogNCBieXRlIGFsaWdubWVudCAqLwoKCVRSQUNFKCJhbGxvY2F0aW5nIGJ1ZmZlciAoc2l6ZSA9ICVsZClcbiIsIGxlbik7CglpZiAoKGJ1ZiA9IGlidWYgPSAoQllURSAqKSBEU09VTkRfdG1wYnVmZmVyKGxlbikpID09IE5VTEwpCgkJcmV0dXJuOwoKCVRSQUNFKCJQaGFzZUNhbmNlbCAoJXApIGxlbiA9ICVsZCwgZGVzdCA9ICVsZFxuIiwgZHNiLCBsZW4sIHdyaXRlcG9zKTsKCglpbGVuID0gRFNPVU5EX01peGVyTm9ybShkc2IsIGlidWYsIGxlbik7CglpZiAoKGRzYi0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19DVFJMUEFOKSB8fAoJICAgIChkc2ItPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfQ1RSTFZPTFVNRSkpCgkJRFNPVU5EX01peGVyVm9sKGRzYiwgaWJ1ZiwgbGVuKTsKCgkvKiBzdWJ0cmFjdCBpbnN0ZWFkIG9mIGFkZCwgdG8gcGhhc2Ugb3V0IHByZW1peGVkIGRhdGEgKi8KCW9idWYgPSBwcmltYXJ5YnVmLT5idWZmZXIgKyB3cml0ZXBvczsKCWZvciAoaSA9IDA7IGkgPCBsZW47IGkgKz0gYWR2YW5jZSkgewoJCW9idWZzID0gKElOVDE2ICopIG9idWY7CgkJaWJ1ZnMgPSAoSU5UMTYgKikgaWJ1ZjsKCQlpZiAocHJpbWFyeWJ1Zi0+d2Z4LndCaXRzUGVyU2FtcGxlID09IDgpIHsKCQkJLyogOC1iaXQgV0FWIGlzIHVuc2lnbmVkICovCgkJCWZpZWxkID0gKCppYnVmIC0gMTI4KTsKCQkJZmllbGQgLT0gKCpvYnVmIC0gMTI4KTsKCQkJZmllbGQgPSBmaWVsZCA+IDEyNyA/IDEyNyA6IGZpZWxkOwoJCQlmaWVsZCA9IGZpZWxkIDwgLTEyOCA/IC0xMjggOiBmaWVsZDsKCQkJKm9idWYgPSBmaWVsZCArIDEyODsKCQl9IGVsc2UgewoJCQkvKiAxNi1iaXQgV0FWIGlzIHNpZ25lZCAqLwoJCQlmaWVsZCA9ICppYnVmczsKCQkJZmllbGQgLT0gKm9idWZzOwoJCQlmaWVsZCA9IGZpZWxkID4gMzI3NjcgPyAzMjc2NyA6IGZpZWxkOwoJCQlmaWVsZCA9IGZpZWxkIDwgLTMyNzY4ID8gLTMyNzY4IDogZmllbGQ7CgkJCSpvYnVmcyA9IGZpZWxkOwoJCX0KCQlpYnVmICs9IGFkdmFuY2U7CgkJb2J1ZiArPSBhZHZhbmNlOwoJCWlmIChvYnVmID49IChCWVRFICopKHByaW1hcnlidWYtPmJ1ZmZlciArIHByaW1hcnlidWYtPmJ1ZmxlbikpCgkJCW9idWYgPSBwcmltYXJ5YnVmLT5idWZmZXI7Cgl9CgkvKiBmcmVlKGJ1Zik7ICovCn0KCnN0YXRpYyB2b2lkIERTT1VORF9NaXhDYW5jZWwoSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiLCBEV09SRCB3cml0ZXBvcywgQk9PTCBjYW5jZWwpCnsKCURXT1JEICAgc2l6ZSwgZmxlbiwgbGVuLCBucG9zLCBubGVuOwoJSU5UCWlBZHZhbmNlID0gZHNiLT53ZngubkJsb2NrQWxpZ247CglJTlQJb0FkdmFuY2UgPSBwcmltYXJ5YnVmLT53ZngubkJsb2NrQWxpZ247CgkvKiBkZXRlcm1pbmUgYW1vdW50IG9mIHByZW1peGVkIGRhdGEgdG8gY2FuY2VsICovCglEV09SRCBwcmltYXJ5X2RvbmUgPQoJCSgoZHNiLT5wcmltYXJ5X21peHBvcyA8IHdyaXRlcG9zKSA/IHByaW1hcnlidWYtPmJ1ZmxlbiA6IDApICsKCQlkc2ItPnByaW1hcnlfbWl4cG9zIC0gd3JpdGVwb3M7CgoJVFJBQ0UoIiglcCwgJWxkKSwgYnVmX21peHBvcz0lbGRcbiIsIGRzYiwgd3JpdGVwb3MsIGRzYi0+YnVmX21peHBvcyk7CgoJLyogYmFja3RyYWNrIHRoZSBtaXggcG9zaXRpb24gKi8KCXNpemUgPSBwcmltYXJ5X2RvbmUgLyBvQWR2YW5jZTsKCWZsZW4gPSBzaXplICogZHNiLT5mcmVxQWRqdXN0OwoJbGVuID0gKGZsZW4gPj4gRFNPVU5EX0ZSRVFTSElGVCkgKiBpQWR2YW5jZTsKCWZsZW4gJj0gKDE8PERTT1VORF9GUkVRU0hJRlQpLTE7Cgl3aGlsZSAoZHNiLT5mcmVxQWNjIDwgZmxlbikgewoJCWxlbiArPSBpQWR2YW5jZTsKCQlkc2ItPmZyZXFBY2MgKz0gMTw8RFNPVU5EX0ZSRVFTSElGVDsKCX0KCWxlbiAlPSBkc2ItPmJ1ZmxlbjsKCW5wb3MgPSAoKGRzYi0+YnVmX21peHBvcyA8IGxlbikgPyBkc2ItPmJ1ZmxlbiA6IDApICsKCQlkc2ItPmJ1Zl9taXhwb3MgLSBsZW47CglpZiAoZHNiLT5sZWFkaW4gJiYgKGRzYi0+c3RhcnRwb3MgPiBucG9zKSAmJiAoZHNiLT5zdGFydHBvcyA8PSBucG9zICsgbGVuKSkgewoJCS8qIHN0b3AgYmFja3RyYWNraW5nIGF0IHN0YXJ0cG9zICovCgkJbnBvcyA9IGRzYi0+c3RhcnRwb3M7CgkJbGVuID0gKChkc2ItPmJ1Zl9taXhwb3MgPCBucG9zKSA/IGRzYi0+YnVmbGVuIDogMCkgKwoJCQlkc2ItPmJ1Zl9taXhwb3MgLSBucG9zOwoJCWZsZW4gPSBkc2ItPmZyZXFBY2M7CgkJbmxlbiA9IGxlbiAvIGRzYi0+d2Z4Lm5CbG9ja0FsaWduOwoJCW5sZW4gPSAoKG5sZW4gPDwgRFNPVU5EX0ZSRVFTSElGVCkgKyBmbGVuKSAvIGRzYi0+ZnJlcUFkanVzdDsKCQlubGVuICo9IHByaW1hcnlidWYtPndmeC5uQmxvY2tBbGlnbjsKCQl3cml0ZXBvcyA9CgkJCSgoZHNiLT5wcmltYXJ5X21peHBvcyA8IG5sZW4pID8gcHJpbWFyeWJ1Zi0+YnVmbGVuIDogMCkgKwoJCQlkc2ItPnByaW1hcnlfbWl4cG9zIC0gbmxlbjsKCX0KCglkc2ItPmZyZXFBY2MgLT0gZmxlbjsKCWRzYi0+YnVmX21peHBvcyA9IG5wb3M7Cglkc2ItPnByaW1hcnlfbWl4cG9zID0gd3JpdGVwb3M7CgoJVFJBQ0UoIm5ldyBidWZfbWl4cG9zPSVsZCwgcHJpbWFyeV9taXhwb3M9JWxkIChsZW49JWxkKVxuIiwKCSAgICAgIGRzYi0+YnVmX21peHBvcywgZHNiLT5wcmltYXJ5X21peHBvcywgbGVuKTsKCglpZiAoY2FuY2VsKSBEU09VTkRfUGhhc2VDYW5jZWwoZHNiLCB3cml0ZXBvcywgbGVuKTsKfQoKc3RhdGljIHZvaWQgRFNPVU5EX01peENhbmNlbEF0KElEaXJlY3RTb3VuZEJ1ZmZlckltcGwgKmRzYiwgRFdPUkQgYnVmX3dyaXRlcG9zKQp7CiNpZiAwCglEV09SRCAgIGksIHNpemUsIGZsZW4sIGxlbiwgbnBvcywgbmxlbjsKCUlOVAlpQWR2YW5jZSA9IGRzYi0+d2Z4Lm5CbG9ja0FsaWduOwoJSU5UCW9BZHZhbmNlID0gcHJpbWFyeWJ1Zi0+d2Z4Lm5CbG9ja0FsaWduOwoJLyogZGV0ZXJtaW5lIGFtb3VudCBvZiBwcmVtaXhlZCBkYXRhIHRvIGNhbmNlbCAqLwoJRFdPUkQgYnVmX2RvbmUgPQoJCSgoZHNiLT5idWZfbWl4cG9zIDwgYnVmX3dyaXRlcG9zKSA/IGRzYi0+YnVmbGVuIDogMCkgKwoJCWRzYi0+YnVmX21peHBvcyAtIGJ1Zl93cml0ZXBvczsKI2VuZGlmCgoJV0FSTigiKCVwLCAlbGQpLCBidWZfbWl4cG9zPSVsZFxuIiwgZHNiLCBidWZfd3JpdGVwb3MsIGRzYi0+YnVmX21peHBvcyk7CgkvKiBzaW5jZSB0aGlzIGlzIG5vdCBpbXBsZW1lbnRlZCB5ZXQsIGp1c3QgY2FuY2VsICpBTEwqIHByZWJ1ZmZlcmluZyBmb3Igbm93CgkgKiAod2hpY2ggaXMgZmFzdGVyIGFueXdheSB3aGVuIHRoZXJlJ3Mgb25lIGEgc2luZ2xlIHNlY29uZGFyeSBidWZmZXIpICovCglwcmltYXJ5YnVmLT5uZWVkX3JlbWl4ID0gVFJVRTsKfQoKc3RhdGljIERXT1JEIERTT1VORF9NaXhPbmUoSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiLCBEV09SRCBwbGF5cG9zLCBEV09SRCB3cml0ZXBvcywgRFdPUkQgbWl4bGVuKQp7CglEV09SRCBsZW4sIHNsZW47CgkvKiBkZXRlcm1pbmUgdGhpcyBidWZmZXIncyB3cml0ZSBwb3NpdGlvbiAqLwoJRFdPUkQgYnVmX3dyaXRlcG9zID0gRFNPVU5EX0NhbGNQbGF5UG9zaXRpb24oZHNiLCBkc2ItPnN0YXRlICYgcHJpbWFyeWJ1Zi0+c3RhdGUsIHdyaXRlcG9zLAoJCQkJCQkgICAgIHdyaXRlcG9zLCBkc2ItPnByaW1hcnlfbWl4cG9zLCBkc2ItPmJ1Zl9taXhwb3MpOwoJLyogZGV0ZXJtaW5lIGhvdyBtdWNoIGFscmVhZHktbWl4ZWQgZGF0YSBleGlzdHMgKi8KCURXT1JEIGJ1Zl9kb25lID0KCQkoKGRzYi0+YnVmX21peHBvcyA8IGJ1Zl93cml0ZXBvcykgPyBkc2ItPmJ1ZmxlbiA6IDApICsKCQlkc2ItPmJ1Zl9taXhwb3MgLSBidWZfd3JpdGVwb3M7CglEV09SRCBwcmltYXJ5X2RvbmUgPQoJCSgoZHNiLT5wcmltYXJ5X21peHBvcyA8IHdyaXRlcG9zKSA/IHByaW1hcnlidWYtPmJ1ZmxlbiA6IDApICsKCQlkc2ItPnByaW1hcnlfbWl4cG9zIC0gd3JpdGVwb3M7CglEV09SRCBhZHZfZG9uZSA9CgkJKChwcmltYXJ5YnVmLT5idWZfbWl4cG9zIDwgd3JpdGVwb3MpID8gcHJpbWFyeWJ1Zi0+YnVmbGVuIDogMCkgKwoJCXByaW1hcnlidWYtPmJ1Zl9taXhwb3MgLSB3cml0ZXBvczsKCWludCBzdGlsbF9iZWhpbmQ7CgoJVFJBQ0UoImJ1Zl93cml0ZXBvcz0lbGQsIHByaW1hcnlfd3JpdGVwb3M9JWxkXG4iLCBidWZfd3JpdGVwb3MsIHdyaXRlcG9zKTsKCVRSQUNFKCJidWZfZG9uZT0lbGQsIHByaW1hcnlfZG9uZT0lbGRcbiIsIGJ1Zl9kb25lLCBwcmltYXJ5X2RvbmUpOwoJVFJBQ0UoImJ1Zl9taXhwb3M9JWxkLCBwcmltYXJ5X21peHBvcz0lbGQsIG1peGxlbj0lbGRcbiIsIGRzYi0+YnVmX21peHBvcywgZHNiLT5wcmltYXJ5X21peHBvcywKCSAgICAgIG1peGxlbik7CglUUkFDRSgibG9vcGluZz0lbGQsIHN0YXJ0cG9zPSVsZCwgbGVhZGluPSVsZFxuIiwgZHNiLT5wbGF5ZmxhZ3MsIGRzYi0+c3RhcnRwb3MsIGRzYi0+bGVhZGluKTsKCgkvKiBzYXZlIHdyaXRlIHBvc2l0aW9uIGZvciBub24tR0VUQ1VSUkVOVFBPU0lUSU9OMi4uLiAqLwoJZHNiLT5wbGF5cG9zID0gYnVmX3dyaXRlcG9zOwoKCS8qIGNoZWNrIHdoZXRoZXIgQ2FsY1BsYXlQb3NpdGlvbiBkZXRlY3RlZCBhIG1peGluZyB1bmRlcnJ1biAqLwoJaWYgKChidWZfZG9uZSA9PSAwKSAmJiAoZHNiLT5wcmltYXJ5X21peHBvcyAhPSB3cml0ZXBvcykpIHsKCQkvKiBpdCBkaWQsIGJ1dCBkaWQgd2UgaGF2ZSBtb3JlIHRvIHBsYXk/ICovCgkJaWYgKChkc2ItPnBsYXlmbGFncyAmIERTQlBMQVlfTE9PUElORykgfHwKCQkgICAgKGRzYi0+YnVmX21peHBvcyA8IGRzYi0+YnVmbGVuKSkgewoJCQkvKiB5ZXMsIGhhdmUgdG8gcmVjb3ZlciAqLwoJCQlFUlIoInVuZGVycnVuIG9uIHNvdW5kIGJ1ZmZlciAlcFxuIiwgZHNiKTsKCQkJVFJBQ0UoInJlY292ZXJpbmcgZnJvbSB1bmRlcnJ1bjogcHJpbWFyeV9taXhwb3M9JWxkXG4iLCB3cml0ZXBvcyk7CgkJfQoJCWRzYi0+cHJpbWFyeV9taXhwb3MgPSB3cml0ZXBvczsKCQlwcmltYXJ5X2RvbmUgPSAwOwoJfQoJLyogZGV0ZXJtaW5lIGhvdyBmYXIgYWhlYWQgd2Ugc2hvdWxkIG1peCAqLwoJaWYgKCgoZHNiLT5wbGF5ZmxhZ3MgJiBEU0JQTEFZX0xPT1BJTkcpIHx8CgkgICAgIChkc2ItPmxlYWRpbiAmJiAoZHNiLT5wcm9iYWJseV92YWxpZF90byAhPSAwKSkpICYmCgkgICAgIShkc2ItPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfU1RBVElDKSkgewoJCS8qIGlmIHRoaXMgaXMgYSBzdHJlYW1pbmcgYnVmZmVyLCBpdCB0eXBpY2FsbHkgbWVhbnMgdGhhdAoJCSAqIHdlIHNob3VsZCBkZWZlciBtaXhpbmcgcGFzdCBwcm9iYWJseV92YWxpZF90byBhcyBsb25nCgkJICogYXMgd2UgY2FuLCB0byBhdm9pZCB1bm5lY2Vzc2FyeSByZW1peGluZyAqLwoJCS8qIHRoZSBoZWF2eS1sb29raW5nIGNhbGN1bGF0aW9ucyBzaG91bGRuJ3QgYmUgdGhhdCBiYWQsCgkJICogYXMgYW55IGdhbWUgaXNuJ3QgbGlrZWx5IHRvIGJlIGhhdmUgbW9yZSB0aGFuIDEgb3IgMgoJCSAqIHN0cmVhbWluZyBidWZmZXJzIGluIHVzZSBhdCBhbnkgdGltZSBhbnl3YXkuLi4gKi8KCQlEV09SRCBwcm9iYWJseV92YWxpZF9sZWZ0ID0KCQkJKGRzYi0+cHJvYmFibHlfdmFsaWRfdG8gPT0gKERXT1JEKS0xKSA/IGRzYi0+YnVmbGVuIDoKCQkJKChkc2ItPnByb2JhYmx5X3ZhbGlkX3RvIDwgYnVmX3dyaXRlcG9zKSA/IGRzYi0+YnVmbGVuIDogMCkgKwoJCQlkc2ItPnByb2JhYmx5X3ZhbGlkX3RvIC0gYnVmX3dyaXRlcG9zOwoJCS8qIGNoZWNrIGZvciBsZWFkaW4gY29uZGl0aW9uICovCgkJaWYgKChwcm9iYWJseV92YWxpZF9sZWZ0ID09IDApICYmCgkJICAgIChkc2ItPnByb2JhYmx5X3ZhbGlkX3RvID09IGRzYi0+c3RhcnRwb3MpICYmCgkJICAgIGRzYi0+bGVhZGluKQoJCQlwcm9iYWJseV92YWxpZF9sZWZ0ID0gZHNiLT5idWZsZW47CgkJVFJBQ0UoInN0cmVhbWluZyBidWZmZXIgcHJvYmFibHlfdmFsaWRfdG89JWxkLCBwcm9iYWJseV92YWxpZF9sZWZ0PSVsZFxuIiwKCQkgICAgICBkc2ItPnByb2JhYmx5X3ZhbGlkX3RvLCBwcm9iYWJseV92YWxpZF9sZWZ0KTsKCQkvKiBjaGVjayB3aGV0aGVyIHRoZSBhcHAncyB0aW1lIGlzIGFscmVhZHkgdXAgKi8KCQlpZiAocHJvYmFibHlfdmFsaWRfbGVmdCA8IGRzYi0+d3JpdGVsZWFkKSB7CgkJCVdBUk4oInByb2JhYmx5X3ZhbGlkX3RvIG5vdyB3aXRoaW4gd3JpdGVsZWFkLCBwb3NzaWJsZSBzdHJlYW1pbmcgdW5kZXJydW5cbiIpOwoJCQkvKiBvbmNlIHdlIHBhc3MgdGhlIHBvaW50IG9mIG5vIHJldHVybiwKCQkJICogbm8gcmVhc29uIHRvIGhvbGQgYmFjayBhbnltb3JlICovCgkJCWRzYi0+cHJvYmFibHlfdmFsaWRfdG8gPSAoRFdPUkQpLTE7CgkJCS8qIHdlIGp1c3QgaGF2ZSB0byBnbyBhaGVhZCBhbmQgbWl4IHdoYXQgd2UgaGF2ZSwKCQkJICogdGhlcmUncyBubyB0ZWxsaW5nIHdoYXQgdGhlIGFwcCBpcyB0aGlua2luZyBhbnl3YXkgKi8KCQl9IGVsc2UgewoJCQkvKiBhZGp1c3QgZm9yIG91ciBmcmVxdWVuY3kgYW5kIG91ciBzYW1wbGUgc2l6ZSAqLwoJCQlwcm9iYWJseV92YWxpZF9sZWZ0ID0gTXVsRGl2KHByb2JhYmx5X3ZhbGlkX2xlZnQsCgkJCQkJCSAgICAgMSA8PCBEU09VTkRfRlJFUVNISUZULAoJCQkJCQkgICAgIGRzYi0+d2Z4Lm5CbG9ja0FsaWduICogZHNiLT5mcmVxQWRqdXN0KSAqCgkJCQkgICAgICAgICAgICAgIHByaW1hcnlidWYtPndmeC5uQmxvY2tBbGlnbjsKCQkJLyogY2hlY2sgd2hldGhlciB0byBjbGlwIG1peF9sZW4gKi8KCQkJaWYgKHByb2JhYmx5X3ZhbGlkX2xlZnQgPCBtaXhsZW4pIHsKCQkJCVRSQUNFKCJjbGlwcGluZyB0byBwcm9iYWJseV92YWxpZF9sZWZ0PSVsZFxuIiwgcHJvYmFibHlfdmFsaWRfbGVmdCk7CgkJCQltaXhsZW4gPSBwcm9iYWJseV92YWxpZF9sZWZ0OwoJCQl9CgkJfQoJfQoJLyogY3V0IG1peGxlbiB3aXRoIHdoYXQncyBhbHJlYWR5IGJlZW4gbWl4ZWQgKi8KCWlmIChtaXhsZW4gPCBwcmltYXJ5X2RvbmUpIHsKCQkvKiBodWg/IGFuZCBzdGlsbCBDYWxjUGxheVBvc2l0aW9uIGRpZG4ndAoJCSAqIGRldGVjdCBhbiB1bmRlcnJ1bj8gKi8KCQlGSVhNRSgicHJvYmxlbSB3aXRoIHVuZGVycnVuIGRldGVjdGlvbiAobWl4bGVuPSVsZCA8IHByaW1hcnlfZG9uZT0lbGQpXG4iLCBtaXhsZW4sIHByaW1hcnlfZG9uZSk7CgkJcmV0dXJuIDA7Cgl9CglsZW4gPSBtaXhsZW4gLSBwcmltYXJ5X2RvbmU7CglUUkFDRSgicmVtYWluaW5nIG1peGxlbj0lbGRcbiIsIGxlbik7CgoJaWYgKGxlbiA8IHByaW1hcnlidWYtPmRzb3VuZC0+ZnJhZ2xlbikgewoJCS8qIHNtYWxsZXIgdGhhbiBhIGZyYWdtZW50LCB3YWl0IHVudGlsIGl0IGdldHMgbGFyZ2VyCgkJICogYmVmb3JlIHdlIHRha2UgdGhlIG1peGluZyBvdmVyaGVhZCAqLwoJCVRSQUNFKCJtaXhsZW4gbm90IHdvcnRoIGl0LCBkZWZlcnJpbmcgbWl4aW5nXG4iKTsKCQlyZXR1cm4gMDsKCX0KCgkvKiBvaywgd2Uga25vdyBob3cgbXVjaCB0byBtaXgsIGxldCdzIGdvICovCglzdGlsbF9iZWhpbmQgPSAoYWR2X2RvbmUgPiBwcmltYXJ5X2RvbmUpOwoJd2hpbGUgKGxlbikgewoJCXNsZW4gPSBwcmltYXJ5YnVmLT5idWZsZW4gLSBkc2ItPnByaW1hcnlfbWl4cG9zOwoJCWlmIChzbGVuID4gbGVuKSBzbGVuID0gbGVuOwoJCXNsZW4gPSBEU09VTkRfTWl4SW5CdWZmZXIoZHNiLCBkc2ItPnByaW1hcnlfbWl4cG9zLCBzbGVuKTsKCgkJaWYgKChkc2ItPnByaW1hcnlfbWl4cG9zIDwgcHJpbWFyeWJ1Zi0+YnVmX21peHBvcykgJiYKCQkgICAgKGRzYi0+cHJpbWFyeV9taXhwb3MgKyBzbGVuID49IHByaW1hcnlidWYtPmJ1Zl9taXhwb3MpKQoJCQlzdGlsbF9iZWhpbmQgPSBGQUxTRTsKCgkJZHNiLT5wcmltYXJ5X21peHBvcyArPSBzbGVuOyBsZW4gLT0gc2xlbjsKCQl3aGlsZSAoZHNiLT5wcmltYXJ5X21peHBvcyA+PSBwcmltYXJ5YnVmLT5idWZsZW4pCgkJCWRzYi0+cHJpbWFyeV9taXhwb3MgLT0gcHJpbWFyeWJ1Zi0+YnVmbGVuOwoKCQlpZiAoKGRzYi0+c3RhdGUgPT0gU1RBVEVfU1RPUFBFRCkgfHwgIXNsZW4pIGJyZWFrOwoJfQoJVFJBQ0UoIm5ldyBwcmltYXJ5X21peHBvcz0lbGQsIHByaW1hcnlfYWR2YmFzZT0lbGRcbiIsIGRzYi0+cHJpbWFyeV9taXhwb3MsIHByaW1hcnlidWYtPmJ1Zl9taXhwb3MpOwoJVFJBQ0UoIm1peGVkIGRhdGEgbGVuPSVsZCwgc3RpbGxfYmVoaW5kPSVkXG4iLCBtaXhsZW4tbGVuLCBzdGlsbF9iZWhpbmQpOwoJLyogcmV0dXJuIGhvdyBmYXIgd2UgdGhpbmsgdGhlIHByaW1hcnkgYnVmZmVyIGNhbgoJICogYWR2YW5jZSBpdHMgdW5kZXJydW4gZGV0ZWN0b3IuLi4qLwoJaWYgKHN0aWxsX2JlaGluZCkgcmV0dXJuIDA7CglpZiAoKG1peGxlbiAtIGxlbikgPCBwcmltYXJ5X2RvbmUpIHJldHVybiAwOwoJc2xlbiA9ICgoZHNiLT5wcmltYXJ5X21peHBvcyA8IHByaW1hcnlidWYtPmJ1Zl9taXhwb3MpID8KCQlwcmltYXJ5YnVmLT5idWZsZW4gOiAwKSArIGRzYi0+cHJpbWFyeV9taXhwb3MgLQoJCXByaW1hcnlidWYtPmJ1Zl9taXhwb3M7CglpZiAoc2xlbiA+IG1peGxlbikgewoJCS8qIHRoZSBwcmltYXJ5X2RvbmUgYW5kIHN0aWxsX2JlaGluZCBjaGVja3MgYWJvdmUgc2hvdWxkIGhhdmUgd29ya2VkICovCgkJRklYTUUoInByb2JsZW0gd2l0aCBhZHZhbmNlbWVudCBjYWxjdWxhdGlvbiAoYWR2bGVuPSVsZCA+IG1peGxlbj0lbGQpXG4iLCBzbGVuLCBtaXhsZW4pOwoJCXNsZW4gPSAwOwoJfQoJcmV0dXJuIHNsZW47Cn0KCnN0YXRpYyBEV09SRCBEU09VTkRfTWl4VG9QcmltYXJ5KERXT1JEIHBsYXlwb3MsIERXT1JEIHdyaXRlcG9zLCBEV09SRCBtaXhsZW4sIEJPT0wgcmVjb3ZlcikKewoJSU5UCQkJaSwgbGVuLCBtYXhsZW4gPSAwOwoJSURpcmVjdFNvdW5kQnVmZmVySW1wbAkqZHNiOwoKCVRSQUNFKCIoJWxkLCVsZCwlbGQpXG4iLCBwbGF5cG9zLCB3cml0ZXBvcywgbWl4bGVuKTsKCWZvciAoaSA9IGRzb3VuZC0+bnJvZmJ1ZmZlcnMgLSAxOyBpID49IDA7IGktLSkgewoJCWRzYiA9IGRzb3VuZC0+YnVmZmVyc1tpXTsKCgkJaWYgKCFkc2IgfHwgIShJQ09NX1ZUQkwoZHNiKSkpCgkJCWNvbnRpbnVlOwoJCWlmIChkc2ItPmJ1ZmxlbiAmJiBkc2ItPnN0YXRlICYmICFkc2ItPmh3YnVmKSB7CgkJCVRSQUNFKCJDaGVja2luZyAlcCwgbWl4bGVuPSVsZFxuIiwgZHNiLCBtaXhsZW4pOwoJCQlFbnRlckNyaXRpY2FsU2VjdGlvbigmKGRzYi0+bG9jaykpOwoJCQlpZiAoZHNiLT5zdGF0ZSA9PSBTVEFURV9TVE9QUElORykgewoJCQkJRFNPVU5EX01peENhbmNlbChkc2IsIHdyaXRlcG9zLCBUUlVFKTsKCQkJCWRzYi0+c3RhdGUgPSBTVEFURV9TVE9QUEVEOwoJCQl9IGVsc2UgewoJCQkJaWYgKChkc2ItPnN0YXRlID09IFNUQVRFX1NUQVJUSU5HKSB8fCByZWNvdmVyKQoJCQkJCWRzYi0+cHJpbWFyeV9taXhwb3MgPSB3cml0ZXBvczsKCQkJCWxlbiA9IERTT1VORF9NaXhPbmUoZHNiLCBwbGF5cG9zLCB3cml0ZXBvcywgbWl4bGVuKTsKCQkJCWlmIChkc2ItPnN0YXRlID09IFNUQVRFX1NUQVJUSU5HKQoJCQkJCWRzYi0+c3RhdGUgPSBTVEFURV9QTEFZSU5HOwoJCQkJbWF4bGVuID0gKGxlbiA+IG1heGxlbikgPyBsZW4gOiBtYXhsZW47CgkJCX0KCQkJTGVhdmVDcml0aWNhbFNlY3Rpb24oJihkc2ItPmxvY2spKTsKCQl9Cgl9CgkKCXJldHVybiBtYXhsZW47Cn0KCnN0YXRpYyB2b2lkIERTT1VORF9NaXhSZXNldChEV09SRCB3cml0ZXBvcykKewoJSU5UCQkJaTsKCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGwJKmRzYjsKCWludCBuZmlsbGVyOwoKCVRSQUNFKCIoJWxkKVxuIiwgd3JpdGVwb3MpOwoKCS8qIHRoZSBzb3VuZCBvZiBzaWxlbmNlICovCgluZmlsbGVyID0gcHJpbWFyeWJ1Zi0+d2Z4LndCaXRzUGVyU2FtcGxlID09IDggPyAxMjggOiAwOwoKCS8qIHJlc2V0IGFsbCBidWZmZXIgbWl4IHBvc2l0aW9ucyAqLwoJZm9yIChpID0gZHNvdW5kLT5ucm9mYnVmZmVycyAtIDE7IGkgPj0gMDsgaS0tKSB7CgkJZHNiID0gZHNvdW5kLT5idWZmZXJzW2ldOwoKCQlpZiAoIWRzYiB8fCAhKElDT01fVlRCTChkc2IpKSkKCQkJY29udGludWU7CgkJaWYgKGRzYi0+YnVmbGVuICYmIGRzYi0+c3RhdGUgJiYgIWRzYi0+aHdidWYpIHsKCQkJVFJBQ0UoIlJlc2V0dGluZyAlcFxuIiwgZHNiKTsKCQkJRW50ZXJDcml0aWNhbFNlY3Rpb24oJihkc2ItPmxvY2spKTsKCQkJaWYgKGRzYi0+c3RhdGUgPT0gU1RBVEVfU1RPUFBJTkcpIHsKCQkJCWRzYi0+c3RhdGUgPSBTVEFURV9TVE9QUEVEOwoJCQl9CgkJCWVsc2UgaWYgKGRzYi0+c3RhdGUgPT0gU1RBVEVfU1RBUlRJTkcpIHsKCQkJCS8qIG5vdGhpbmcgKi8KCQkJfSBlbHNlIHsKCQkJCURTT1VORF9NaXhDYW5jZWwoZHNiLCB3cml0ZXBvcywgRkFMU0UpOwoJCQl9CgkJCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCYoZHNiLT5sb2NrKSk7CgkJfQoJfQoKCS8qIHdpcGUgb3V0IHByZW1peGVkIGRhdGEgKi8KCWlmIChwcmltYXJ5YnVmLT5idWZfbWl4cG9zIDwgd3JpdGVwb3MpIHsKCQltZW1zZXQocHJpbWFyeWJ1Zi0+YnVmZmVyICsgd3JpdGVwb3MsIG5maWxsZXIsIHByaW1hcnlidWYtPmJ1ZmxlbiAtIHdyaXRlcG9zKTsKCQltZW1zZXQocHJpbWFyeWJ1Zi0+YnVmZmVyLCBuZmlsbGVyLCBwcmltYXJ5YnVmLT5idWZfbWl4cG9zKTsKCX0gZWxzZSB7CgkJbWVtc2V0KHByaW1hcnlidWYtPmJ1ZmZlciArIHdyaXRlcG9zLCBuZmlsbGVyLCBwcmltYXJ5YnVmLT5idWZfbWl4cG9zIC0gd3JpdGVwb3MpOwoJfQoKCS8qIHJlc2V0IHByaW1hcnkgbWl4IHBvc2l0aW9uICovCglwcmltYXJ5YnVmLT5idWZfbWl4cG9zID0gd3JpdGVwb3M7Cn0KCnN0YXRpYyB2b2lkIERTT1VORF9DaGVja1Jlc2V0KElEaXJlY3RTb3VuZEltcGwgKmRzb3VuZCwgRFdPUkQgd3JpdGVwb3MpCnsKCWlmIChwcmltYXJ5YnVmLT5uZWVkX3JlbWl4KSB7CgkJRFNPVU5EX01peFJlc2V0KHdyaXRlcG9zKTsKCQlwcmltYXJ5YnVmLT5uZWVkX3JlbWl4ID0gRkFMU0U7CgkJLyogbWF4aW1pemUgSGFsZi1MaWZlIHBlcmZvcm1hbmNlICovCgkJZHNvdW5kLT5wcmVidWYgPSBEU19TTkRfUVVFVUVfTUlOOwoJfSBlbHNlIHsKCQkvKiBpZiAoZHNvdW5kLT5wcmVidWYgPCBEU19TTkRfUVVFVUVfTUFYKSBkc291bmQtPnByZWJ1ZisrOyAqLwoJfQoJVFJBQ0UoInByZW1peCBhZGp1c3Q6ICVkXG4iLCBkc291bmQtPnByZWJ1Zik7Cn0KCnN0YXRpYyB2b2lkIERTT1VORF9XYXZlUXVldWUoSURpcmVjdFNvdW5kSW1wbCAqZHNvdW5kLCBEV09SRCBtaXhxKQp7CglpZiAobWl4cSArIGRzb3VuZC0+cHdxdWV1ZSA+IERTX0hFTF9RVUVVRSkgbWl4cSA9IERTX0hFTF9RVUVVRSAtIGRzb3VuZC0+cHdxdWV1ZTsKCVRSQUNFKCJxdWV1ZWluZyAlbGQgYnVmZmVycywgc3RhcnRpbmcgYXQgJWRcbiIsIG1peHEsIGRzb3VuZC0+cHd3cml0ZSk7Cglmb3IgKDsgbWl4cTsgbWl4cS0tKSB7CgkJd2F2ZU91dFdyaXRlKGRzb3VuZC0+aHdvLCBkc291bmQtPnB3YXZlW2Rzb3VuZC0+cHd3cml0ZV0sIHNpemVvZihXQVZFSERSKSk7CgkJZHNvdW5kLT5wd3dyaXRlKys7CgkJaWYgKGRzb3VuZC0+cHd3cml0ZSA+PSBEU19IRUxfRlJBR1MpIGRzb3VuZC0+cHd3cml0ZSA9IDA7CgkJZHNvdW5kLT5wd3F1ZXVlKys7Cgl9Cn0KCi8qICNkZWZpbmUgU1lOQ19DQUxMQkFDSyAqLwoKc3RhdGljIHZvaWQgRFNPVU5EX1BlcmZvcm1NaXgodm9pZCkKewoJaW50IG5maWxsZXI7CglCT09MIGZvcmNlZDsKCUhSRVNVTFQgaHJlczsKCglFbnRlckNyaXRpY2FsU2VjdGlvbigmKGRzb3VuZC0+bG9jaykpOwoKCWlmICghcHJpbWFyeWJ1ZiB8fCAhcHJpbWFyeWJ1Zi0+cmVmKSB7CgkJLyogc2VlbXMgdGhlIHByaW1hcnkgYnVmZmVyIGlzIGN1cnJlbnRseSBiZWluZyByZWxlYXNlZCAqLwoJCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCYoZHNvdW5kLT5sb2NrKSk7CgkJcmV0dXJuOwoJfQoKCS8qIHRoZSBzb3VuZCBvZiBzaWxlbmNlICovCgluZmlsbGVyID0gcHJpbWFyeWJ1Zi0+d2Z4LndCaXRzUGVyU2FtcGxlID09IDggPyAxMjggOiAwOwoKCS8qIHdoZXRoZXIgdGhlIHByaW1hcnkgaXMgZm9yY2VkIHRvIHBsYXkgZXZlbiB3aXRob3V0IHNlY29uZGFyeSBidWZmZXJzICovCglmb3JjZWQgPSAoKHByaW1hcnlidWYtPnN0YXRlID09IFNUQVRFX1BMQVlJTkcpIHx8IChwcmltYXJ5YnVmLT5zdGF0ZSA9PSBTVEFURV9TVEFSVElORykpOwoKICAgICAgICBUUkFDRSgiZW50ZXJpbmcgYXQgJWxkXG4iLCBHZXRUaWNrQ291bnQoKSk7CglpZiAoZHNvdW5kLT5wcmlvbGV2ZWwgIT0gRFNTQ0xfV1JJVEVQUklNQVJZKSB7CgkJQk9PTCBwYXVzZWQgPSAoKHByaW1hcnlidWYtPnN0YXRlID09IFNUQVRFX1NUT1BQRUQpIHx8IChwcmltYXJ5YnVmLT5zdGF0ZSA9PSBTVEFURV9TVEFSVElORykpOwoJCS8qIEZJWE1FOiBkb2N1bWVudCB2YXJpYWJsZXMgKi8KIAkJRFdPUkQgcGxheXBvcywgd3JpdGVwb3MsIGlucSwgbWF4cSwgZnJhZzsKIAkJaWYgKHByaW1hcnlidWYtPmh3YnVmKSB7CgkJCWhyZXMgPSBJRHNEcml2ZXJCdWZmZXJfR2V0UG9zaXRpb24ocHJpbWFyeWJ1Zi0+aHdidWYsICZwbGF5cG9zLCAmd3JpdGVwb3MpOwoJCQlpZiAoaHJlcykgewoJCQkgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJihkc291bmQtPmxvY2spKTsKCQkJICAgIHJldHVybjsKCQkJfQoJCQkvKiBXZWxsLCB3ZSAqY291bGQqIGRvIEp1c3QtSW4tVGltZSBtaXhpbmcgdXNpbmcgdGhlIHdyaXRlcG9zLAoJCQkgKiBidXQgdGhhdCdzIGEgbGl0dGxlIGJpdCBhbWJpdGlvdXMgYW5kIHVubmVjZXNzYXJ5Li4uICovCgkJCS8qIHJhdGhlciBhZGQgb3VyIHNhZmV0eSBtYXJnaW4gdG8gdGhlIHdyaXRlcG9zLCBpZiB3ZSdyZSBwbGF5aW5nICovCgkJCWlmICghcGF1c2VkKSB7CgkJCQl3cml0ZXBvcyArPSBwcmltYXJ5YnVmLT53cml0ZWxlYWQ7CgkJCQl3aGlsZSAod3JpdGVwb3MgPj0gcHJpbWFyeWJ1Zi0+YnVmbGVuKQoJCQkJCXdyaXRlcG9zIC09IHByaW1hcnlidWYtPmJ1ZmxlbjsKCQkJfSBlbHNlIHdyaXRlcG9zID0gcGxheXBvczsKCQl9CgkJZWxzZSB7CiAJCQlwbGF5cG9zID0gZHNvdW5kLT5wd3BsYXkgKiBkc291bmQtPmZyYWdsZW47CiAJCQl3cml0ZXBvcyA9IHBsYXlwb3M7CiAJCQlpZiAoIXBhdXNlZCkgewoJIAkJCXdyaXRlcG9zICs9IERTX0hFTF9NQVJHSU4gKiBkc291bmQtPmZyYWdsZW47CgkgCQkJd2hpbGUgKHdyaXRlcG9zID49IHByaW1hcnlidWYtPmJ1ZmxlbikKIAkJCQkJd3JpdGVwb3MgLT0gcHJpbWFyeWJ1Zi0+YnVmbGVuOwoJIAkJfQoJCX0KCQlUUkFDRSgicHJpbWFyeSBwbGF5cG9zPSVsZCwgd3JpdGVwb3M9JWxkLCBjbHJwb3M9JWxkLCBtaXhwb3M9JWxkXG4iLAoJCSAgICAgIHBsYXlwb3Msd3JpdGVwb3MscHJpbWFyeWJ1Zi0+cGxheXBvcyxwcmltYXJ5YnVmLT5idWZfbWl4cG9zKTsKCQkvKiB3aXBlIG91dCBqdXN0LXBsYXllZCBzb3VuZCBkYXRhICovCgkJaWYgKHBsYXlwb3MgPCBwcmltYXJ5YnVmLT5wbGF5cG9zKSB7CgkJCW1lbXNldChwcmltYXJ5YnVmLT5idWZmZXIgKyBwcmltYXJ5YnVmLT5wbGF5cG9zLCBuZmlsbGVyLCBwcmltYXJ5YnVmLT5idWZsZW4gLSBwcmltYXJ5YnVmLT5wbGF5cG9zKTsKCQkJbWVtc2V0KHByaW1hcnlidWYtPmJ1ZmZlciwgbmZpbGxlciwgcGxheXBvcyk7CgkJfSBlbHNlIHsKCQkJbWVtc2V0KHByaW1hcnlidWYtPmJ1ZmZlciArIHByaW1hcnlidWYtPnBsYXlwb3MsIG5maWxsZXIsIHBsYXlwb3MgLSBwcmltYXJ5YnVmLT5wbGF5cG9zKTsKCQl9CgkJcHJpbWFyeWJ1Zi0+cGxheXBvcyA9IHBsYXlwb3M7CgoJCUVudGVyQ3JpdGljYWxTZWN0aW9uKCYocHJpbWFyeWJ1Zi0+bG9jaykpOwoKCQkvKiByZXNldCBtaXhpbmcgaWYgbmVjZXNzYXJ5ICovCgkJRFNPVU5EX0NoZWNrUmVzZXQoZHNvdW5kLCB3cml0ZXBvcyk7CgoJCS8qIGNoZWNrIGhvdyBtdWNoIHByZWJ1ZmZlcmluZyBpcyBsZWZ0ICovCgkJaW5xID0gcHJpbWFyeWJ1Zi0+YnVmX21peHBvczsKCQlpZiAoaW5xIDwgd3JpdGVwb3MpCgkJCWlucSArPSBwcmltYXJ5YnVmLT5idWZsZW47CgkJaW5xIC09IHdyaXRlcG9zOwoKCQkvKiBmaW5kIHRoZSBtYXhpbXVtIHdlIGNhbiBwcmVidWZmZXIgKi8KCQlpZiAoIXBhdXNlZCkgewoJCQltYXhxID0gcGxheXBvczsKCQkJaWYgKG1heHEgPCB3cml0ZXBvcykKCQkJCW1heHEgKz0gcHJpbWFyeWJ1Zi0+YnVmbGVuOwoJCQltYXhxIC09IHdyaXRlcG9zOwoJCX0gZWxzZSBtYXhxID0gcHJpbWFyeWJ1Zi0+YnVmbGVuOwoKCQkvKiBjbGlwIG1heHEgdG8gZHNvdW5kLT5wcmVidWYgKi8KCQlmcmFnID0gZHNvdW5kLT5wcmVidWYgKiBkc291bmQtPmZyYWdsZW47CgkJaWYgKG1heHEgPiBmcmFnKSBtYXhxID0gZnJhZzsKCgkJLyogY2hlY2sgZm9yIGNvbnNpc3RlbmN5ICovCgkJaWYgKGlucSA+IG1heHEpIHsKCQkJLyogdGhlIHBsYXliYWNrIHBvc2l0aW9uIG11c3QgaGF2ZSBwYXNzZWQgb3VyIGxhc3QKCQkJICogbWl4ZWQgcG9zaXRpb24sIGkuZS4gaXQncyBhbiB1bmRlcnJ1biwgb3Igd2UgaGF2ZQoJCQkgKiBub3RoaW5nIG1vcmUgdG8gcGxheSAqLwoJCQlUUkFDRSgicmVhY2hlZCBlbmQgb2YgbWl4ZWQgZGF0YSAoaW5xPSVsZCwgbWF4cT0lbGQpXG4iLCBpbnEsIG1heHEpOwoJCQlpbnEgPSAwOwoJCQkvKiBzdG9wIHRoZSBwbGF5YmFjayBub3csIHRvIGFsbG93IGJ1ZmZlcnMgdG8gcmVmaWxsICovCgkJCWlmIChwcmltYXJ5YnVmLT5zdGF0ZSA9PSBTVEFURV9QTEFZSU5HKSB7CgkJCQlwcmltYXJ5YnVmLT5zdGF0ZSA9IFNUQVRFX1NUQVJUSU5HOwoJCQl9CgkJCWVsc2UgaWYgKHByaW1hcnlidWYtPnN0YXRlID09IFNUQVRFX1NUT1BQSU5HKSB7CgkJCQlwcmltYXJ5YnVmLT5zdGF0ZSA9IFNUQVRFX1NUT1BQRUQ7CgkJCX0KCQkJZWxzZSB7CgkJCQkvKiBob3cgY2FuIHdlIGhhdmUgYW4gdW5kZXJydW4gaWYgd2UgYXJlbid0IHBsYXlpbmc/ICovCgkJCQlXQVJOKCJ1bmV4cGVjdGVkIHByaW1hcnkgc3RhdGUgKCVsZClcbiIsIHByaW1hcnlidWYtPnN0YXRlKTsKCQkJfQojaWZkZWYgU1lOQ19DQUxMQkFDSwoJCQkvKiBEU09VTkRfY2FsbGJhY2sgbWF5IG5lZWQgdGhpcyBsb2NrICovCgkJCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCYocHJpbWFyeWJ1Zi0+bG9jaykpOwojZW5kaWYKCQkJRFNPVU5EX1ByaW1hcnlTdG9wKHByaW1hcnlidWYpOwojaWZkZWYgU1lOQ19DQUxMQkFDSwoJCQlFbnRlckNyaXRpY2FsU2VjdGlvbigmKHByaW1hcnlidWYtPmxvY2spKTsKI2VuZGlmCgkJCWlmIChwcmltYXJ5YnVmLT5od2J1ZikgewoJCQkJLyogdGhlIFN0b3AgaXMgc3VwcG9zZWQgdG8gcmVzZXQgcGxheSBwb3NpdGlvbiB0byBiZWdpbm5pbmcgb2YgYnVmZmVyICovCgkJCQkvKiB1bmZvcnR1bmF0ZWx5LCBPU1MgaXMgbm90IGFibGUgdG8gZG8gc28sIHNvIGdldCBjdXJyZW50IHBvaW50ZXIgKi8KCQkJCWhyZXMgPSBJRHNEcml2ZXJCdWZmZXJfR2V0UG9zaXRpb24ocHJpbWFyeWJ1Zi0+aHdidWYsICZwbGF5cG9zLCBOVUxMKTsKCQkJCWlmIChocmVzKSB7CgkJCQkJTGVhdmVDcml0aWNhbFNlY3Rpb24oJihkc291bmQtPmxvY2spKTsKCQkJCQlMZWF2ZUNyaXRpY2FsU2VjdGlvbigmKHByaW1hcnlidWYtPmxvY2spKTsKCQkJCQlyZXR1cm47CgkJCQl9CgkJCX0gZWxzZSB7CgkgCQkJcGxheXBvcyA9IGRzb3VuZC0+cHdwbGF5ICogZHNvdW5kLT5mcmFnbGVuOwoJCQl9CgkJCXdyaXRlcG9zID0gcGxheXBvczsKCQkJcHJpbWFyeWJ1Zi0+cGxheXBvcyA9IHBsYXlwb3M7CgkJCXByaW1hcnlidWYtPmJ1Zl9taXhwb3MgPSB3cml0ZXBvczsKCQkJaW5xID0gMDsKCQkJbWF4cSA9IHByaW1hcnlidWYtPmJ1ZmxlbjsKCQkJaWYgKG1heHEgPiBmcmFnKSBtYXhxID0gZnJhZzsKCQkJbWVtc2V0KHByaW1hcnlidWYtPmJ1ZmZlciwgbmZpbGxlciwgcHJpbWFyeWJ1Zi0+YnVmbGVuKTsKCQkJcGF1c2VkID0gVFJVRTsKCQl9CgoJCS8qIGRvIHRoZSBtaXhpbmcgKi8KCQlmcmFnID0gRFNPVU5EX01peFRvUHJpbWFyeShwbGF5cG9zLCB3cml0ZXBvcywgbWF4cSwgcGF1c2VkKTsKCQlpZiAoZm9yY2VkKSBmcmFnID0gbWF4cSAtIGlucTsKCQlwcmltYXJ5YnVmLT5idWZfbWl4cG9zICs9IGZyYWc7CgkJd2hpbGUgKHByaW1hcnlidWYtPmJ1Zl9taXhwb3MgPj0gcHJpbWFyeWJ1Zi0+YnVmbGVuKQoJCQlwcmltYXJ5YnVmLT5idWZfbWl4cG9zIC09IHByaW1hcnlidWYtPmJ1ZmxlbjsKCgkJaWYgKGZyYWcpIHsKCQkJLyogYnVmZmVycyBoYXZlIGJlZW4gZmlsbGVkLCByZXN0YXJ0IHBsYXliYWNrICovCgkJCWlmIChwcmltYXJ5YnVmLT5zdGF0ZSA9PSBTVEFURV9TVEFSVElORykgewoJCQkJcHJpbWFyeWJ1Zi0+c3RhdGUgPSBTVEFURV9QTEFZSU5HOwoJCQl9CgkJCWVsc2UgaWYgKHByaW1hcnlidWYtPnN0YXRlID09IFNUQVRFX1NUT1BQRUQpIHsKCQkJCS8qIHRoZSBwcmltYXJ5YnVmIGlzIHN1cHBvc2VkIHRvIHBsYXkgaWYgdGhlcmUncyBzb21ldGhpbmcgdG8gcGxheQoJCQkJICogZXZlbiBpZiBpdCBpcyByZXBvcnRlZCBhcyBzdG9wcGVkLCBzbyBkb24ndCBsZXQgdGhpcyBjb25mdXNlIHlvdSAqLwoJCQkJcHJpbWFyeWJ1Zi0+c3RhdGUgPSBTVEFURV9TVE9QUElORzsKCQkJfQoJCQlMZWF2ZUNyaXRpY2FsU2VjdGlvbigmKHByaW1hcnlidWYtPmxvY2spKTsKCQkJaWYgKHBhdXNlZCkgewoJCQkJRFNPVU5EX1ByaW1hcnlQbGF5KHByaW1hcnlidWYpOwoJCQkJVFJBQ0UoInN0YXJ0aW5nIHBsYXliYWNrXG4iKTsKCQkJfQoJCX0KCQllbHNlCgkJCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCYocHJpbWFyeWJ1Zi0+bG9jaykpOwoJfSBlbHNlIHsKCQkvKiBpbiB0aGUgRFNTQ0xfV1JJVEVQUklNQVJZIG1vZGUsIHRoZSBhcHAgaXMgdG90YWxseSBpbiBjaGFyZ2UuLi4gKi8KCQlpZiAocHJpbWFyeWJ1Zi0+c3RhdGUgPT0gU1RBVEVfU1RBUlRJTkcpIHsKCQkJRFNPVU5EX1ByaW1hcnlQbGF5KHByaW1hcnlidWYpOwoJCQlwcmltYXJ5YnVmLT5zdGF0ZSA9IFNUQVRFX1BMQVlJTkc7CgkJfSAKCQllbHNlIGlmIChwcmltYXJ5YnVmLT5zdGF0ZSA9PSBTVEFURV9TVE9QUElORykgewoJCQlEU09VTkRfUHJpbWFyeVN0b3AocHJpbWFyeWJ1Zik7CgkJCXByaW1hcnlidWYtPnN0YXRlID0gU1RBVEVfU1RPUFBFRDsKCQl9Cgl9CglUUkFDRSgiY29tcGxldGVkIHByb2Nlc3NpbmcgYXQgJWxkXG4iLCBHZXRUaWNrQ291bnQoKSk7CglMZWF2ZUNyaXRpY2FsU2VjdGlvbigmKGRzb3VuZC0+bG9jaykpOwp9CgpzdGF0aWMgdm9pZCBDQUxMQkFDSyBEU09VTkRfdGltZXIoVUlOVCB0aW1lcklELCBVSU5UIG1zZywgRFdPUkQgZHdVc2VyLCBEV09SRCBkdzEsIERXT1JEIGR3MikKewoJaWYgKCFkc291bmQgfHwgIXByaW1hcnlidWYpIHsKCQlFUlIoImRzb3VuZCBkaWVkIHdpdGhvdXQga2lsbGluZyB1cz9cbiIpOwoJCXRpbWVLaWxsRXZlbnQodGltZXJJRCk7CgkJdGltZUVuZFBlcmlvZChEU19USU1FX1JFUyk7CgkJcmV0dXJuOwoJfQoKCVRSQUNFKCJlbnRlcmVkXG4iKTsKCURTT1VORF9QZXJmb3JtTWl4KCk7Cn0KCnN0YXRpYyB2b2lkIENBTExCQUNLIERTT1VORF9jYWxsYmFjayhIV0FWRU9VVCBod28sIFVJTlQgbXNnLCBEV09SRCBkd1VzZXIsIERXT1JEIGR3MSwgRFdPUkQgZHcyKQp7CiAgICAgICAgSURpcmVjdFNvdW5kSW1wbCogVGhpcyA9IChJRGlyZWN0U291bmRJbXBsKilkd1VzZXI7CglUUkFDRSgiZW50ZXJpbmcgYXQgJWxkLCBtc2c9JTA4eFxuIiwgR2V0VGlja0NvdW50KCksIG1zZyk7CglpZiAobXNnID09IE1NX1dPTV9ET05FKSB7CgkJRFdPUkQgaW5xLCBtaXhxLCBmcmFnbGVuLCBidWZsZW4sIHB3cGxheSwgcGxheXBvcywgbWl4cG9zOwoJCWlmIChUaGlzLT5wd3F1ZXVlID09IChEV09SRCktMSkgewoJCQlUUkFDRSgiY29tcGxldGVkIGR1ZSB0byByZXNldFxuIik7CgkJCXJldHVybjsKCQl9Ci8qIGl0IGNvdWxkIGJlIGEgYmFkIGlkZWEgdG8gZW50ZXIgY3JpdGljYWwgc2VjdGlvbiBoZXJlLi4uIGlmIHRoZXJlJ3MgbG9jayBjb250ZW50aW9uLAogKiB0aGUgcmVzdWx0aW5nIHNjaGVkdWxpbmcgZGVsYXlzIG1pZ2h0IG9ic3RydWN0IHRoZSB3aW5tbSBwbGF5ZXIgdGhyZWFkICovCiNpZmRlZiBTWU5DX0NBTExCQUNLCgkJRW50ZXJDcml0aWNhbFNlY3Rpb24oJihwcmltYXJ5YnVmLT5sb2NrKSk7CiNlbmRpZgoJCS8qIHJldHJpZXZlIGN1cnJlbnQgdmFsdWVzICovCgkJZnJhZ2xlbiA9IGRzb3VuZC0+ZnJhZ2xlbjsKCQlidWZsZW4gPSBwcmltYXJ5YnVmLT5idWZsZW47CgkJcHdwbGF5ID0gZHNvdW5kLT5wd3BsYXk7CgkJcGxheXBvcyA9IHB3cGxheSAqIGZyYWdsZW47CgkJbWl4cG9zID0gcHJpbWFyeWJ1Zi0+YnVmX21peHBvczsKCQkvKiBjaGVjayByZW1haW5pbmcgbWl4ZWQgZGF0YSAqLwoJCWlucSA9ICgobWl4cG9zIDwgcGxheXBvcykgPyBidWZsZW4gOiAwKSArIG1peHBvcyAtIHBsYXlwb3M7CgkJbWl4cSA9IGlucSAvIGZyYWdsZW47CgkJaWYgKChpbnEgLSAobWl4cSAqIGZyYWdsZW4pKSA+IDApIG1peHErKzsKCQkvKiBjb21wbGV0ZSB0aGUgcGxheWluZyBidWZmZXIgKi8KCQlUUkFDRSgiZG9uZSBwbGF5aW5nIHByaW1hcnkgcG9zPSVsZFxuIiwgcGxheXBvcyk7CgkJcHdwbGF5Kys7CgkJaWYgKHB3cGxheSA+PSBEU19IRUxfRlJBR1MpIHB3cGxheSA9IDA7CgkJLyogd3JpdGUgbmV3IHZhbHVlcyAqLwoJCWRzb3VuZC0+cHdwbGF5ID0gcHdwbGF5OwoJCWRzb3VuZC0+cHdxdWV1ZS0tOwoJCS8qIHF1ZXVlIG5ldyBidWZmZXIgaWYgd2UgaGF2ZSBkYXRhIGZvciBpdCAqLwoJCWlmIChpbnE+MSkgRFNPVU5EX1dhdmVRdWV1ZShUaGlzLCBpbnEtMSk7CiNpZmRlZiBTWU5DX0NBTExCQUNLCgkJTGVhdmVDcml0aWNhbFNlY3Rpb24oJihwcmltYXJ5YnVmLT5sb2NrKSk7CiNlbmRpZgoJfQoJVFJBQ0UoImNvbXBsZXRlZFxuIik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlEaXJlY3RTb3VuZENyZWF0ZSAoRFNPVU5ELjEpCiAqLwpIUkVTVUxUIFdJTkFQSSBEaXJlY3RTb3VuZENyZWF0ZShSRUZHVUlEIGxwR1VJRCxMUERJUkVDVFNPVU5EICpwcERTLElVbmtub3duICpwVW5rT3V0ZXIgKQp7CglJRGlyZWN0U291bmRJbXBsKiogaXBwRFM9KElEaXJlY3RTb3VuZEltcGwqKilwcERTOwoJUElEU0RSSVZFUiBkcnYgPSBOVUxMOwoJV0FWRU9VVENBUFNBIHdjYXBzOwoJdW5zaWduZWQgd29kLCB3b2RuOwoJSFJFU1VMVCBlcnIgPSBEU19PSzsKCglpZiAobHBHVUlEKQoJCVRSQUNFKCIoJXAsJXAsJXApXG4iLGxwR1VJRCxpcHBEUyxwVW5rT3V0ZXIpOwoJZWxzZQoJCVRSQUNFKCJEaXJlY3RTb3VuZENyZWF0ZSAoJXApXG4iLCBpcHBEUyk7CgoJaWYgKGlwcERTID09IE5VTEwpCgkJcmV0dXJuIERTRVJSX0lOVkFMSURQQVJBTTsKCglpZiAocHJpbWFyeWJ1ZikgewoJCUlEaXJlY3RTb3VuZF9BZGRSZWYoKExQRElSRUNUU09VTkQpZHNvdW5kKTsKCQkqaXBwRFMgPSBkc291bmQ7CgkJcmV0dXJuIERTX09LOwoJfQoKCS8qIEVudW1lcmF0ZSBXSU5NTSBhdWRpbyBkZXZpY2VzIGFuZCBmaW5kIHRoZSBvbmUgd2Ugd2FudCAqLwoJd29kbiA9IHdhdmVPdXRHZXROdW1EZXZzKCk7CglpZiAoIXdvZG4pIHJldHVybiBEU0VSUl9OT0RSSVZFUjsKCgkvKiBGSVhNRTogSG93IGRvIHdlIGZpbmQgdGhlIEdVSUQgb2YgYW4gYXVkaW8gZGV2aWNlPyAqLwoJLyogV2VsbCwganVzdCB1c2UgdGhlIGZpcnN0IGF2YWlsYWJsZSBkZXZpY2UgZm9yIG5vdy4uLiAqLwoJd29kID0gMDsKCS8qIEdldCBvdXRwdXQgZGV2aWNlIGNhcHMgKi8KCXdhdmVPdXRHZXREZXZDYXBzQSh3b2QsICZ3Y2Fwcywgc2l6ZW9mKHdjYXBzKSk7CgkvKiBEUlZfUVVFUllEU09VTkRJRkFDRSBpcyBhICJXaW5lIGV4dGVuc2lvbiIgdG8gZ2V0IHRoZSBEU291bmQgaW50ZXJmYWNlICovCgl3YXZlT3V0TWVzc2FnZSh3b2QsIERSVl9RVUVSWURTT1VORElGQUNFLCAoRFdPUkQpJmRydiwgMCk7CgoJLyogQWxsb2NhdGUgbWVtb3J5ICovCgkqaXBwRFMgPSAoSURpcmVjdFNvdW5kSW1wbCopSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksMCxzaXplb2YoSURpcmVjdFNvdW5kSW1wbCkpOwoJaWYgKCppcHBEUyA9PSBOVUxMKQoJCXJldHVybiBEU0VSUl9PVVRPRk1FTU9SWTsKCglJQ09NX1ZUQkwoKmlwcERTKQk9ICZkc3Z0OwoJKCppcHBEUyktPnJlZgkJPSAxOwoKCSgqaXBwRFMpLT5kcml2ZXIJPSBkcnY7CgkoKmlwcERTKS0+ZnJhZ2xlbgk9IDA7CgkoKmlwcERTKS0+cHJpb2xldmVsCT0gRFNTQ0xfTk9STUFMOyAKCSgqaXBwRFMpLT5ucm9mYnVmZmVycwk9IDA7CgkoKmlwcERTKS0+YnVmZmVycwk9IE5VTEw7CgkoKmlwcERTKS0+cHJpbWFyeQk9IE5VTEw7IAoJKCppcHBEUyktPmxpc3RlbmVyCT0gTlVMTDsgCgoJKCppcHBEUyktPnByZWJ1Zgk9IERTX1NORF9RVUVVRV9NQVg7CgoJLyogR2V0IGRyaXZlciBkZXNjcmlwdGlvbiAqLwoJaWYgKGRydikgewoJCUlEc0RyaXZlcl9HZXREcml2ZXJEZXNjKGRydiwmKCgqaXBwRFMpLT5kcnZkZXNjKSk7Cgl9IGVsc2UgewoJCS8qIGlmIG5vIERpcmVjdFNvdW5kIGludGVyZmFjZSBhdmFpbGFibGUsIHVzZSBXSU5NTSBBUEkgaW5zdGVhZCAqLwoJCSgqaXBwRFMpLT5kcnZkZXNjLmR3RmxhZ3MgPSBEU0RERVNDX0RPTU1TWVNURU1PUEVOIHwgRFNEREVTQ19ET01NU1lTVEVNU0VURk9STUFUOwoJCSgqaXBwRFMpLT5kcnZkZXNjLmRuRGV2Tm9kZSA9IHdvZDsgLyogRklYTUU/ICovCgl9CgoJLyogU2V0IGRlZmF1bHQgd2F2ZSBmb3JtYXQgKG1heSBuZWVkIGl0IGZvciB3YXZlT3V0T3BlbikgKi8KCSgqaXBwRFMpLT53Zngud0Zvcm1hdFRhZwk9IFdBVkVfRk9STUFUX1BDTTsKCSgqaXBwRFMpLT53ZngubkNoYW5uZWxzCQk9IDI7CgkoKmlwcERTKS0+d2Z4Lm5TYW1wbGVzUGVyU2VjCT0gMjIwNTA7CgkoKmlwcERTKS0+d2Z4Lm5BdmdCeXRlc1BlclNlYwk9IDQ0MTAwOwoJKCppcHBEUyktPndmeC5uQmxvY2tBbGlnbgk9IDI7CgkoKmlwcERTKS0+d2Z4LndCaXRzUGVyU2FtcGxlCT0gODsKCgkvKiBJZiB0aGUgZHJpdmVyIHJlcXVlc3RzIGJlaW5nIG9wZW5lZCB0aHJvdWdoIE1NU1lTVEVNCgkgKiAod2hpY2ggaXMgcmVjb21tZW5kZWQgYnkgdGhlIERESyksIGl0IGlzIHN1cHBvc2VkIHRvIGhhcHBlbgoJICogYmVmb3JlIHRoZSBEaXJlY3RTb3VuZCBpbnRlcmZhY2UgaXMgb3BlbmVkICovCglpZiAoKCppcHBEUyktPmRydmRlc2MuZHdGbGFncyAmIERTRERFU0NfRE9NTVNZU1RFTU9QRU4pIHsKCQkvKiBGSVhNRTogaXMgdGhpcyByaWdodD8gKi8KCQllcnIgPSBtbUVycih3YXZlT3V0T3BlbigmKCgqaXBwRFMpLT5od28pLCAoKmlwcERTKS0+ZHJ2ZGVzYy5kbkRldk5vZGUsICYoKCppcHBEUyktPndmeCksCgkJCQkJKERXT1JEKURTT1VORF9jYWxsYmFjaywgKERXT1JEKSgqaXBwRFMpLAoJCQkJCUNBTExCQUNLX0ZVTkNUSU9OIHwgV0FWRV9ESVJFQ1RTT1VORCkpOwoJfQoKCWlmIChkcnYgJiYgKGVyciA9PSBEU19PSykpCgkJZXJyID0gSURzRHJpdmVyX09wZW4oZHJ2KTsKCgkvKiBGSVhNRTogZG8gd2Ugd2FudCB0byBoYW5kbGUgYSB0ZW1wb3JhcmlseSBidXN5IGRldmljZT8gKi8KCWlmIChlcnIgIT0gRFNfT0spIHsKCQlIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsKmlwcERTKTsKCQkqaXBwRFMgPSBOVUxMOwoJCXJldHVybiBlcnI7Cgl9CgoJLyogdGhlIGRyaXZlciBpcyBub3cgb3Blbiwgc28gaXQncyBub3cgYWxsb3dlZCB0byBjYWxsIEdldENhcHMgKi8KCWlmIChkcnYpIHsKCQlJRHNEcml2ZXJfR2V0Q2FwcyhkcnYsJigoKmlwcERTKS0+ZHJ2Y2FwcykpOwoJfSBlbHNlIHsKCQl1bnNpZ25lZCBjOwoKCQkvKiBGSVhNRTogbG9vayBhdCB3Y2FwcyAqLwoJCSgqaXBwRFMpLT5kcnZjYXBzLmR3RmxhZ3MgPQoJCQlEU0NBUFNfUFJJTUFSWTE2QklUIHwgRFNDQVBTX1BSSU1BUllTVEVSRU87CgkJaWYgKERTX0VNVUxEUklWRVIpCgkJICAgICgqaXBwRFMpLT5kcnZjYXBzLmR3RmxhZ3MgfD0gRFNDQVBTX0VNVUxEUklWRVI7CgoJCS8qIEFsbG9jYXRlIG1lbW9yeSBmb3IgSEVMIGJ1ZmZlciBoZWFkZXJzICovCgkJZm9yIChjPTA7IGM8RFNfSEVMX0ZSQUdTOyBjKyspIHsKCQkJKCppcHBEUyktPnB3YXZlW2NdID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksSEVBUF9aRVJPX01FTU9SWSxzaXplb2YoV0FWRUhEUikpOwoJCQlpZiAoISgqaXBwRFMpLT5wd2F2ZVtjXSkgewoJCQkJLyogQXJnaCwgb3V0IG9mIG1lbW9yeSAqLwoJCQkJd2hpbGUgKGMtLSkgewoJCQkJCUhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCwoKmlwcERTKS0+cHdhdmVbY10pOwoJCQkJCXdhdmVPdXRDbG9zZSgoKmlwcERTKS0+aHdvKTsKCQkJCQlIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsKmlwcERTKTsKCQkJCQkqaXBwRFMgPSBOVUxMOwoJCQkJCXJldHVybiBEU0VSUl9PVVRPRk1FTU9SWTsKCQkJCX0KCQkJfQoJCX0KCX0KCglJbml0aWFsaXplQ3JpdGljYWxTZWN0aW9uKCYoKCppcHBEUyktPmxvY2spKTsKCglpZiAoIWRzb3VuZCkgewoJCWRzb3VuZCA9ICgqaXBwRFMpOwoJCWlmIChwcmltYXJ5YnVmID09IE5VTEwpIHsKCQkJRFNCVUZGRVJERVNDCWRzYmQ7CgkJCUhSRVNVTFQJCWhyOwoKCQkJZHNiZC5kd1NpemUgPSBzaXplb2YoRFNCVUZGRVJERVNDKTsKCQkJZHNiZC5kd0ZsYWdzID0gRFNCQ0FQU19QUklNQVJZQlVGRkVSOwoJCQlkc2JkLmR3QnVmZmVyQnl0ZXMgPSAwOwoJCQlkc2JkLmxwd2Z4Rm9ybWF0ID0gJihkc291bmQtPndmeCk7CgkJCWhyID0gSURpcmVjdFNvdW5kX0NyZWF0ZVNvdW5kQnVmZmVyKCpwcERTLCAmZHNiZCwgKExQRElSRUNUU09VTkRCVUZGRVIqKSZwcmltYXJ5YnVmLCBOVUxMKTsKCQkJaWYgKGhyICE9IERTX09LKQoJCQkJcmV0dXJuIGhyOwoKCQkJLyogZHNvdW5kLT5wcmltYXJ5IGlzIE5VTEwgLSBkb24ndCBuZWVkIHRvIFJlbGVhc2UgKi8KCQkJZHNvdW5kLT5wcmltYXJ5ID0gcHJpbWFyeWJ1ZjsKCQkJSURpcmVjdFNvdW5kQnVmZmVyX0FkZFJlZigoTFBESVJFQ1RTT1VOREJVRkZFUilwcmltYXJ5YnVmKTsKCQl9CgkJdGltZUJlZ2luUGVyaW9kKERTX1RJTUVfUkVTKTsKCQlkc291bmQtPnRpbWVySUQgPSB0aW1lU2V0RXZlbnQoRFNfVElNRV9ERUwsIERTX1RJTUVfUkVTLCBEU09VTkRfdGltZXIsCgkJCQkJICAgICAgIChEV09SRClkc291bmQsIFRJTUVfUEVSSU9ESUMgfCBUSU1FX0NBTExCQUNLX0ZVTkNUSU9OKTsKCX0KCXJldHVybiBEU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEaXJlY3RTb3VuZENhcHR1cmVDcmVhdGUgW0RTT1VORC42XQogKgogKiBDcmVhdGUgYW5kIGluaXRpYWxpemUgYSBEaXJlY3RTb3VuZENhcHR1cmUgaW50ZXJmYWNlCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRFNfT0sKICogICAgRmFpbHVyZTogRFNFUlJfTk9BR0dSRUdBVElPTiwgRFNFUlJfQUxMT0NBVEVELCBEU0VSUl9JTlZBTElEUEFSQU0sCiAqICAgICAgICAgICAgIERTRVJSX09VVE9GTUVNT1JZCiAqLwpIUkVTVUxUIFdJTkFQSSBEaXJlY3RTb3VuZENhcHR1cmVDcmVhdGUoCglMUENHVUlEIGxwY0dVSUQsCglMUERJUkVDVFNPVU5EQ0FQVFVSRSogbHBscERTQywKCUxQVU5LTk9XTiBwVW5rT3V0ZXIgKQp7CglUUkFDRSgiKCVzLCVwLCVwKVxuIiwgZGVidWdzdHJfZ3VpZChscGNHVUlEKSwgbHBscERTQywgcFVua091dGVyKTsKCglpZiggcFVua091dGVyICkgewoJCXJldHVybiBEU0VSUl9OT0FHR1JFR0FUSU9OOwoJfQoKCS8qIERlZmF1bHQgZGV2aWNlPyAqLwoJaWYgKCAhbHBjR1VJRCApIHsKCQlyZXR1cm4gRFNPVU5EX0NyZWF0ZURpcmVjdFNvdW5kQ2FwdHVyZSggKExQVk9JRCopbHBscERTQyApOwoJfQoKCUZJWE1FKCAiVW5rbm93biBHVUlEICVzXG4iLCBkZWJ1Z3N0cl9ndWlkKGxwY0dVSUQpICk7CgkqbHBscERTQyA9IE5VTEw7CgoJcmV0dXJuIERTRVJSX09VVE9GTUVNT1JZOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERpcmVjdFNvdW5kQ2FwdHVyZUVudW1lcmF0ZUEgW0RTT1VORC43XQogKgogKiBFbnVtZXJhdGUgYWxsIERpcmVjdFNvdW5kIGRyaXZlcnMgaW5zdGFsbGVkIGluIHRoZSBzeXN0ZW0KICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBEU19PSwogKiAgICBGYWlsdXJlOiBEU0VSUl9JTlZBTElEUEFSQU0KICovCkhSRVNVTFQgV0lOQVBJIERpcmVjdFNvdW5kQ2FwdHVyZUVudW1lcmF0ZUEoCiAgICAgICAgTFBEU0VOVU1DQUxMQkFDS0EgbHBEU0VudW1DYWxsYmFjaywKICAgICAgICBMUFZPSUQgbHBDb250ZXh0KQp7CglUUkFDRSgiKCVwLCVwKVxuIiwgbHBEU0VudW1DYWxsYmFjaywgbHBDb250ZXh0ICk7CgoJaWYgKCBscERTRW51bUNhbGxiYWNrICkKCQlscERTRW51bUNhbGxiYWNrKE5VTEwsIldJTkUgUHJpbWFyeSBTb3VuZCBDYXB0dXJlIERyaXZlciIsCiAgICAgICAgICAgICAgICAgICAgIlNvdW5kQ2FwIixscENvbnRleHQpOwoKCglyZXR1cm4gRFNfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGlyZWN0U291bmRDYXB0dXJlRW51bWVyYXRlVyBbRFNPVU5ELjhdCiAqCiAqIEVudW1lcmF0ZSBhbGwgRGlyZWN0U291bmQgZHJpdmVycyBpbnN0YWxsZWQgaW4gdGhlIHN5c3RlbQogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IERTX09LCiAqICAgIEZhaWx1cmU6IERTRVJSX0lOVkFMSURQQVJBTQogKi8KSFJFU1VMVCBXSU5BUEkgRGlyZWN0U291bmRDYXB0dXJlRW51bWVyYXRlVygKICAgICAgICBMUERTRU5VTUNBTExCQUNLVyBscERTRW51bUNhbGxiYWNrLAogICAgICAgIExQVk9JRCBscENvbnRleHQpCnsKICAgICAgICBGSVhNRSgiKCVwLCVwKTpzdHViXG4iLCBscERTRW51bUNhbGxiYWNrLCBscENvbnRleHQgKTsKICAgICAgICByZXR1cm4gRFNfT0s7Cn0gCgpzdGF0aWMgSFJFU1VMVApEU09VTkRfQ3JlYXRlRGlyZWN0U291bmRDYXB0dXJlKCBMUFZPSUQqIHBwb2JqICkKewoJKnBwb2JqID0gSGVhcEFsbG9jKCBHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoIElEaXJlY3RTb3VuZENhcHR1cmVJbXBsICkgKTsKCglpZiAoICpwcG9iaiA9PSBOVUxMICkgewoJCXJldHVybiBEU0VSUl9PVVRPRk1FTU9SWTsKCX0KCgl7CgkJSUNPTV9USElTKElEaXJlY3RTb3VuZENhcHR1cmVJbXBsLCpwcG9iaik7CgoJCVRoaXMtPnJlZiA9IDE7CgkJSUNPTV9WVEJMKFRoaXMpID0gJmRzY3Z0OwoKCQlJbml0aWFsaXplQ3JpdGljYWxTZWN0aW9uKCAmVGhpcy0+bG9jayApOwoJfQoKCXJldHVybiBTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdFNvdW5kQ2FwdHVyZUltcGxfUXVlcnlJbnRlcmZhY2UoCglMUERJUkVDVFNPVU5EQ0FQVFVSRSBpZmFjZSwKCVJFRklJRCByaWlkLAoJTFBWT0lEKiBwcG9iaiApCnsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRDYXB0dXJlSW1wbCxpZmFjZSk7CgoJRklYTUUoICIoJXApLT4oJXMsJXApOiBzdHViXG4iLCBUaGlzLCBkZWJ1Z3N0cl9ndWlkKHJpaWQpLCBwcG9iaiApOwoKCXJldHVybiBFX0ZBSUw7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkKSURpcmVjdFNvdW5kQ2FwdHVyZUltcGxfQWRkUmVmKCBMUERJUkVDVFNPVU5EQ0FQVFVSRSBpZmFjZSApCnsKCVVMT05HIHVSZWY7CiAgICAgICAgSUNPTV9USElTKElEaXJlY3RTb3VuZENhcHR1cmVJbXBsLGlmYWNlKTsKCglFbnRlckNyaXRpY2FsU2VjdGlvbiggJlRoaXMtPmxvY2sgKTsKCglUUkFDRSggIiglcCkgd2FzIDB4JTA4bHhcbiIsIFRoaXMsIFRoaXMtPnJlZiApOwoJdVJlZiA9ICsrKFRoaXMtPnJlZik7CgoJTGVhdmVDcml0aWNhbFNlY3Rpb24oICZUaGlzLT5sb2NrICk7CgogICAgICAgIHJldHVybiB1UmVmOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJCklEaXJlY3RTb3VuZENhcHR1cmVJbXBsX1JlbGVhc2UoIExQRElSRUNUU09VTkRDQVBUVVJFIGlmYWNlICkKewoJVUxPTkcgdVJlZjsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRDYXB0dXJlSW1wbCxpZmFjZSk7CgoJRW50ZXJDcml0aWNhbFNlY3Rpb24oICZUaGlzLT5sb2NrICk7CgoJVFJBQ0UoICIoJXApIHdhcyAweCUwOGx4XG4iLCBUaGlzLCBUaGlzLT5yZWYgKTsKCXVSZWYgPSAtLShUaGlzLT5yZWYpOwoKCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCAmVGhpcy0+bG9jayApOwoKCWlmICggdVJlZiA9PSAwICkgewoJCURlbGV0ZUNyaXRpY2FsU2VjdGlvbiggJlRoaXMtPmxvY2sgKTsKCQlIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcyApOwoJfQoKCXJldHVybiB1UmVmOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdFNvdW5kQ2FwdHVyZUltcGxfQ3JlYXRlQ2FwdHVyZUJ1ZmZlcigKCUxQRElSRUNUU09VTkRDQVBUVVJFIGlmYWNlLAoJTFBDRFNDQlVGRkVSREVTQyBscGNEU0NCdWZmZXJEZXNjLAoJTFBESVJFQ1RTT1VORENBUFRVUkVCVUZGRVIqIGxwbHBEU0NhcHR1cmVCdWZmZXIsIAoJTFBVTktOT1dOIHBVbmsgKQp7CglIUkVTVUxUIGhyOwoJSUNPTV9USElTKElEaXJlY3RTb3VuZENhcHR1cmVJbXBsLGlmYWNlKTsKCglUUkFDRSggIiglcCktPiglcCwlcCwlcClcbiIsIFRoaXMsIGxwY0RTQ0J1ZmZlckRlc2MsIGxwbHBEU0NhcHR1cmVCdWZmZXIsIHBVbmsgKTsKCglpZiAoIHBVbmsgKSB7CgkJcmV0dXJuIERTRVJSX0lOVkFMSURQQVJBTTsKCX0KCglociA9IERTT1VORF9DcmVhdGVEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXIoIGxwY0RTQ0J1ZmZlckRlc2MsIChMUFZPSUQqKWxwbHBEU0NhcHR1cmVCdWZmZXIgKTsKCglyZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0U291bmRDYXB0dXJlSW1wbF9HZXRDYXBzKAoJTFBESVJFQ1RTT1VORENBUFRVUkUgaWZhY2UsCglMUERTQ0NBUFMgbHBEU0NDYXBzICkKewogICAgICAgIElDT01fVEhJUyhJRGlyZWN0U291bmRDYXB0dXJlSW1wbCxpZmFjZSk7CgogICAgICAgIEZJWE1FKCAiKCVwKS0+KCVwKTogc3R1YlxuIiwgVGhpcywgbHBEU0NDYXBzICk7CgogICAgICAgIHJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3RTb3VuZENhcHR1cmVJbXBsX0luaXRpYWxpemUoCglMUERJUkVDVFNPVU5EQ0FQVFVSRSBpZmFjZSwKCUxQQ0dVSUQgbHBjR1VJRCApCnsKICAgICAgICBJQ09NX1RISVMoSURpcmVjdFNvdW5kQ2FwdHVyZUltcGwsaWZhY2UpOwoKICAgICAgICBGSVhNRSggIiglcCktPiglcCk6IHN0dWJcbiIsIFRoaXMsIGxwY0dVSUQgKTsKCiAgICAgICAgcmV0dXJuIERTX09LOwp9CgoKc3RhdGljIElDT01fVlRBQkxFKElEaXJlY3RTb3VuZENhcHR1cmUpIGRzY3Z0ID0KewogICAgICAgIElDT01fTVNWVEFCTEVfQ09NUEFUX0R1bW15UlRUSVZBTFVFCiAgICAgICAgLyogSVVua25vd24gbWV0aG9kcyAqLwogICAgICAgIElEaXJlY3RTb3VuZENhcHR1cmVJbXBsX1F1ZXJ5SW50ZXJmYWNlLAogICAgICAgIElEaXJlY3RTb3VuZENhcHR1cmVJbXBsX0FkZFJlZiwKICAgICAgICBJRGlyZWN0U291bmRDYXB0dXJlSW1wbF9SZWxlYXNlLAoKICAgICAgICAvKiBJRGlyZWN0U291bmRDYXB0dXJlIG1ldGhvZHMgKi8KICAgICAgICBJRGlyZWN0U291bmRDYXB0dXJlSW1wbF9DcmVhdGVDYXB0dXJlQnVmZmVyLAogICAgICAgIElEaXJlY3RTb3VuZENhcHR1cmVJbXBsX0dldENhcHMsCiAgICAgICAgSURpcmVjdFNvdW5kQ2FwdHVyZUltcGxfSW5pdGlhbGl6ZSAKfTsKCnN0YXRpYyBIUkVTVUxUCkRTT1VORF9DcmVhdGVEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXIoIExQQ0RTQ0JVRkZFUkRFU0MgbHBjRFNDQnVmZmVyRGVzYywgTFBWT0lEKiBwcG9iaiApCnsKCglGSVhNRSggIiglcCwlcCk6IGlnbm9yaW5nIGxwY0RTQ0J1ZmZlckRlc2NcbiIsIGxwY0RTQ0J1ZmZlckRlc2MsIHBwb2JqICk7CgoJKnBwb2JqID0gSGVhcEFsbG9jKCBHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoIElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsICkgKTsKCglpZiAoICpwcG9iaiA9PSBOVUxMICkgewoJCXJldHVybiBEU0VSUl9PVVRPRk1FTU9SWTsKCX0KCgl7CgkJSUNPTV9USElTKElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsLCpwcG9iaik7CgoJCVRoaXMtPnJlZiA9IDE7CgkJSUNPTV9WVEJMKFRoaXMpID0gJmRzY2J2dDsKCgkJSW5pdGlhbGl6ZUNyaXRpY2FsU2VjdGlvbiggJlRoaXMtPmxvY2sgKTsKCX0KCglyZXR1cm4gU19PSzsKfQoKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbF9RdWVyeUludGVyZmFjZSgKICAgICAgICBMUERJUkVDVFNPVU5EQ0FQVFVSRUJVRkZFUiBpZmFjZSwKICAgICAgICBSRUZJSUQgcmlpZCwKICAgICAgICBMUFZPSUQqIHBwb2JqICkKewogICAgICAgIElDT01fVEhJUyhJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbCxpZmFjZSk7CgogICAgICAgIEZJWE1FKCAiKCVwKS0+KCVzLCVwKTogc3R1YlxuIiwgVGhpcywgZGVidWdzdHJfZ3VpZChyaWlkKSwgcHBvYmogKTsKCiAgICAgICAgcmV0dXJuIEVfRkFJTDsKfQoKc3RhdGljIFVMT05HIFdJTkFQSQpJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbF9BZGRSZWYoIExQRElSRUNUU09VTkRDQVBUVVJFQlVGRkVSIGlmYWNlICkKewogICAgICAgIFVMT05HIHVSZWY7CiAgICAgICAgSUNPTV9USElTKElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsLGlmYWNlKTsKCiAgICAgICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oICZUaGlzLT5sb2NrICk7CgoJVFJBQ0UoICIoJXApIHdhcyAweCUwOGx4XG4iLCBUaGlzLCBUaGlzLT5yZWYgKTsKICAgICAgICB1UmVmID0gKysoVGhpcy0+cmVmKTsKCiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oICZUaGlzLT5sb2NrICk7CgogICAgICAgIHJldHVybiB1UmVmOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJCklEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX1JlbGVhc2UoIExQRElSRUNUU09VTkRDQVBUVVJFQlVGRkVSIGlmYWNlICkKewogICAgICAgIFVMT05HIHVSZWY7CiAgICAgICAgSUNPTV9USElTKElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsLGlmYWNlKTsKCiAgICAgICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oICZUaGlzLT5sb2NrICk7CgoJVFJBQ0UoICIoJXApIHdhcyAweCUwOGx4XG4iLCBUaGlzLCBUaGlzLT5yZWYgKTsKICAgICAgICB1UmVmID0gLS0oVGhpcy0+cmVmKTsKCiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oICZUaGlzLT5sb2NrICk7CgogICAgICAgIGlmICggdVJlZiA9PSAwICkgewoJCURlbGV0ZUNyaXRpY2FsU2VjdGlvbiggJlRoaXMtPmxvY2sgKTsKICAgICAgICAgICAgICAgIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzICk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gdVJlZjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX0dldENhcHMoCiAgICAgICAgTFBESVJFQ1RTT1VORENBUFRVUkVCVUZGRVIgaWZhY2UsCglMUERTQ0JDQVBTIGxwRFNDQkNhcHMgKQp7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGwsaWZhY2UpOwoKCUZJWE1FKCAiKCVwKS0+KCVwKTogc3R1YlxuIiwgVGhpcywgbHBEU0NCQ2FwcyApOwoKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX0dldEN1cnJlbnRQb3NpdGlvbigKICAgICAgICBMUERJUkVDVFNPVU5EQ0FQVFVSRUJVRkZFUiBpZmFjZSwKCUxQRFdPUkQgbHBkd0NhcHR1cmVQb3NpdGlvbiwKCUxQRFdPUkQgbHBkd1JlYWRQb3NpdGlvbiApCnsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbCxpZmFjZSk7CgoJRklYTUUoICIoJXApLT4oJXAsJXApOiBzdHViXG4iLCBUaGlzLCBscGR3Q2FwdHVyZVBvc2l0aW9uLCBscGR3UmVhZFBvc2l0aW9uICk7CgoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGxfR2V0Rm9ybWF0KAogICAgICAgIExQRElSRUNUU09VTkRDQVBUVVJFQlVGRkVSIGlmYWNlLAoJTFBXQVZFRk9STUFURVggbHB3ZnhGb3JtYXQsIAoJRFdPUkQgZHdTaXplQWxsb2NhdGVkLCAKCUxQRFdPUkQgbHBkd1NpemVXcml0dGVuICkKewoJSUNPTV9USElTKElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsLGlmYWNlKTsKCglGSVhNRSggIiglcCktPiglcCwweCUwOGx4LCVwKTogc3R1YlxuIiwgVGhpcywgbHB3ZnhGb3JtYXQsIGR3U2l6ZUFsbG9jYXRlZCwgbHBkd1NpemVXcml0dGVuICk7CgoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGxfR2V0U3RhdHVzKAogICAgICAgIExQRElSRUNUU09VTkRDQVBUVVJFQlVGRkVSIGlmYWNlLAoJTFBEV09SRCBscGR3U3RhdHVzICkKewoJSUNPTV9USElTKElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsLGlmYWNlKTsKCglGSVhNRSggIiglcCktPiglcCk6IHN0dWJcbiIsIFRoaXMsIGxwZHdTdGF0dXMgKTsKCglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbF9Jbml0aWFsaXplKAogICAgICAgIExQRElSRUNUU09VTkRDQVBUVVJFQlVGRkVSIGlmYWNlLAoJTFBESVJFQ1RTT1VORENBUFRVUkUgbHBEU0MsIAoJTFBDRFNDQlVGRkVSREVTQyBscGNEU0NCRGVzYyApCnsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbCxpZmFjZSk7CgoJRklYTUUoICIoJXApLT4oJXAsJXApOiBzdHViXG4iLCBUaGlzLCBscERTQywgbHBjRFNDQkRlc2MgKTsKCglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbF9Mb2NrKAogICAgICAgIExQRElSRUNUU09VTkRDQVBUVVJFQlVGRkVSIGlmYWNlLAoJRFdPUkQgZHdSZWFkQ3Vzb3IsIAoJRFdPUkQgZHdSZWFkQnl0ZXMsIAoJTFBWT0lEKiBscGxwdkF1ZGlvUHRyMSwgCglMUERXT1JEIGxwZHdBdWRpb0J5dGVzMSwgCglMUFZPSUQqIGxwbHB2QXVkaW9QdHIyLCAKCUxQRFdPUkQgbHBkd0F1ZGlvQnl0ZXMyLCAKCURXT1JEIGR3RmxhZ3MgKQp7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGwsaWZhY2UpOwoKCUZJWE1FKCAiKCVwKS0+KCUwOGx1LCUwOGx1LCVwLCVwLCVwLCVwLDB4JTA4bHgpOiBzdHViXG4iLCBUaGlzLCBkd1JlYWRDdXNvciwgZHdSZWFkQnl0ZXMsIGxwbHB2QXVkaW9QdHIxLCBscGR3QXVkaW9CeXRlczEsIGxwbHB2QXVkaW9QdHIyLCBscGR3QXVkaW9CeXRlczIsIGR3RmxhZ3MgKTsKCglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbF9TdGFydCgKICAgICAgICBMUERJUkVDVFNPVU5EQ0FQVFVSRUJVRkZFUiBpZmFjZSwKCURXT1JEIGR3RmxhZ3MgKQp7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGwsaWZhY2UpOwoKCUZJWE1FKCAiKCVwKS0+KDB4JTA4bHgpOiBzdHViXG4iLCBUaGlzLCBkd0ZsYWdzICk7CgoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGxfU3RvcCggTFBESVJFQ1RTT1VORENBUFRVUkVCVUZGRVIgaWZhY2UgKQp7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGwsaWZhY2UpOwoKCUZJWE1FKCAiKCVwKTogc3R1YlxuIiwgVGhpcyApOwoKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX1VubG9jaygKICAgICAgICBMUERJUkVDVFNPVU5EQ0FQVFVSRUJVRkZFUiBpZmFjZSwKCUxQVk9JRCBscHZBdWRpb1B0cjEsIAoJRFdPUkQgZHdBdWRpb0J5dGVzMSwgCglMUFZPSUQgbHB2QXVkaW9QdHIyLCAKCURXT1JEIGR3QXVkaW9CeXRlczIgKQp7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGwsaWZhY2UpOwoKCUZJWE1FKCAiKCVwKS0+KCVwLCUwOGx1LCVwLCUwOGx1KTogc3R1YlxuIiwgVGhpcywgbHB2QXVkaW9QdHIxLCBkd0F1ZGlvQnl0ZXMxLCBscHZBdWRpb1B0cjIsIGR3QXVkaW9CeXRlczIgKTsKCglyZXR1cm4gRFNfT0s7Cn0KCgpzdGF0aWMgSUNPTV9WVEFCTEUoSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlcikgZHNjYnZ0ID0KewogICAgICAgIElDT01fTVNWVEFCTEVfQ09NUEFUX0R1bW15UlRUSVZBTFVFCiAgICAgICAgLyogSVVua25vd24gbWV0aG9kcyAqLwogICAgICAgIElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX1F1ZXJ5SW50ZXJmYWNlLAogICAgICAgIElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX0FkZFJlZiwKICAgICAgICBJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbF9SZWxlYXNlLAoKICAgICAgICAvKiBJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVyIG1ldGhvZHMgKi8KICAgICAgICBJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbF9HZXRDYXBzLAogICAgICAgIElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX0dldEN1cnJlbnRQb3NpdGlvbiwKICAgICAgICBJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbF9HZXRGb3JtYXQsCiAgICAgICAgSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGxfR2V0U3RhdHVzLAogICAgICAgIElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX0luaXRpYWxpemUsCiAgICAgICAgSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGxfTG9jaywKICAgICAgICBJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbF9TdGFydCwKICAgICAgICBJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbF9TdG9wLAogICAgICAgIElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX1VubG9jawp9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGlyZWN0U291bmQgQ2xhc3NGYWN0b3J5CiAqLwp0eXBlZGVmIHN0cnVjdAp7CiAgICAvKiBJVW5rbm93biBmaWVsZHMgKi8KICAgIElDT01fVkZJRUxEKElDbGFzc0ZhY3RvcnkpOwogICAgRFdPUkQgICAgICAgICAgICAgICAgICAgICAgIHJlZjsKfSBJQ2xhc3NGYWN0b3J5SW1wbDsKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSAKRFNDRl9RdWVyeUludGVyZmFjZShMUENMQVNTRkFDVE9SWSBpZmFjZSxSRUZJSUQgcmlpZCxMUFZPSUQgKnBwb2JqKSB7CglJQ09NX1RISVMoSUNsYXNzRmFjdG9yeUltcGwsaWZhY2UpOwoKCUZJWE1FKCIoJXApLT4oJXMsJXApLHN0dWIhXG4iLFRoaXMsZGVidWdzdHJfZ3VpZChyaWlkKSxwcG9iaik7CglyZXR1cm4gRV9OT0lOVEVSRkFDRTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSQpEU0NGX0FkZFJlZihMUENMQVNTRkFDVE9SWSBpZmFjZSkgewoJSUNPTV9USElTKElDbGFzc0ZhY3RvcnlJbXBsLGlmYWNlKTsKCXJldHVybiArKyhUaGlzLT5yZWYpOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIERTQ0ZfUmVsZWFzZShMUENMQVNTRkFDVE9SWSBpZmFjZSkgewoJSUNPTV9USElTKElDbGFzc0ZhY3RvcnlJbXBsLGlmYWNlKTsKCS8qIHN0YXRpYyBjbGFzcywgd29uJ3QgYmUgIGZyZWVkICovCglyZXR1cm4gLS0oVGhpcy0+cmVmKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIERTQ0ZfQ3JlYXRlSW5zdGFuY2UoCglMUENMQVNTRkFDVE9SWSBpZmFjZSxMUFVOS05PV04gcE91dGVyLFJFRklJRCByaWlkLExQVk9JRCAqcHBvYmoKKSB7CglJQ09NX1RISVMoSUNsYXNzRmFjdG9yeUltcGwsaWZhY2UpOwoKCVRSQUNFKCIoJXApLT4oJXAsJXMsJXApXG4iLFRoaXMscE91dGVyLGRlYnVnc3RyX2d1aWQocmlpZCkscHBvYmopOwoJaWYgKCBJc0VxdWFsR1VJRCggJklJRF9JRGlyZWN0U291bmQsIHJpaWQgKSApIHsKCQkvKiBGSVhNRTogcmV1c2UgYWxyZWFkeSBjcmVhdGVkIGRzb3VuZCBpZiBwcmVzZW50PyAqLwoJCXJldHVybiBEaXJlY3RTb3VuZENyZWF0ZShyaWlkLChMUERJUkVDVFNPVU5EKilwcG9iaixwT3V0ZXIpOwoJfQoJcmV0dXJuIEVfTk9JTlRFUkZBQ0U7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBEU0NGX0xvY2tTZXJ2ZXIoTFBDTEFTU0ZBQ1RPUlkgaWZhY2UsQk9PTCBkb2xvY2spIHsKCUlDT01fVEhJUyhJQ2xhc3NGYWN0b3J5SW1wbCxpZmFjZSk7CglGSVhNRSgiKCVwKS0+KCVkKSxzdHViIVxuIixUaGlzLGRvbG9jayk7CglyZXR1cm4gU19PSzsKfQoKc3RhdGljIElDT01fVlRBQkxFKElDbGFzc0ZhY3RvcnkpIERTQ0ZfVnRibCA9IHsKCUlDT01fTVNWVEFCTEVfQ09NUEFUX0R1bW15UlRUSVZBTFVFCglEU0NGX1F1ZXJ5SW50ZXJmYWNlLAoJRFNDRl9BZGRSZWYsCglEU0NGX1JlbGVhc2UsCglEU0NGX0NyZWF0ZUluc3RhbmNlLAoJRFNDRl9Mb2NrU2VydmVyCn07CnN0YXRpYyBJQ2xhc3NGYWN0b3J5SW1wbCBEU09VTkRfQ0YgPSB7JkRTQ0ZfVnRibCwgMSB9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGxsR2V0Q2xhc3NPYmplY3QgW0RTT1VORC41XQogKiBSZXRyaWV2ZXMgY2xhc3Mgb2JqZWN0IGZyb20gYSBETEwgb2JqZWN0CiAqCiAqIE5PVEVTCiAqICAgIERvY3Mgc2F5IHJldHVybnMgU1REQVBJCiAqCiAqIFBBUkFNUwogKiAgICByY2xzaWQgW0ldIENMU0lEIGZvciB0aGUgY2xhc3Mgb2JqZWN0CiAqICAgIHJpaWQgICBbSV0gUmVmZXJlbmNlIHRvIGlkZW50aWZpZXIgb2YgaW50ZXJmYWNlIGZvciBjbGFzcyBvYmplY3QKICogICAgcHB2ICAgIFtPXSBBZGRyZXNzIG9mIHZhcmlhYmxlIHRvIHJlY2VpdmUgaW50ZXJmYWNlIHBvaW50ZXIgZm9yIHJpaWQKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBTX09LCiAqICAgIEZhaWx1cmU6IENMQVNTX0VfQ0xBU1NOT1RBVkFJTEFCTEUsIEVfT1VUT0ZNRU1PUlksIEVfSU5WQUxJREFSRywKICogICAgICAgICAgICAgRV9VTkVYUEVDVEVECiAqLwpEV09SRCBXSU5BUEkgRFNPVU5EX0RsbEdldENsYXNzT2JqZWN0KFJFRkNMU0lEIHJjbHNpZCxSRUZJSUQgcmlpZCxMUFZPSUQgKnBwdikKewogICAgVFJBQ0UoIiglcCwlcCwlcClcbiIsIGRlYnVnc3RyX2d1aWQocmNsc2lkKSwgZGVidWdzdHJfZ3VpZChyaWlkKSwgcHB2KTsKICAgIGlmICggSXNFcXVhbENMU0lEKCAmSUlEX0lDbGFzc0ZhY3RvcnksIHJpaWQgKSApIHsKICAgIAkqcHB2ID0gKExQVk9JRCkmRFNPVU5EX0NGOwoJSUNsYXNzRmFjdG9yeV9BZGRSZWYoKElDbGFzc0ZhY3RvcnkqKSpwcHYpOwogICAgcmV0dXJuIFNfT0s7CiAgICB9CgogICAgRklYTUUoIiglcCwlcCwlcCk6IG5vIGludGVyZmFjZSBmb3VuZC5cbiIsIGRlYnVnc3RyX2d1aWQocmNsc2lkKSwgZGVidWdzdHJfZ3VpZChyaWlkKSwgcHB2KTsKICAgIHJldHVybiBDTEFTU19FX0NMQVNTTk9UQVZBSUxBQkxFOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGxsQ2FuVW5sb2FkTm93IFtEU09VTkQuNF0gIERldGVybWluZXMgd2hldGhlciB0aGUgRExMIGlzIGluIHVzZS4KICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBTX09LCiAqICAgIEZhaWx1cmU6IFNfRkFMU0UKICovCkRXT1JEIFdJTkFQSSBEU09VTkRfRGxsQ2FuVW5sb2FkTm93KHZvaWQpCnsKICAgIEZJWE1FKCIodm9pZCk6IHN0dWJcbiIpOwogICAgcmV0dXJuIFNfRkFMU0U7Cn0K