LyogIAkJCURpcmVjdFNvdW5kCiAqIAogKiBDb3B5cmlnaHQgMTk5OCBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggUm9iIFJpZ2dzCiAqIENvcHlyaWdodCAyMDAwLTIwMDEgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzLCBJbmMuCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KLyoKICogTW9zdCB0aHJlYWQgbG9ja2luZyBpcyBjb21wbGV0ZS4gVGhlcmUgbWF5IGJlIGEgZmV3IHJhY2UKICogY29uZGl0aW9ucyBzdGlsbCBsdXJraW5nLgogKgogKiBUZXN0ZWQgd2l0aCBhIFNvdW5kYmxhc3RlciBjbG9uZSwgYSBHcmF2aXMgVWx0cmFTb3VuZCBDbGFzc2ljLAogKiBhbmQgYSBUdXJ0bGUgQmVhY2ggVHJvcGV6Ky4KICoKICogVE9ETzoKICoJSW1wbGVtZW50IERpcmVjdFNvdW5kQ2FwdHVyZSBBUEkKICoJSW1wbGVtZW50IFNldENvb3BlcmF0aXZlTGV2ZWwgcHJvcGVybHkgKG5lZWQgdG8gYWRkcmVzcyBmb2N1cyBpc3N1ZXMpCiAqCUltcGxlbWVudCBEaXJlY3RTb3VuZDNEQnVmZmVycyAoc3R1YnMgaW4gcGxhY2UpCiAqCVVzZSBoYXJkd2FyZSAzRCBzdXBwb3J0IGlmIGF2YWlsYWJsZQogKiAgICAgIEFkZCBjcml0aWNhbCBzZWN0aW9uIGxvY2tpbmcgaW5zaWRlIFJlbGVhc2UgYW5kIEFkZFJlZiBtZXRob2RzCiAqICAgICAgSGFuZGxlIHN0YXRpYyBidWZmZXJzIC0gcHV0IHRob3NlIGluIGhhcmR3YXJlLCBub24tc3RhdGljIG5vdCBpbiBoYXJkd2FyZQogKiAgICAgIEhhcmR3YXJlIER1cGxpY2F0ZVNvdW5kQnVmZmVyCiAqICAgICAgUHJvcGVyIHZvbHVtZSBjYWxjdWxhdGlvbiwgYW5kIHNldHRpbmcgdm9sdW1lIGluIEhFTCBwcmltYXJ5IGJ1ZmZlcgogKiAgICAgIE9wdGltaXplIFdJTk1NIGFuZCBuZWdvdGlhdGUgZnJhZ21lbnQgc2l6ZSwgZGVjcmVhc2UgRFNfSEVMX01BUkdJTgogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgIndpbmUvcG9ydC5oIgoKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3lzL2ZjbnRsLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxtYXRoLmg+CS8qIEluc29tbmlhIC0gcG93KCkgZnVuY3Rpb24gKi8KCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbnJlZy5oIgojaW5jbHVkZSAid2ludXNlci5oIgojaW5jbHVkZSAid2luZ2RpLmgiCiNpbmNsdWRlICJ3aW51c2VyLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAibW1zeXN0ZW0uaCIKI2luY2x1ZGUgIm1tZGRrLmgiCiNpbmNsdWRlICJ3aW5lL3dpbmRlZjE2LmgiCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgojaW5jbHVkZSAiZHNvdW5kLmgiCiNpbmNsdWRlICJkc2RyaXZlci5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoZHNvdW5kKTsKCi8qIHRoZXNlIGFyZSBlbGlnaWJsZSBmb3IgdHVuaW5nLi4uIHRoZXkgbXVzdCBiZSBoaWdoIG9uIHNsb3cgbWFjaGluZXMuLi4gKi8KLyogc29tZSBzdHVmZiBtYXkgZ2V0IG1vcmUgcmVzcG9uc2l2ZSB3aXRoIGxvd2VyIHZhbHVlcyB0aG91Z2guLi4gKi8KI2RlZmluZSBEU19FTVVMRFJJVkVSIDEgLyogc29tZSBnYW1lcyAoUXVha2UgMiwgVVQpIHJlZnVzZSB0byBhY2NlcHQKCQkJCWVtdWxhdGVkIGRzb3VuZCBkZXZpY2VzLiBzZXQgdG8gMCAhICovIAojZGVmaW5lIERTX0hFTF9GUkFHUyA0OCAvKiBIRUwgb25seTogbnVtYmVyIG9mIHdhdmVPdXQgZnJhZ21lbnRzIGluIHByaW1hcnkgYnVmZmVyCgkJCSAqIChjaGFuZ2luZyB0aGlzIHdvbid0IGhlbHAgeW91KSAqLwojZGVmaW5lIERTX0hFTF9NQVJHSU4gNSAvKiBIRUwgb25seTogbnVtYmVyIG9mIHdhdmVPdXQgZnJhZ21lbnRzIGFoZWFkIHRvIG1peCBpbiBuZXcgYnVmZmVycwoJCQkgKiAoa2VlcCB0aGlzIGNsb3NlIG9yIGVxdWFsIHRvIERTX0hFTF9RVUVVRSBmb3IgYmVzdCByZXN1bHRzKSAqLwojZGVmaW5lIERTX0hFTF9RVUVVRSAgNSAvKiBIRUwgb25seTogbnVtYmVyIG9mIHdhdmVPdXQgZnJhZ21lbnRzIGFoZWFkIHRvIHF1ZXVlIHRvIGRyaXZlcgoJCQkgKiAodGhpcyB3aWxsIGFmZmVjdCBIRUwgc291bmQgcmVsaWFiaWxpdHkgYW5kIGxhdGVuY3kpICovCgojZGVmaW5lIERTX1NORF9RVUVVRV9NQVggMjggLyogbWF4IG51bWJlciBvZiBmcmFnbWVudHMgdG8gcHJlYnVmZmVyICovCiNkZWZpbmUgRFNfU05EX1FVRVVFX01JTiAxMiAvKiBtaW4gbnVtYmVyIG9mIGZyYWdtZW50cyB0byBwcmVidWZmZXIgKi8KCi8qIExpbnV4IGRvZXMgbm90IHN1cHBvcnQgYmV0dGVyIHRpbWluZyB0aGFuIDEwbXMgKi8KI2RlZmluZSBEU19USU1FX1JFUyAxMCAgLyogUmVzb2x1dGlvbiBvZiBtdWx0aW1lZGlhIHRpbWVyICovCiNkZWZpbmUgRFNfVElNRV9ERUwgMTAgIC8qIERlbGF5IG9mIG11bHRpbWVkaWEgdGltZXIgY2FsbGJhY2ssIGFuZCBkdXJhdGlvbiBvZiBIRUwgZnJhZ21lbnQgKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBQcmVkZWNsYXJlIHRoZSBpbnRlcmZhY2UgaW1wbGVtZW50YXRpb24gc3RydWN0dXJlcwogKi8KdHlwZWRlZiBzdHJ1Y3QgSURpcmVjdFNvdW5kSW1wbCBJRGlyZWN0U291bmRJbXBsOwp0eXBlZGVmIHN0cnVjdCBJRGlyZWN0U291bmRCdWZmZXJJbXBsIElEaXJlY3RTb3VuZEJ1ZmZlckltcGw7CnR5cGVkZWYgc3RydWN0IElEaXJlY3RTb3VuZE5vdGlmeUltcGwgSURpcmVjdFNvdW5kTm90aWZ5SW1wbDsKdHlwZWRlZiBzdHJ1Y3QgSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGwgSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGw7CnR5cGVkZWYgc3RydWN0IElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbCBJRGlyZWN0U291bmQzREJ1ZmZlckltcGw7CnR5cGVkZWYgc3RydWN0IElEaXJlY3RTb3VuZENhcHR1cmVJbXBsIElEaXJlY3RTb3VuZENhcHR1cmVJbXBsOwp0eXBlZGVmIHN0cnVjdCBJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbCBJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbDsKdHlwZWRlZiBzdHJ1Y3QgSUtzUHJvcGVydHlTZXRJbXBsIElLc1Byb3BlcnR5U2V0SW1wbDsKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdFNvdW5kIGltcGxlbWVudGF0aW9uIHN0cnVjdHVyZQogKi8Kc3RydWN0IElEaXJlY3RTb3VuZEltcGwKewogICAgLyogSVVua25vd24gZmllbGRzICovCiAgICBJQ09NX1ZGSUVMRChJRGlyZWN0U291bmQpOwogICAgRFdPUkQgICAgICAgICAgICAgICAgICAgICAgcmVmOwogICAgLyogSURpcmVjdFNvdW5kSW1wbCBmaWVsZHMgKi8KICAgIFBJRFNEUklWRVIgICAgICAgICAgICAgICAgICBkcml2ZXI7CiAgICBEU0RSSVZFUkRFU0MgICAgICAgICAgICAgICAgZHJ2ZGVzYzsKICAgIERTRFJJVkVSQ0FQUyAgICAgICAgICAgICAgICBkcnZjYXBzOwogICAgSFdBVkVPVVQgICAgICAgICAgICAgICAgICAgIGh3bzsKICAgIExQV0FWRUhEUiAgICAgICAgICAgICAgICAgICBwd2F2ZVtEU19IRUxfRlJBR1NdOwogICAgVUlOVCAgICAgICAgICAgICAgICAgICAgICAgIHRpbWVySUQsIHB3cGxheSwgcHd3cml0ZSwgcHdxdWV1ZSwgcHJlYnVmOwogICAgRFdPUkQgICAgICAgICAgICAgICAgICAgICAgIGZyYWdsZW47CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgICAgcHJpb2xldmVsOwogICAgaW50ICAgICAgICAgICAgICAgICAgICAgICAgIG5yb2ZidWZmZXJzOwogICAgSURpcmVjdFNvdW5kQnVmZmVySW1wbCoqICAgIGJ1ZmZlcnM7CiAgICBJRGlyZWN0U291bmRCdWZmZXJJbXBsKiAgICAgcHJpbWFyeTsKICAgIElEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsKiBsaXN0ZW5lcjsKICAgIFdBVkVGT1JNQVRFWCAgICAgICAgICAgICAgICB3Zng7IC8qIGN1cnJlbnQgbWFpbiB3YXZlZm9ybWF0ICovCiAgICBDUklUSUNBTF9TRUNUSU9OCQlsb2NrOwp9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3RTb3VuZEJ1ZmZlciBpbXBsZW1lbnRhdGlvbiBzdHJ1Y3R1cmUKICovCnN0cnVjdCBJRGlyZWN0U291bmRCdWZmZXJJbXBsCnsKICAgIC8qIEZJWE1FOiBkb2N1bWVudCAqLwogICAgLyogSVVua25vd24gZmllbGRzICovCiAgICBJQ09NX1ZGSUVMRChJRGlyZWN0U291bmRCdWZmZXIpOwogICAgRFdPUkQgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmOwogICAgLyogSURpcmVjdFNvdW5kQnVmZmVySW1wbCBmaWVsZHMgKi8KICAgIFBJRFNEUklWRVJCVUZGRVIgICAgICAgICAgaHdidWY7CiAgICBXQVZFRk9STUFURVggICAgICAgICAgICAgIHdmeDsKICAgIExQQllURSAgICAgICAgICAgICAgICAgICAgYnVmZmVyOwogICAgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsKiBkczNkYjsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgICAgcGxheWZsYWdzLHN0YXRlLGxlYWRpbjsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgICAgcGxheXBvcyxzdGFydHBvcyx3cml0ZWxlYWQsYnVmbGVuOwogICAgRFdPUkQgICAgICAgICAgICAgICAgICAgICBuQXZnQnl0ZXNQZXJTZWM7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgIGZyZXE7CiAgICBEU1ZPTFVNRVBBTiAgICAgICAgICAgICAgIHZvbHBhbjsKICAgIElEaXJlY3RTb3VuZEJ1ZmZlckltcGwqICAgcGFyZW50OyAgICAgICAgIC8qIGZvciBkdXBsaWNhdGVzICovCiAgICBJRGlyZWN0U291bmRJbXBsKiAgICAgICAgIGRzb3VuZDsKICAgIERTQlVGRkVSREVTQyAgICAgICAgICAgICAgZHNiZDsKICAgIExQRFNCUE9TSVRJT05OT1RJRlkgICAgICAgbm90aWZpZXM7CiAgICBpbnQgICAgICAgICAgICAgICAgICAgICAgIG5yb2Zub3RpZmllczsKICAgIENSSVRJQ0FMX1NFQ1RJT04gICAgICAgICAgbG9jazsKICAgIC8qIHVzZWQgZm9yIGZyZXF1ZW5jeSBjb252ZXJzaW9uIChQZXJmZWN0UGl0Y2gpICovCiAgICBVTE9ORyAgICAgICAgICAgICAgICAgICAgIGZyZXFBZGp1c3QsIGZyZXFBY2M7CiAgICAvKiB1c2VkIGZvciBpbnRlbGxpZ2VudCAod2VsbCwgc29ydCBvZikgcHJlYnVmZmVyaW5nICovCiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgIHByb2JhYmx5X3ZhbGlkX3RvOwogICAgRFdPUkQgICAgICAgICAgICAgICAgICAgICBwcmltYXJ5X21peHBvcywgYnVmX21peHBvczsKICAgIEJPT0wgICAgICAgICAgICAgICAgICAgICAgbmVlZF9yZW1peDsKfTsKCiNkZWZpbmUgU1RBVEVfU1RPUFBFRCAgMAojZGVmaW5lIFNUQVRFX1NUQVJUSU5HIDEKI2RlZmluZSBTVEFURV9QTEFZSU5HICAyCiNkZWZpbmUgU1RBVEVfU1RPUFBJTkcgMwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3RTb3VuZE5vdGlmeSBpbXBsZW1lbnRhdGlvbiBzdHJ1Y3R1cmUKICovCnN0cnVjdCBJRGlyZWN0U291bmROb3RpZnlJbXBsCnsKICAgIC8qIElVbmtub3duIGZpZWxkcyAqLwogICAgSUNPTV9WRklFTEQoSURpcmVjdFNvdW5kTm90aWZ5KTsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZjsKICAgIC8qIElEaXJlY3RTb3VuZE5vdGlmeUltcGwgZmllbGRzICovCiAgICBJRGlyZWN0U291bmRCdWZmZXJJbXBsKiBkc2I7Cn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogIElEaXJlY3RTb3VuZDNETGlzdGVuZXIgaW1wbGVtZW50YXRpb24gc3RydWN0dXJlCiAqLwpzdHJ1Y3QgSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGwKewogICAgLyogSVVua25vd24gZmllbGRzICovCiAgICBJQ09NX1ZGSUVMRChJRGlyZWN0U291bmQzRExpc3RlbmVyKTsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWY7CiAgICAvKiBJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbCBmaWVsZHMgKi8KICAgIElEaXJlY3RTb3VuZEJ1ZmZlckltcGwqIGRzYjsKICAgIERTM0RMSVNURU5FUiAgICAgICAgICAgIGRzM2RsOwogICAgQ1JJVElDQUxfU0VDVElPTiAgICAgICAgbG9jazsgICAKfTsKCnN0cnVjdCBJS3NQcm9wZXJ0eVNldEltcGwgCnsKICAgIC8qIElVbmtub3duIGZpZWxkcyAqLwogICAgSUNPTV9WRklFTEQoSUtzUHJvcGVydHlTZXQpOwogICAgRFdPUkQJCQlyZWY7CiAgICAvKiBJS3NQcm9wZXJ0eVNldEltcGwgZmllbGRzICovCiAgICBJRGlyZWN0U291bmQzREJ1ZmZlckltcGwJKmRzM2RiOwkvKiBiYWNrcHRyLCBubyByZWYgKi8KfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0U291bmQzREJ1ZmZlciBpbXBsZW1lbnRhdGlvbiBzdHJ1Y3R1cmUKICovCnN0cnVjdCBJRGlyZWN0U291bmQzREJ1ZmZlckltcGwKewogICAgLyogSVVua25vd24gZmllbGRzICovCiAgICBJQ09NX1ZGSUVMRChJRGlyZWN0U291bmQzREJ1ZmZlcik7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZjsKICAgIC8qIElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbCBmaWVsZHMgKi8KICAgIElEaXJlY3RTb3VuZEJ1ZmZlckltcGwqIGRzYjsKICAgIERTM0RCVUZGRVIgICAgICAgICAgICAgIGRzM2RiOwogICAgTFBCWVRFICAgICAgICAgICAgICAgICAgYnVmZmVyOwogICAgRFdPUkQgICAgICAgICAgICAgICAgICAgYnVmbGVuOwogICAgQ1JJVElDQUxfU0VDVElPTiAgICAgICAgbG9jazsKICAgIElLc1Byb3BlcnR5U2V0SW1wbCogICAgIGlrczsKfTsKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdFNvdW5kQ2FwdHVyZSBpbXBsZW1lbnRhdGlvbiBzdHJ1Y3R1cmUKICovCnN0cnVjdCBJRGlyZWN0U291bmRDYXB0dXJlSW1wbAp7CiAgICAvKiBJVW5rbm93biBmaWVsZHMgKi8KICAgIElDT01fVkZJRUxEKElEaXJlY3RTb3VuZENhcHR1cmUpOwogICAgRFdPUkQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWY7CgogICAgLyogSURpcmVjdFNvdW5kQ2FwdHVyZUltcGwgZmllbGRzICovCiAgICBDUklUSUNBTF9TRUNUSU9OICAgICAgICBsb2NrOwp9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3RTb3VuZENhcHR1cmUgaW1wbGVtZW50YXRpb24gc3RydWN0dXJlCiAqLwpzdHJ1Y3QgSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGwKewogICAgLyogSVVua25vd24gZmllbGRzICovCiAgICBJQ09NX1ZGSUVMRChJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVyKTsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmOwoKICAgIC8qIElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsIGZpZWxkcyAqLwogICAgQ1JJVElDQUxfU0VDVElPTiAgICAgICAgbG9jazsKfTsKCgovKiAjZGVmaW5lIFVTRV9EU09VTkQzRCAxICovCgojZGVmaW5lIERTT1VORF9GUkVRU0hJRlQgKDE0KQoKc3RhdGljIElEaXJlY3RTb3VuZEltcGwqCWRzb3VuZCA9IE5VTEw7CgpzdGF0aWMgSURpcmVjdFNvdW5kQnVmZmVySW1wbCoJcHJpbWFyeWJ1ZiA9IE5VTEw7CgpzdGF0aWMgdm9pZCBEU09VTkRfQ2hlY2tFdmVudChJRGlyZWN0U291bmRCdWZmZXJJbXBsICpkc2IsIGludCBsZW4pOwpzdGF0aWMgdm9pZCBEU09VTkRfTWl4Q2FuY2VsQXQoSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiLCBEV09SRCBidWZfd3JpdGVwb3MpOwoKc3RhdGljIHZvaWQgRFNPVU5EX1dhdmVRdWV1ZShJRGlyZWN0U291bmRJbXBsICpkc291bmQsIERXT1JEIG1peHEpOwpzdGF0aWMgdm9pZCBEU09VTkRfUGVyZm9ybU1peCh2b2lkKTsKc3RhdGljIHZvaWQgQ0FMTEJBQ0sgRFNPVU5EX2NhbGxiYWNrKEhXQVZFT1VUIGh3bywgVUlOVCBtc2csIERXT1JEIGR3VXNlciwgRFdPUkQgZHcxLCBEV09SRCBkdzIpOwoKc3RhdGljIEhSRVNVTFQgRFNPVU5EX0NyZWF0ZURpcmVjdFNvdW5kQ2FwdHVyZSggTFBWT0lEKiBwcG9iaiApOwpzdGF0aWMgSFJFU1VMVCBEU09VTkRfQ3JlYXRlRGlyZWN0U291bmRDYXB0dXJlQnVmZmVyKCBMUENEU0NCVUZGRVJERVNDIGxwY0RTQ0J1ZmZlckRlc2MsIExQVk9JRCogcHBvYmogKTsKCnN0YXRpYyBJQ09NX1ZUQUJMRShJRGlyZWN0U291bmRDYXB0dXJlKSBkc2N2dDsKc3RhdGljIElDT01fVlRBQkxFKElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXIpIGRzY2J2dDsKCnN0YXRpYyBIUkVTVUxUIG1tRXJyKFVJTlQgZXJyKQp7Cglzd2l0Y2goZXJyKSB7CgljYXNlIE1NU1lTRVJSX05PRVJST1I6CgkJcmV0dXJuIERTX09LOwoJY2FzZSBNTVNZU0VSUl9BTExPQ0FURUQ6CgkJcmV0dXJuIERTRVJSX0FMTE9DQVRFRDsKCWNhc2UgTU1TWVNFUlJfSU5WQUxIQU5ETEU6CgkJcmV0dXJuIERTRVJSX0dFTkVSSUM7IC8qIEZJWE1FICovCgljYXNlIE1NU1lTRVJSX05PRFJJVkVSOgoJCXJldHVybiBEU0VSUl9OT0RSSVZFUjsKCWNhc2UgTU1TWVNFUlJfTk9NRU06CgkJcmV0dXJuIERTRVJSX09VVE9GTUVNT1JZOwoJY2FzZSBNTVNZU0VSUl9JTlZBTFBBUkFNOgoJCXJldHVybiBEU0VSUl9JTlZBTElEUEFSQU07CglkZWZhdWx0OgoJCUZJWE1FKCJVbmtub3duIE1NU1lTIGVycm9yICVkXG4iLGVycik7CgkJcmV0dXJuIERTRVJSX0dFTkVSSUM7Cgl9Cn0KCnN0YXRpYyBpbnQJZHNfZW11bGRyaXZlciA9IERTX0VNVUxEUklWRVI7CnN0YXRpYyBpbnQJZHNfaGVsX21hcmdpbiA9IERTX0hFTF9NQVJHSU47CnN0YXRpYyBpbnQJZHNfaGVsX3F1ZXVlID0gRFNfSEVMX1FVRVVFOwpzdGF0aWMgaW50CWRzX3NuZF9xdWV1ZV9tYXggPSBEU19TTkRfUVVFVUVfTUFYOwpzdGF0aWMgaW50CWRzX3NuZF9xdWV1ZV9taW4gPSBEU19TTkRfUVVFVUVfTUlOOwoKLyogCiAqIENhbGwgdGhlIGNhbGxiYWNrIHByb3ZpZGVkIHRvIERpcmVjdFNvdW5kRW51bWVyYXRlQS4KICovCgppbmxpbmUgc3RhdGljIHZvaWQgZW51bWVyYXRlX2RldmljZXMoTFBEU0VOVU1DQUxMQkFDS0EgbHBEU0VudW1DYWxsYmFjaywKCQkJCSAgICAgTFBWT0lEIGxwQ29udGV4dCkKewogICAgaWYgKGxwRFNFbnVtQ2FsbGJhY2sgIT0gTlVMTCkKCWlmIChscERTRW51bUNhbGxiYWNrKE5VTEwsICJQcmltYXJ5IERpcmVjdFNvdW5kIERyaXZlciIsCgkJCSAgICAgInNvdW5kIiwgbHBDb250ZXh0KSkKCSAgICBscERTRW51bUNhbGxiYWNrKChMUEdVSUQpJkRTREVWSURfV2luZVBsYXliYWNrLAoJCQkgICAgICJXSU5FIERpcmVjdFNvdW5kIiwgInNvdW5kIiwKCQkJICAgICBscENvbnRleHQpOwp9CgoKLyoKICogR2V0IGEgY29uZmlnIGtleSBmcm9tIGVpdGhlciB0aGUgYXBwLXNwZWNpZmljIG9yIHRoZSBkZWZhdWx0IGNvbmZpZwogKi8KCmlubGluZSBzdGF0aWMgRFdPUkQgZ2V0X2NvbmZpZ19rZXkoIEhLRVkgZGVma2V5LCBIS0VZIGFwcGtleSwgY29uc3QgY2hhciAqbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhciAqYnVmZmVyLCBEV09SRCBzaXplICkKewogICAgaWYgKGFwcGtleSAmJiAhUmVnUXVlcnlWYWx1ZUV4QSggYXBwa2V5LCBuYW1lLCAwLCBOVUxMLCBidWZmZXIsICZzaXplICkpIHJldHVybiAwOwogICAgcmV0dXJuIFJlZ1F1ZXJ5VmFsdWVFeEEoIGRlZmtleSwgbmFtZSwgMCwgTlVMTCwgYnVmZmVyLCAmc2l6ZSApOwp9CgoKLyoKICogU2V0dXAgdGhlIGRzb3VuZCBvcHRpb25zLgogKi8KCmlubGluZSBzdGF0aWMgdm9pZCBzZXR1cF9kc291bmRfb3B0aW9ucyh2b2lkKQp7CiAgICBjaGFyIGJ1ZmZlcltNQVhfUEFUSCsxXTsKICAgIEhLRVkgaGtleSwgYXBwa2V5ID0gMDsKICAgIAogICAgYnVmZmVyW01BWF9QQVRIXT0nXDAnOwogICAgCiAgICBpZiAoUmVnQ3JlYXRlS2V5RXhBKCBIS0VZX0xPQ0FMX01BQ0hJTkUsICJTb2Z0d2FyZVxcV2luZVxcV2luZVxcQ29uZmlnXFxkc291bmQiLCAwLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgUkVHX09QVElPTl9WT0xBVElMRSwgS0VZX0FMTF9BQ0NFU1MsIE5VTEwsICZoa2V5LCBOVUxMICkpCiAgICB7CiAgICAgICAgRVJSKCJDYW5ub3QgY3JlYXRlIGNvbmZpZyByZWdpc3RyeSBrZXlcbiIgKTsKICAgICAgICBFeGl0UHJvY2VzcygxKTsKICAgIH0KCiAgICBpZiAoR2V0TW9kdWxlRmlsZU5hbWUxNiggR2V0Q3VycmVudFRhc2soKSwgYnVmZmVyLCBNQVhfUEFUSCApIHx8CiAgICAgICAgR2V0TW9kdWxlRmlsZU5hbWVBKCAwLCBidWZmZXIsIE1BWF9QQVRIICkpCiAgICB7CiAgICAgICAgSEtFWSB0bXBrZXk7CgogICAgICAgIGlmICghUmVnT3BlbktleUEoIEhLRVlfTE9DQUxfTUFDSElORSwgIlNvZnR3YXJlXFxXaW5lXFxXaW5lXFxDb25maWdcXEFwcERlZmF1bHRzIiwgJnRtcGtleSApKQogICAgICAgIHsKCSAgICBjaGFyIGFwcG5hbWVbTUFYX1BBVEgrMTZdOwoJICAgIGNoYXIgKnAgPSBzdHJyY2hyKCBidWZmZXIsICdcXCcgKTsKCSAgICBpZiAocCE9TlVMTCkgewoJICAgIAkgICAgYXBwbmFtZVtNQVhfUEFUSF09J1wwJzsKCSAgICAJICAgIHN0cm5jcHkoYXBwbmFtZSxwKzEsTUFYX1BBVEgpOwoJCSAgICBzdHJjYXQoYXBwbmFtZSwiXFxkc291bmQiKTsKCQkgICAgVFJBQ0UoImFwcG5hbWUgPSBbJXNdIFxuIixhcHBuYW1lKTsKCQkgICAgaWYgKFJlZ09wZW5LZXlBKCB0bXBrZXksIGFwcG5hbWUsICZhcHBrZXkgKSkgYXBwa2V5ID0gMDsKICAgICAgICAgICAgCQlSZWdDbG9zZUtleSggdG1wa2V5ICk7CgkgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKiBnZXQgb3B0aW9ucyAqLwoKICAgIGlmICghZ2V0X2NvbmZpZ19rZXkoIGhrZXksIGFwcGtleSwgIkVtdWxEcml2ZXIiLCBidWZmZXIsIE1BWF9QQVRIICkpIAogICAgICAgIGRzX2VtdWxkcml2ZXIgPSBzdHJjbXAoYnVmZmVyLCAiTiIpOwoKICAgIGlmICghZ2V0X2NvbmZpZ19rZXkoIGhrZXksIGFwcGtleSwgIkhFTG1hcmdpbiIsIGJ1ZmZlciwgTUFYX1BBVEggKSkgCiAgICAgICAgZHNfaGVsX21hcmdpbiA9IGF0b2koYnVmZmVyKTsKCiAgICBpZiAoIWdldF9jb25maWdfa2V5KCBoa2V5LCBhcHBrZXksICJIRUxxdWV1ZSIsIGJ1ZmZlciwgTUFYX1BBVEggKSkKICAgICAgICBkc19oZWxfcXVldWUgPSBhdG9pKGJ1ZmZlcik7CgogICAgaWYgKCFnZXRfY29uZmlnX2tleSggaGtleSwgYXBwa2V5LCAiU25kUXVldWVNYXgiLCBidWZmZXIsIE1BWF9QQVRIICkpCiAgICAgICAgZHNfc25kX3F1ZXVlX21heCA9IGF0b2koYnVmZmVyKTsKCiAgICBpZiAoIWdldF9jb25maWdfa2V5KCBoa2V5LCBhcHBrZXksICJTbmRRdWV1ZU1pbiIsIGJ1ZmZlciwgTUFYX1BBVEggKSkKICAgICAgICBkc19zbmRfcXVldWVfbWluID0gYXRvaShidWZmZXIpOwoKICAgIGlmIChhcHBrZXkpIFJlZ0Nsb3NlS2V5KCBhcHBrZXkgKTsKICAgIFJlZ0Nsb3NlS2V5KCBoa2V5ICk7CgogICAgaWYgKGRzX2VtdWxkcml2ZXIgIT0gRFNfRU1VTERSSVZFUiApCglXQVJOKCJkc19lbXVsZHJpdmVyID0gJWQgKGRlZmF1bHQ9JWQpXG4iLGRzX2VtdWxkcml2ZXIsIERTX0VNVUxEUklWRVIpOwogICAgaWYgKGRzX2hlbF9tYXJnaW4gIT0gRFNfSEVMX01BUkdJTiApIAoJV0FSTigiZHNfaGVsX21hcmdpbiA9ICVkIChkZWZhdWx0PSVkKVxuIixkc19oZWxfbWFyZ2luLCBEU19IRUxfTUFSR0lOICk7CiAgICBpZiAoZHNfaGVsX3F1ZXVlICE9IERTX0hFTF9RVUVVRSApCiAgICAJV0FSTigiZHNfaGVsX3F1ZXVlID0gJWQgKGRlZmF1bHQ9JWQpXG4iLGRzX2hlbF9xdWV1ZSwgRFNfSEVMX1FVRVVFICk7ICAgICAgICAgIAogICAgaWYgKGRzX3NuZF9xdWV1ZV9tYXggIT0gRFNfU05EX1FVRVVFX01BWCkKCVdBUk4oImRzX3NuZF9xdWV1ZV9tYXggPSAlZCAoZGVmYXVsdD0lZClcbiIsZHNfc25kX3F1ZXVlX21heCAsRFNfU05EX1FVRVVFX01BWCk7CiAgICBpZiAoZHNfc25kX3F1ZXVlX21pbiAhPSBEU19TTkRfUVVFVUVfTUlOKQoJV0FSTigiZHNfc25kX3F1ZXVlX21pbiA9ICVkIChkZWZhdWx0PSVkKVxuIixkc19zbmRfcXVldWVfbWluICxEU19TTkRfUVVFVUVfTUlOKTsKCn0KCgoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGlyZWN0U291bmRFbnVtZXJhdGVBIFtEU09VTkQuMl0gIAogKgogKiBFbnVtZXJhdGUgYWxsIERpcmVjdFNvdW5kIGRyaXZlcnMgaW5zdGFsbGVkIGluIHRoZSBzeXN0ZW0KICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBEU19PSwogKiAgICBGYWlsdXJlOiBEU0VSUl9JTlZBTElEUEFSQU0KICovCkhSRVNVTFQgV0lOQVBJIERpcmVjdFNvdW5kRW51bWVyYXRlQSgKCUxQRFNFTlVNQ0FMTEJBQ0tBIGxwRFNFbnVtQ2FsbGJhY2ssCglMUFZPSUQgbHBDb250ZXh0KQp7CglXQVZFT1VUQ0FQU0Egd2NhcHM7Cgl1bnNpZ25lZCBkZXZzLCB3b2Q7CgoJVFJBQ0UoImxwRFNFbnVtQ2FsbGJhY2sgPSAlcCwgbHBDb250ZXh0ID0gJXBcbiIsIAoJICAgICAgbHBEU0VudW1DYWxsYmFjaywgbHBDb250ZXh0KTsKCglkZXZzID0gd2F2ZU91dEdldE51bURldnMoKTsKCWZvciAod29kID0gMDsgd29kIDwgZGV2czsgKyt3b2QpIHsKCQl3YXZlT3V0R2V0RGV2Q2Fwc0Eod29kLCAmd2NhcHMsIHNpemVvZih3Y2FwcykpOwoJCWlmICh3Y2Fwcy5kd1N1cHBvcnQgJiBXQVZFQ0FQU19ESVJFQ1RTT1VORCkgewoJCQlUUkFDRSgiLSBEZXZpY2UgJXUgc3VwcG9ydHMgRGlyZWN0U291bmRcbiIsIHdvZCk7CgkJCWVudW1lcmF0ZV9kZXZpY2VzKGxwRFNFbnVtQ2FsbGJhY2ssIGxwQ29udGV4dCk7CgkJCXJldHVybiBEU19PSzsKCQl9Cgl9CglyZXR1cm4gRFNfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGlyZWN0U291bmRFbnVtZXJhdGVXIFtEU09VTkQuM10gIAogKgogKiBFbnVtZXJhdGUgYWxsIERpcmVjdFNvdW5kIGRyaXZlcnMgaW5zdGFsbGVkIGluIHRoZSBzeXN0ZW0KICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBEU19PSwogKiAgICBGYWlsdXJlOiBEU0VSUl9JTlZBTElEUEFSQU0KICovCkhSRVNVTFQgV0lOQVBJIERpcmVjdFNvdW5kRW51bWVyYXRlVygKCUxQRFNFTlVNQ0FMTEJBQ0tXIGxwRFNFbnVtQ2FsbGJhY2ssIAoJTFBWT0lEIGxwQ29udGV4dCApCnsKICAgICAgICBGSVhNRSgibHBEU0VudW1DYWxsYmFjayA9ICVwLCBscENvbnRleHQgPSAlcDogc3R1YlxuIiwgCiAgICAgICAgICAgICAgICBscERTRW51bUNhbGxiYWNrLCBscENvbnRleHQpOwoKICAgICAgICByZXR1cm4gRFNfT0s7Cn0KCgpzdGF0aWMgdm9pZCBfZHVtcF9EU0JDQVBTKERXT1JEIHhtYXNrKSB7CglzdHJ1Y3QgewoJCURXT1JECW1hc2s7CgkJY2hhcgkqbmFtZTsKCX0gZmxhZ3NbXSA9IHsKI2RlZmluZSBGRSh4KSB7IHgsICN4IH0sCgkJRkUoRFNCQ0FQU19QUklNQVJZQlVGRkVSKQoJCUZFKERTQkNBUFNfU1RBVElDKQoJCUZFKERTQkNBUFNfTE9DSEFSRFdBUkUpCgkJRkUoRFNCQ0FQU19MT0NTT0ZUV0FSRSkKCQlGRShEU0JDQVBTX0NUUkwzRCkKCQlGRShEU0JDQVBTX0NUUkxGUkVRVUVOQ1kpCgkJRkUoRFNCQ0FQU19DVFJMUEFOKQoJCUZFKERTQkNBUFNfQ1RSTFZPTFVNRSkKCQlGRShEU0JDQVBTX0NUUkxQT1NJVElPTk5PVElGWSkKCQlGRShEU0JDQVBTX0NUUkxERUZBVUxUKQoJCUZFKERTQkNBUFNfQ1RSTEFMTCkKCQlGRShEU0JDQVBTX1NUSUNLWUZPQ1VTKQoJCUZFKERTQkNBUFNfR0xPQkFMRk9DVVMpCgkJRkUoRFNCQ0FQU19HRVRDVVJSRU5UUE9TSVRJT04yKQoJCUZFKERTQkNBUFNfTVVURTNEQVRNQVhESVNUQU5DRSkKI3VuZGVmIEZFCgl9OwoJaW50CWk7CgoJZm9yIChpPTA7aTxzaXplb2YoZmxhZ3MpL3NpemVvZihmbGFnc1swXSk7aSsrKQoJCWlmICgoZmxhZ3NbaV0ubWFzayAmIHhtYXNrKSA9PSBmbGFnc1tpXS5tYXNrKQoJCQlEUFJJTlRGKCIlcyAiLGZsYWdzW2ldLm5hbWUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgSUtzUHJvcGVydHlTZXQKICovCgovKiBJVW5rbm93biBtZXRob2RzICovCiNpZmRlZiBVU0VfRFNPVU5EM0QKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElLc1Byb3BlcnR5U2V0SW1wbF9RdWVyeUludGVyZmFjZSgKCUxQS1NQUk9QRVJUWVNFVCBpZmFjZSwgUkVGSUlEIHJpaWQsIExQVk9JRCAqcHBvYmoKKSB7CglJQ09NX1RISVMoSUtzUHJvcGVydHlTZXRJbXBsLGlmYWNlKTsKCglGSVhNRSgiKCVwLCVzLCVwKSwgc3R1YiFcbiIsVGhpcyxkZWJ1Z3N0cl9ndWlkKHJpaWQpLHBwb2JqKTsKCXJldHVybiBFX0ZBSUw7Cn0KI2VuZGlmCgojaWZkZWYgVVNFX0RTT1VORDNECnN0YXRpYyBVTE9ORyBXSU5BUEkgSUtzUHJvcGVydHlTZXRJbXBsX0FkZFJlZihMUEtTUFJPUEVSVFlTRVQgaWZhY2UpIHsKCUlDT01fVEhJUyhJS3NQcm9wZXJ0eVNldEltcGwsaWZhY2UpOwoKCVRoaXMtPnJlZisrOwoJcmV0dXJuIFRoaXMtPnJlZjsKfQojZW5kaWYKCiNpZmRlZiBVU0VfRFNPVU5EM0QKc3RhdGljIFVMT05HIFdJTkFQSSBJS3NQcm9wZXJ0eVNldEltcGxfUmVsZWFzZShMUEtTUFJPUEVSVFlTRVQgaWZhY2UpIHsKCUlDT01fVEhJUyhJS3NQcm9wZXJ0eVNldEltcGwsaWZhY2UpOwoKCVRoaXMtPnJlZi0tOwoJcmV0dXJuIFRoaXMtPnJlZjsKfQojZW5kaWYKCiNpZmRlZiBVU0VfRFNPVU5EM0QKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElLc1Byb3BlcnR5U2V0SW1wbF9HZXQoTFBLU1BST1BFUlRZU0VUIGlmYWNlLAoJUkVGR1VJRCBndWlkUHJvcFNldCwgVUxPTkcgZHdQcm9wSUQsCglMUFZPSUQgcEluc3RhbmNlRGF0YSwgVUxPTkcgY2JJbnN0YW5jZURhdGEsCglMUFZPSUQgcFByb3BEYXRhLCBVTE9ORyBjYlByb3BEYXRhLAoJUFVMT05HIHBjYlJldHVybmVkCikgewoJSUNPTV9USElTKElLc1Byb3BlcnR5U2V0SW1wbCxpZmFjZSk7CgoJRklYTUUoIiglcCwlcywlbGQsJXAsJWxkLCVwLCVsZCwlcCksIHN0dWIhXG4iLFRoaXMsZGVidWdzdHJfZ3VpZChndWlkUHJvcFNldCksZHdQcm9wSUQscEluc3RhbmNlRGF0YSxjYkluc3RhbmNlRGF0YSxwUHJvcERhdGEsY2JQcm9wRGF0YSxwY2JSZXR1cm5lZCk7CglyZXR1cm4gRV9QUk9QX0lEX1VOU1VQUE9SVEVEOwp9CiNlbmRpZgoKI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUtzUHJvcGVydHlTZXRJbXBsX1NldChMUEtTUFJPUEVSVFlTRVQgaWZhY2UsCglSRUZHVUlEIGd1aWRQcm9wU2V0LCBVTE9ORyBkd1Byb3BJRCwKCUxQVk9JRCBwSW5zdGFuY2VEYXRhLCBVTE9ORyBjYkluc3RhbmNlRGF0YSwKCUxQVk9JRCBwUHJvcERhdGEsIFVMT05HIGNiUHJvcERhdGEKKSB7CglJQ09NX1RISVMoSUtzUHJvcGVydHlTZXRJbXBsLGlmYWNlKTsKCglGSVhNRSgiKCVwLCVzLCVsZCwlcCwlbGQsJXAsJWxkKSwgc3R1YiFcbiIsVGhpcyxkZWJ1Z3N0cl9ndWlkKGd1aWRQcm9wU2V0KSxkd1Byb3BJRCxwSW5zdGFuY2VEYXRhLGNiSW5zdGFuY2VEYXRhLHBQcm9wRGF0YSxjYlByb3BEYXRhKTsKCXJldHVybiBFX1BST1BfSURfVU5TVVBQT1JURUQ7Cn0KI2VuZGlmCgojaWZkZWYgVVNFX0RTT1VORDNECnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJS3NQcm9wZXJ0eVNldEltcGxfUXVlcnlTdXBwb3J0KExQS1NQUk9QRVJUWVNFVCBpZmFjZSwKCVJFRkdVSUQgZ3VpZFByb3BTZXQsIFVMT05HIGR3UHJvcElELCBQVUxPTkcgcFR5cGVTdXBwb3J0CikgewoJSUNPTV9USElTKElLc1Byb3BlcnR5U2V0SW1wbCxpZmFjZSk7CgoJRklYTUUoIiglcCwlcywlbGQsJXApLCBzdHViIVxuIixUaGlzLGRlYnVnc3RyX2d1aWQoZ3VpZFByb3BTZXQpLGR3UHJvcElELHBUeXBlU3VwcG9ydCk7CglyZXR1cm4gRV9QUk9QX0lEX1VOU1VQUE9SVEVEOwp9CiNlbmRpZgoKI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgSUNPTV9WVEFCTEUoSUtzUHJvcGVydHlTZXQpIGlrc3Z0ID0gewoJSUNPTV9NU1ZUQUJMRV9DT01QQVRfRHVtbXlSVFRJVkFMVUUKCUlLc1Byb3BlcnR5U2V0SW1wbF9RdWVyeUludGVyZmFjZSwKCUlLc1Byb3BlcnR5U2V0SW1wbF9BZGRSZWYsCglJS3NQcm9wZXJ0eVNldEltcGxfUmVsZWFzZSwKCUlLc1Byb3BlcnR5U2V0SW1wbF9HZXQsCglJS3NQcm9wZXJ0eVNldEltcGxfU2V0LAoJSUtzUHJvcGVydHlTZXRJbXBsX1F1ZXJ5U3VwcG9ydAp9OwojZW5kaWYKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgICBJRGlyZWN0U291bmQzREJ1ZmZlcgogKi8KCi8qIElVbmtub3duIG1ldGhvZHMgKi8KI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX1F1ZXJ5SW50ZXJmYWNlKAoJTFBESVJFQ1RTT1VORDNEQlVGRkVSIGlmYWNlLCBSRUZJSUQgcmlpZCwgTFBWT0lEICpwcG9iaikKewoJSUNPTV9USElTKElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbCxpZmFjZSk7CgoJaWYgKCBJc0VxdWFsR1VJRCggJklJRF9JS3NQcm9wZXJ0eVNldCwgcmlpZCApICkgewoJICAgIElEaXJlY3RTb3VuZDNEQnVmZmVyX0FkZFJlZihpZmFjZSk7CgkgICAgKnBwb2JqID0gVGhpcy0+aWtzOwoJICAgIHJldHVybiBTX09LOwoJfQoKCUZJWE1FKCIoJXAsJXMsJXApLCBubyBzdWNoIGludGVyZmFjZS5cbiIsVGhpcyxkZWJ1Z3N0cl9ndWlkKHJpaWQpLHBwb2JqKTsKCXJldHVybiBFX0ZBSUw7Cn0KI2VuZGlmCgojaWZkZWYgVVNFX0RTT1VORDNECnN0YXRpYyBVTE9ORyBXSU5BUEkgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX0FkZFJlZihMUERJUkVDVFNPVU5EM0RCVUZGRVIgaWZhY2UpCnsKCUlDT01fVEhJUyhJRGlyZWN0U291bmQzREJ1ZmZlckltcGwsaWZhY2UpOwoJVGhpcy0+cmVmKys7CglyZXR1cm4gVGhpcy0+cmVmOwp9CiNlbmRpZgoKI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgVUxPTkcgV0lOQVBJIElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9SZWxlYXNlKExQRElSRUNUU09VTkQzREJVRkZFUiBpZmFjZSkKewoJSUNPTV9USElTKElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbCxpZmFjZSk7CgoJVFJBQ0UoIiglcCkgcmVmIHdhcyAlbGRcbiIsIFRoaXMsIFRoaXMtPnJlZik7CgoJaWYoLS1UaGlzLT5yZWYpCgkJcmV0dXJuIFRoaXMtPnJlZjsKCglpZiAoVGhpcy0+ZHNiKQoJCUlEaXJlY3RTb3VuZEJ1ZmZlcl9SZWxlYXNlKChMUERJUkVDVFNPVU5EQlVGRkVSKVRoaXMtPmRzYik7CgoJRGVsZXRlQ3JpdGljYWxTZWN0aW9uKCZUaGlzLT5sb2NrKTsKCglIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsVGhpcy0+YnVmZmVyKTsKCUhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCxUaGlzKTsKCglyZXR1cm4gMDsKfQojZW5kaWYKCi8qIElEaXJlY3RTb3VuZDNEQnVmZmVyIG1ldGhvZHMgKi8KI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX0dldEFsbFBhcmFtZXRlcnMoCglMUERJUkVDVFNPVU5EM0RCVUZGRVIgaWZhY2UsCglMUERTM0RCVUZGRVIgbHBEczNkQnVmZmVyKQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KI2VuZGlmCgojaWZkZWYgVVNFX0RTT1VORDNECnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfR2V0Q29uZUFuZ2xlcygKCUxQRElSRUNUU09VTkQzREJVRkZFUiBpZmFjZSwKCUxQRFdPUkQgbHBkd0luc2lkZUNvbmVBbmdsZSwKCUxQRFdPUkQgbHBkd091dHNpZGVDb25lQW5nbGUpCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQojZW5kaWYKCiNpZmRlZiBVU0VfRFNPVU5EM0QKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9HZXRDb25lT3JpZW50YXRpb24oCglMUERJUkVDVFNPVU5EM0RCVUZGRVIgaWZhY2UsCglMUEQzRFZFQ1RPUiBscHZDb25lT3JpZW50YXRpb24pCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQojZW5kaWYKCiNpZmRlZiBVU0VfRFNPVU5EM0QKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9HZXRDb25lT3V0c2lkZVZvbHVtZSgKCUxQRElSRUNUU09VTkQzREJVRkZFUiBpZmFjZSwKCUxQTE9ORyBscGxDb25lT3V0c2lkZVZvbHVtZSkKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CiNlbmRpZgoKI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX0dldE1heERpc3RhbmNlKAoJTFBESVJFQ1RTT1VORDNEQlVGRkVSIGlmYWNlLAoJTFBEM0RWQUxVRSBscGZNYXhEaXN0YW5jZSkKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CiNlbmRpZgoKI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX0dldE1pbkRpc3RhbmNlKAoJTFBESVJFQ1RTT1VORDNEQlVGRkVSIGlmYWNlLAoJTFBEM0RWQUxVRSBscGZNaW5EaXN0YW5jZSkKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CiNlbmRpZgoKI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX0dldE1vZGUoCglMUERJUkVDVFNPVU5EM0RCVUZGRVIgaWZhY2UsCglMUERXT1JEIGxwZHdNb2RlKQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KI2VuZGlmCgojaWZkZWYgVVNFX0RTT1VORDNECnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfR2V0UG9zaXRpb24oCglMUERJUkVDVFNPVU5EM0RCVUZGRVIgaWZhY2UsCglMUEQzRFZFQ1RPUiBscHZQb3NpdGlvbikKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CiNlbmRpZgoKI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX0dldFZlbG9jaXR5KAoJTFBESVJFQ1RTT1VORDNEQlVGRkVSIGlmYWNlLAoJTFBEM0RWRUNUT1IgbHB2VmVsb2NpdHkpCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQojZW5kaWYKCiNpZmRlZiBVU0VfRFNPVU5EM0QKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9TZXRBbGxQYXJhbWV0ZXJzKAoJTFBESVJFQ1RTT1VORDNEQlVGRkVSIGlmYWNlLAoJTFBDRFMzREJVRkZFUiBscGNEczNkQnVmZmVyLAoJRFdPUkQgZHdBcHBseSkKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CiNlbmRpZgoKI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX1NldENvbmVBbmdsZXMoCglMUERJUkVDVFNPVU5EM0RCVUZGRVIgaWZhY2UsCglEV09SRCBkd0luc2lkZUNvbmVBbmdsZSwKCURXT1JEIGR3T3V0c2lkZUNvbmVBbmdsZSwKCURXT1JEIGR3QXBwbHkpCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQojZW5kaWYKCiNpZmRlZiBVU0VfRFNPVU5EM0QKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9TZXRDb25lT3JpZW50YXRpb24oCglMUERJUkVDVFNPVU5EM0RCVUZGRVIgaWZhY2UsCglEM0RWQUxVRSB4LCBEM0RWQUxVRSB5LCBEM0RWQUxVRSB6LAoJRFdPUkQgZHdBcHBseSkKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CiNlbmRpZgoKI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX1NldENvbmVPdXRzaWRlVm9sdW1lKAoJTFBESVJFQ1RTT1VORDNEQlVGRkVSIGlmYWNlLAoJTE9ORyBsQ29uZU91dHNpZGVWb2x1bWUsCglEV09SRCBkd0FwcGx5KQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KI2VuZGlmCgojaWZkZWYgVVNFX0RTT1VORDNECnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfU2V0TWF4RGlzdGFuY2UoCglMUERJUkVDVFNPVU5EM0RCVUZGRVIgaWZhY2UsCglEM0RWQUxVRSBmTWF4RGlzdGFuY2UsCglEV09SRCBkd0FwcGx5KQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KI2VuZGlmCgojaWZkZWYgVVNFX0RTT1VORDNECnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfU2V0TWluRGlzdGFuY2UoCglMUERJUkVDVFNPVU5EM0RCVUZGRVIgaWZhY2UsCglEM0RWQUxVRSBmTWluRGlzdGFuY2UsCglEV09SRCBkd0FwcGx5KQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KI2VuZGlmCgojaWZkZWYgVVNFX0RTT1VORDNECnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfU2V0TW9kZSgKCUxQRElSRUNUU09VTkQzREJVRkZFUiBpZmFjZSwKCURXT1JEIGR3TW9kZSwKCURXT1JEIGR3QXBwbHkpCnsKCUlDT01fVEhJUyhJRGlyZWN0U291bmQzREJ1ZmZlckltcGwsaWZhY2UpOwoJVFJBQ0UoIm1vZGUgPSAlbHhcbiIsIGR3TW9kZSk7CglUaGlzLT5kczNkYi5kd01vZGUgPSBkd01vZGU7CglyZXR1cm4gRFNfT0s7Cn0KI2VuZGlmCgojaWZkZWYgVVNFX0RTT1VORDNECnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfU2V0UG9zaXRpb24oCglMUERJUkVDVFNPVU5EM0RCVUZGRVIgaWZhY2UsCglEM0RWQUxVRSB4LCBEM0RWQUxVRSB5LCBEM0RWQUxVRSB6LAoJRFdPUkQgZHdBcHBseSkKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CiNlbmRpZgoKI2lmZGVmIFVTRV9EU09VTkQzRApzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX1NldFZlbG9jaXR5KAoJTFBESVJFQ1RTT1VORDNEQlVGRkVSIGlmYWNlLAoJRDNEVkFMVUUgeCwgRDNEVkFMVUUgeSwgRDNEVkFMVUUgeiwKCURXT1JEIGR3QXBwbHkpCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQojZW5kaWYKCiNpZmRlZiBVU0VfRFNPVU5EM0QKc3RhdGljIElDT01fVlRBQkxFKElEaXJlY3RTb3VuZDNEQnVmZmVyKSBkczNkYnZ0ID0gCnsKCUlDT01fTVNWVEFCTEVfQ09NUEFUX0R1bW15UlRUSVZBTFVFCgkvKiBJVW5rbm93biBtZXRob2RzICovCglJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfUXVlcnlJbnRlcmZhY2UsCglJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfQWRkUmVmLAoJSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX1JlbGVhc2UsCgkvKiBJRGlyZWN0U291bmQzREJ1ZmZlciBtZXRob2RzICovCglJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfR2V0QWxsUGFyYW1ldGVycywKCUlEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9HZXRDb25lQW5nbGVzLAoJSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX0dldENvbmVPcmllbnRhdGlvbiwKCUlEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9HZXRDb25lT3V0c2lkZVZvbHVtZSwKCUlEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9HZXRNYXhEaXN0YW5jZSwKCUlEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9HZXRNaW5EaXN0YW5jZSwKCUlEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9HZXRNb2RlLAoJSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX0dldFBvc2l0aW9uLAoJSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX0dldFZlbG9jaXR5LAoJSURpcmVjdFNvdW5kM0RCdWZmZXJJbXBsX1NldEFsbFBhcmFtZXRlcnMsCglJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfU2V0Q29uZUFuZ2xlcywKCUlEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9TZXRDb25lT3JpZW50YXRpb24sCglJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfU2V0Q29uZU91dHNpZGVWb2x1bWUsCglJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfU2V0TWF4RGlzdGFuY2UsCglJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfU2V0TWluRGlzdGFuY2UsCglJRGlyZWN0U291bmQzREJ1ZmZlckltcGxfU2V0TW9kZSwKCUlEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9TZXRQb3NpdGlvbiwKCUlEaXJlY3RTb3VuZDNEQnVmZmVySW1wbF9TZXRWZWxvY2l0eSwKfTsKI2VuZGlmCgojaWZkZWYgVVNFX0RTT1VORDNECnN0YXRpYyBpbnQgRFNPVU5EX0NyZWF0ZTNEQnVmZmVyKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwqIGRzYikKewoJRFdPUkQJaSwgdGVtcCwgaVNpemUsIG9TaXplLCBvZmZzZXQ7CglMUEJZVEUJYklidWYsIGJPYnVmLCBiVGJ1ZiA9IE5VTEw7CglMUFdPUkQJd0lidWYsIHdPYnVmLCB3VGJ1ZiA9IE5VTEw7CgoJLyogSW5zaWRlIERpcmVjdFggc2F5cyBpdCdzIHN0dXBpZCBidXQgYWxsb3dlZCAqLwoJaWYgKGRzYi0+d2Z4Lm5DaGFubmVscyA9PSAyKSB7CgkJLyogQ29udmVydCB0byBtb25vICovCgkJaWYgKGRzYi0+d2Z4LndCaXRzUGVyU2FtcGxlID09IDE2KSB7CgkJCWlTaXplID0gZHNiLT5idWZsZW4gLyA0OwoJCQl3VGJ1ZiA9IG1hbGxvYyhkc2ItPmJ1ZmxlbiAvIDIpOwoJCQlpZiAod1RidWYgPT0gTlVMTCkKCQkJCXJldHVybiBEU0VSUl9PVVRPRk1FTU9SWTsKCQkJZm9yIChpID0gMDsgaSA8IGlTaXplOyBpKyspCgkJCQl3VGJ1ZltpXSA9IChkc2ItPmJ1ZmZlcltpICogMl0gKyBkc2ItPmJ1ZmZlclsoaSAqIDIpICsgMV0pIC8gMjsKCQkJd0lidWYgPSB3VGJ1ZjsKCQl9IGVsc2UgewoJCQlpU2l6ZSA9IGRzYi0+YnVmbGVuIC8gMjsKCQkJYlRidWYgPSBtYWxsb2MoZHNiLT5idWZsZW4gLyAyKTsKCQkJaWYgKGJUYnVmID09IE5VTEwpCgkJCQlyZXR1cm4gRFNFUlJfT1VUT0ZNRU1PUlk7CgkJCWZvciAoaSA9IDA7IGkgPCBpU2l6ZTsgaSsrKQoJCQkJYlRidWZbaV0gPSAoZHNiLT5idWZmZXJbaSAqIDJdICsgZHNiLT5idWZmZXJbKGkgKiAyKSArIDFdKSAvIDI7CgkJCWJJYnVmID0gYlRidWY7CgkJfQoJfSBlbHNlIHsKCQlpZiAoZHNiLT53Zngud0JpdHNQZXJTYW1wbGUgPT0gMTYpIHsKCQkJaVNpemUgPSBkc2ItPmJ1ZmxlbiAvIDI7CgkJCXdJYnVmID0gKExQV09SRCkgZHNiLT5idWZmZXI7CgkJfSBlbHNlIHsKCQkJYklidWYgPSAoTFBCWVRFKSBkc2ItPmJ1ZmZlcjsKCQkJaVNpemUgPSBkc2ItPmJ1ZmxlbjsKCQl9Cgl9CgoJaWYgKHByaW1hcnlidWYtPndmeC53Qml0c1BlclNhbXBsZSA9PSAxNikgewoJCXdPYnVmID0gKExQV09SRCkgZHNiLT5kczNkYi0+YnVmZmVyOwoJCW9TaXplID0gZHNiLT5kczNkYi0+YnVmbGVuIC8gMjsKCX0gZWxzZSB7CgkJYk9idWYgPSAoTFBCWVRFKSBkc2ItPmRzM2RiLT5idWZmZXI7CgkJb1NpemUgPSBkc2ItPmRzM2RiLT5idWZsZW47Cgl9CgoJb2Zmc2V0ID0gcHJpbWFyeWJ1Zi0+d2Z4Lm5TYW1wbGVzUGVyU2VjIC8gMTAwOwkJLyogMTBtcyAqLwoJaWYgKHByaW1hcnlidWYtPndmeC53Qml0c1BlclNhbXBsZSA9PSAxNiAmJiBkc2ItPndmeC53Qml0c1BlclNhbXBsZSA9PSAxNikKCQlmb3IgKGkgPSAwOyBpIDwgaVNpemU7IGkrKykgewoJCQl0ZW1wID0gd0lidWZbaV07CgkJCWlmIChpID49IG9mZnNldCkKCQkJCXRlbXAgKz0gd0lidWZbaSAtIG9mZnNldF0gPj4gOTsKCQkJZWxzZQoJCQkJdGVtcCArPSB3SWJ1ZltpICsgaVNpemUgLSBvZmZzZXRdID4+IDk7CgkJCXdPYnVmW2kgKiAyXSA9IHRlbXA7CgkJCXdPYnVmWyhpICogMikgKyAxXSA9IHRlbXA7CgkJfQoJZWxzZSBpZiAocHJpbWFyeWJ1Zi0+d2Z4LndCaXRzUGVyU2FtcGxlID09IDggJiYgZHNiLT53Zngud0JpdHNQZXJTYW1wbGUgPT0gOCkKCQlmb3IgKGkgPSAwOyBpIDwgaVNpemU7IGkrKykgewoJCQl0ZW1wID0gYklidWZbaV07CgkJCWlmIChpID49IG9mZnNldCkKCQkJCXRlbXAgKz0gYklidWZbaSAtIG9mZnNldF0gPj4gNTsKCQkJZWxzZQoJCQkJdGVtcCArPSBiSWJ1ZltpICsgaVNpemUgLSBvZmZzZXRdID4+IDU7CgkJCWJPYnVmW2kgKiAyXSA9IHRlbXA7CgkJCWJPYnVmWyhpICogMikgKyAxXSA9IHRlbXA7CgkJfQoJCglpZiAod1RidWYpCgkJZnJlZSh3VGJ1Zik7CglpZiAoYlRidWYpCgkJZnJlZShiVGJ1Zik7CgoJcmV0dXJuIERTX09LOwp9CiNlbmRpZgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgSURpcmVjdFNvdW5kM0RMaXN0ZW5lcgogKi8KCi8qIElVbmtub3duIG1ldGhvZHMgKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX1F1ZXJ5SW50ZXJmYWNlKAoJTFBESVJFQ1RTT1VORDNETElTVEVORVIgaWZhY2UsIFJFRklJRCByaWlkLCBMUFZPSUQgKnBwb2JqKQp7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGwsaWZhY2UpOwoKCVRSQUNFKCIoJXAsJXMsJXApXG4iLFRoaXMsZGVidWdzdHJfZ3VpZChyaWlkKSxwcG9iaik7CglyZXR1cm4gRV9GQUlMOwp9CgkKc3RhdGljIFVMT05HIFdJTkFQSSBJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9BZGRSZWYoTFBESVJFQ1RTT1VORDNETElTVEVORVIgaWZhY2UpCnsKCUlDT01fVEhJUyhJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbCxpZmFjZSk7CglUaGlzLT5yZWYrKzsKCXJldHVybiBUaGlzLT5yZWY7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfUmVsZWFzZShMUERJUkVDVFNPVU5EM0RMSVNURU5FUiBpZmFjZSkKewoJVUxPTkcgdWxSZXR1cm47CglJQ09NX1RISVMoSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGwsaWZhY2UpOwoKCVRSQUNFKCIoJXApIHJlZiB3YXMgJWxkXG4iLCBUaGlzLCBUaGlzLT5yZWYpOwoKCXVsUmV0dXJuID0gLS1UaGlzLT5yZWY7CgoJLyogRnJlZSBhbGwgcmVzb3VyY2VzICovCglpZiggdWxSZXR1cm4gPT0gMCApIHsKCQlpZihUaGlzLT5kc2IpCgkJCUlEaXJlY3RTb3VuZEJ1ZmZlcl9SZWxlYXNlKChMUERJUkVDVFNPVU5EQlVGRkVSKVRoaXMtPmRzYik7CgkJRGVsZXRlQ3JpdGljYWxTZWN0aW9uKCZUaGlzLT5sb2NrKTsKCQlIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsVGhpcyk7Cgl9CgoJcmV0dXJuIHVsUmV0dXJuOwp9CgovKiBJRGlyZWN0U291bmQzRExpc3RlbmVyIG1ldGhvZHMgKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX0dldEFsbFBhcmFtZXRlcigKCUxQRElSRUNUU09VTkQzRExJU1RFTkVSIGlmYWNlLAoJTFBEUzNETElTVEVORVIgbHBEUzNETCkKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfR2V0RGlzdGFuY2VGYWN0b3IoCglMUERJUkVDVFNPVU5EM0RMSVNURU5FUiBpZmFjZSwKCUxQRDNEVkFMVUUgbHBmRGlzdGFuY2VGYWN0b3IpCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX0dldERvcHBsZXJGYWN0b3IoCglMUERJUkVDVFNPVU5EM0RMSVNURU5FUiBpZmFjZSwKCUxQRDNEVkFMVUUgbHBmRG9wcGxlckZhY3RvcikKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfR2V0T3JpZW50YXRpb24oCglMUERJUkVDVFNPVU5EM0RMSVNURU5FUiBpZmFjZSwKCUxQRDNEVkVDVE9SIGxwdk9yaWVudEZyb250LAoJTFBEM0RWRUNUT1IgbHB2T3JpZW50VG9wKQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9HZXRQb3NpdGlvbigKCUxQRElSRUNUU09VTkQzRExJU1RFTkVSIGlmYWNlLAoJTFBEM0RWRUNUT1IgbHB2UG9zaXRpb24pCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX0dldFJvbGxvZmZGYWN0b3IoCglMUERJUkVDVFNPVU5EM0RMSVNURU5FUiBpZmFjZSwKCUxQRDNEVkFMVUUgbHBmUm9sbG9mZkZhY3RvcikKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfR2V0VmVsb2NpdHkoCglMUERJUkVDVFNPVU5EM0RMSVNURU5FUiBpZmFjZSwKCUxQRDNEVkVDVE9SIGxwdlZlbG9jaXR5KQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9TZXRBbGxQYXJhbWV0ZXJzKAoJTFBESVJFQ1RTT1VORDNETElTVEVORVIgaWZhY2UsCglMUENEUzNETElTVEVORVIgbHBjRFMzREwsCglEV09SRCBkd0FwcGx5KQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9TZXREaXN0YW5jZUZhY3RvcigKCUxQRElSRUNUU09VTkQzRExJU1RFTkVSIGlmYWNlLAoJRDNEVkFMVUUgZkRpc3RhbmNlRmFjdG9yLAoJRFdPUkQgZHdBcHBseSkKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfU2V0RG9wcGxlckZhY3RvcigKCUxQRElSRUNUU09VTkQzRExJU1RFTkVSIGlmYWNlLAoJRDNEVkFMVUUgZkRvcHBsZXJGYWN0b3IsCglEV09SRCBkd0FwcGx5KQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9TZXRPcmllbnRhdGlvbigKCUxQRElSRUNUU09VTkQzRExJU1RFTkVSIGlmYWNlLAoJRDNEVkFMVUUgeEZyb250LCBEM0RWQUxVRSB5RnJvbnQsIEQzRFZBTFVFIHpGcm9udCwKCUQzRFZBTFVFIHhUb3AsIEQzRFZBTFVFIHlUb3AsIEQzRFZBTFVFIHpUb3AsCglEV09SRCBkd0FwcGx5KQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9TZXRQb3NpdGlvbigKCUxQRElSRUNUU09VTkQzRExJU1RFTkVSIGlmYWNlLAoJRDNEVkFMVUUgeCwgRDNEVkFMVUUgeSwgRDNEVkFMVUUgeiwKCURXT1JEIGR3QXBwbHkpCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX1NldFJvbGxvZmZGYWN0b3IoCglMUERJUkVDVFNPVU5EM0RMSVNURU5FUiBpZmFjZSwKCUQzRFZBTFVFIGZSb2xsb2ZmRmFjdG9yLAoJRFdPUkQgZHdBcHBseSkKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfU2V0VmVsb2NpdHkoCglMUERJUkVDVFNPVU5EM0RMSVNURU5FUiBpZmFjZSwKCUQzRFZBTFVFIHgsIEQzRFZBTFVFIHksIEQzRFZBTFVFIHosCglEV09SRCBkd0FwcGx5KQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9Db21taXREZWZlcnJlZFNldHRpbmdzKAoJTFBESVJFQ1RTT1VORDNETElTVEVORVIgaWZhY2UpCgp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBJQ09NX1ZUQUJMRShJRGlyZWN0U291bmQzRExpc3RlbmVyKSBkczNkbHZ0ID0gCnsKCUlDT01fTVNWVEFCTEVfQ09NUEFUX0R1bW15UlRUSVZBTFVFCgkvKiBJVW5rbm93biBtZXRob2RzICovCglJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9RdWVyeUludGVyZmFjZSwKCUlEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX0FkZFJlZiwKCUlEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX1JlbGVhc2UsCgkvKiBJRGlyZWN0U291bmQzRExpc3RlbmVyIG1ldGhvZHMgKi8KCUlEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX0dldEFsbFBhcmFtZXRlciwKCUlEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX0dldERpc3RhbmNlRmFjdG9yLAoJSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfR2V0RG9wcGxlckZhY3RvciwKCUlEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX0dldE9yaWVudGF0aW9uLAoJSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfR2V0UG9zaXRpb24sCglJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9HZXRSb2xsb2ZmRmFjdG9yLAoJSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfR2V0VmVsb2NpdHksCglJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9TZXRBbGxQYXJhbWV0ZXJzLAoJSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfU2V0RGlzdGFuY2VGYWN0b3IsCglJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9TZXREb3BwbGVyRmFjdG9yLAoJSURpcmVjdFNvdW5kM0RMaXN0ZW5lckltcGxfU2V0T3JpZW50YXRpb24sCglJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9TZXRQb3NpdGlvbiwKCUlEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX1NldFJvbGxvZmZGYWN0b3IsCglJRGlyZWN0U291bmQzRExpc3RlbmVySW1wbF9TZXRWZWxvY2l0eSwKCUlEaXJlY3RTb3VuZDNETGlzdGVuZXJJbXBsX0NvbW1pdERlZmVycmVkU2V0dGluZ3MsCn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJSURpcmVjdFNvdW5kTm90aWZ5CiAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdFNvdW5kTm90aWZ5SW1wbF9RdWVyeUludGVyZmFjZSgKCUxQRElSRUNUU09VTkROT1RJRlkgaWZhY2UsUkVGSUlEIHJpaWQsTFBWT0lEICpwcG9iagopIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmROb3RpZnlJbXBsLGlmYWNlKTsKCglUUkFDRSgiKCVwLCVzLCVwKVxuIixUaGlzLGRlYnVnc3RyX2d1aWQocmlpZCkscHBvYmopOwoJcmV0dXJuIEVfRkFJTDsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBJRGlyZWN0U291bmROb3RpZnlJbXBsX0FkZFJlZihMUERJUkVDVFNPVU5ETk9USUZZIGlmYWNlKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kTm90aWZ5SW1wbCxpZmFjZSk7CglyZXR1cm4gKysoVGhpcy0+cmVmKTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBJRGlyZWN0U291bmROb3RpZnlJbXBsX1JlbGVhc2UoTFBESVJFQ1RTT1VORE5PVElGWSBpZmFjZSkgewoJSUNPTV9USElTKElEaXJlY3RTb3VuZE5vdGlmeUltcGwsaWZhY2UpOwoKCVRSQUNFKCIoJXApIHJlZiB3YXMgJWxkXG4iLCBUaGlzLCBUaGlzLT5yZWYpOwoKCVRoaXMtPnJlZi0tOwoJaWYgKCFUaGlzLT5yZWYpIHsKCQlJRGlyZWN0U291bmRCdWZmZXJfUmVsZWFzZSgoTFBESVJFQ1RTT1VOREJVRkZFUilUaGlzLT5kc2IpOwoJCUhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCxUaGlzKTsKCQlyZXR1cm4gMDsKCX0KCXJldHVybiBUaGlzLT5yZWY7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmROb3RpZnlJbXBsX1NldE5vdGlmaWNhdGlvblBvc2l0aW9ucygKCUxQRElSRUNUU09VTkROT1RJRlkgaWZhY2UsRFdPUkQgaG93bXVjaCxMUENEU0JQT1NJVElPTk5PVElGWSBub3RpZnkKKSB7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kTm90aWZ5SW1wbCxpZmFjZSk7CglpbnQJaTsKCglpZiAoVFJBQ0VfT04oZHNvdW5kKSkgewoJICAgIFRSQUNFKCIoJXAsMHglMDhseCwlcClcbiIsVGhpcyxob3dtdWNoLG5vdGlmeSk7CgkgICAgZm9yIChpPTA7aTxob3dtdWNoO2krKykKCQkgICAgVFJBQ0UoIm5vdGlmeSBhdCAlbGQgdG8gMHglMDhseFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vdGlmeVtpXS5kd09mZnNldCwoRFdPUkQpbm90aWZ5W2ldLmhFdmVudE5vdGlmeSk7Cgl9CglUaGlzLT5kc2ItPm5vdGlmaWVzID0gSGVhcFJlQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSxIRUFQX1pFUk9fTUVNT1JZLFRoaXMtPmRzYi0+bm90aWZpZXMsKFRoaXMtPmRzYi0+bnJvZm5vdGlmaWVzK2hvd211Y2gpKnNpemVvZihEU0JQT1NJVElPTk5PVElGWSkpOwoJbWVtY3B5KAlUaGlzLT5kc2ItPm5vdGlmaWVzK1RoaXMtPmRzYi0+bnJvZm5vdGlmaWVzLAoJCW5vdGlmeSwKCQlob3dtdWNoKnNpemVvZihEU0JQT1NJVElPTk5PVElGWSkKCSk7CglUaGlzLT5kc2ItPm5yb2Zub3RpZmllcys9aG93bXVjaDsKCglyZXR1cm4gU19PSzsKfQoKc3RhdGljIElDT01fVlRBQkxFKElEaXJlY3RTb3VuZE5vdGlmeSkgZHNudnQgPSAKewoJSUNPTV9NU1ZUQUJMRV9DT01QQVRfRHVtbXlSVFRJVkFMVUUKCUlEaXJlY3RTb3VuZE5vdGlmeUltcGxfUXVlcnlJbnRlcmZhY2UsCglJRGlyZWN0U291bmROb3RpZnlJbXBsX0FkZFJlZiwKCUlEaXJlY3RTb3VuZE5vdGlmeUltcGxfUmVsZWFzZSwKCUlEaXJlY3RTb3VuZE5vdGlmeUltcGxfU2V0Tm90aWZpY2F0aW9uUG9zaXRpb25zLAp9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUlEaXJlY3RTb3VuZEJ1ZmZlcgogKi8KCnN0YXRpYyB2b2lkIERTT1VORF9SZWNhbGNWb2xQYW4oUERTVk9MVU1FUEFOIHZvbHBhbikKewoJZG91YmxlIHRlbXA7CgoJLyogdGhlIEFtcEZhY3RvcnMgYXJlIGV4cHJlc3NlZCBpbiAxNi4xNiBmaXhlZCBwb2ludCAqLwoJdm9scGFuLT5kd1ZvbEFtcEZhY3RvciA9IChVTE9ORykgKHBvdygyLjAsIHZvbHBhbi0+bFZvbHVtZSAvIDYwMC4wKSAqIDY1NTM2KTsKCS8qIEZJWE1FOiBkd1BhbntMZWZ0fFJpZ2h0fUFtcEZhY3RvciAqLwoKCS8qIEZJWE1FOiB1c2UgY2FsY3VsYXRlZCB2b2wgYW5kIHBhbiBhbXBmYWN0b3JzICovCgl0ZW1wID0gKGRvdWJsZSkgKHZvbHBhbi0+bFZvbHVtZSAtICh2b2xwYW4tPmxQYW4gPiAwID8gdm9scGFuLT5sUGFuIDogMCkpOwoJdm9scGFuLT5kd1RvdGFsTGVmdEFtcEZhY3RvciA9IChVTE9ORykgKHBvdygyLjAsIHRlbXAgLyA2MDAuMCkgKiA2NTUzNik7Cgl0ZW1wID0gKGRvdWJsZSkgKHZvbHBhbi0+bFZvbHVtZSArICh2b2xwYW4tPmxQYW4gPCAwID8gdm9scGFuLT5sUGFuIDogMCkpOwoJdm9scGFuLT5kd1RvdGFsUmlnaHRBbXBGYWN0b3IgPSAoVUxPTkcpIChwb3coMi4wLCB0ZW1wIC8gNjAwLjApICogNjU1MzYpOwoKCVRSQUNFKCJsZWZ0ID0gJWx4LCByaWdodCA9ICVseFxuIiwgdm9scGFuLT5kd1RvdGFsTGVmdEFtcEZhY3Rvciwgdm9scGFuLT5kd1RvdGFsUmlnaHRBbXBGYWN0b3IpOwp9CgpzdGF0aWMgdm9pZCBEU09VTkRfUmVjYWxjRm9ybWF0KElEaXJlY3RTb3VuZEJ1ZmZlckltcGwgKmRzYikKewoJRFdPUkQgc3c7CgoJc3cgPSBkc2ItPndmeC5uQ2hhbm5lbHMgKiAoZHNiLT53Zngud0JpdHNQZXJTYW1wbGUgLyA4KTsKCWlmICgoZHNiLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX1BSSU1BUllCVUZGRVIpICYmIGRzYi0+aHdidWYpIHsKCQlEV09SRCBmcmFnbGVuOwoJCS8qIGxldCBmcmFnbWVudCBzaXplIGFwcHJveGltYXRlIHRoZSB0aW1lciBkZWxheSAqLwoJCWZyYWdsZW4gPSAoZHNiLT5mcmVxICogRFNfVElNRV9ERUwgLyAxMDAwKSAqIHN3OwoJCS8qIHJlZHVjZSBmcmFnbWVudCBzaXplIHVudGlsIGFuIGludGVnZXIgbnVtYmVyIG9mIHRoZW0gZml0cyBpbiB0aGUgYnVmZmVyICovCgkJLyogKEZJWE1FOiB0aGlzIG1heSBvciBtYXkgbm90IGJlIGEgZ29vZCBpZGVhKSAqLwoJCXdoaWxlIChkc2ItPmJ1ZmxlbiAlIGZyYWdsZW4pIGZyYWdsZW4gLT0gc3c7CgkJZHNiLT5kc291bmQtPmZyYWdsZW4gPSBmcmFnbGVuOwoJCVRSQUNFKCJmcmFnbGVuPSVsZFxuIiwgZHNiLT5kc291bmQtPmZyYWdsZW4pOwoJfQoJLyogY2FsY3VsYXRlIHRoZSAxMG1zIHdyaXRlIGxlYWQgKi8KCWRzYi0+d3JpdGVsZWFkID0gKGRzYi0+ZnJlcSAvIDEwMCkgKiBzdzsKfQoKc3RhdGljIEhSRVNVTFQgRFNPVU5EX1ByaW1hcnlPcGVuKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwgKmRzYikKewoJSFJFU1VMVCBlcnIgPSBEU19PSzsKCgkvKiBhcmUgd2UgdXNpbmcgd2F2ZU91dCBzdHVmZj8gKi8KCWlmICghZHNiLT5od2J1ZikgewoJCUxQQllURSBuZXdidWY7CgkJRFdPUkQgYnVmbGVuOwoJCUhSRVNVTFQgbWVyciA9IERTX09LOwoJCS8qIFN0YXJ0IGluIHBhdXNlIG1vZGUsIHRvIGFsbG93IGJ1ZmZlcnMgdG8gZ2V0IGZpbGxlZCAqLwoJCXdhdmVPdXRQYXVzZShkc2ItPmRzb3VuZC0+aHdvKTsKCQlpZiAoZHNiLT5zdGF0ZSA9PSBTVEFURV9QTEFZSU5HKSBkc2ItPnN0YXRlID0gU1RBVEVfU1RBUlRJTkc7CgkJZWxzZSBpZiAoZHNiLT5zdGF0ZSA9PSBTVEFURV9TVE9QUElORykgZHNiLT5zdGF0ZSA9IFNUQVRFX1NUT1BQRUQ7CgkJLyogdXNlIGZyYWdtZW50cyBvZiAxMG1zICgxLzEwMHMpIGVhY2ggKHdoaWNoIHNob3VsZCBnZXQgdXMgd2l0aGluCgkJICogdGhlIGRvY3VtZW50ZWQgd3JpdGUgY3Vyc29yIGxlYWQgb2YgMTAtMTVtcykgKi8KCQlidWZsZW4gPSAoKGRzYi0+d2Z4Lm5BdmdCeXRlc1BlclNlYyAvIDEwMCkgJiB+MykgKiBEU19IRUxfRlJBR1M7CgkJVFJBQ0UoImRlc2lyZWQgYnVmbGVuPSVsZCwgb2xkIGJ1ZmZlcj0lcFxuIiwgYnVmbGVuLCBkc2ItPmJ1ZmZlcik7CgkJLyogcmVhbGxvY2F0ZSBlbXVsYXRlZCBwcmltYXJ5IGJ1ZmZlciAqLwoJCW5ld2J1ZiA9IChMUEJZVEUpSGVhcFJlQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwwLGRzYi0+YnVmZmVyLGJ1Zmxlbik7CgkJaWYgKG5ld2J1ZiA9PSBOVUxMKSB7CgkJCUVSUigiZmFpbGVkIHRvIGFsbG9jYXRlIHByaW1hcnkgYnVmZmVyXG4iKTsKCQkJbWVyciA9IERTRVJSX09VVE9GTUVNT1JZOwoJCQkvKiBidXQgdGhlIG9sZCBidWZmZXIgbWlnaHQgc3RpbGwgZXhpc3RzIGFuZCBtdXN0IGJlIHJlLXByZXBhcmVkICovCgkJfSBlbHNlIHsKCQkJZHNiLT5idWZmZXIgPSBuZXdidWY7CgkJCWRzYi0+YnVmbGVuID0gYnVmbGVuOwoJCX0KCQlpZiAoZHNiLT5idWZmZXIpIHsKCQkJdW5zaWduZWQgYzsKCQkJSURpcmVjdFNvdW5kSW1wbCAqZHMgPSBkc2ItPmRzb3VuZDsKCgkJCWRzLT5mcmFnbGVuID0gZHNiLT5idWZsZW4gLyBEU19IRUxfRlJBR1M7CgoJCQkvKiBwcmVwYXJlIGZyYWdtZW50IGhlYWRlcnMgKi8KCQkJZm9yIChjPTA7IGM8RFNfSEVMX0ZSQUdTOyBjKyspIHsKCQkJCWRzLT5wd2F2ZVtjXS0+bHBEYXRhID0gZHNiLT5idWZmZXIgKyBjKmRzLT5mcmFnbGVuOwoJCQkJZHMtPnB3YXZlW2NdLT5kd0J1ZmZlckxlbmd0aCA9IGRzLT5mcmFnbGVuOwoJCQkJZHMtPnB3YXZlW2NdLT5kd1VzZXIgPSAoRFdPUkQpZHNiOwoJCQkJZHMtPnB3YXZlW2NdLT5kd0ZsYWdzID0gMDsKCQkJCWRzLT5wd2F2ZVtjXS0+ZHdMb29wcyA9IDA7CgkJCQllcnIgPSBtbUVycih3YXZlT3V0UHJlcGFyZUhlYWRlcihkcy0+aHdvLGRzLT5wd2F2ZVtjXSxzaXplb2YoV0FWRUhEUikpKTsKCQkJCWlmIChlcnIgIT0gRFNfT0spIHsKCQkJCQl3aGlsZSAoYy0tKQoJCQkJCQl3YXZlT3V0VW5wcmVwYXJlSGVhZGVyKGRzLT5od28sZHMtPnB3YXZlW2NdLHNpemVvZihXQVZFSERSKSk7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCX0KCgkJCWRzLT5wd3BsYXkgPSAwOwoJCQlkcy0+cHd3cml0ZSA9IDA7CgkJCWRzLT5wd3F1ZXVlID0gMDsKCQkJbWVtc2V0KGRzYi0+YnVmZmVyLCAoZHNiLT53Zngud0JpdHNQZXJTYW1wbGUgPT0gMTYpID8gMCA6IDEyOCwgZHNiLT5idWZsZW4pOwoJCQlUUkFDRSgiZnJhZ2xlbj0lbGRcbiIsIGRzLT5mcmFnbGVuKTsKCQkJRFNPVU5EX1dhdmVRdWV1ZShkc2ItPmRzb3VuZCwgKERXT1JEKS0xKTsKCQl9CgkJaWYgKChlcnIgPT0gRFNfT0spICYmIChtZXJyICE9IERTX09LKSkKCQkJZXJyID0gbWVycjsKCX0KCXJldHVybiBlcnI7Cn0KCgpzdGF0aWMgdm9pZCBEU09VTkRfUHJpbWFyeUNsb3NlKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwgKmRzYikKewoJLyogYXJlIHdlIHVzaW5nIHdhdmVPdXQgc3R1ZmY/ICovCglpZiAoIWRzYi0+aHdidWYpIHsKCQl1bnNpZ25lZCBjOwoJCUlEaXJlY3RTb3VuZEltcGwgKmRzID0gZHNiLT5kc291bmQ7CgoJCWRzLT5wd3F1ZXVlID0gKERXT1JEKS0xOyAvKiByZXNldHRpbmcgcXVldWVzICovCgkJd2F2ZU91dFJlc2V0KGRzLT5od28pOwoJCWZvciAoYz0wOyBjPERTX0hFTF9GUkFHUzsgYysrKQoJCQl3YXZlT3V0VW5wcmVwYXJlSGVhZGVyKGRzLT5od28sIGRzLT5wd2F2ZVtjXSwgc2l6ZW9mKFdBVkVIRFIpKTsKCQlkcy0+cHdxdWV1ZSA9IDA7Cgl9Cn0KCnN0YXRpYyBIUkVTVUxUIERTT1VORF9QcmltYXJ5UGxheShJRGlyZWN0U291bmRCdWZmZXJJbXBsICpkc2IpCnsKCUhSRVNVTFQgZXJyID0gRFNfT0s7CglpZiAoZHNiLT5od2J1ZikKCQllcnIgPSBJRHNEcml2ZXJCdWZmZXJfUGxheShkc2ItPmh3YnVmLCAwLCAwLCBEU0JQTEFZX0xPT1BJTkcpOwoJZWxzZQoJCWVyciA9IG1tRXJyKHdhdmVPdXRSZXN0YXJ0KGRzYi0+ZHNvdW5kLT5od28pKTsKCXJldHVybiBlcnI7Cn0KCnN0YXRpYyBIUkVTVUxUIERTT1VORF9QcmltYXJ5U3RvcChJRGlyZWN0U291bmRCdWZmZXJJbXBsICpkc2IpCnsKCUhSRVNVTFQgZXJyID0gRFNfT0s7CgoJVFJBQ0UoIlxuIik7CgoJaWYgKGRzYi0+aHdidWYpIHsKCQllcnIgPSBJRHNEcml2ZXJCdWZmZXJfU3RvcChkc2ItPmh3YnVmKTsKCQlpZiAoZXJyID09IERTRVJSX0JVRkZFUkxPU1QpIHsKCQkJLyogV2luZS1vbmx5OiB0aGUgZHJpdmVyIHdhbnRzIHVzIHRvIHJlb3BlbiB0aGUgZGV2aWNlICovCgkJCS8qIEZJWE1FOiBjaGVjayBmb3IgZXJyb3JzICovCgkJCUlEc0RyaXZlckJ1ZmZlcl9SZWxlYXNlKHByaW1hcnlidWYtPmh3YnVmKTsKCQkJd2F2ZU91dENsb3NlKGRzYi0+ZHNvdW5kLT5od28pOwoJCQlkc2ItPmRzb3VuZC0+aHdvID0gMDsKCQkJZXJyID0gbW1FcnIod2F2ZU91dE9wZW4oJihkc2ItPmRzb3VuZC0+aHdvKSwgZHNiLT5kc291bmQtPmRydmRlc2MuZG5EZXZOb2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmKHByaW1hcnlidWYtPndmeCksIChEV09SRClEU09VTkRfY2FsbGJhY2ssIChEV09SRClkc2ItPmRzb3VuZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0FMTEJBQ0tfRlVOQ1RJT04gfCBXQVZFX0RJUkVDVFNPVU5EKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnIgPT0gRFNfT0spCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnIgPSBJRHNEcml2ZXJfQ3JlYXRlU291bmRCdWZmZXIoZHNiLT5kc291bmQtPmRyaXZlciwmKGRzYi0+d2Z4KSxkc2ItPmRzYmQuZHdGbGFncywwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYoZHNiLT5idWZsZW4pLCYoZHNiLT5idWZmZXIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUFZPSUQpJihkc2ItPmh3YnVmKSk7CgkJfQoJfQoJZWxzZQoJCWVyciA9IG1tRXJyKHdhdmVPdXRQYXVzZShkc2ItPmRzb3VuZC0+aHdvKSk7CglyZXR1cm4gZXJyOwp9CgovKiBUaGlzIHNldHMgdGhpcyBmb3JtYXQgZm9yIHRoZSA8ZW0+UHJpbWFyeSBCdWZmZXIgT25seTwvZW0+ICovCi8qIFNlZSBmaWxlOi8vL2Nkcm9tL3NkazUyL2RvY3Mvd29yZGRvYy9kc291bmQuZG9jIHBhZ2UgMTIwICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0U291bmRCdWZmZXJJbXBsX1NldEZvcm1hdCgKCUxQRElSRUNUU09VTkRCVUZGRVIgaWZhY2UsTFBXQVZFRk9STUFURVggd2ZleAopIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRCdWZmZXJJbXBsLGlmYWNlKTsKCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGwqKiBkc2I7CglIUkVTVUxUIGVyciA9IERTX09LOwoJaW50CQkJaTsKCgkvKiBMZXQncyBiZSBwZWRhbnRpYyEgKi8KCWlmICgod2ZleCA9PSBOVUxMKSB8fAoJICAgICh3ZmV4LT53Rm9ybWF0VGFnICE9IFdBVkVfRk9STUFUX1BDTSkgfHwKCSAgICAod2ZleC0+bkNoYW5uZWxzIDwgMSkgfHwgKHdmZXgtPm5DaGFubmVscyA+IDIpIHx8CgkgICAgKHdmZXgtPm5TYW1wbGVzUGVyU2VjIDwgMSkgfHwKCSAgICAod2ZleC0+bkJsb2NrQWxpZ24gPCAxKSB8fCAod2ZleC0+bkNoYW5uZWxzID4gNCkgfHwKCSAgICAoKHdmZXgtPndCaXRzUGVyU2FtcGxlICE9IDgpICYmICh3ZmV4LT53Qml0c1BlclNhbXBsZSAhPSAxNikpKSB7CgkJVFJBQ0UoImZhaWxlZCBwZWRhbnRpYyBjaGVjayFcbiIpOwoJCXJldHVybiBEU0VSUl9JTlZBTElEUEFSQU07Cgl9CgoJLyogKioqKiAqLwoJRW50ZXJDcml0aWNhbFNlY3Rpb24oJihUaGlzLT5kc291bmQtPmxvY2spKTsKCglpZiAocHJpbWFyeWJ1Zi0+d2Z4Lm5TYW1wbGVzUGVyU2VjICE9IHdmZXgtPm5TYW1wbGVzUGVyU2VjKSB7CgkJZHNiID0gZHNvdW5kLT5idWZmZXJzOwoJCWZvciAoaSA9IDA7IGkgPCBkc291bmQtPm5yb2ZidWZmZXJzOyBpKyssIGRzYisrKSB7CgkJCS8qICoqKiogKi8KCQkJRW50ZXJDcml0aWNhbFNlY3Rpb24oJigoKmRzYiktPmxvY2spKTsKCgkJCSgqZHNiKS0+ZnJlcUFkanVzdCA9ICgoKmRzYiktPmZyZXEgPDwgRFNPVU5EX0ZSRVFTSElGVCkgLwoJCQkJd2ZleC0+blNhbXBsZXNQZXJTZWM7CgoJCQlMZWF2ZUNyaXRpY2FsU2VjdGlvbigmKCgqZHNiKS0+bG9jaykpOwoJCQkvKiAqKioqICovCgkJfQoJfQoKCW1lbWNweSgmKHByaW1hcnlidWYtPndmeCksIHdmZXgsIHNpemVvZihwcmltYXJ5YnVmLT53ZngpKTsKCglUUkFDRSgiKGZvcm1hdHRhZz0weCUwNHgsY2hhbnM9JWQsc2FtcGxlcmF0ZT0lbGQsIgoJCSAgICJieXRlc3BlcnNlYz0lbGQsYmxvY2thbGlnbj0lZCxiaXRzcGVyc2FtcD0lZCxjYlNpemU9JWQpXG4iLAoJCSAgIHdmZXgtPndGb3JtYXRUYWcsIHdmZXgtPm5DaGFubmVscywgd2ZleC0+blNhbXBsZXNQZXJTZWMsCgkJICAgd2ZleC0+bkF2Z0J5dGVzUGVyU2VjLCB3ZmV4LT5uQmxvY2tBbGlnbiwgCgkJICAgd2ZleC0+d0JpdHNQZXJTYW1wbGUsIHdmZXgtPmNiU2l6ZSk7CgoJcHJpbWFyeWJ1Zi0+d2Z4Lm5BdmdCeXRlc1BlclNlYyA9CgkJVGhpcy0+d2Z4Lm5TYW1wbGVzUGVyU2VjICogVGhpcy0+d2Z4Lm5CbG9ja0FsaWduOwoKCWlmIChwcmltYXJ5YnVmLT5kc291bmQtPmRydmRlc2MuZHdGbGFncyAmIERTRERFU0NfRE9NTVNZU1RFTVNFVEZPUk1BVCkgewoJCS8qIEZJWE1FOiBjaGVjayBmb3IgZXJyb3JzICovCgkJRFNPVU5EX1ByaW1hcnlDbG9zZShwcmltYXJ5YnVmKTsKCQl3YXZlT3V0Q2xvc2UoVGhpcy0+ZHNvdW5kLT5od28pOwoJCVRoaXMtPmRzb3VuZC0+aHdvID0gMDsKICAgICAgICAgICAgICAgIGVyciA9IG1tRXJyKHdhdmVPdXRPcGVuKCYoVGhpcy0+ZHNvdW5kLT5od28pLCBUaGlzLT5kc291bmQtPmRydmRlc2MuZG5EZXZOb2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJihwcmltYXJ5YnVmLT53ZngpLCAoRFdPUkQpRFNPVU5EX2NhbGxiYWNrLCAoRFdPUkQpVGhpcy0+ZHNvdW5kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0FMTEJBQ0tfRlVOQ1RJT04gfCBXQVZFX0RJUkVDVFNPVU5EKSk7CiAgICAgICAgICAgICAgICBpZiAoZXJyID09IERTX09LKQogICAgICAgICAgICAgICAgICAgIERTT1VORF9QcmltYXJ5T3BlbihwcmltYXJ5YnVmKTsKCX0KCWlmIChwcmltYXJ5YnVmLT5od2J1ZikgewoJCWVyciA9IElEc0RyaXZlckJ1ZmZlcl9TZXRGb3JtYXQocHJpbWFyeWJ1Zi0+aHdidWYsICYocHJpbWFyeWJ1Zi0+d2Z4KSk7CgkJaWYgKGVyciA9PSBEU0VSUl9CVUZGRVJMT1NUKSB7CgkJCS8qIFdpbmUtb25seTogdGhlIGRyaXZlciB3YW50cyB1cyB0byByZWNyZWF0ZSB0aGUgSFcgYnVmZmVyICovCgkJCUlEc0RyaXZlckJ1ZmZlcl9SZWxlYXNlKHByaW1hcnlidWYtPmh3YnVmKTsKCQkJZXJyID0gSURzRHJpdmVyX0NyZWF0ZVNvdW5kQnVmZmVyKHByaW1hcnlidWYtPmRzb3VuZC0+ZHJpdmVyLCYocHJpbWFyeWJ1Zi0+d2Z4KSxwcmltYXJ5YnVmLT5kc2JkLmR3RmxhZ3MsMCwKCQkJCQkJCSAgJihwcmltYXJ5YnVmLT5idWZsZW4pLCYocHJpbWFyeWJ1Zi0+YnVmZmVyKSwKCQkJCQkJCSAgKExQVk9JRCkmKHByaW1hcnlidWYtPmh3YnVmKSk7CgkJCWlmIChwcmltYXJ5YnVmLT5zdGF0ZSA9PSBTVEFURV9QTEFZSU5HKSBwcmltYXJ5YnVmLT5zdGF0ZSA9IFNUQVRFX1NUQVJUSU5HOwoJCQllbHNlIGlmIChwcmltYXJ5YnVmLT5zdGF0ZSA9PSBTVEFURV9TVE9QUElORykgcHJpbWFyeWJ1Zi0+c3RhdGUgPSBTVEFURV9TVE9QUEVEOwoJCX0KICAgICAgICAgICAgICAgIC8qIEZJWE1FOiBzaG91bGQgd2Ugc2V0IGVyciBiYWNrIHRvIERTX09LIGluIGFsbCBjYXNlcyA/ICovCgl9CglEU09VTkRfUmVjYWxjRm9ybWF0KHByaW1hcnlidWYpOwoKCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCYoVGhpcy0+ZHNvdW5kLT5sb2NrKSk7CgkvKiAqKioqICovCgoJcmV0dXJuIGVycjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZEJ1ZmZlckltcGxfU2V0Vm9sdW1lKAoJTFBESVJFQ1RTT1VOREJVRkZFUiBpZmFjZSxMT05HIHZvbAopIHsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRCdWZmZXJJbXBsLGlmYWNlKTsKCglUUkFDRSgiKCVwLCVsZClcbiIsVGhpcyx2b2wpOwoKCS8qIEknbSBub3Qgc3VyZSBpZiB3ZSBuZWVkIHRoaXMgZm9yIHByaW1hcnkgYnVmZmVyICovCglpZiAoIShUaGlzLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX0NUUkxWT0xVTUUpKQoJCXJldHVybiBEU0VSUl9DT05UUk9MVU5BVkFJTDsKCglpZiAoKHZvbCA+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+IChkc19zbmRfcXVldWVfbWF4ICogcHJpbWFyeWJ1Zi0+ZHNvdW5kLT5mcmFnbGVuICsgcHdyaXRlICsgcHJpbWFyeWJ1Zi0+d3JpdGVsZWFkKSkgewoJCVdBUk4oImRldGVjdGVkIGFuIHVuZGVycnVuOiBwcmltYXJ5IHF1ZXVlIHdhcyAlbGRcbiIscG1peCk7CgkJcG1peCA9IDA7Cgl9CgkvKiBkaXZpZGUgdGhlIG9mZnNldCBieSBpdHMgc2FtcGxlIHNpemUgKi8KCXBtaXggLz0gcHJpbWFyeWJ1Zi0+d2Z4Lm5CbG9ja0FsaWduOwoJVFJBQ0UoInByaW1hcnkgYmFjay1zYW1wbGVzPSVsZFxuIixwbWl4KTsKCS8qIGFkanVzdCBmb3Igb3VyIGZyZXF1ZW5jeSAqLwoJcG1peCA9IChwbWl4ICogVGhpcy0+ZnJlcUFkanVzdCkgPj4gRFNPVU5EX0ZSRVFTSElGVDsKCS8qIG11bHRpcGx5IGJ5IG91ciBvd24gc2FtcGxlIHNpemUgKi8KCXBtaXggKj0gVGhpcy0+d2Z4Lm5CbG9ja0FsaWduOwoJVFJBQ0UoInRoaXMgYmFjay1vZmZzZXQ9JWxkXG4iLCBwbWl4KTsKCS8qIHN1YnRyYWN0IGZyb20gb3VyIGxhc3QgbWl4ZWQgcG9zaXRpb24gKi8KCWJwbGF5ID0gYm1peDsKCXdoaWxlIChicGxheSA8IHBtaXgpIGJwbGF5ICs9IFRoaXMtPmJ1ZmxlbjsgLyogd3JhcGFyb3VuZCAqLwoJYnBsYXkgLT0gcG1peDsKCWlmIChUaGlzLT5sZWFkaW4gJiYgKChicGxheSA8IFRoaXMtPnN0YXJ0cG9zKSB8fCAoYnBsYXkgPiBibWl4KSkpIHsKCQkvKiBzZWVtcyB3ZSBoYXZlbid0IHN0YXJ0ZWQgcGxheWluZyB5ZXQgKi8KCQlUUkFDRSgidGhpcyBzdGlsbCBpbiBsZWFkLWluIHBoYXNlXG4iKTsKCQlicGxheSA9IFRoaXMtPnN0YXJ0cG9zOwoJfQoJLyogcmV0dXJuIHRoZSByZXN1bHQgKi8KCXJldHVybiBicGxheTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3RTb3VuZEJ1ZmZlckltcGxfR2V0Q3VycmVudFBvc2l0aW9uKAoJTFBESVJFQ1RTT1VOREJVRkZFUiBpZmFjZSxMUERXT1JEIHBsYXlwb3MsTFBEV09SRCB3cml0ZXBvcwopIHsKCUhSRVNVTFQJaHJlczsgCglJQ09NX1RISVMoSURpcmVjdFNvdW5kQnVmZmVySW1wbCxpZmFjZSk7CglUUkFDRSgiKCVwLCVwLCVwKVxuIixUaGlzLHBsYXlwb3Msd3JpdGVwb3MpOwoJaWYgKFRoaXMtPmh3YnVmKSB7CgkJaHJlcz1JRHNEcml2ZXJCdWZmZXJfR2V0UG9zaXRpb24oVGhpcy0+aHdidWYscGxheXBvcyx3cml0ZXBvcyk7CgkJaWYgKGhyZXMpCgkJICAgIHJldHVybiBocmVzOwoJfQoJZWxzZSBpZiAoVGhpcy0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19QUklNQVJZQlVGRkVSKSB7CgkJaWYgKHBsYXlwb3MpIHsKCQkJTU1USU1FIG10aW1lOwoJCQltdGltZS53VHlwZSA9IFRJTUVfQllURVM7CgkJCXdhdmVPdXRHZXRQb3NpdGlvbihUaGlzLT5kc291bmQtPmh3bywgJm10aW1lLCBzaXplb2YobXRpbWUpKTsKCQkJbXRpbWUudS5jYiA9IG10aW1lLnUuY2IgJSBUaGlzLT5idWZsZW47CgkJCSpwbGF5cG9zID0gbXRpbWUudS5jYjsKCQl9CgkJaWYgKHdyaXRlcG9zKSB7CgkJCS8qIHRoZSB3cml0ZXBvcyBzaG91bGQgb25seSBiZSB1c2VkIGJ5IGFwcHMgd2l0aCBXUklURVBSSU1BUlkgcHJpb3JpdHksCgkJCSAqIGluIHdoaWNoIGNhc2Ugb3VyIHNvZnR3YXJlIG1peGVyIGlzIGRpc2FibGVkIGFueXdheSAqLwoJCQkqd3JpdGVwb3MgPSAoVGhpcy0+ZHNvdW5kLT5wd3BsYXkgKyBkc19oZWxfbWFyZ2luKSAqIFRoaXMtPmRzb3VuZC0+ZnJhZ2xlbjsKCQkJd2hpbGUgKCp3cml0ZXBvcyA+PSBUaGlzLT5idWZsZW4pCgkJCQkqd3JpdGVwb3MgLT0gVGhpcy0+YnVmbGVuOwoJCX0KCX0gZWxzZSB7CgkJaWYgKHBsYXlwb3MgJiYgKFRoaXMtPnN0YXRlICE9IFNUQVRFX1BMQVlJTkcpKSB7CgkJCS8qIHdlIGhhdmVuJ3QgYmVlbiBtZXJnZWQgaW50byB0aGUgcHJpbWFyeSBidWZmZXIgKHlldCkgKi8KCQkJKnBsYXlwb3MgPSBUaGlzLT5idWZfbWl4cG9zOwoJCX0KCQllbHNlIGlmIChwbGF5cG9zKSB7CgkJCURXT1JEIHBwbGF5LCBwd3JpdGUsIGxwbGF5LCBzcGxheSwgcHN0YXRlOwoJCQkvKiBsZXQncyBnZXQgdGhpcyBleGFjdDsgZmlyc3QsIHJlY3Vyc2l2ZWx5IGNhbGwgR2V0UG9zaXRpb24gb24gdGhlIHByaW1hcnkgKi8KCQkJRW50ZXJDcml0aWNhbFNlY3Rpb24oJihwcmltYXJ5YnVmLT5sb2NrKSk7CgkJCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGxfR2V0Q3VycmVudFBvc2l0aW9uKChMUERJUkVDVFNPVU5EQlVGRkVSKXByaW1hcnlidWYsICZwcGxheSwgJnB3cml0ZSk7CgkJCS8qIGRldGVjdCBIRUwgbW9kZSB1bmRlcnJ1biAqLwoJCQlwc3RhdGUgPSBwcmltYXJ5YnVmLT5zdGF0ZTsKCQkJaWYgKCEocHJpbWFyeWJ1Zi0+aHdidWYgfHwgcHJpbWFyeWJ1Zi0+ZHNvdW5kLT5wd3F1ZXVlKSkgewoJCQkJVFJBQ0UoImRldGVjdGVkIGFuIHVuZGVycnVuXG4iKTsKCQkJCS8qIHBwbGF5ID0gPyAqLwoJCQkJaWYgKHBzdGF0ZSA9PSBTVEFURV9QTEFZSU5HKQoJCQkJCXBzdGF0ZSA9IFNUQVRFX1NUQVJUSU5HOwoJCQkJZWxzZSBpZiAocHN0YXRlID09IFNUQVRFX1NUT1BQSU5HKQoJCQkJCXBzdGF0ZSA9IFNUQVRFX1NUT1BQRUQ7CgkJCX0KCQkJLyogZ2V0IGRhdGEgZm9yIG91cnNlbHZlcyB3aGlsZSB3ZSBzdGlsbCBoYXZlIHRoZSBsb2NrICovCgkJCXBzdGF0ZSAmPSBUaGlzLT5zdGF0ZTsKCQkJbHBsYXkgPSBUaGlzLT5wcmltYXJ5X21peHBvczsKCQkJc3BsYXkgPSBUaGlzLT5idWZfbWl4cG9zOwoJCQlpZiAoKFRoaXMtPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfR0VUQ1VSUkVOVFBPU0lUSU9OMikgfHwgcHJpbWFyeWJ1Zi0+aHdidWYpIHsKCQkJCS8qIGNhbGN1bGF0ZSBwbGF5IHBvc2l0aW9uIHVzaW5nIHRoaXMgKi8KCQkJCSpwbGF5cG9zID0gRFNPVU5EX0NhbGNQbGF5UG9zaXRpb24oVGhpcywgcHN0YXRlLCBwcGxheSwgcHdyaXRlLCBscGxheSwgc3BsYXkpOwoJCQl9IGVsc2UgewoJCQkJLyogKHVubGVzcyB0aGUgYXBwIGlzbid0IHVzaW5nIEdFVENVUlJFTlRQT1NJVElPTjIpICovCgkJCQkvKiBkb24ndCBrbm93IGV4YWN0bHkgaG93IHRoaXMgc2hvdWxkIGJlIGhhbmRsZWQuLi4KCQkJCSAqIHRoZSBkb2NzIHNheXMgdGhhdCBwbGF5IGN1cnNvciBpcyByZXBvcnRlZCBhcyBkaXJlY3RseQoJCQkJICogYmVoaW5kIHdyaXRlIGN1cnNvciwgaG1tLi4uICovCgkJCQkvKiBsZXQncyBqdXN0IGRvIHdoYXQgbWlnaHQgd29yayBmb3IgSGFsZi1MaWZlICovCgkJCQlEV09SRCB3cDsKCQkJCXdwID0gKFRoaXMtPmRzb3VuZC0+cHdwbGF5ICsgZHNfaGVsX21hcmdpbikgKiBUaGlzLT5kc291bmQtPmZyYWdsZW47CgkJCQl3aGlsZSAod3AgPj0gcHJpbWFyeWJ1Zi0+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+PiA4OwoJCglyZXR1cm4gYjsKfQoKCnN0YXRpYyBpbmxpbmUgdm9pZCBjcF9maWVsZHMoY29uc3QgSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiLCBCWVRFICppYnVmLCBCWVRFICpvYnVmICkKewoJSU5UIAlmbCA9IDAsIGZyID0gMDsKCWlmIChkc2ItPndmeC5uQ2hhbm5lbHMgPT0gMikgewoJCWlmIChkc2ItPndmeC53Qml0c1BlclNhbXBsZSA9PSA4KSAgewoJCQkvKiBhdm9pZCBuZWVkbGVzcyA4LT4xNi0+OCBjb252ZXJzaW9uICovCgkJCWlmICggKHByaW1hcnlidWYtPndmeC53Qml0c1BlclNhbXBsZSA9PSA4KSAmJiAocHJpbWFyeWJ1Zi0+d2Z4Lm5DaGFubmVscyA9PSAyKSApIHsKCQkJCSpvYnVmPSppYnVmOwoJCQkJKihvYnVmKzEpPSooaWJ1ZisxKTsKCQkJCXJldHVybjsKCQkJfQoJCQlmbCA9IGN2dFU4dG9TMTYoKmlidWYpOwoJCQlmciA9IGN2dFU4dG9TMTYoKihpYnVmICsgMSkpOwoJCX0gZWxzZSBpZiAoZHNiLT53Zngud0JpdHNQZXJTYW1wbGUgPT0gMTYpIHsKCQkJZmwgPSAqKChJTlQxNiAqKWlidWYpOwoJCQlmciA9ICooKChJTlQxNiAqKWlidWYpICsgMSk7CgkJfQoJfSBlbHNlIGlmIChkc2ItPndmeC5uQ2hhbm5lbHMgPT0gMSkgewoJCWlmIChkc2ItPndmeC53Qml0c1BlclNhbXBsZSA9PSA4KSB7CgkJCS8qIGF2b2lkIG5lZWRsZXNzIDgtPjE2LT44IGNvbnZlcnNpb24gKi8KCQkJaWYgKCAocHJpbWFyeWJ1Zi0+d2Z4LndCaXRzUGVyU2FtcGxlID09IDgpICYmIChwcmltYXJ5YnVmLT53ZngubkNoYW5uZWxzID09IDEpICkgewoJCQkJKm9idWY9KmlidWY7CgkJCQlyZXR1cm47CgkJCX0KCQkJZmwgPSBjdnRVOHRvUzE2KCppYnVmKTsKCQkJZnIgPSBmbDsKCQl9IGVsc2UgaWYgKGRzYi0+d2Z4LndCaXRzUGVyU2FtcGxlID09IDE2KSB7CgkJCWZsID0gKigoSU5UMTYgKilpYnVmKTsKCQkJZnIgPSBmbDsKCQl9Cgl9CglpZiAocHJpbWFyeWJ1Zi0+d2Z4Lm5DaGFubmVscyA9PSAyKSB7CgkJaWYgKHByaW1hcnlidWYtPndmeC53Qml0c1BlclNhbXBsZSA9PSA4KSB7CgkJCSpvYnVmID0gY3Z0UzE2dG9VOChmbCk7CgkJCSoob2J1ZiArIDEpID0gY3Z0UzE2dG9VOChmcik7CgkJCXJldHVybjsKCQl9CgkJaWYgKHByaW1hcnlidWYtPndmeC53Qml0c1BlclNhbXBsZSA9PSAxNikgewoJCQkqKChJTlQxNiAqKW9idWYpID0gZmw7CgkJCSooKChJTlQxNiAqKW9idWYpICsgMSkgPSBmcjsKCQkJcmV0dXJuOwoJCX0KCX0JCglpZiAocHJpbWFyeWJ1Zi0+d2Z4Lm5DaGFubmVscyA9PSAxKSB7CgkJZmwgPSAoZmwgKyBmcikgPj4gMTsKCQlpZiAocHJpbWFyeWJ1Zi0+d2Z4LndCaXRzUGVyU2FtcGxlID09IDgpIHsKCQkJKm9idWYgPSBjdnRTMTZ0b1U4KGZsKTsKCQkJcmV0dXJuOwoJCX0KCQlpZiAocHJpbWFyeWJ1Zi0+d2Z4LndCaXRzUGVyU2FtcGxlID09IDE2KSB7CgkJCSooKElOVDE2ICopb2J1ZikgPSBmbDsKCQkJcmV0dXJuOwoJCX0KCX0KfQoKLyogTm93IHdpdGggUGVyZmVjdFBpdGNoICh0bSkgdGVjaG5vbG9neSAqLwpzdGF0aWMgSU5UIERTT1VORF9NaXhlck5vcm0oSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiLCBCWVRFICpidWYsIElOVCBsZW4pCnsKCUlOVAlpLCBzaXplLCBpcG9zLCBpbGVuOwoJQllURQkqaWJwLCAqb2JwOwoJSU5UCWlBZHZhbmNlID0gZHNiLT53ZngubkJsb2NrQWxpZ247CglJTlQJb0FkdmFuY2UgPSBwcmltYXJ5YnVmLT53ZngubkJsb2NrQWxpZ247CgoJaWJwID0gZHNiLT5idWZmZXIgKyBkc2ItPmJ1Zl9taXhwb3M7CglvYnAgPSBidWY7CgoJVFJBQ0UoIiglcCwgJXAsICVwKSwgYnVmX21peHBvcz0lbGRcbiIsIGRzYiwgaWJwLCBvYnAsIGRzYi0+YnVmX21peHBvcyk7CgkvKiBDaGVjayBmb3IgdGhlIGJlc3QgY2FzZSAqLwoJaWYgKChkc2ItPmZyZXEgPT0gcHJpbWFyeWJ1Zi0+d2Z4Lm5TYW1wbGVzUGVyU2VjKSAmJgoJICAgIChkc2ItPndmeC53Qml0c1BlclNhbXBsZSA9PSBwcmltYXJ5YnVmLT53Zngud0JpdHNQZXJTYW1wbGUpICYmCgkgICAgKGRzYi0+d2Z4Lm5DaGFubmVscyA9PSBwcmltYXJ5YnVmLT53ZngubkNoYW5uZWxzKSkgewoJICAgICAgICBEV09SRCBieXRlc2xlZnQgPSBkc2ItPmJ1ZmxlbiAtIGRzYi0+YnVmX21peHBvczsKCQlUUkFDRSgiKCVwKSBCZXN0IGNhc2VcbiIsIGRzYik7CgkgICAgCWlmIChsZW4gPD0gYnl0ZXNsZWZ0ICkKCQkJbWVtY3B5KG9icCwgaWJwLCBsZW4pOwoJCWVsc2UgeyAvKiB3cmFwICovCgkJCW1lbWNweShvYnAsIGlicCwgYnl0ZXNsZWZ0ICk7CgkJCW1lbWNweShvYnAgKyBieXRlc2xlZnQsIGRzYi0+YnVmZmVyLCBsZW4gLSBieXRlc2xlZnQpOwoJCX0KCQlyZXR1cm4gbGVuOwoJfQoJCgkvKiBDaGVjayBmb3Igc2FtZSBzYW1wbGUgcmF0ZSAqLwoJaWYgKGRzYi0+ZnJlcSA9PSBwcmltYXJ5YnVmLT53ZngublNhbXBsZXNQZXJTZWMpIHsKCQlUUkFDRSgiKCVwKSBTYW1lIHNhbXBsZSByYXRlICVsZCA9IHByaW1hcnkgJWxkXG4iLCBkc2IsCgkJCWRzYi0+ZnJlcSwgcHJpbWFyeWJ1Zi0+d2Z4Lm5TYW1wbGVzUGVyU2VjKTsKCQlpbGVuID0gMDsKCQlmb3IgKGkgPSAwOyBpIDwgbGVuOyBpICs9IG9BZHZhbmNlKSB7CgkJCWNwX2ZpZWxkcyhkc2IsIGlicCwgb2JwICk7CgkJCWlicCArPSBpQWR2YW5jZTsKCQkJaWxlbiArPSBpQWR2YW5jZTsKCQkJb2JwICs9IG9BZHZhbmNlOwoJCQlpZiAoaWJwID49IChCWVRFICopKGRzYi0+YnVmZmVyICsgZHNiLT5idWZsZW4pKQoJCQkJaWJwID0gZHNiLT5idWZmZXI7CS8qIHdyYXAgKi8KCQl9CgkJcmV0dXJuIChpbGVuKTsJCgl9CgoJLyogTWl4IGluIGRpZmZlcmVudCBzYW1wbGUgcmF0ZXMgKi8KCS8qICovCgkvKiBOZXcgUGVyZmVjdFBpdGNoKHRtKSBUZWNobm9sb2d5IChjKSAxOTk4IFJvYiBSaWdncyAqLwoJLyogUGF0ZW50IFBlbmRpbmcgOi1dICovCgoJLyogUGF0ZW50IGVuaGFuY2VtZW50cyAoYykgMjAwMCBPdmUgS+V2ZW4sCgkgKiBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMgSW5jLiAqLwoKLyoJRklYTUUoIiglcCkgQWRqdXN0aW5nIGZyZXF1ZW5jeTogJWxkIC0+ICVsZCAobmVlZCBvcHRpbWl6YXRpb24pXG4iLAoJCWRzYiwgZHNiLT5mcmVxLCBwcmltYXJ5YnVmLT53ZngublNhbXBsZXNQZXJTZWMpOwoqLwoJc2l6ZSA9IGxlbiAvIG9BZHZhbmNlOwoJaWxlbiA9IDA7CglpcG9zID0gZHNiLT5idWZfbWl4cG9zOwoJZm9yIChpID0gMDsgaSA8IHNpemU7IGkrKykgewoJCWNwX2ZpZWxkcyhkc2IsIChkc2ItPmJ1ZmZlciArIGlwb3MpLCBvYnApOwoJCW9icCArPSBvQWR2YW5jZTsKCQlkc2ItPmZyZXFBY2MgKz0gZHNiLT5mcmVxQWRqdXN0OwoJCWlmIChkc2ItPmZyZXFBY2MgPj0gKDE8PERTT1VORF9GUkVRU0hJRlQpKSB7CgkJCVVMT05HIGFkdiA9IChkc2ItPmZyZXFBY2M+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+YnVmZmVyLCBuZmlsbGVyLCBwcmltYXJ5YnVmLT5idWZfbWl4cG9zKTsKCX0gZWxzZSB7CgkJbWVtc2V0KHByaW1hcnlidWYtPmJ1ZmZlciArIHdyaXRlcG9zLCBuZmlsbGVyLCBwcmltYXJ5YnVmLT5idWZfbWl4cG9zIC0gd3JpdGVwb3MpOwoJfQoKCS8qIHJlc2V0IHByaW1hcnkgbWl4IHBvc2l0aW9uICovCglwcmltYXJ5YnVmLT5idWZfbWl4cG9zID0gd3JpdGVwb3M7Cn0KCnN0YXRpYyB2b2lkIERTT1VORF9DaGVja1Jlc2V0KElEaXJlY3RTb3VuZEltcGwgKmRzb3VuZCwgRFdPUkQgd3JpdGVwb3MpCnsKCWlmIChwcmltYXJ5YnVmLT5uZWVkX3JlbWl4KSB7CgkJRFNPVU5EX01peFJlc2V0KHdyaXRlcG9zKTsKCQlwcmltYXJ5YnVmLT5uZWVkX3JlbWl4ID0gRkFMU0U7CgkJLyogbWF4aW1pemUgSGFsZi1MaWZlIHBlcmZvcm1hbmNlICovCgkJZHNvdW5kLT5wcmVidWYgPSBkc19zbmRfcXVldWVfbWluOwoJfSBlbHNlIHsKCQkvKiBpZiAoZHNvdW5kLT5wcmVidWYgPCBkc19zbmRfcXVldWVfbWF4KSBkc291bmQtPnByZWJ1ZisrOyAqLwoJfQoJVFJBQ0UoInByZW1peCBhZGp1c3Q6ICVkXG4iLCBkc291bmQtPnByZWJ1Zik7Cn0KCnN0YXRpYyB2b2lkIERTT1VORF9XYXZlUXVldWUoSURpcmVjdFNvdW5kSW1wbCAqZHNvdW5kLCBEV09SRCBtaXhxKQp7CglpZiAobWl4cSArIGRzb3VuZC0+cHdxdWV1ZSA+IGRzX2hlbF9xdWV1ZSkgbWl4cSA9IGRzX2hlbF9xdWV1ZSAtIGRzb3VuZC0+cHdxdWV1ZTsKCVRSQUNFKCJxdWV1ZWluZyAlbGQgYnVmZmVycywgc3RhcnRpbmcgYXQgJWRcbiIsIG1peHEsIGRzb3VuZC0+cHd3cml0ZSk7Cglmb3IgKDsgbWl4cTsgbWl4cS0tKSB7CgkJd2F2ZU91dFdyaXRlKGRzb3VuZC0+aHdvLCBkc291bmQtPnB3YXZlW2Rzb3VuZC0+cHd3cml0ZV0sIHNpemVvZihXQVZFSERSKSk7CgkJZHNvdW5kLT5wd3dyaXRlKys7CgkJaWYgKGRzb3VuZC0+cHd3cml0ZSA+PSBEU19IRUxfRlJBR1MpIGRzb3VuZC0+cHd3cml0ZSA9IDA7CgkJZHNvdW5kLT5wd3F1ZXVlKys7Cgl9Cn0KCi8qICNkZWZpbmUgU1lOQ19DQUxMQkFDSyAqLwoKc3RhdGljIHZvaWQgRFNPVU5EX1BlcmZvcm1NaXgodm9pZCkKewoJaW50IG5maWxsZXI7CglCT09MIGZvcmNlZDsKCUhSRVNVTFQgaHJlczsKCglFbnRlckNyaXRpY2FsU2VjdGlvbigmKGRzb3VuZC0+bG9jaykpOwoKCWlmICghcHJpbWFyeWJ1ZiB8fCAhcHJpbWFyeWJ1Zi0+cmVmKSB7CgkJLyogc2VlbXMgdGhlIHByaW1hcnkgYnVmZmVyIGlzIGN1cnJlbnRseSBiZWluZyByZWxlYXNlZCAqLwoJCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCYoZHNvdW5kLT5sb2NrKSk7CgkJcmV0dXJuOwoJfQoKCS8qIHRoZSBzb3VuZCBvZiBzaWxlbmNlICovCgluZmlsbGVyID0gcHJpbWFyeWJ1Zi0+d2Z4LndCaXRzUGVyU2FtcGxlID09IDggPyAxMjggOiAwOwoKCS8qIHdoZXRoZXIgdGhlIHByaW1hcnkgaXMgZm9yY2VkIHRvIHBsYXkgZXZlbiB3aXRob3V0IHNlY29uZGFyeSBidWZmZXJzICovCglmb3JjZWQgPSAoKHByaW1hcnlidWYtPnN0YXRlID09IFNUQVRFX1BMQVlJTkcpIHx8IChwcmltYXJ5YnVmLT5zdGF0ZSA9PSBTVEFURV9TVEFSVElORykpOwoKICAgICAgICBUUkFDRSgiZW50ZXJpbmcgYXQgJWxkXG4iLCBHZXRUaWNrQ291bnQoKSk7CglpZiAoZHNvdW5kLT5wcmlvbGV2ZWwgIT0gRFNTQ0xfV1JJVEVQUklNQVJZKSB7CgkJQk9PTCBwYXVzZWQgPSAoKHByaW1hcnlidWYtPnN0YXRlID09IFNUQVRFX1NUT1BQRUQpIHx8IChwcmltYXJ5YnVmLT5zdGF0ZSA9PSBTVEFURV9TVEFSVElORykpOwoJCS8qIEZJWE1FOiBkb2N1bWVudCB2YXJpYWJsZXMgKi8KIAkJRFdPUkQgcGxheXBvcywgd3JpdGVwb3MsIGlucSwgbWF4cSwgZnJhZzsKIAkJaWYgKHByaW1hcnlidWYtPmh3YnVmKSB7CgkJCWhyZXMgPSBJRHNEcml2ZXJCdWZmZXJfR2V0UG9zaXRpb24ocHJpbWFyeWJ1Zi0+aHdidWYsICZwbGF5cG9zLCAmd3JpdGVwb3MpOwoJCQlpZiAoaHJlcykgewoJCQkgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJihkc291bmQtPmxvY2spKTsKCQkJICAgIHJldHVybjsKCQkJfQoJCQkvKiBXZWxsLCB3ZSAqY291bGQqIGRvIEp1c3QtSW4tVGltZSBtaXhpbmcgdXNpbmcgdGhlIHdyaXRlcG9zLAoJCQkgKiBidXQgdGhhdCdzIGEgbGl0dGxlIGJpdCBhbWJpdGlvdXMgYW5kIHVubmVjZXNzYXJ5Li4uICovCgkJCS8qIHJhdGhlciBhZGQgb3VyIHNhZmV0eSBtYXJnaW4gdG8gdGhlIHdyaXRlcG9zLCBpZiB3ZSdyZSBwbGF5aW5nICovCgkJCWlmICghcGF1c2VkKSB7CgkJCQl3cml0ZXBvcyArPSBwcmltYXJ5YnVmLT53cml0ZWxlYWQ7CgkJCQl3aGlsZSAod3JpdGVwb3MgPj0gcHJpbWFyeWJ1Zi0+YnVmbGVuKQoJCQkJCXdyaXRlcG9zIC09IHByaW1hcnlidWYtPmJ1ZmxlbjsKCQkJfSBlbHNlIHdyaXRlcG9zID0gcGxheXBvczsKCQl9CgkJZWxzZSB7CiAJCQlwbGF5cG9zID0gZHNvdW5kLT5wd3BsYXkgKiBkc291bmQtPmZyYWdsZW47CiAJCQl3cml0ZXBvcyA9IHBsYXlwb3M7CiAJCQlpZiAoIXBhdXNlZCkgewoJIAkJCXdyaXRlcG9zICs9IGRzX2hlbF9tYXJnaW4gKiBkc291bmQtPmZyYWdsZW47CgkgCQkJd2hpbGUgKHdyaXRlcG9zID49IHByaW1hcnlidWYtPmJ1ZmxlbikKIAkJCQkJd3JpdGVwb3MgLT0gcHJpbWFyeWJ1Zi0+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+MSkgRFNPVU5EX1dhdmVRdWV1ZShUaGlzLCBpbnEtMSk7CiNpZmRlZiBTWU5DX0NBTExCQUNLCgkJTGVhdmVDcml0aWNhbFNlY3Rpb24oJihwcmltYXJ5YnVmLT5sb2NrKSk7CiNlbmRpZgoJfQoJVFJBQ0UoImNvbXBsZXRlZFxuIik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlEaXJlY3RTb3VuZENyZWF0ZSAoRFNPVU5ELjEpCiAqLwpIUkVTVUxUIFdJTkFQSSBEaXJlY3RTb3VuZENyZWF0ZShSRUZHVUlEIGxwR1VJRCxMUERJUkVDVFNPVU5EICpwcERTLElVbmtub3duICpwVW5rT3V0ZXIgKQp7CglJRGlyZWN0U291bmRJbXBsKiogaXBwRFM9KElEaXJlY3RTb3VuZEltcGwqKilwcERTOwoJUElEU0RSSVZFUiBkcnYgPSBOVUxMOwoJV0FWRU9VVENBUFNBIHdjYXBzOwoJdW5zaWduZWQgd29kLCB3b2RuOwoJSFJFU1VMVCBlcnIgPSBEU19PSzsJCgoJaWYgKGxwR1VJRCkKCQlUUkFDRSgiKCVwLCVwLCVwKVxuIixscEdVSUQsaXBwRFMscFVua091dGVyKTsKCWVsc2UKCQlUUkFDRSgiRGlyZWN0U291bmRDcmVhdGUgKCVwKVxuIiwgaXBwRFMpOwoKCWlmIChpcHBEUyA9PSBOVUxMKQoJCXJldHVybiBEU0VSUl9JTlZBTElEUEFSQU07CgoJaWYgKHByaW1hcnlidWYpIHsKCQlJRGlyZWN0U291bmRfQWRkUmVmKChMUERJUkVDVFNPVU5EKWRzb3VuZCk7CgkJKmlwcERTID0gZHNvdW5kOwoJCXJldHVybiBEU19PSzsKCX0KCgkvKiBHZXQgZHNvdW5kIGNvbmZpZ3VyYXRpb24gKi8KCXNldHVwX2Rzb3VuZF9vcHRpb25zKCk7CgoJLyogRW51bWVyYXRlIFdJTk1NIGF1ZGlvIGRldmljZXMgYW5kIGZpbmQgdGhlIG9uZSB3ZSB3YW50ICovCgl3b2RuID0gd2F2ZU91dEdldE51bURldnMoKTsKCWlmICghd29kbikgcmV0dXJuIERTRVJSX05PRFJJVkVSOwoKCS8qIEZJWE1FOiBIb3cgZG8gd2UgZmluZCB0aGUgR1VJRCBvZiBhbiBhdWRpbyBkZXZpY2U/ICovCgl3b2QgPSAwOyAvKiBzdGFydCBhdCB0aGUgZmlyc3QgYXVkaW8gZGV2aWNlICovCgoJLyogR2V0IG91dHB1dCBkZXZpY2UgY2FwcyAqLwoJd2F2ZU91dEdldERldkNhcHNBKHdvZCwgJndjYXBzLCBzaXplb2Yod2NhcHMpKTsKCS8qIERSVl9RVUVSWURTT1VORElGQUNFIGlzIGEgIldpbmUgZXh0ZW5zaW9uIiB0byBnZXQgdGhlIERTb3VuZCBpbnRlcmZhY2UgKi8KCXdhdmVPdXRNZXNzYWdlKHdvZCwgRFJWX1FVRVJZRFNPVU5ESUZBQ0UsIChEV09SRCkmZHJ2LCAwKTsKCgkvKiBBbGxvY2F0ZSBtZW1vcnkgKi8KCSppcHBEUyA9IChJRGlyZWN0U291bmRJbXBsKilIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwwLHNpemVvZihJRGlyZWN0U291bmRJbXBsKSk7CglpZiAoKmlwcERTID09IE5VTEwpCgkJcmV0dXJuIERTRVJSX09VVE9GTUVNT1JZOwoKCUlDT01fVlRCTCgqaXBwRFMpCT0gJmRzdnQ7CgkoKmlwcERTKS0+cmVmCQk9IDE7CgoJKCppcHBEUyktPmRyaXZlcgk9IGRydjsKCSgqaXBwRFMpLT5mcmFnbGVuCT0gMDsKCSgqaXBwRFMpLT5wcmlvbGV2ZWwJPSBEU1NDTF9OT1JNQUw7IAoJKCppcHBEUyktPm5yb2ZidWZmZXJzCT0gMDsKCSgqaXBwRFMpLT5idWZmZXJzCT0gTlVMTDsKCSgqaXBwRFMpLT5wcmltYXJ5CT0gTlVMTDsgCgkoKmlwcERTKS0+bGlzdGVuZXIJPSBOVUxMOyAKCgkoKmlwcERTKS0+cHJlYnVmCT0gZHNfc25kX3F1ZXVlX21heDsKCgkvKiBHZXQgZHJpdmVyIGRlc2NyaXB0aW9uICovCglpZiAoZHJ2KSB7CgkJSURzRHJpdmVyX0dldERyaXZlckRlc2MoZHJ2LCYoKCppcHBEUyktPmRydmRlc2MpKTsKCX0gZWxzZSB7CgkJLyogaWYgbm8gRGlyZWN0U291bmQgaW50ZXJmYWNlIGF2YWlsYWJsZSwgdXNlIFdJTk1NIEFQSSBpbnN0ZWFkICovCgkJKCppcHBEUyktPmRydmRlc2MuZHdGbGFncyA9IERTRERFU0NfRE9NTVNZU1RFTU9QRU4gfCBEU0RERVNDX0RPTU1TWVNURU1TRVRGT1JNQVQ7CgkJKCppcHBEUyktPmRydmRlc2MuZG5EZXZOb2RlID0gd29kOyAvKiBGSVhNRT8gKi8KCX0KCgkvKiBTZXQgZGVmYXVsdCB3YXZlIGZvcm1hdCAobWF5IG5lZWQgaXQgZm9yIHdhdmVPdXRPcGVuKSAqLwoJKCppcHBEUyktPndmeC53Rm9ybWF0VGFnCT0gV0FWRV9GT1JNQVRfUENNOwoJKCppcHBEUyktPndmeC5uQ2hhbm5lbHMJCT0gMjsKCSgqaXBwRFMpLT53ZngublNhbXBsZXNQZXJTZWMJPSAyMjA1MDsKCSgqaXBwRFMpLT53ZngubkF2Z0J5dGVzUGVyU2VjCT0gNDQxMDA7CgkoKmlwcERTKS0+d2Z4Lm5CbG9ja0FsaWduCT0gMjsKCSgqaXBwRFMpLT53Zngud0JpdHNQZXJTYW1wbGUJPSA4OwoKCS8qIElmIHRoZSBkcml2ZXIgcmVxdWVzdHMgYmVpbmcgb3BlbmVkIHRocm91Z2ggTU1TWVNURU0KCSAqICh3aGljaCBpcyByZWNvbW1lbmRlZCBieSB0aGUgRERLKSwgaXQgaXMgc3VwcG9zZWQgdG8gaGFwcGVuCgkgKiBiZWZvcmUgdGhlIERpcmVjdFNvdW5kIGludGVyZmFjZSBpcyBvcGVuZWQgKi8KCWlmICgoKmlwcERTKS0+ZHJ2ZGVzYy5kd0ZsYWdzICYgRFNEREVTQ19ET01NU1lTVEVNT1BFTikKCXsKCQkvKiBGSVhNRTogaXMgdGhpcyByaWdodD8gKi8KCgkgICAgICAgICgqaXBwRFMpLT5kcnZkZXNjLmRuRGV2Tm9kZSA9IDA7CgkJZXJyID0gRFNFUlJfQUxMT0NBVEVEOwoKCQkvKiBpZiB0aGlzIGRldmljZSBpcyBidXN5IHRyeSB0aGUgbmV4dCBvbmUgKi8KCQl3aGlsZSgoZXJyID09IERTRVJSX0FMTE9DQVRFRCkgJiYgCgkJCSgoKmlwcERTKS0+ZHJ2ZGVzYy5kbkRldk5vZGUgPCB3b2RuKSkKICAJCXsKCQkgIGVyciA9IG1tRXJyKHdhdmVPdXRPcGVuKCYoKCppcHBEUyktPmh3byksIAoJCQkoKmlwcERTKS0+ZHJ2ZGVzYy5kbkRldk5vZGUsICYoKCppcHBEUyktPndmeCksCgkJCShEV09SRClEU09VTkRfY2FsbGJhY2ssIChEV09SRCkoKmlwcERTKSwKCQkJQ0FMTEJBQ0tfRlVOQ1RJT04gfCBXQVZFX0RJUkVDVFNPVU5EKSk7CiAgICAgICAgICAgICAgICAgICgqaXBwRFMpLT5kcnZkZXNjLmRuRGV2Tm9kZSsrOyAvKiBuZXh0IHdhdmUgZGV2aWNlICovCgkJfQoKICAgICAgICAgICAgICAgICgqaXBwRFMpLT5kcnZkZXNjLmRuRGV2Tm9kZS0tOyAvKiB0YWtlIGF3YXkgbGFzdCBpbmNyZW1lbnQgKi8KCQkKCX0KCglpZiAoZHJ2ICYmIChlcnIgPT0gRFNfT0spKQoJCWVyciA9IElEc0RyaXZlcl9PcGVuKGRydik7CgoJLyogRklYTUU6IGRvIHdlIHdhbnQgdG8gaGFuZGxlIGEgdGVtcG9yYXJpbHkgYnVzeSBkZXZpY2U/ICovCglpZiAoZXJyICE9IERTX09LKSB7CgkJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLCppcHBEUyk7CgkJKmlwcERTID0gTlVMTDsKCQlyZXR1cm4gZXJyOwoJfQoKCS8qIHRoZSBkcml2ZXIgaXMgbm93IG9wZW4sIHNvIGl0J3Mgbm93IGFsbG93ZWQgdG8gY2FsbCBHZXRDYXBzICovCglpZiAoZHJ2KSB7CgkJSURzRHJpdmVyX0dldENhcHMoZHJ2LCYoKCppcHBEUyktPmRydmNhcHMpKTsKCX0gZWxzZSB7CgkJdW5zaWduZWQgYzsKCgoJCS8qIEZJWE1FOiBsb29rIGF0IHdjYXBzICovCgkJKCppcHBEUyktPmRydmNhcHMuZHdGbGFncyA9CgkJCURTQ0FQU19QUklNQVJZMTZCSVQgfCBEU0NBUFNfUFJJTUFSWVNURVJFTzsKCQlpZiAoZHNfZW11bGRyaXZlcikKCQkgICAgKCppcHBEUyktPmRydmNhcHMuZHdGbGFncyB8PSBEU0NBUFNfRU1VTERSSVZFUjsKCgkJLyogQWxsb2NhdGUgbWVtb3J5IGZvciBIRUwgYnVmZmVyIGhlYWRlcnMgKi8KCQlmb3IgKGM9MDsgYzxEU19IRUxfRlJBR1M7IGMrKykgewoJCQkoKmlwcERTKS0+cHdhdmVbY10gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSxIRUFQX1pFUk9fTUVNT1JZLHNpemVvZihXQVZFSERSKSk7CgkJCWlmICghKCppcHBEUyktPnB3YXZlW2NdKSB7CgkJCQkvKiBBcmdoLCBvdXQgb2YgbWVtb3J5ICovCgkJCQl3aGlsZSAoYy0tKSB7CgkJCQkJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLCgqaXBwRFMpLT5wd2F2ZVtjXSk7CgkJCQkJd2F2ZU91dENsb3NlKCgqaXBwRFMpLT5od28pOwoJCQkJCUhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCwqaXBwRFMpOwoJCQkJCSppcHBEUyA9IE5VTEw7CgkJCQkJcmV0dXJuIERTRVJSX09VVE9GTUVNT1JZOwoJCQkJfQoJCQl9CgkJfQoJfQoKCUluaXRpYWxpemVDcml0aWNhbFNlY3Rpb24oJigoKmlwcERTKS0+bG9jaykpOwoKCWlmICghZHNvdW5kKSB7CgkJZHNvdW5kID0gKCppcHBEUyk7CgkJaWYgKHByaW1hcnlidWYgPT0gTlVMTCkgewoJCQlEU0JVRkZFUkRFU0MJZHNiZDsKCQkJSFJFU1VMVAkJaHI7CgoJCQlkc2JkLmR3U2l6ZSA9IHNpemVvZihEU0JVRkZFUkRFU0MpOwoJCQlkc2JkLmR3RmxhZ3MgPSBEU0JDQVBTX1BSSU1BUllCVUZGRVI7CgkJCWRzYmQuZHdCdWZmZXJCeXRlcyA9IDA7CgkJCWRzYmQubHB3ZnhGb3JtYXQgPSAmKGRzb3VuZC0+d2Z4KTsKCQkJaHIgPSBJRGlyZWN0U291bmRfQ3JlYXRlU291bmRCdWZmZXIoKnBwRFMsICZkc2JkLCAoTFBESVJFQ1RTT1VOREJVRkZFUiopJnByaW1hcnlidWYsIE5VTEwpOwoJCQlpZiAoaHIgIT0gRFNfT0spCgkJCQlyZXR1cm4gaHI7CgoJCQkvKiBkc291bmQtPnByaW1hcnkgaXMgTlVMTCAtIGRvbid0IG5lZWQgdG8gUmVsZWFzZSAqLwoJCQlkc291bmQtPnByaW1hcnkgPSBwcmltYXJ5YnVmOwoJCQlJRGlyZWN0U291bmRCdWZmZXJfQWRkUmVmKChMUERJUkVDVFNPVU5EQlVGRkVSKXByaW1hcnlidWYpOwoJCX0KCQl0aW1lQmVnaW5QZXJpb2QoRFNfVElNRV9SRVMpOwoJCWRzb3VuZC0+dGltZXJJRCA9IHRpbWVTZXRFdmVudChEU19USU1FX0RFTCwgRFNfVElNRV9SRVMsIERTT1VORF90aW1lciwKCQkJCQkgICAgICAgKERXT1JEKWRzb3VuZCwgVElNRV9QRVJJT0RJQyB8IFRJTUVfQ0FMTEJBQ0tfRlVOQ1RJT04pOwoJfQoJcmV0dXJuIERTX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERpcmVjdFNvdW5kQ2FwdHVyZUNyZWF0ZSBbRFNPVU5ELjZdCiAqCiAqIENyZWF0ZSBhbmQgaW5pdGlhbGl6ZSBhIERpcmVjdFNvdW5kQ2FwdHVyZSBpbnRlcmZhY2UKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBEU19PSwogKiAgICBGYWlsdXJlOiBEU0VSUl9OT0FHR1JFR0FUSU9OLCBEU0VSUl9BTExPQ0FURUQsIERTRVJSX0lOVkFMSURQQVJBTSwKICogICAgICAgICAgICAgRFNFUlJfT1VUT0ZNRU1PUlkKICovCkhSRVNVTFQgV0lOQVBJIERpcmVjdFNvdW5kQ2FwdHVyZUNyZWF0ZSgKCUxQQ0dVSUQgbHBjR1VJRCwKCUxQRElSRUNUU09VTkRDQVBUVVJFKiBscGxwRFNDLAoJTFBVTktOT1dOIHBVbmtPdXRlciApCnsKCVRSQUNFKCIoJXMsJXAsJXApXG4iLCBkZWJ1Z3N0cl9ndWlkKGxwY0dVSUQpLCBscGxwRFNDLCBwVW5rT3V0ZXIpOwoKCWlmKCBwVW5rT3V0ZXIgKSB7CgkJcmV0dXJuIERTRVJSX05PQUdHUkVHQVRJT047Cgl9CgoJLyogRGVmYXVsdCBkZXZpY2U/ICovCglpZiAoICFscGNHVUlEICkgewoJCXJldHVybiBEU09VTkRfQ3JlYXRlRGlyZWN0U291bmRDYXB0dXJlKCAoTFBWT0lEKilscGxwRFNDICk7Cgl9CgoJRklYTUUoICJVbmtub3duIEdVSUQgJXNcbiIsIGRlYnVnc3RyX2d1aWQobHBjR1VJRCkgKTsKCSpscGxwRFNDID0gTlVMTDsKCglyZXR1cm4gRFNFUlJfT1VUT0ZNRU1PUlk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGlyZWN0U291bmRDYXB0dXJlRW51bWVyYXRlQSBbRFNPVU5ELjddCiAqCiAqIEVudW1lcmF0ZSBhbGwgRGlyZWN0U291bmQgZHJpdmVycyBpbnN0YWxsZWQgaW4gdGhlIHN5c3RlbQogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IERTX09LCiAqICAgIEZhaWx1cmU6IERTRVJSX0lOVkFMSURQQVJBTQogKi8KSFJFU1VMVCBXSU5BUEkgRGlyZWN0U291bmRDYXB0dXJlRW51bWVyYXRlQSgKICAgICAgICBMUERTRU5VTUNBTExCQUNLQSBscERTRW51bUNhbGxiYWNrLAogICAgICAgIExQVk9JRCBscENvbnRleHQpCnsKCVRSQUNFKCIoJXAsJXApXG4iLCBscERTRW51bUNhbGxiYWNrLCBscENvbnRleHQgKTsKCglpZiAoIGxwRFNFbnVtQ2FsbGJhY2sgKQoJCWxwRFNFbnVtQ2FsbGJhY2soTlVMTCwiV0lORSBQcmltYXJ5IFNvdW5kIENhcHR1cmUgRHJpdmVyIiwKICAgICAgICAgICAgICAgICAgICAiU291bmRDYXAiLGxwQ29udGV4dCk7CgoKCXJldHVybiBEU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEaXJlY3RTb3VuZENhcHR1cmVFbnVtZXJhdGVXIFtEU09VTkQuOF0KICoKICogRW51bWVyYXRlIGFsbCBEaXJlY3RTb3VuZCBkcml2ZXJzIGluc3RhbGxlZCBpbiB0aGUgc3lzdGVtCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogRFNfT0sKICogICAgRmFpbHVyZTogRFNFUlJfSU5WQUxJRFBBUkFNCiAqLwpIUkVTVUxUIFdJTkFQSSBEaXJlY3RTb3VuZENhcHR1cmVFbnVtZXJhdGVXKAogICAgICAgIExQRFNFTlVNQ0FMTEJBQ0tXIGxwRFNFbnVtQ2FsbGJhY2ssCiAgICAgICAgTFBWT0lEIGxwQ29udGV4dCkKewogICAgICAgIEZJWE1FKCIoJXAsJXApOnN0dWJcbiIsIGxwRFNFbnVtQ2FsbGJhY2ssIGxwQ29udGV4dCApOwogICAgICAgIHJldHVybiBEU19PSzsKfSAKCnN0YXRpYyBIUkVTVUxUCkRTT1VORF9DcmVhdGVEaXJlY3RTb3VuZENhcHR1cmUoIExQVk9JRCogcHBvYmogKQp7CgkqcHBvYmogPSBIZWFwQWxsb2MoIEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZiggSURpcmVjdFNvdW5kQ2FwdHVyZUltcGwgKSApOwoKCWlmICggKnBwb2JqID09IE5VTEwgKSB7CgkJcmV0dXJuIERTRVJSX09VVE9GTUVNT1JZOwoJfQoKCXsKCQlJQ09NX1RISVMoSURpcmVjdFNvdW5kQ2FwdHVyZUltcGwsKnBwb2JqKTsKCgkJVGhpcy0+cmVmID0gMTsKCQlJQ09NX1ZUQkwoVGhpcykgPSAmZHNjdnQ7CgoJCUluaXRpYWxpemVDcml0aWNhbFNlY3Rpb24oICZUaGlzLT5sb2NrICk7Cgl9CgoJcmV0dXJuIFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0U291bmRDYXB0dXJlSW1wbF9RdWVyeUludGVyZmFjZSgKCUxQRElSRUNUU09VTkRDQVBUVVJFIGlmYWNlLAoJUkVGSUlEIHJpaWQsCglMUFZPSUQqIHBwb2JqICkKewoJSUNPTV9USElTKElEaXJlY3RTb3VuZENhcHR1cmVJbXBsLGlmYWNlKTsKCglGSVhNRSggIiglcCktPiglcywlcCk6IHN0dWJcbiIsIFRoaXMsIGRlYnVnc3RyX2d1aWQocmlpZCksIHBwb2JqICk7CgoJcmV0dXJuIEVfRkFJTDsKfQoKc3RhdGljIFVMT05HIFdJTkFQSQpJRGlyZWN0U291bmRDYXB0dXJlSW1wbF9BZGRSZWYoIExQRElSRUNUU09VTkRDQVBUVVJFIGlmYWNlICkKewoJVUxPTkcgdVJlZjsKICAgICAgICBJQ09NX1RISVMoSURpcmVjdFNvdW5kQ2FwdHVyZUltcGwsaWZhY2UpOwoKCUVudGVyQ3JpdGljYWxTZWN0aW9uKCAmVGhpcy0+bG9jayApOwoKCVRSQUNFKCAiKCVwKSB3YXMgMHglMDhseFxuIiwgVGhpcywgVGhpcy0+cmVmICk7Cgl1UmVmID0gKysoVGhpcy0+cmVmKTsKCglMZWF2ZUNyaXRpY2FsU2VjdGlvbiggJlRoaXMtPmxvY2sgKTsKCiAgICAgICAgcmV0dXJuIHVSZWY7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkKSURpcmVjdFNvdW5kQ2FwdHVyZUltcGxfUmVsZWFzZSggTFBESVJFQ1RTT1VORENBUFRVUkUgaWZhY2UgKQp7CglVTE9ORyB1UmVmOwoJSUNPTV9USElTKElEaXJlY3RTb3VuZENhcHR1cmVJbXBsLGlmYWNlKTsKCglFbnRlckNyaXRpY2FsU2VjdGlvbiggJlRoaXMtPmxvY2sgKTsKCglUUkFDRSggIiglcCkgd2FzIDB4JTA4bHhcbiIsIFRoaXMsIFRoaXMtPnJlZiApOwoJdVJlZiA9IC0tKFRoaXMtPnJlZik7CgoJTGVhdmVDcml0aWNhbFNlY3Rpb24oICZUaGlzLT5sb2NrICk7CgoJaWYgKCB1UmVmID09IDAgKSB7CgkJRGVsZXRlQ3JpdGljYWxTZWN0aW9uKCAmVGhpcy0+bG9jayApOwoJCUhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzICk7Cgl9CgoJcmV0dXJuIHVSZWY7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0U291bmRDYXB0dXJlSW1wbF9DcmVhdGVDYXB0dXJlQnVmZmVyKAoJTFBESVJFQ1RTT1VORENBUFRVUkUgaWZhY2UsCglMUENEU0NCVUZGRVJERVNDIGxwY0RTQ0J1ZmZlckRlc2MsCglMUERJUkVDVFNPVU5EQ0FQVFVSRUJVRkZFUiogbHBscERTQ2FwdHVyZUJ1ZmZlciwgCglMUFVOS05PV04gcFVuayApCnsKCUhSRVNVTFQgaHI7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQ2FwdHVyZUltcGwsaWZhY2UpOwoKCVRSQUNFKCAiKCVwKS0+KCVwLCVwLCVwKVxuIiwgVGhpcywgbHBjRFNDQnVmZmVyRGVzYywgbHBscERTQ2FwdHVyZUJ1ZmZlciwgcFVuayApOwoKCWlmICggcFVuayApIHsKCQlyZXR1cm4gRFNFUlJfSU5WQUxJRFBBUkFNOwoJfQoKCWhyID0gRFNPVU5EX0NyZWF0ZURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlciggbHBjRFNDQnVmZmVyRGVzYywgKExQVk9JRCopbHBscERTQ2FwdHVyZUJ1ZmZlciApOwoKCXJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3RTb3VuZENhcHR1cmVJbXBsX0dldENhcHMoCglMUERJUkVDVFNPVU5EQ0FQVFVSRSBpZmFjZSwKCUxQRFNDQ0FQUyBscERTQ0NhcHMgKQp7CiAgICAgICAgSUNPTV9USElTKElEaXJlY3RTb3VuZENhcHR1cmVJbXBsLGlmYWNlKTsKCiAgICAgICAgRklYTUUoICIoJXApLT4oJXApOiBzdHViXG4iLCBUaGlzLCBscERTQ0NhcHMgKTsKCiAgICAgICAgcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdFNvdW5kQ2FwdHVyZUltcGxfSW5pdGlhbGl6ZSgKCUxQRElSRUNUU09VTkRDQVBUVVJFIGlmYWNlLAoJTFBDR1VJRCBscGNHVUlEICkKewogICAgICAgIElDT01fVEhJUyhJRGlyZWN0U291bmRDYXB0dXJlSW1wbCxpZmFjZSk7CgogICAgICAgIEZJWE1FKCAiKCVwKS0+KCVwKTogc3R1YlxuIiwgVGhpcywgbHBjR1VJRCApOwoKICAgICAgICByZXR1cm4gRFNfT0s7Cn0KCgpzdGF0aWMgSUNPTV9WVEFCTEUoSURpcmVjdFNvdW5kQ2FwdHVyZSkgZHNjdnQgPQp7CiAgICAgICAgSUNPTV9NU1ZUQUJMRV9DT01QQVRfRHVtbXlSVFRJVkFMVUUKICAgICAgICAvKiBJVW5rbm93biBtZXRob2RzICovCiAgICAgICAgSURpcmVjdFNvdW5kQ2FwdHVyZUltcGxfUXVlcnlJbnRlcmZhY2UsCiAgICAgICAgSURpcmVjdFNvdW5kQ2FwdHVyZUltcGxfQWRkUmVmLAogICAgICAgIElEaXJlY3RTb3VuZENhcHR1cmVJbXBsX1JlbGVhc2UsCgogICAgICAgIC8qIElEaXJlY3RTb3VuZENhcHR1cmUgbWV0aG9kcyAqLwogICAgICAgIElEaXJlY3RTb3VuZENhcHR1cmVJbXBsX0NyZWF0ZUNhcHR1cmVCdWZmZXIsCiAgICAgICAgSURpcmVjdFNvdW5kQ2FwdHVyZUltcGxfR2V0Q2FwcywKICAgICAgICBJRGlyZWN0U291bmRDYXB0dXJlSW1wbF9Jbml0aWFsaXplIAp9OwoKc3RhdGljIEhSRVNVTFQKRFNPVU5EX0NyZWF0ZURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlciggTFBDRFNDQlVGRkVSREVTQyBscGNEU0NCdWZmZXJEZXNjLCBMUFZPSUQqIHBwb2JqICkKewoKCUZJWE1FKCAiKCVwLCVwKTogaWdub3JpbmcgbHBjRFNDQnVmZmVyRGVzY1xuIiwgbHBjRFNDQnVmZmVyRGVzYywgcHBvYmogKTsKCgkqcHBvYmogPSBIZWFwQWxsb2MoIEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZiggSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGwgKSApOwoKCWlmICggKnBwb2JqID09IE5VTEwgKSB7CgkJcmV0dXJuIERTRVJSX09VVE9GTUVNT1JZOwoJfQoKCXsKCQlJQ09NX1RISVMoSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGwsKnBwb2JqKTsKCgkJVGhpcy0+cmVmID0gMTsKCQlJQ09NX1ZUQkwoVGhpcykgPSAmZHNjYnZ0OwoKCQlJbml0aWFsaXplQ3JpdGljYWxTZWN0aW9uKCAmVGhpcy0+bG9jayApOwoJfQoKCXJldHVybiBTX09LOwp9CgoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX1F1ZXJ5SW50ZXJmYWNlKAogICAgICAgIExQRElSRUNUU09VTkRDQVBUVVJFQlVGRkVSIGlmYWNlLAogICAgICAgIFJFRklJRCByaWlkLAogICAgICAgIExQVk9JRCogcHBvYmogKQp7CiAgICAgICAgSUNPTV9USElTKElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsLGlmYWNlKTsKCiAgICAgICAgRklYTUUoICIoJXApLT4oJXMsJXApOiBzdHViXG4iLCBUaGlzLCBkZWJ1Z3N0cl9ndWlkKHJpaWQpLCBwcG9iaiApOwoKICAgICAgICByZXR1cm4gRV9GQUlMOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJCklEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX0FkZFJlZiggTFBESVJFQ1RTT1VORENBUFRVUkVCVUZGRVIgaWZhY2UgKQp7CiAgICAgICAgVUxPTkcgdVJlZjsKICAgICAgICBJQ09NX1RISVMoSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGwsaWZhY2UpOwoKICAgICAgICBFbnRlckNyaXRpY2FsU2VjdGlvbiggJlRoaXMtPmxvY2sgKTsKCglUUkFDRSggIiglcCkgd2FzIDB4JTA4bHhcbiIsIFRoaXMsIFRoaXMtPnJlZiApOwogICAgICAgIHVSZWYgPSArKyhUaGlzLT5yZWYpOwoKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbiggJlRoaXMtPmxvY2sgKTsKCiAgICAgICAgcmV0dXJuIHVSZWY7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkKSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGxfUmVsZWFzZSggTFBESVJFQ1RTT1VORENBUFRVUkVCVUZGRVIgaWZhY2UgKQp7CiAgICAgICAgVUxPTkcgdVJlZjsKICAgICAgICBJQ09NX1RISVMoSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGwsaWZhY2UpOwoKICAgICAgICBFbnRlckNyaXRpY2FsU2VjdGlvbiggJlRoaXMtPmxvY2sgKTsKCglUUkFDRSggIiglcCkgd2FzIDB4JTA4bHhcbiIsIFRoaXMsIFRoaXMtPnJlZiApOwogICAgICAgIHVSZWYgPSAtLShUaGlzLT5yZWYpOwoKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbiggJlRoaXMtPmxvY2sgKTsKCiAgICAgICAgaWYgKCB1UmVmID09IDAgKSB7CgkJRGVsZXRlQ3JpdGljYWxTZWN0aW9uKCAmVGhpcy0+bG9jayApOwogICAgICAgICAgICAgICAgSGVhcEZyZWUoIEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMgKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiB1UmVmOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGxfR2V0Q2FwcygKICAgICAgICBMUERJUkVDVFNPVU5EQ0FQVFVSRUJVRkZFUiBpZmFjZSwKCUxQRFNDQkNBUFMgbHBEU0NCQ2FwcyApCnsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbCxpZmFjZSk7CgoJRklYTUUoICIoJXApLT4oJXApOiBzdHViXG4iLCBUaGlzLCBscERTQ0JDYXBzICk7CgoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGxfR2V0Q3VycmVudFBvc2l0aW9uKAogICAgICAgIExQRElSRUNUU09VTkRDQVBUVVJFQlVGRkVSIGlmYWNlLAoJTFBEV09SRCBscGR3Q2FwdHVyZVBvc2l0aW9uLAoJTFBEV09SRCBscGR3UmVhZFBvc2l0aW9uICkKewoJSUNPTV9USElTKElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsLGlmYWNlKTsKCglGSVhNRSggIiglcCktPiglcCwlcCk6IHN0dWJcbiIsIFRoaXMsIGxwZHdDYXB0dXJlUG9zaXRpb24sIGxwZHdSZWFkUG9zaXRpb24gKTsKCglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbF9HZXRGb3JtYXQoCiAgICAgICAgTFBESVJFQ1RTT1VORENBUFRVUkVCVUZGRVIgaWZhY2UsCglMUFdBVkVGT1JNQVRFWCBscHdmeEZvcm1hdCwgCglEV09SRCBkd1NpemVBbGxvY2F0ZWQsIAoJTFBEV09SRCBscGR3U2l6ZVdyaXR0ZW4gKQp7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGwsaWZhY2UpOwoKCUZJWE1FKCAiKCVwKS0+KCVwLDB4JTA4bHgsJXApOiBzdHViXG4iLCBUaGlzLCBscHdmeEZvcm1hdCwgZHdTaXplQWxsb2NhdGVkLCBscGR3U2l6ZVdyaXR0ZW4gKTsKCglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbF9HZXRTdGF0dXMoCiAgICAgICAgTFBESVJFQ1RTT1VORENBUFRVUkVCVUZGRVIgaWZhY2UsCglMUERXT1JEIGxwZHdTdGF0dXMgKQp7CglJQ09NX1RISVMoSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGwsaWZhY2UpOwoKCUZJWE1FKCAiKCVwKS0+KCVwKTogc3R1YlxuIiwgVGhpcywgbHBkd1N0YXR1cyApOwoKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX0luaXRpYWxpemUoCiAgICAgICAgTFBESVJFQ1RTT1VORENBUFRVUkVCVUZGRVIgaWZhY2UsCglMUERJUkVDVFNPVU5EQ0FQVFVSRSBscERTQywgCglMUENEU0NCVUZGRVJERVNDIGxwY0RTQ0JEZXNjICkKewoJSUNPTV9USElTKElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsLGlmYWNlKTsKCglGSVhNRSggIiglcCktPiglcCwlcCk6IHN0dWJcbiIsIFRoaXMsIGxwRFNDLCBscGNEU0NCRGVzYyApOwoKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX0xvY2soCiAgICAgICAgTFBESVJFQ1RTT1VORENBUFRVUkVCVUZGRVIgaWZhY2UsCglEV09SRCBkd1JlYWRDdXNvciwgCglEV09SRCBkd1JlYWRCeXRlcywgCglMUFZPSUQqIGxwbHB2QXVkaW9QdHIxLCAKCUxQRFdPUkQgbHBkd0F1ZGlvQnl0ZXMxLCAKCUxQVk9JRCogbHBscHZBdWRpb1B0cjIsIAoJTFBEV09SRCBscGR3QXVkaW9CeXRlczIsIAoJRFdPUkQgZHdGbGFncyApCnsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbCxpZmFjZSk7CgoJRklYTUUoICIoJXApLT4oJTA4bHUsJTA4bHUsJXAsJXAsJXAsJXAsMHglMDhseCk6IHN0dWJcbiIsIFRoaXMsIGR3UmVhZEN1c29yLCBkd1JlYWRCeXRlcywgbHBscHZBdWRpb1B0cjEsIGxwZHdBdWRpb0J5dGVzMSwgbHBscHZBdWRpb1B0cjIsIGxwZHdBdWRpb0J5dGVzMiwgZHdGbGFncyApOwoKCXJldHVybiBEU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX1N0YXJ0KAogICAgICAgIExQRElSRUNUU09VTkRDQVBUVVJFQlVGRkVSIGlmYWNlLAoJRFdPUkQgZHdGbGFncyApCnsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbCxpZmFjZSk7CgoJRklYTUUoICIoJXApLT4oMHglMDhseCk6IHN0dWJcbiIsIFRoaXMsIGR3RmxhZ3MgKTsKCglyZXR1cm4gRFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbF9TdG9wKCBMUERJUkVDVFNPVU5EQ0FQVFVSRUJVRkZFUiBpZmFjZSApCnsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbCxpZmFjZSk7CgoJRklYTUUoICIoJXApOiBzdHViXG4iLCBUaGlzICk7CgoJcmV0dXJuIERTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGxfVW5sb2NrKAogICAgICAgIExQRElSRUNUU09VTkRDQVBUVVJFQlVGRkVSIGlmYWNlLAoJTFBWT0lEIGxwdkF1ZGlvUHRyMSwgCglEV09SRCBkd0F1ZGlvQnl0ZXMxLCAKCUxQVk9JRCBscHZBdWRpb1B0cjIsIAoJRFdPUkQgZHdBdWRpb0J5dGVzMiApCnsKCUlDT01fVEhJUyhJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbCxpZmFjZSk7CgoJRklYTUUoICIoJXApLT4oJXAsJTA4bHUsJXAsJTA4bHUpOiBzdHViXG4iLCBUaGlzLCBscHZBdWRpb1B0cjEsIGR3QXVkaW9CeXRlczEsIGxwdkF1ZGlvUHRyMiwgZHdBdWRpb0J5dGVzMiApOwoKCXJldHVybiBEU19PSzsKfQoKCnN0YXRpYyBJQ09NX1ZUQUJMRShJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVyKSBkc2NidnQgPQp7CiAgICAgICAgSUNPTV9NU1ZUQUJMRV9DT01QQVRfRHVtbXlSVFRJVkFMVUUKICAgICAgICAvKiBJVW5rbm93biBtZXRob2RzICovCiAgICAgICAgSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGxfUXVlcnlJbnRlcmZhY2UsCiAgICAgICAgSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGxfQWRkUmVmLAogICAgICAgIElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX1JlbGVhc2UsCgogICAgICAgIC8qIElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXIgbWV0aG9kcyAqLwogICAgICAgIElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX0dldENhcHMsCiAgICAgICAgSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGxfR2V0Q3VycmVudFBvc2l0aW9uLAogICAgICAgIElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX0dldEZvcm1hdCwKICAgICAgICBJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbF9HZXRTdGF0dXMsCiAgICAgICAgSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGxfSW5pdGlhbGl6ZSwKICAgICAgICBJRGlyZWN0U291bmRDYXB0dXJlQnVmZmVySW1wbF9Mb2NrLAogICAgICAgIElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX1N0YXJ0LAogICAgICAgIElEaXJlY3RTb3VuZENhcHR1cmVCdWZmZXJJbXBsX1N0b3AsCiAgICAgICAgSURpcmVjdFNvdW5kQ2FwdHVyZUJ1ZmZlckltcGxfVW5sb2NrCn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEaXJlY3RTb3VuZCBDbGFzc0ZhY3RvcnkKICovCnR5cGVkZWYgc3RydWN0CnsKICAgIC8qIElVbmtub3duIGZpZWxkcyAqLwogICAgSUNPTV9WRklFTEQoSUNsYXNzRmFjdG9yeSk7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgICAgcmVmOwp9IElDbGFzc0ZhY3RvcnlJbXBsOwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIApEU0NGX1F1ZXJ5SW50ZXJmYWNlKExQQ0xBU1NGQUNUT1JZIGlmYWNlLFJFRklJRCByaWlkLExQVk9JRCAqcHBvYmopIHsKCUlDT01fVEhJUyhJQ2xhc3NGYWN0b3J5SW1wbCxpZmFjZSk7CgoJRklYTUUoIiglcCktPiglcywlcCksc3R1YiFcbiIsVGhpcyxkZWJ1Z3N0cl9ndWlkKHJpaWQpLHBwb2JqKTsKCXJldHVybiBFX05PSU5URVJGQUNFOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJCkRTQ0ZfQWRkUmVmKExQQ0xBU1NGQUNUT1JZIGlmYWNlKSB7CglJQ09NX1RISVMoSUNsYXNzRmFjdG9yeUltcGwsaWZhY2UpOwoJcmV0dXJuICsrKFRoaXMtPnJlZik7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgRFNDRl9SZWxlYXNlKExQQ0xBU1NGQUNUT1JZIGlmYWNlKSB7CglJQ09NX1RISVMoSUNsYXNzRmFjdG9yeUltcGwsaWZhY2UpOwoJLyogc3RhdGljIGNsYXNzLCB3b24ndCBiZSAgZnJlZWQgKi8KCXJldHVybiAtLShUaGlzLT5yZWYpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgRFNDRl9DcmVhdGVJbnN0YW5jZSgKCUxQQ0xBU1NGQUNUT1JZIGlmYWNlLExQVU5LTk9XTiBwT3V0ZXIsUkVGSUlEIHJpaWQsTFBWT0lEICpwcG9iagopIHsKCUlDT01fVEhJUyhJQ2xhc3NGYWN0b3J5SW1wbCxpZmFjZSk7CgoJVFJBQ0UoIiglcCktPiglcCwlcywlcClcbiIsVGhpcyxwT3V0ZXIsZGVidWdzdHJfZ3VpZChyaWlkKSxwcG9iaik7CglpZiAoIElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3RTb3VuZCwgcmlpZCApICkgewoJCS8qIEZJWE1FOiByZXVzZSBhbHJlYWR5IGNyZWF0ZWQgZHNvdW5kIGlmIHByZXNlbnQ/ICovCgkJcmV0dXJuIERpcmVjdFNvdW5kQ3JlYXRlKHJpaWQsKExQRElSRUNUU09VTkQqKXBwb2JqLHBPdXRlcik7Cgl9CglyZXR1cm4gRV9OT0lOVEVSRkFDRTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIERTQ0ZfTG9ja1NlcnZlcihMUENMQVNTRkFDVE9SWSBpZmFjZSxCT09MIGRvbG9jaykgewoJSUNPTV9USElTKElDbGFzc0ZhY3RvcnlJbXBsLGlmYWNlKTsKCUZJWE1FKCIoJXApLT4oJWQpLHN0dWIhXG4iLFRoaXMsZG9sb2NrKTsKCXJldHVybiBTX09LOwp9CgpzdGF0aWMgSUNPTV9WVEFCTEUoSUNsYXNzRmFjdG9yeSkgRFNDRl9WdGJsID0gewoJSUNPTV9NU1ZUQUJMRV9DT01QQVRfRHVtbXlSVFRJVkFMVUUKCURTQ0ZfUXVlcnlJbnRlcmZhY2UsCglEU0NGX0FkZFJlZiwKCURTQ0ZfUmVsZWFzZSwKCURTQ0ZfQ3JlYXRlSW5zdGFuY2UsCglEU0NGX0xvY2tTZXJ2ZXIKfTsKc3RhdGljIElDbGFzc0ZhY3RvcnlJbXBsIERTT1VORF9DRiA9IHsmRFNDRl9WdGJsLCAxIH07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEbGxHZXRDbGFzc09iamVjdCBbRFNPVU5ELjVdCiAqIFJldHJpZXZlcyBjbGFzcyBvYmplY3QgZnJvbSBhIERMTCBvYmplY3QKICoKICogTk9URVMKICogICAgRG9jcyBzYXkgcmV0dXJucyBTVERBUEkKICoKICogUEFSQU1TCiAqICAgIHJjbHNpZCBbSV0gQ0xTSUQgZm9yIHRoZSBjbGFzcyBvYmplY3QKICogICAgcmlpZCAgIFtJXSBSZWZlcmVuY2UgdG8gaWRlbnRpZmllciBvZiBpbnRlcmZhY2UgZm9yIGNsYXNzIG9iamVjdAogKiAgICBwcHYgICAgW09dIEFkZHJlc3Mgb2YgdmFyaWFibGUgdG8gcmVjZWl2ZSBpbnRlcmZhY2UgcG9pbnRlciBmb3IgcmlpZAogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IFNfT0sKICogICAgRmFpbHVyZTogQ0xBU1NfRV9DTEFTU05PVEFWQUlMQUJMRSwgRV9PVVRPRk1FTU9SWSwgRV9JTlZBTElEQVJHLAogKiAgICAgICAgICAgICBFX1VORVhQRUNURUQKICovCkRXT1JEIFdJTkFQSSBEU09VTkRfRGxsR2V0Q2xhc3NPYmplY3QoUkVGQ0xTSUQgcmNsc2lkLFJFRklJRCByaWlkLExQVk9JRCAqcHB2KQp7CiAgICBUUkFDRSgiKCVwLCVwLCVwKVxuIiwgZGVidWdzdHJfZ3VpZChyY2xzaWQpLCBkZWJ1Z3N0cl9ndWlkKHJpaWQpLCBwcHYpOwogICAgaWYgKCBJc0VxdWFsQ0xTSUQoICZJSURfSUNsYXNzRmFjdG9yeSwgcmlpZCApICkgewogICAgCSpwcHYgPSAoTFBWT0lEKSZEU09VTkRfQ0Y7CglJQ2xhc3NGYWN0b3J5X0FkZFJlZigoSUNsYXNzRmFjdG9yeSopKnBwdik7CiAgICByZXR1cm4gU19PSzsKICAgIH0KCiAgICBGSVhNRSgiKCVwLCVwLCVwKTogbm8gaW50ZXJmYWNlIGZvdW5kLlxuIiwgZGVidWdzdHJfZ3VpZChyY2xzaWQpLCBkZWJ1Z3N0cl9ndWlkKHJpaWQpLCBwcHYpOwogICAgcmV0dXJuIENMQVNTX0VfQ0xBU1NOT1RBVkFJTEFCTEU7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEbGxDYW5VbmxvYWROb3cgW0RTT1VORC40XSAgRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBETEwgaXMgaW4gdXNlLgogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IFNfT0sKICogICAgRmFpbHVyZTogU19GQUxTRQogKi8KRFdPUkQgV0lOQVBJIERTT1VORF9EbGxDYW5VbmxvYWROb3codm9pZCkKewogICAgRklYTUUoIih2b2lkKTogc3R1YlxuIik7CiAgICByZXR1cm4gU19GQUxTRTsKfQo=