LyoKICogQ09NIHByb3h5IGltcGxlbWVudGF0aW9uCiAqCiAqIENvcHlyaWdodCAyMDAxIE92ZSBL5XZlbiwgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKiAKICogVE9ETzogSGFuZGxlIG5vbi1pMzg2IGFyY2hpdGVjdHVyZXMKICogICAgICAgR2V0IHJpZCBvZiAjaWYgMCdlZCBjb2RlLgogKi8KCiNpbmNsdWRlIDxzdGRhcmcuaD4KCiNkZWZpbmUgQ09CSk1BQ1JPUwoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKCiNpbmNsdWRlICJvYmpiYXNlLmgiCiNpbmNsdWRlICJycGNwcm94eS5oIgoKI2luY2x1ZGUgImNwc2YuaCIKI2luY2x1ZGUgIm5kcl9taXNjLmgiCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChvbGUpOwoKc3RydWN0IFN0dWJsZXNzVGh1bms7CgovKiBJIGRvbid0IGtub3cgd2hhdCBNUydzIHN0ZCBwcm94eSBzdHJ1Y3R1cmUgbG9va3MgbGlrZSwKICAgc28gdGhpcyBwcm9iYWJseSBkb2Vzbid0IG1hdGNoLCBidXQgdGhhdCBzaG91bGRuJ3QgbWF0dGVyICovCnR5cGVkZWYgc3RydWN0IHsKICBjb25zdCBJUnBjUHJveHlCdWZmZXJWdGJsICpscFZ0Ymw7CiAgTFBWT0lEICpQVnRibDsKICBEV09SRCBSZWZDb3VudDsKICBjb25zdCBNSURMX1NUVUJMRVNTX1BST1hZX0lORk8gKnN0dWJsZXNzOwogIGNvbnN0IElJRCogcGlpZDsKICBMUFVOS05PV04gcFVua091dGVyOwogIFBDSW50ZXJmYWNlTmFtZSBuYW1lOwogIExQUFNGQUNUT1JZQlVGRkVSIHBQU0ZhY3Rvcnk7CiAgTFBSUENDSEFOTkVMQlVGRkVSIHBDaGFubmVsOwogIHN0cnVjdCBTdHVibGVzc1RodW5rICp0aHVua3M7Cn0gU3RkUHJveHlJbXBsOwoKc3RhdGljIGNvbnN0IElScGNQcm94eUJ1ZmZlclZ0YmwgU3RkUHJveHlfVnRibDsKCiNkZWZpbmUgSUNPTV9USElTX01VTFRJKGltcGwsZmllbGQsaWZhY2UpIGltcGwqIGNvbnN0IFRoaXM9KGltcGwqKSgoY2hhciopKGlmYWNlKSAtIG9mZnNldG9mKGltcGwsZmllbGQpKQoKLyogSG93IHRoZSBXaW5kb3dzIHN0dWJsZXNzIHByb3h5IHRodW5rcyB3b3JrIGlzIGV4cGxhaW5lZCBhdAogKiBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2xpYnJhcnkvZW4tdXMvZG5tc2o5OS9odG1sL2NvbTAxOTkuYXNwLAogKiBidXQgSSdsbCB1c2UgYSBzbGlnaHRseSBkaWZmZXJlbnQgbWV0aG9kLCB0byBtYWtlIGxpZmUgZWFzaWVyICovCgojaWYgZGVmaW5lZChfX2kzODZfXykKCiNpbmNsdWRlICJwc2hwYWNrMS5oIgoKc3RydWN0IFN0dWJsZXNzVGh1bmsgewogIEJZVEUgcHVzaDsKICBEV09SRCBpbmRleDsKICBCWVRFIGNhbGw7CiAgTE9ORyBoYW5kbGVyOwogIEJZVEUgcmV0OwogIFdPUkQgYnl0ZXM7CiAgQllURSBwYWRbM107Cn07CgojaW5jbHVkZSAicG9wcGFjay5oIgoKLyogYWRqdXN0IHRoZSBzdGFjayBzaXplIHNpbmNlIHdlIGRvbid0IHVzZSBXaW5kb3dzJ3MgbWV0aG9kICovCiNkZWZpbmUgU1RBQ0tfQURKVVNUIHNpemVvZihEV09SRCkKCiNkZWZpbmUgRklMTF9TVFVCTEVTUyh4LGlkeCxzdGspIFwKIHgtPnB1c2ggPSAweDY4OyAvKiBwdXNobCBbaW1tZWRpYXRlXSAqLyBcCiB4LT5pbmRleCA9IChpZHgpOyBcCiB4LT5jYWxsID0gMHhlODsgLyogY2FsbCBbbmVhcl0gKi8gXAogeC0+aGFuZGxlciA9IChjaGFyKilPYmplY3RTdHVibGVzcyAtIChjaGFyKikmeC0+cmV0OyBcCiB4LT5yZXQgPSAweGMyOyAvKiByZXQgW2ltbWVkaWF0ZV0gKi8gXAogeC0+Ynl0ZXMgPSBzdGs7IFwKIHgtPnBhZFswXSA9IDB4OGQ7IC8qIGxlYWwgKCVlc2kpLCVlc2kgKi8gXAogeC0+cGFkWzFdID0gMHg3NjsgXAogeC0+cGFkWzJdID0gMHgwMDsKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBPYmplY3RTdHVibGVzcyhEV09SRCBpbmRleCkKewogIGNoYXIgKmFyZ3MgPSAoY2hhciopKCZpbmRleCArIDIpOwogIExQVk9JRCBpZmFjZSA9ICooTFBWT0lEKilhcmdzOwoKICBJQ09NX1RISVNfTVVMVEkoU3RkUHJveHlJbXBsLFBWdGJsLGlmYWNlKTsKCiAgUEZPUk1BVF9TVFJJTkcgZnMgPSBUaGlzLT5zdHVibGVzcy0+UHJvY0Zvcm1hdFN0cmluZyArIFRoaXMtPnN0dWJsZXNzLT5Gb3JtYXRTdHJpbmdPZmZzZXRbaW5kZXhdOwogIHVuc2lnbmVkIGJ5dGVzID0gKihjb25zdCBXT1JEKikoZnMrOCkgLSBTVEFDS19BREpVU1Q7CiAgVFJBQ0UoIiglcCktPiglbGQpKFslZCBieXRlc10pIHJldD0lMDhseFxuIiwgaWZhY2UsIGluZGV4LCBieXRlcywgKihEV09SRCopKGFyZ3MrYnl0ZXMpKTsKCiAgcmV0dXJuIFJQQ1JUNF9OZHJDbGllbnRDYWxsMihUaGlzLT5zdHVibGVzcy0+cFN0dWJEZXNjLCBmcywgYXJncyk7Cn0KCiNlbHNlICAvKiBfX2kzODZfXyAqLwoKLyogY2FuJ3QgZG8gdGhhdCBvbiB0aGlzIGFyY2ggKi8Kc3RydWN0IFN0dWJsZXNzVGh1bmsgeyBpbnQgZHVtbXk7IH07CiNkZWZpbmUgRklMTF9TVFVCTEVTUyh4LGlkeCxzdGspIFwKIEVSUigic3R1Ymxlc3MgcHJveGllcyBhcmUgbm90IHN1cHBvcnRlZCBvbiB0aGlzIGFyY2hpdGVjdHVyZVxuIik7CiNkZWZpbmUgU1RBQ0tfQURKVVNUIDAKCiNlbmRpZiAgLyogX19pMzg2X18gKi8KCkhSRVNVTFQgV0lOQVBJIFN0ZFByb3h5X0NvbnN0cnVjdChSRUZJSUQgcmlpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBVTktOT1dOIHBVbmtPdXRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUENJbnRlcmZhY2VOYW1lIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENJbnRlcmZhY2VQcm94eVZ0YmwgKnZ0YmwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENJbnRlcmZhY2VTdHViVnRibCAqc3Z0YmwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQUFNGQUNUT1JZQlVGRkVSIHBQU0ZhY3RvcnksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQUlBDUFJPWFlCVUZGRVIgKnBwUHJveHksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQVk9JRCAqcHB2T2JqKQp7CiAgU3RkUHJveHlJbXBsICpUaGlzOwogIGNvbnN0IE1JRExfU1RVQkxFU1NfUFJPWFlfSU5GTyAqc3R1Ymxlc3MgPSBOVUxMOwoKICBUUkFDRSgiKCVwLCVwLCVwLCVwLCVwKSAlc1xuIiwgcFVua091dGVyLCB2dGJsLCBwUFNGYWN0b3J5LCBwcFByb3h5LCBwcHZPYmosIG5hbWUpOwoKICAvKiBJIGNhbid0IGZpbmQgYW55IG90aGVyIHdheSB0byBkZXRlY3Qgc3R1Ymxlc3MgcHJveGllcyB0aGFuIHRoaXMgaGFjayAqLwogIGlmICghSXNFcXVhbEdVSUQodnRibC0+aGVhZGVyLnBpaWQsIHJpaWQpKSB7CiAgICBzdHVibGVzcyA9ICooY29uc3Qgdm9pZCAqKil2dGJsOwogICAgdnRibCA9IChDSW50ZXJmYWNlUHJveHlWdGJsICopKChjb25zdCB2b2lkICoqKXZ0YmwgKyAxKTsKICAgIFRSQUNFKCJzdHVibGVzcz0lcFxuIiwgc3R1Ymxlc3MpOwogIH0KCiAgVFJBQ0UoImlpZD0lc1xuIiwgZGVidWdzdHJfZ3VpZCh2dGJsLT5oZWFkZXIucGlpZCkpOwogIFRSQUNFKCJ2dGJsPSVwXG4iLCB2dGJsLT5WdGJsKTsKCiAgaWYgKCFJc0VxdWFsR1VJRCh2dGJsLT5oZWFkZXIucGlpZCwgcmlpZCkpIHsKICAgIEVSUigiSUlEIG1pc21hdGNoIGR1cmluZyBwcm94eSBjcmVhdGlvblxuIik7CiAgICByZXR1cm4gUlBDX0VfVU5FWFBFQ1RFRDsKICB9CgogIFRoaXMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSxIRUFQX1pFUk9fTUVNT1JZLHNpemVvZihTdGRQcm94eUltcGwpKTsKICBpZiAoIVRoaXMpIHJldHVybiBFX09VVE9GTUVNT1JZOwoKICBpZiAoc3R1Ymxlc3MpIHsKICAgIHVuc2lnbmVkIGksIGNvdW50ID0gc3Z0YmwtPmhlYWRlci5EaXNwYXRjaFRhYmxlQ291bnQ7CiAgICAvKiBNYXliZSB0aGUgb3JpZ2luYWwgdnRibCBpcyBqdXN0IG1vZGlmaWVkIGRpcmVjdGx5IHRvIHBvaW50IGF0CiAgICAgKiBPYmplY3RTdHVibGVzc0NsaWVudFhYWCB0aHVua3MgaW4gcmVhbCBXaW5kb3dzLCBidXQgSSBkb24ndCBsaWtlIGl0CiAgICAgKi8KICAgIFRSQUNFKCJzdHVibGVzcyB0aHVua3M6IGNvdW50PSVkXG4iLCBjb3VudCk7CiAgICBUaGlzLT50aHVua3MgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwwLHNpemVvZihzdHJ1Y3QgU3R1Ymxlc3NUaHVuaykqY291bnQpOwogICAgVGhpcy0+UFZ0YmwgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwwLHNpemVvZihMUFZPSUQpKmNvdW50KTsKICAgIGZvciAoaT0wOyBpPGNvdW50OyBpKyspIHsKICAgICAgc3RydWN0IFN0dWJsZXNzVGh1bmsgKnRodW5rID0gJlRoaXMtPnRodW5rc1tpXTsKICAgICAgaWYgKHZ0YmwtPlZ0YmxbaV0gPT0gKExQVk9JRCktMSkgewogICAgICAgIFBGT1JNQVRfU1RSSU5HIGZzID0gc3R1Ymxlc3MtPlByb2NGb3JtYXRTdHJpbmcgKyBzdHVibGVzcy0+Rm9ybWF0U3RyaW5nT2Zmc2V0W2ldOwogICAgICAgIHVuc2lnbmVkIGJ5dGVzID0gKihjb25zdCBXT1JEKikoZnMrOCkgLSBTVEFDS19BREpVU1Q7CiAgICAgICAgVFJBQ0UoIm1ldGhvZCAlZDogc3RhY2tzaXplPSVkXG4iLCBpLCBieXRlcyk7CiAgICAgICAgRklMTF9TVFVCTEVTUyh0aHVuaywgaSwgYnl0ZXMpCiAgICAgICAgVGhpcy0+UFZ0YmxbaV0gPSB0aHVuazsKICAgICAgfQogICAgICBlbHNlIHsKICAgICAgICBtZW1zZXQodGh1bmssIDAsIHNpemVvZihzdHJ1Y3QgU3R1Ymxlc3NUaHVuaykpOwogICAgICAgIFRoaXMtPlBWdGJsW2ldID0gdnRibC0+VnRibFtpXTsKICAgICAgfQogICAgfQogIH0KICBlbHNlIAogICAgVGhpcy0+UFZ0YmwgPSB2dGJsLT5WdGJsOwoKICBUaGlzLT5scFZ0YmwgPSAmU3RkUHJveHlfVnRibDsKICAvKiBvbmUgcmVmZXJlbmNlIGZvciB0aGUgcHJveHkgKi8KICBUaGlzLT5SZWZDb3VudCA9IDE7CiAgVGhpcy0+c3R1Ymxlc3MgPSBzdHVibGVzczsKICBUaGlzLT5waWlkID0gdnRibC0+aGVhZGVyLnBpaWQ7CiAgVGhpcy0+cFVua091dGVyID0gcFVua091dGVyOwogIFRoaXMtPm5hbWUgPSBuYW1lOwogIFRoaXMtPnBQU0ZhY3RvcnkgPSBwUFNGYWN0b3J5OwogIFRoaXMtPnBDaGFubmVsID0gTlVMTDsKICAqcHBQcm94eSA9IChMUFJQQ1BST1hZQlVGRkVSKSZUaGlzLT5scFZ0Ymw7CiAgKnBwdk9iaiA9ICZUaGlzLT5QVnRibDsKICBJVW5rbm93bl9BZGRSZWYoKElVbmtub3duICopKnBwdk9iaik7CiAgSVBTRmFjdG9yeUJ1ZmZlcl9BZGRSZWYocFBTRmFjdG9yeSk7CgogIHJldHVybiBTX09LOwp9CgpzdGF0aWMgdm9pZCBXSU5BUEkgU3RkUHJveHlfRGVzdHJ1Y3QoTFBSUENQUk9YWUJVRkZFUiBpZmFjZSkKewogIElDT01fVEhJU19NVUxUSShTdGRQcm94eUltcGwsbHBWdGJsLGlmYWNlKTsKCiAgaWYgKFRoaXMtPnBDaGFubmVsKQogICAgSVJwY1Byb3h5QnVmZmVyX0Rpc2Nvbm5lY3QoaWZhY2UpOwoKICBJUFNGYWN0b3J5QnVmZmVyX1JlbGVhc2UoVGhpcy0+cFBTRmFjdG9yeSk7CiAgaWYgKFRoaXMtPnRodW5rcykgewogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLFRoaXMtPlBWdGJsKTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCxUaGlzLT50aHVua3MpOwogIH0KICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsVGhpcyk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBTdGRQcm94eV9RdWVyeUludGVyZmFjZShMUFJQQ1BST1hZQlVGRkVSIGlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUZJSUQgcmlpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBWT0lEICpvYmopCnsKICBJQ09NX1RISVNfTVVMVEkoU3RkUHJveHlJbXBsLGxwVnRibCxpZmFjZSk7CiAgVFJBQ0UoIiglcCktPlF1ZXJ5SW50ZXJmYWNlKCVzLCVwKVxuIixUaGlzLGRlYnVnc3RyX2d1aWQocmlpZCksb2JqKTsKCiAgaWYgKElzRXF1YWxHVUlEKCZJSURfSVVua25vd24scmlpZCkgfHwKICAgICAgSXNFcXVhbEdVSUQoVGhpcy0+cGlpZCxyaWlkKSkgewogICAgKm9iaiA9ICZUaGlzLT5QVnRibDsKICAgIFRoaXMtPlJlZkNvdW50Kys7CiAgICByZXR1cm4gU19PSzsKICB9CgogIGlmIChJc0VxdWFsR1VJRCgmSUlEX0lScGNQcm94eUJ1ZmZlcixyaWlkKSkgewogICAgKm9iaiA9ICZUaGlzLT5scFZ0Ymw7CiAgICBUaGlzLT5SZWZDb3VudCsrOwogICAgcmV0dXJuIFNfT0s7CiAgfQoKICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBTdGRQcm94eV9BZGRSZWYoTFBSUENQUk9YWUJVRkZFUiBpZmFjZSkKewogIElDT01fVEhJU19NVUxUSShTdGRQcm94eUltcGwsbHBWdGJsLGlmYWNlKTsKICBUUkFDRSgiKCVwKS0+QWRkUmVmKClcbiIsVGhpcyk7CgogIHJldHVybiArKyhUaGlzLT5SZWZDb3VudCk7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgU3RkUHJveHlfUmVsZWFzZShMUFJQQ1BST1hZQlVGRkVSIGlmYWNlKQp7CiAgSUNPTV9USElTX01VTFRJKFN0ZFByb3h5SW1wbCxscFZ0YmwsaWZhY2UpOwogIFRSQUNFKCIoJXApLT5SZWxlYXNlKClcbiIsVGhpcyk7CgogIGlmICghLS0oVGhpcy0+UmVmQ291bnQpKSB7CiAgICBTdGRQcm94eV9EZXN0cnVjdCgoTFBSUENQUk9YWUJVRkZFUikmVGhpcy0+bHBWdGJsKTsKICAgIHJldHVybiAwOwogIH0KICByZXR1cm4gVGhpcy0+UmVmQ291bnQ7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBTdGRQcm94eV9Db25uZWN0KExQUlBDUFJPWFlCVUZGRVIgaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBSUENDSEFOTkVMQlVGRkVSIHBDaGFubmVsKQp7CiAgSUNPTV9USElTX01VTFRJKFN0ZFByb3h5SW1wbCxscFZ0YmwsaWZhY2UpOwogIFRSQUNFKCIoJXApLT5Db25uZWN0KCVwKVxuIixUaGlzLHBDaGFubmVsKTsKCiAgVGhpcy0+cENoYW5uZWwgPSBwQ2hhbm5lbDsKICBJUnBjQ2hhbm5lbEJ1ZmZlcl9BZGRSZWYocENoYW5uZWwpOwogIHJldHVybiBTX09LOwp9CgpzdGF0aWMgVk9JRCBXSU5BUEkgU3RkUHJveHlfRGlzY29ubmVjdChMUFJQQ1BST1hZQlVGRkVSIGlmYWNlKQp7CiAgSUNPTV9USElTX01VTFRJKFN0ZFByb3h5SW1wbCxscFZ0YmwsaWZhY2UpOwogIFRSQUNFKCIoJXApLT5EaXNjb25uZWN0KClcbiIsVGhpcyk7CgogIElScGNDaGFubmVsQnVmZmVyX1JlbGVhc2UoVGhpcy0+cENoYW5uZWwpOwogIFRoaXMtPnBDaGFubmVsID0gTlVMTDsKfQoKc3RhdGljIGNvbnN0IElScGNQcm94eUJ1ZmZlclZ0YmwgU3RkUHJveHlfVnRibCA9CnsKICBTdGRQcm94eV9RdWVyeUludGVyZmFjZSwKICBTdGRQcm94eV9BZGRSZWYsCiAgU3RkUHJveHlfUmVsZWFzZSwKICBTdGRQcm94eV9Db25uZWN0LAogIFN0ZFByb3h5X0Rpc2Nvbm5lY3QKfTsKCkhSRVNVTFQgV0lOQVBJIFN0ZFByb3h5X0dldENoYW5uZWwoTFBWT0lEIGlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBSUENDSEFOTkVMQlVGRkVSICpwcENoYW5uZWwpCnsKICBJQ09NX1RISVNfTVVMVEkoU3RkUHJveHlJbXBsLFBWdGJsLGlmYWNlKTsKICBUUkFDRSgiKCVwKS0+R2V0Q2hhbm5lbCglcCkgJXNcbiIsVGhpcyxwcENoYW5uZWwsVGhpcy0+bmFtZSk7CgogICpwcENoYW5uZWwgPSBUaGlzLT5wQ2hhbm5lbDsKICByZXR1cm4gU19PSzsKfQoKSFJFU1VMVCBXSU5BUEkgU3RkUHJveHlfR2V0SUlEKExQVk9JRCBpZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgSUlEICoqcHBpaWQpCnsKICBJQ09NX1RISVNfTVVMVEkoU3RkUHJveHlJbXBsLFBWdGJsLGlmYWNlKTsKICBUUkFDRSgiKCVwKS0+R2V0SUlEKCVwKSAlc1xuIixUaGlzLHBwaWlkLFRoaXMtPm5hbWUpOwoKICAqcHBpaWQgPSBUaGlzLT5waWlkOwogIHJldHVybiBTX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJVW5rbm93bl9RdWVyeUludGVyZmFjZV9Qcm94eShMUFVOS05PV04gaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVGSUlEIHJpaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBWT0lEICpwcHZPYmopCnsKICBJQ09NX1RISVNfTVVMVEkoU3RkUHJveHlJbXBsLFBWdGJsLGlmYWNlKTsKICBUUkFDRSgiKCVwKS0+UXVlcnlJbnRlcmZhY2UoJXMsJXApICVzXG4iLFRoaXMsZGVidWdzdHJfZ3VpZChyaWlkKSxwcHZPYmosVGhpcy0+bmFtZSk7CiAgcmV0dXJuIElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKFRoaXMtPnBVbmtPdXRlcixyaWlkLHBwdk9iaik7Cn0KClVMT05HIFdJTkFQSSBJVW5rbm93bl9BZGRSZWZfUHJveHkoTFBVTktOT1dOIGlmYWNlKQp7CiAgSUNPTV9USElTX01VTFRJKFN0ZFByb3h5SW1wbCxQVnRibCxpZmFjZSk7CiAgVFJBQ0UoIiglcCktPkFkZFJlZigpICVzXG4iLFRoaXMsVGhpcy0+bmFtZSk7CiNpZiAwIC8qIGludGVyZmFjZSByZWZjb3VudGluZyAqLwogIHJldHVybiArKyhUaGlzLT5SZWZDb3VudCk7CiNlbHNlIC8qIG9iamVjdCByZWZjb3VudGluZyAqLwogIHJldHVybiBJVW5rbm93bl9BZGRSZWYoVGhpcy0+cFVua091dGVyKTsKI2VuZGlmCn0KClVMT05HIFdJTkFQSSBJVW5rbm93bl9SZWxlYXNlX1Byb3h5KExQVU5LTk9XTiBpZmFjZSkKewogIElDT01fVEhJU19NVUxUSShTdGRQcm94eUltcGwsUFZ0YmwsaWZhY2UpOwogIFRSQUNFKCIoJXApLT5SZWxlYXNlKCkgJXNcbiIsVGhpcyxUaGlzLT5uYW1lKTsKI2lmIDAgLyogaW50ZXJmYWNlIHJlZmNvdW50aW5nICovCiAgaWYgKCEtLShUaGlzLT5SZWZDb3VudCkpIHsKICAgIFN0ZFByb3h5X0Rlc3RydWN0KChMUFJQQ1BST1hZQlVGRkVSKSZUaGlzLT5scFZ0YmwpOwogICAgcmV0dXJuIDA7CiAgfQogIHJldHVybiBUaGlzLT5SZWZDb3VudDsKI2Vsc2UgLyogb2JqZWN0IHJlZmNvdW50aW5nICovCiAgcmV0dXJuIElVbmtub3duX1JlbGVhc2UoVGhpcy0+cFVua091dGVyKTsKI2VuZGlmCn0KCkhSRVNVTFQgV0lOQVBJCkNyZWF0ZVByb3h5RnJvbVR5cGVJbmZvKCBMUFRZUEVJTkZPIHBUeXBlSW5mbywgTFBVTktOT1dOIHBVbmtPdXRlciwgUkVGSUlEIHJpaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICBMUFJQQ1BST1hZQlVGRkVSICpwcFByb3h5LCBMUFZPSUQgKnBwdiApCnsKICAgIEZJWE1FKCIlcCAlcCAlcyAlcCAlcFxuIiwgcFR5cGVJbmZvLCBwVW5rT3V0ZXIsIGRlYnVnc3RyX2d1aWQocmlpZCksIHBwUHJveHksIHBwdik7CiAgICByZXR1cm4gRV9OT1RJTVBMOwp9Cg==