LyoKICogQ09NIHByb3h5IGltcGxlbWVudGF0aW9uCiAqCiAqIENvcHlyaWdodCAyMDAxIE92ZSBL5XZlbiwgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKiAKICogVE9ETzogSGFuZGxlIG5vbi1pMzg2IGFyY2hpdGVjdHVyZXMKICogICAgICAgR2V0IHJpZCBvZiAjaWYgMCdlZCBjb2RlLgogKi8KCiNpbmNsdWRlIDxzdGRhcmcuaD4KCiNkZWZpbmUgQ09CSk1BQ1JPUwoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKCiNpbmNsdWRlICJvYmpiYXNlLmgiCiNpbmNsdWRlICJycGNwcm94eS5oIgoKI2luY2x1ZGUgImNwc2YuaCIKI2luY2x1ZGUgIm5kcl9taXNjLmgiCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChvbGUpOwoKc3RydWN0IFN0dWJsZXNzVGh1bms7CgovKiBJIGRvbid0IGtub3cgd2hhdCBNUydzIHN0ZCBwcm94eSBzdHJ1Y3R1cmUgbG9va3MgbGlrZSwKICAgc28gdGhpcyBwcm9iYWJseSBkb2Vzbid0IG1hdGNoLCBidXQgdGhhdCBzaG91bGRuJ3QgbWF0dGVyICovCnR5cGVkZWYgc3RydWN0IHsKICBjb25zdCBJUnBjUHJveHlCdWZmZXJWdGJsICpscFZ0Ymw7CiAgTFBWT0lEICpQVnRibDsKICBEV09SRCBSZWZDb3VudDsKICBjb25zdCBNSURMX1NUVUJMRVNTX1BST1hZX0lORk8gKnN0dWJsZXNzOwogIGNvbnN0IElJRCogcGlpZDsKICBMUFVOS05PV04gcFVua091dGVyOwogIFBDSW50ZXJmYWNlTmFtZSBuYW1lOwogIExQUFNGQUNUT1JZQlVGRkVSIHBQU0ZhY3Rvcnk7CiAgTFBSUENDSEFOTkVMQlVGRkVSIHBDaGFubmVsOwogIHN0cnVjdCBTdHVibGVzc1RodW5rICp0aHVua3M7Cn0gU3RkUHJveHlJbXBsOwoKc3RhdGljIGNvbnN0IElScGNQcm94eUJ1ZmZlclZ0YmwgU3RkUHJveHlfVnRibDsKCiNkZWZpbmUgSUNPTV9USElTX01VTFRJKGltcGwsZmllbGQsaWZhY2UpIGltcGwqIGNvbnN0IFRoaXM9KGltcGwqKSgoY2hhciopKGlmYWNlKSAtIG9mZnNldG9mKGltcGwsZmllbGQpKQoKLyogSG93IHRoZSBXaW5kb3dzIHN0dWJsZXNzIHByb3h5IHRodW5rcyB3b3JrIGlzIGV4cGxhaW5lZCBhdAogKiBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2xpYnJhcnkvZW4tdXMvZG5tc2o5OS9odG1sL2NvbTAxOTkuYXNwLAogKiBidXQgSSdsbCB1c2UgYSBzbGlnaHRseSBkaWZmZXJlbnQgbWV0aG9kLCB0byBtYWtlIGxpZmUgZWFzaWVyICovCgojaWYgZGVmaW5lZChfX2kzODZfXykKCiNpbmNsdWRlICJwc2hwYWNrMS5oIgoKc3RydWN0IFN0dWJsZXNzVGh1bmsgewogIEJZVEUgcHVzaDsKICBEV09SRCBpbmRleDsKICBCWVRFIGNhbGw7CiAgTE9ORyBoYW5kbGVyOwogIEJZVEUgcmV0OwogIFdPUkQgYnl0ZXM7CiAgQllURSBwYWRbM107Cn07CgojaW5jbHVkZSAicG9wcGFjay5oIgoKLyogYWRqdXN0IHRoZSBzdGFjayBzaXplIHNpbmNlIHdlIGRvbid0IHVzZSBXaW5kb3dzJ3MgbWV0aG9kICovCiNkZWZpbmUgU1RBQ0tfQURKVVNUIHNpemVvZihEV09SRCkKCiNkZWZpbmUgRklMTF9TVFVCTEVTUyh4LGlkeCxzdGspIFwKIHgtPnB1c2ggPSAweDY4OyAvKiBwdXNobCBbaW1tZWRpYXRlXSAqLyBcCiB4LT5pbmRleCA9IChpZHgpOyBcCiB4LT5jYWxsID0gMHhlODsgLyogY2FsbCBbbmVhcl0gKi8gXAogeC0+aGFuZGxlciA9IChjaGFyKilPYmplY3RTdHVibGVzcyAtIChjaGFyKikmeC0+cmV0OyBcCiB4LT5yZXQgPSAweGMyOyAvKiByZXQgW2ltbWVkaWF0ZV0gKi8gXAogeC0+Ynl0ZXMgPSBzdGs7IFwKIHgtPnBhZFswXSA9IDB4OGQ7IC8qIGxlYWwgKCVlc2kpLCVlc2kgKi8gXAogeC0+cGFkWzFdID0gMHg3NjsgXAogeC0+cGFkWzJdID0gMHgwMDsKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBPYmplY3RTdHVibGVzcyhEV09SRCBpbmRleCkKewogIGNoYXIgKmFyZ3MgPSAoY2hhciopKCZpbmRleCArIDIpOwogIExQVk9JRCBpZmFjZSA9ICooTFBWT0lEKilhcmdzOwoKICBJQ09NX1RISVNfTVVMVEkoU3RkUHJveHlJbXBsLFBWdGJsLGlmYWNlKTsKCiAgUEZPUk1BVF9TVFJJTkcgZnMgPSBUaGlzLT5zdHVibGVzcy0+UHJvY0Zvcm1hdFN0cmluZyArIFRoaXMtPnN0dWJsZXNzLT5Gb3JtYXRTdHJpbmdPZmZzZXRbaW5kZXhdOwogIHVuc2lnbmVkIGJ5dGVzID0gKihjb25zdCBXT1JEKikoZnMrOCkgLSBTVEFDS19BREpVU1Q7CiAgVFJBQ0UoIiglcCktPiglbGQpKFslZCBieXRlc10pIHJldD0lMDhseFxuIiwgaWZhY2UsIGluZGV4LCBieXRlcywgKihEV09SRCopKGFyZ3MrYnl0ZXMpKTsKCiAgcmV0dXJuIE5kckNsaWVudENhbGwyKFRoaXMtPnN0dWJsZXNzLT5wU3R1YkRlc2MsIGZzLCBhcmdzKTsKfQoKI2Vsc2UgIC8qIF9faTM4Nl9fICovCgovKiBjYW4ndCBkbyB0aGF0IG9uIHRoaXMgYXJjaCAqLwpzdHJ1Y3QgU3R1Ymxlc3NUaHVuayB7IGludCBkdW1teTsgfTsKI2RlZmluZSBGSUxMX1NUVUJMRVNTKHgsaWR4LHN0aykgXAogRVJSKCJzdHVibGVzcyBwcm94aWVzIGFyZSBub3Qgc3VwcG9ydGVkIG9uIHRoaXMgYXJjaGl0ZWN0dXJlXG4iKTsKI2RlZmluZSBTVEFDS19BREpVU1QgMAoKI2VuZGlmICAvKiBfX2kzODZfXyAqLwoKSFJFU1VMVCBXSU5BUEkgU3RkUHJveHlfQ29uc3RydWN0KFJFRklJRCByaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFVOS05PV04gcFVua091dGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBQcm94eUZpbGVJbmZvICpQcm94eUluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBJbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBQU0ZBQ1RPUllCVUZGRVIgcFBTRmFjdG9yeSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBSUENQUk9YWUJVRkZFUiAqcHBQcm94eSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBWT0lEICpwcHZPYmopCnsKICBTdGRQcm94eUltcGwgKlRoaXM7CiAgY29uc3QgTUlETF9TVFVCTEVTU19QUk9YWV9JTkZPICpzdHVibGVzcyA9IE5VTEw7CiAgUENJbnRlcmZhY2VOYW1lIG5hbWUgPSBQcm94eUluZm8tPnBOYW1lc0FycmF5W0luZGV4XTsKICBDSW50ZXJmYWNlUHJveHlWdGJsICp2dGJsID0gUHJveHlJbmZvLT5wUHJveHlWdGJsTGlzdFtJbmRleF07CgogIFRSQUNFKCIoJXAsJXAsJXAsJXAsJXApICVzXG4iLCBwVW5rT3V0ZXIsIHZ0YmwsIHBQU0ZhY3RvcnksIHBwUHJveHksIHBwdk9iaiwgbmFtZSk7CgogIC8qIFRhYmxlVmVyc2lvbiA9IDIgbWVhbnMgaXQgaXMgdGhlIHN0dWJsZXNzIHZlcnNpb24gb2YgQ0ludGVyZmFjZVByb3h5VnRibCAqLwogIGlmIChQcm94eUluZm8tPlRhYmxlVmVyc2lvbiA+IDEpIHsKICAgIHN0dWJsZXNzID0gKihjb25zdCB2b2lkICoqKXZ0Ymw7CiAgICB2dGJsID0gKENJbnRlcmZhY2VQcm94eVZ0YmwgKikoKGNvbnN0IHZvaWQgKiopdnRibCArIDEpOwogICAgVFJBQ0UoInN0dWJsZXNzPSVwXG4iLCBzdHVibGVzcyk7CiAgfQoKICBUUkFDRSgiaWlkPSVzXG4iLCBkZWJ1Z3N0cl9ndWlkKHZ0YmwtPmhlYWRlci5waWlkKSk7CiAgVFJBQ0UoInZ0Ymw9JXBcbiIsIHZ0YmwtPlZ0YmwpOwoKICBpZiAoIUlzRXF1YWxHVUlEKHZ0YmwtPmhlYWRlci5waWlkLCByaWlkKSkgewogICAgRVJSKCJJSUQgbWlzbWF0Y2ggZHVyaW5nIHByb3h5IGNyZWF0aW9uXG4iKTsKICAgIHJldHVybiBSUENfRV9VTkVYUEVDVEVEOwogIH0KCiAgVGhpcyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLEhFQVBfWkVST19NRU1PUlksc2l6ZW9mKFN0ZFByb3h5SW1wbCkpOwogIGlmICghVGhpcykgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CgogIGlmIChzdHVibGVzcykgewogICAgQ0ludGVyZmFjZVN0dWJWdGJsICpzdnRibCA9IFByb3h5SW5mby0+cFN0dWJWdGJsTGlzdFtJbmRleF07CiAgICB1bnNpZ25lZCBsb25nIGksIGNvdW50ID0gc3Z0YmwtPmhlYWRlci5EaXNwYXRjaFRhYmxlQ291bnQ7CiAgICAvKiBNYXliZSB0aGUgb3JpZ2luYWwgdnRibCBpcyBqdXN0IG1vZGlmaWVkIGRpcmVjdGx5IHRvIHBvaW50IGF0CiAgICAgKiBPYmplY3RTdHVibGVzc0NsaWVudFhYWCB0aHVua3MgaW4gcmVhbCBXaW5kb3dzLCBidXQgSSBkb24ndCBsaWtlIGl0CiAgICAgKi8KICAgIFRSQUNFKCJzdHVibGVzcyB0aHVua3M6IGNvdW50PSVsZFxuIiwgY291bnQpOwogICAgVGhpcy0+dGh1bmtzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksMCxzaXplb2Yoc3RydWN0IFN0dWJsZXNzVGh1bmspKmNvdW50KTsKICAgIFRoaXMtPlBWdGJsID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksMCxzaXplb2YoTFBWT0lEKSpjb3VudCk7CiAgICBmb3IgKGk9MDsgaTxjb3VudDsgaSsrKSB7CiAgICAgIHN0cnVjdCBTdHVibGVzc1RodW5rICp0aHVuayA9ICZUaGlzLT50aHVua3NbaV07CiAgICAgIGlmICh2dGJsLT5WdGJsW2ldID09IChMUFZPSUQpLTEpIHsKICAgICAgICBQRk9STUFUX1NUUklORyBmcyA9IHN0dWJsZXNzLT5Qcm9jRm9ybWF0U3RyaW5nICsgc3R1Ymxlc3MtPkZvcm1hdFN0cmluZ09mZnNldFtpXTsKICAgICAgICB1bnNpZ25lZCBieXRlcyA9ICooY29uc3QgV09SRCopKGZzKzgpIC0gU1RBQ0tfQURKVVNUOwogICAgICAgIFRSQUNFKCJtZXRob2QgJWxkOiBzdGFja3NpemU9JWRcbiIsIGksIGJ5dGVzKTsKICAgICAgICBGSUxMX1NUVUJMRVNTKHRodW5rLCBpLCBieXRlcykKICAgICAgICBUaGlzLT5QVnRibFtpXSA9IHRodW5rOwogICAgICB9CiAgICAgIGVsc2UgewogICAgICAgIG1lbXNldCh0aHVuaywgMCwgc2l6ZW9mKHN0cnVjdCBTdHVibGVzc1RodW5rKSk7CiAgICAgICAgVGhpcy0+UFZ0YmxbaV0gPSB2dGJsLT5WdGJsW2ldOwogICAgICB9CiAgICB9CiAgfQogIGVsc2UgCiAgICBUaGlzLT5QVnRibCA9IHZ0YmwtPlZ0Ymw7CgogIFRoaXMtPmxwVnRibCA9ICZTdGRQcm94eV9WdGJsOwogIC8qIG9uZSByZWZlcmVuY2UgZm9yIHRoZSBwcm94eSAqLwogIFRoaXMtPlJlZkNvdW50ID0gMTsKICBUaGlzLT5zdHVibGVzcyA9IHN0dWJsZXNzOwogIFRoaXMtPnBpaWQgPSB2dGJsLT5oZWFkZXIucGlpZDsKICBUaGlzLT5wVW5rT3V0ZXIgPSBwVW5rT3V0ZXI7CiAgVGhpcy0+bmFtZSA9IG5hbWU7CiAgVGhpcy0+cFBTRmFjdG9yeSA9IHBQU0ZhY3Rvcnk7CiAgVGhpcy0+cENoYW5uZWwgPSBOVUxMOwogICpwcFByb3h5ID0gKExQUlBDUFJPWFlCVUZGRVIpJlRoaXMtPmxwVnRibDsKICAqcHB2T2JqID0gJlRoaXMtPlBWdGJsOwogIC8qIGlmIHRoZXJlIGlzIG5vIG91dGVyIHVua25vd24gdGhlbiB0aGUgY2FsbGVyIHdpbGwgY29udHJvbCB0aGUgbGlmZXRpbWUKICAgKiBvZiB0aGUgcHJveHkgb2JqZWN0IHRocm91Z2ggdGhlIHByb3h5IGJ1ZmZlciwgc28gbm8gbmVlZCB0byBpbmNyZW1lbnQgdGhlCiAgICogcmVmIGNvdW50IG9mIHRoZSBwcm94eSBvYmplY3QgKi8KICBpZiAocFVua091dGVyKQogICAgSVVua25vd25fQWRkUmVmKChJVW5rbm93biAqKSpwcHZPYmopOwogIElQU0ZhY3RvcnlCdWZmZXJfQWRkUmVmKHBQU0ZhY3RvcnkpOwoKICByZXR1cm4gU19PSzsKfQoKc3RhdGljIHZvaWQgV0lOQVBJIFN0ZFByb3h5X0Rlc3RydWN0KExQUlBDUFJPWFlCVUZGRVIgaWZhY2UpCnsKICBJQ09NX1RISVNfTVVMVEkoU3RkUHJveHlJbXBsLGxwVnRibCxpZmFjZSk7CgogIGlmIChUaGlzLT5wQ2hhbm5lbCkKICAgIElScGNQcm94eUJ1ZmZlcl9EaXNjb25uZWN0KGlmYWNlKTsKCiAgSVBTRmFjdG9yeUJ1ZmZlcl9SZWxlYXNlKFRoaXMtPnBQU0ZhY3RvcnkpOwogIGlmIChUaGlzLT50aHVua3MpIHsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCxUaGlzLT5QVnRibCk7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsVGhpcy0+dGh1bmtzKTsKICB9CiAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLFRoaXMpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgU3RkUHJveHlfUXVlcnlJbnRlcmZhY2UoTFBSUENQUk9YWUJVRkZFUiBpZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVGSUlEIHJpaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQVk9JRCAqb2JqKQp7CiAgSUNPTV9USElTX01VTFRJKFN0ZFByb3h5SW1wbCxscFZ0YmwsaWZhY2UpOwogIFRSQUNFKCIoJXApLT5RdWVyeUludGVyZmFjZSglcywlcClcbiIsVGhpcyxkZWJ1Z3N0cl9ndWlkKHJpaWQpLG9iaik7CgogIGlmIChJc0VxdWFsR1VJRCgmSUlEX0lVbmtub3duLHJpaWQpIHx8CiAgICAgIElzRXF1YWxHVUlEKFRoaXMtPnBpaWQscmlpZCkpIHsKICAgICpvYmogPSAmVGhpcy0+UFZ0Ymw7CiAgICBUaGlzLT5SZWZDb3VudCsrOwogICAgcmV0dXJuIFNfT0s7CiAgfQoKICBpZiAoSXNFcXVhbEdVSUQoJklJRF9JUnBjUHJveHlCdWZmZXIscmlpZCkpIHsKICAgICpvYmogPSAmVGhpcy0+bHBWdGJsOwogICAgVGhpcy0+UmVmQ291bnQrKzsKICAgIHJldHVybiBTX09LOwogIH0KCiAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgU3RkUHJveHlfQWRkUmVmKExQUlBDUFJPWFlCVUZGRVIgaWZhY2UpCnsKICBJQ09NX1RISVNfTVVMVEkoU3RkUHJveHlJbXBsLGxwVnRibCxpZmFjZSk7CiAgVFJBQ0UoIiglcCktPkFkZFJlZigpXG4iLFRoaXMpOwoKICByZXR1cm4gKysoVGhpcy0+UmVmQ291bnQpOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIFN0ZFByb3h5X1JlbGVhc2UoTFBSUENQUk9YWUJVRkZFUiBpZmFjZSkKewogIElDT01fVEhJU19NVUxUSShTdGRQcm94eUltcGwsbHBWdGJsLGlmYWNlKTsKICBUUkFDRSgiKCVwKS0+UmVsZWFzZSgpXG4iLFRoaXMpOwoKICBpZiAoIS0tKFRoaXMtPlJlZkNvdW50KSkgewogICAgU3RkUHJveHlfRGVzdHJ1Y3QoKExQUlBDUFJPWFlCVUZGRVIpJlRoaXMtPmxwVnRibCk7CiAgICByZXR1cm4gMDsKICB9CiAgcmV0dXJuIFRoaXMtPlJlZkNvdW50Owp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgU3RkUHJveHlfQ29ubmVjdChMUFJQQ1BST1hZQlVGRkVSIGlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQUlBDQ0hBTk5FTEJVRkZFUiBwQ2hhbm5lbCkKewogIElDT01fVEhJU19NVUxUSShTdGRQcm94eUltcGwsbHBWdGJsLGlmYWNlKTsKICBUUkFDRSgiKCVwKS0+Q29ubmVjdCglcClcbiIsVGhpcyxwQ2hhbm5lbCk7CgogIFRoaXMtPnBDaGFubmVsID0gcENoYW5uZWw7CiAgSVJwY0NoYW5uZWxCdWZmZXJfQWRkUmVmKHBDaGFubmVsKTsKICByZXR1cm4gU19PSzsKfQoKc3RhdGljIFZPSUQgV0lOQVBJIFN0ZFByb3h5X0Rpc2Nvbm5lY3QoTFBSUENQUk9YWUJVRkZFUiBpZmFjZSkKewogIElDT01fVEhJU19NVUxUSShTdGRQcm94eUltcGwsbHBWdGJsLGlmYWNlKTsKICBUUkFDRSgiKCVwKS0+RGlzY29ubmVjdCgpXG4iLFRoaXMpOwoKICBJUnBjQ2hhbm5lbEJ1ZmZlcl9SZWxlYXNlKFRoaXMtPnBDaGFubmVsKTsKICBUaGlzLT5wQ2hhbm5lbCA9IE5VTEw7Cn0KCnN0YXRpYyBjb25zdCBJUnBjUHJveHlCdWZmZXJWdGJsIFN0ZFByb3h5X1Z0YmwgPQp7CiAgU3RkUHJveHlfUXVlcnlJbnRlcmZhY2UsCiAgU3RkUHJveHlfQWRkUmVmLAogIFN0ZFByb3h5X1JlbGVhc2UsCiAgU3RkUHJveHlfQ29ubmVjdCwKICBTdGRQcm94eV9EaXNjb25uZWN0Cn07CgpIUkVTVUxUIFdJTkFQSSBTdGRQcm94eV9HZXRDaGFubmVsKExQVk9JRCBpZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQUlBDQ0hBTk5FTEJVRkZFUiAqcHBDaGFubmVsKQp7CiAgSUNPTV9USElTX01VTFRJKFN0ZFByb3h5SW1wbCxQVnRibCxpZmFjZSk7CiAgVFJBQ0UoIiglcCktPkdldENoYW5uZWwoJXApICVzXG4iLFRoaXMscHBDaGFubmVsLFRoaXMtPm5hbWUpOwoKICAqcHBDaGFubmVsID0gVGhpcy0+cENoYW5uZWw7CiAgcmV0dXJuIFNfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIFN0ZFByb3h5X0dldElJRChMUFZPSUQgaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IElJRCAqKnBwaWlkKQp7CiAgSUNPTV9USElTX01VTFRJKFN0ZFByb3h5SW1wbCxQVnRibCxpZmFjZSk7CiAgVFJBQ0UoIiglcCktPkdldElJRCglcCkgJXNcbiIsVGhpcyxwcGlpZCxUaGlzLT5uYW1lKTsKCiAgKnBwaWlkID0gVGhpcy0+cGlpZDsKICByZXR1cm4gU19PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVVua25vd25fUXVlcnlJbnRlcmZhY2VfUHJveHkoTFBVTktOT1dOIGlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFRklJRCByaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQVk9JRCAqcHB2T2JqKQp7CiAgSUNPTV9USElTX01VTFRJKFN0ZFByb3h5SW1wbCxQVnRibCxpZmFjZSk7CiAgVFJBQ0UoIiglcCktPlF1ZXJ5SW50ZXJmYWNlKCVzLCVwKSAlc1xuIixUaGlzLGRlYnVnc3RyX2d1aWQocmlpZCkscHB2T2JqLFRoaXMtPm5hbWUpOwogIHJldHVybiBJVW5rbm93bl9RdWVyeUludGVyZmFjZShUaGlzLT5wVW5rT3V0ZXIscmlpZCxwcHZPYmopOwp9CgpVTE9ORyBXSU5BUEkgSVVua25vd25fQWRkUmVmX1Byb3h5KExQVU5LTk9XTiBpZmFjZSkKewogIElDT01fVEhJU19NVUxUSShTdGRQcm94eUltcGwsUFZ0YmwsaWZhY2UpOwogIFRSQUNFKCIoJXApLT5BZGRSZWYoKSAlc1xuIixUaGlzLFRoaXMtPm5hbWUpOwojaWYgMCAvKiBpbnRlcmZhY2UgcmVmY291bnRpbmcgKi8KICByZXR1cm4gKysoVGhpcy0+UmVmQ291bnQpOwojZWxzZSAvKiBvYmplY3QgcmVmY291bnRpbmcgKi8KICByZXR1cm4gSVVua25vd25fQWRkUmVmKFRoaXMtPnBVbmtPdXRlcik7CiNlbmRpZgp9CgpVTE9ORyBXSU5BUEkgSVVua25vd25fUmVsZWFzZV9Qcm94eShMUFVOS05PV04gaWZhY2UpCnsKICBJQ09NX1RISVNfTVVMVEkoU3RkUHJveHlJbXBsLFBWdGJsLGlmYWNlKTsKICBUUkFDRSgiKCVwKS0+UmVsZWFzZSgpICVzXG4iLFRoaXMsVGhpcy0+bmFtZSk7CiNpZiAwIC8qIGludGVyZmFjZSByZWZjb3VudGluZyAqLwogIGlmICghLS0oVGhpcy0+UmVmQ291bnQpKSB7CiAgICBTdGRQcm94eV9EZXN0cnVjdCgoTFBSUENQUk9YWUJVRkZFUikmVGhpcy0+bHBWdGJsKTsKICAgIHJldHVybiAwOwogIH0KICByZXR1cm4gVGhpcy0+UmVmQ291bnQ7CiNlbHNlIC8qIG9iamVjdCByZWZjb3VudGluZyAqLwogIHJldHVybiBJVW5rbm93bl9SZWxlYXNlKFRoaXMtPnBVbmtPdXRlcik7CiNlbmRpZgp9CgpIUkVTVUxUIFdJTkFQSQpDcmVhdGVQcm94eUZyb21UeXBlSW5mbyggTFBUWVBFSU5GTyBwVHlwZUluZm8sIExQVU5LTk9XTiBwVW5rT3V0ZXIsIFJFRklJRCByaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgTFBSUENQUk9YWUJVRkZFUiAqcHBQcm94eSwgTFBWT0lEICpwcHYgKQp7CiAgICBGSVhNRSgiJXAgJXAgJXMgJXAgJXBcbiIsIHBUeXBlSW5mbywgcFVua091dGVyLCBkZWJ1Z3N0cl9ndWlkKHJpaWQpLCBwcFByb3h5LCBwcHYpOwogICAgcmV0dXJuIEVfTk9USU1QTDsKfQo=