LyoKICogQ09NIHByb3h5IGltcGxlbWVudGF0aW9uCiAqCiAqIENvcHlyaWdodCAyMDAxIE92ZSBL5XZlbiwgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKiAKICogVE9ETzogSGFuZGxlIG5vbi1pMzg2IGFyY2hpdGVjdHVyZXMKICogICAgICAgR2V0IHJpZCBvZiAjaWYgMCdlZCBjb2RlLgogKi8KCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCgojaW5jbHVkZSAib2JqYmFzZS5oIgojaW5jbHVkZSAicnBjcHJveHkuaCIKCiNpbmNsdWRlICJjcHNmLmgiCiNpbmNsdWRlICJuZHJfbWlzYy5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwob2xlKTsKCnN0cnVjdCBTdHVibGVzc1RodW5rOwoKLyogSSBkb24ndCBrbm93IHdoYXQgTVMncyBzdGQgcHJveHkgc3RydWN0dXJlIGxvb2tzIGxpa2UsCiAgIHNvIHRoaXMgcHJvYmFibHkgZG9lc24ndCBtYXRjaCwgYnV0IHRoYXQgc2hvdWxkbid0IG1hdHRlciAqLwp0eXBlZGVmIHN0cnVjdCB7CiAgSUNPTV9WVEFCTEUoSVJwY1Byb3h5QnVmZmVyKSAqbHBWdGJsOwogIExQVk9JRCAqUFZ0Ymw7CiAgRFdPUkQgUmVmQ291bnQ7CiAgY29uc3QgTUlETF9TVFVCTEVTU19QUk9YWV9JTkZPICpzdHVibGVzczsKICBjb25zdCBJSUQqIHBpaWQ7CiAgTFBVTktOT1dOIHBVbmtPdXRlcjsKICBQQ0ludGVyZmFjZU5hbWUgbmFtZTsKICBMUFBTRkFDVE9SWUJVRkZFUiBwUFNGYWN0b3J5OwogIExQUlBDQ0hBTk5FTEJVRkZFUiBwQ2hhbm5lbDsKICBzdHJ1Y3QgU3R1Ymxlc3NUaHVuayAqdGh1bmtzOwp9IFN0ZFByb3h5SW1wbDsKCnN0YXRpYyBJQ09NX1ZUQUJMRShJUnBjUHJveHlCdWZmZXIpIFN0ZFByb3h5X1Z0Ymw7CgovKiBIb3cgdGhlIFdpbmRvd3Mgc3R1Ymxlc3MgcHJveHkgdGh1bmtzIHdvcmsgaXMgZXhwbGFpbmVkIGF0CiAqIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vbGlicmFyeS9lbi11cy9kbm1zajk5L2h0bWwvY29tMDE5OS5hc3AsCiAqIGJ1dCBJJ2xsIHVzZSBhIHNsaWdodGx5IGRpZmZlcmVudCBtZXRob2QsIHRvIG1ha2UgbGlmZSBlYXNpZXIgKi8KCiNpZiBkZWZpbmVkKF9faTM4Nl9fKQoKc3RydWN0IFN0dWJsZXNzVGh1bmsgewogIEJZVEUgcHVzaCBXSU5FX1BBQ0tFRDsKICBEV09SRCBpbmRleCBXSU5FX1BBQ0tFRDsKICBCWVRFIGNhbGwgV0lORV9QQUNLRUQ7CiAgTE9ORyBoYW5kbGVyIFdJTkVfUEFDS0VEOwogIEJZVEUgcmV0IFdJTkVfUEFDS0VEOwogIFdPUkQgYnl0ZXMgV0lORV9QQUNLRUQ7CiAgQllURSBwYWRbM107Cn07CgovKiBhZGp1c3QgdGhlIHN0YWNrIHNpemUgc2luY2Ugd2UgZG9uJ3QgdXNlIFdpbmRvd3MncyBtZXRob2QgKi8KI2RlZmluZSBTVEFDS19BREpVU1Qgc2l6ZW9mKERXT1JEKQoKI2RlZmluZSBGSUxMX1NUVUJMRVNTKHgsaWR4LHN0aykgXAogeC0+cHVzaCA9IDB4Njg7IC8qIHB1c2hsIFtpbW1lZGlhdGVdICovIFwKIHgtPmluZGV4ID0gKGlkeCk7IFwKIHgtPmNhbGwgPSAweGU4OyAvKiBjYWxsIFtuZWFyXSAqLyBcCiB4LT5oYW5kbGVyID0gKGNoYXIqKU9iamVjdFN0dWJsZXNzIC0gKGNoYXIqKSZ4LT5yZXQ7IFwKIHgtPnJldCA9IDB4YzI7IC8qIHJldCBbaW1tZWRpYXRlXSAqLyBcCiB4LT5ieXRlcyA9IHN0azsgXAogeC0+cGFkWzBdID0gMHg4ZDsgLyogbGVhbCAoJWVzaSksJWVzaSAqLyBcCiB4LT5wYWRbMV0gPSAweDc2OyBcCiB4LT5wYWRbMl0gPSAweDAwOwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIE9iamVjdFN0dWJsZXNzKERXT1JEIGluZGV4KQp7CiAgY2hhciAqYXJncyA9IChjaGFyKikoJmluZGV4ICsgMik7CiAgTFBWT0lEIGlmYWNlID0gKihMUFZPSUQqKWFyZ3M7CgogIElDT01fVEhJU19NVUxUSShTdGRQcm94eUltcGwsUFZ0YmwsaWZhY2UpOwoKICBQRk9STUFUX1NUUklORyBmcyA9IFRoaXMtPnN0dWJsZXNzLT5Qcm9jRm9ybWF0U3RyaW5nICsgVGhpcy0+c3R1Ymxlc3MtPkZvcm1hdFN0cmluZ09mZnNldFtpbmRleF07CiAgdW5zaWduZWQgYnl0ZXMgPSAqKFdPUkQqKShmcys4KSAtIFNUQUNLX0FESlVTVDsKICBUUkFDRSgiKCVwKS0+KCVsZCkoWyVkIGJ5dGVzXSkgcmV0PSUwOGx4XG4iLCBpZmFjZSwgaW5kZXgsIGJ5dGVzLCAqKERXT1JEKikoYXJncytieXRlcykpOwoKICByZXR1cm4gUlBDUlQ0X05kckNsaWVudENhbGwyKFRoaXMtPnN0dWJsZXNzLT5wU3R1YkRlc2MsIGZzLCBhcmdzKTsKfQoKI2Vsc2UgIC8qIF9faTM4Nl9fICovCgovKiBjYW4ndCBkbyB0aGF0IG9uIHRoaXMgYXJjaCAqLwpzdHJ1Y3QgU3R1Ymxlc3NUaHVuayB7IGludCBkdW1teTsgfTsKI2RlZmluZSBGSUxMX1NUVUJMRVNTKHgsaWR4LHN0aykgXAogRVJSKCJzdHVibGVzcyBwcm94aWVzIGFyZSBub3Qgc3VwcG9ydGVkIG9uIHRoaXMgYXJjaGl0ZWN0dXJlXG4iKTsKI2RlZmluZSBTVEFDS19BREpVU1QgMAoKI2VuZGlmICAvKiBfX2kzODZfXyAqLwoKSFJFU1VMVCBXSU5BUEkgU3RkUHJveHlfQ29uc3RydWN0KFJFRklJRCByaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFVOS05PV04gcFVua091dGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQQ0ludGVyZmFjZU5hbWUgbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0ludGVyZmFjZVByb3h5VnRibCAqdnRibCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0ludGVyZmFjZVN0dWJWdGJsICpzdnRibCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBQU0ZBQ1RPUllCVUZGRVIgcFBTRmFjdG9yeSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBSUENQUk9YWUJVRkZFUiAqcHBQcm94eSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBWT0lEICpwcHZPYmopCnsKICBTdGRQcm94eUltcGwgKlRoaXM7CiAgY29uc3QgTUlETF9TVFVCTEVTU19QUk9YWV9JTkZPICpzdHVibGVzcyA9IE5VTEw7CgogIFRSQUNFKCIoJXAsJXAsJXAsJXAsJXApICVzXG4iLCBwVW5rT3V0ZXIsIHZ0YmwsIHBQU0ZhY3RvcnksIHBwUHJveHksIHBwdk9iaiwgbmFtZSk7CgogIC8qIEkgY2FuJ3QgZmluZCBhbnkgb3RoZXIgd2F5IHRvIGRldGVjdCBzdHVibGVzcyBwcm94aWVzIHRoYW4gdGhpcyBoYWNrICovCiAgaWYgKCFJc0VxdWFsR1VJRCh2dGJsLT5oZWFkZXIucGlpZCwgcmlpZCkpIHsKICAgIHN0dWJsZXNzID0gKigoY29uc3Qgdm9pZCAqKil2dGJsKSsrOwogICAgVFJBQ0UoInN0dWJsZXNzPSVwXG4iLCBzdHVibGVzcyk7CiAgfQoKICBUUkFDRSgiaWlkPSVzXG4iLCBkZWJ1Z3N0cl9ndWlkKHZ0YmwtPmhlYWRlci5waWlkKSk7CiAgVFJBQ0UoInZ0Ymw9JXBcbiIsIHZ0YmwtPlZ0YmwpOwoKICBpZiAoIUlzRXF1YWxHVUlEKHZ0YmwtPmhlYWRlci5waWlkLCByaWlkKSkgewogICAgRVJSKCJJSUQgbWlzbWF0Y2ggZHVyaW5nIHByb3h5IGNyZWF0aW9uXG4iKTsKICAgIHJldHVybiBSUENfRV9VTkVYUEVDVEVEOwogIH0KCiAgVGhpcyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLEhFQVBfWkVST19NRU1PUlksc2l6ZW9mKFN0ZFByb3h5SW1wbCkpOwogIGlmICghVGhpcykgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CgogIGlmIChzdHVibGVzcykgewogICAgdW5zaWduZWQgaSwgY291bnQgPSBzdnRibC0+aGVhZGVyLkRpc3BhdGNoVGFibGVDb3VudDsKICAgIC8qIE1heWJlIHRoZSBvcmlnaW5hbCB2dGJsIGlzIGp1c3QgbW9kaWZpZWQgZGlyZWN0bHkgdG8gcG9pbnQgYXQKICAgICAqIE9iamVjdFN0dWJsZXNzQ2xpZW50WFhYIHRodW5rcyBpbiByZWFsIFdpbmRvd3MsIGJ1dCBJIGRvbid0IGxpa2UgaXQKICAgICAqLwogICAgVFJBQ0UoInN0dWJsZXNzIHRodW5rczogY291bnQ9JWRcbiIsIGNvdW50KTsKICAgIFRoaXMtPnRodW5rcyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLDAsc2l6ZW9mKHN0cnVjdCBTdHVibGVzc1RodW5rKSpjb3VudCk7CiAgICBUaGlzLT5QVnRibCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLDAsc2l6ZW9mKExQVk9JRCkqY291bnQpOwogICAgZm9yIChpPTA7IGk8Y291bnQ7IGkrKykgewogICAgICBzdHJ1Y3QgU3R1Ymxlc3NUaHVuayAqdGh1bmsgPSAmVGhpcy0+dGh1bmtzW2ldOwogICAgICBpZiAodnRibC0+VnRibFtpXSA9PSAoTFBWT0lEKS0xKSB7CiAgICAgICAgUEZPUk1BVF9TVFJJTkcgZnMgPSBzdHVibGVzcy0+UHJvY0Zvcm1hdFN0cmluZyArIHN0dWJsZXNzLT5Gb3JtYXRTdHJpbmdPZmZzZXRbaV07CiAgICAgICAgdW5zaWduZWQgYnl0ZXMgPSAqKFdPUkQqKShmcys4KSAtIFNUQUNLX0FESlVTVDsKICAgICAgICBUUkFDRSgibWV0aG9kICVkOiBzdGFja3NpemU9JWRcbiIsIGksIGJ5dGVzKTsKICAgICAgICBGSUxMX1NUVUJMRVNTKHRodW5rLCBpLCBieXRlcykKICAgICAgICBUaGlzLT5QVnRibFtpXSA9IHRodW5rOwogICAgICB9CiAgICAgIGVsc2UgewogICAgICAgIG1lbXNldCh0aHVuaywgMCwgc2l6ZW9mKHN0cnVjdCBTdHVibGVzc1RodW5rKSk7CiAgICAgICAgVGhpcy0+UFZ0YmxbaV0gPSB2dGJsLT5WdGJsW2ldOwogICAgICB9CiAgICB9CiAgfQogIGVsc2UgCiAgICBUaGlzLT5QVnRibCA9IHZ0YmwtPlZ0Ymw7CgogIFRoaXMtPmxwVnRibCA9ICZTdGRQcm94eV9WdGJsOwogIFRoaXMtPlJlZkNvdW50ID0gMTsKICBUaGlzLT5zdHVibGVzcyA9IHN0dWJsZXNzOwogIFRoaXMtPnBpaWQgPSB2dGJsLT5oZWFkZXIucGlpZDsKICBUaGlzLT5wVW5rT3V0ZXIgPSBwVW5rT3V0ZXI7CiAgVGhpcy0+bmFtZSA9IG5hbWU7CiAgVGhpcy0+cFBTRmFjdG9yeSA9IHBQU0ZhY3Rvcnk7CiAgVGhpcy0+cENoYW5uZWwgPSBOVUxMOwogICpwcFByb3h5ID0gKExQUlBDUFJPWFlCVUZGRVIpJlRoaXMtPmxwVnRibDsKICAqcHB2T2JqID0gJlRoaXMtPlBWdGJsOwogIElQU0ZhY3RvcnlCdWZmZXJfQWRkUmVmKHBQU0ZhY3RvcnkpOwoKICByZXR1cm4gU19PSzsKfQoKc3RhdGljIHZvaWQgV0lOQVBJIFN0ZFByb3h5X0Rlc3RydWN0KExQUlBDUFJPWFlCVUZGRVIgaWZhY2UpCnsKICBJQ09NX1RISVNfTVVMVEkoU3RkUHJveHlJbXBsLGxwVnRibCxpZmFjZSk7CgogIElQU0ZhY3RvcnlCdWZmZXJfUmVsZWFzZShUaGlzLT5wUFNGYWN0b3J5KTsKICBpZiAoVGhpcy0+dGh1bmtzKSB7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsVGhpcy0+UFZ0YmwpOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLFRoaXMtPnRodW5rcyk7CiAgfQogIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCxUaGlzKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFN0ZFByb3h5X1F1ZXJ5SW50ZXJmYWNlKExQUlBDUFJPWFlCVUZGRVIgaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFRklJRCByaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFZPSUQgKm9iaikKewogIElDT01fVEhJU19NVUxUSShTdGRQcm94eUltcGwsbHBWdGJsLGlmYWNlKTsKICBUUkFDRSgiKCVwKS0+UXVlcnlJbnRlcmZhY2UoJXMsJXApXG4iLFRoaXMsZGVidWdzdHJfZ3VpZChyaWlkKSxvYmopOwoKICBpZiAoSXNFcXVhbEdVSUQoJklJRF9JVW5rbm93bixyaWlkKSB8fAogICAgICBJc0VxdWFsR1VJRChUaGlzLT5waWlkLHJpaWQpKSB7CiAgICAqb2JqID0gJlRoaXMtPlBWdGJsOwogICAgVGhpcy0+UmVmQ291bnQrKzsKICAgIHJldHVybiBTX09LOwogIH0KCiAgaWYgKElzRXF1YWxHVUlEKCZJSURfSVJwY1Byb3h5QnVmZmVyLHJpaWQpKSB7CiAgICAqb2JqID0gJlRoaXMtPmxwVnRibDsKICAgIFRoaXMtPlJlZkNvdW50Kys7CiAgICByZXR1cm4gU19PSzsKICB9CgogIHJldHVybiBFX05PSU5URVJGQUNFOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIFN0ZFByb3h5X0FkZFJlZihMUFJQQ1BST1hZQlVGRkVSIGlmYWNlKQp7CiAgSUNPTV9USElTX01VTFRJKFN0ZFByb3h5SW1wbCxscFZ0YmwsaWZhY2UpOwogIFRSQUNFKCIoJXApLT5BZGRSZWYoKVxuIixUaGlzKTsKCiAgcmV0dXJuICsrKFRoaXMtPlJlZkNvdW50KTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBTdGRQcm94eV9SZWxlYXNlKExQUlBDUFJPWFlCVUZGRVIgaWZhY2UpCnsKICBJQ09NX1RISVNfTVVMVEkoU3RkUHJveHlJbXBsLGxwVnRibCxpZmFjZSk7CiAgVFJBQ0UoIiglcCktPlJlbGVhc2UoKVxuIixUaGlzKTsKCiAgaWYgKCEtLShUaGlzLT5SZWZDb3VudCkpIHsKICAgIFN0ZFByb3h5X0Rlc3RydWN0KChMUFJQQ1BST1hZQlVGRkVSKSZUaGlzLT5scFZ0YmwpOwogICAgcmV0dXJuIDA7CiAgfQogIHJldHVybiBUaGlzLT5SZWZDb3VudDsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFN0ZFByb3h5X0Nvbm5lY3QoTFBSUENQUk9YWUJVRkZFUiBpZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFJQQ0NIQU5ORUxCVUZGRVIgcENoYW5uZWwpCnsKICBJQ09NX1RISVNfTVVMVEkoU3RkUHJveHlJbXBsLGxwVnRibCxpZmFjZSk7CiAgVFJBQ0UoIiglcCktPkNvbm5lY3QoJXApXG4iLFRoaXMscENoYW5uZWwpOwoKICBUaGlzLT5wQ2hhbm5lbCA9IHBDaGFubmVsOwogIHJldHVybiBTX09LOwp9CgpzdGF0aWMgVk9JRCBXSU5BUEkgU3RkUHJveHlfRGlzY29ubmVjdChMUFJQQ1BST1hZQlVGRkVSIGlmYWNlKQp7CiAgSUNPTV9USElTX01VTFRJKFN0ZFByb3h5SW1wbCxscFZ0YmwsaWZhY2UpOwogIFRSQUNFKCIoJXApLT5EaXNjb25uZWN0KClcbiIsVGhpcyk7CgogIFRoaXMtPnBDaGFubmVsID0gTlVMTDsKfQoKc3RhdGljIElDT01fVlRBQkxFKElScGNQcm94eUJ1ZmZlcikgU3RkUHJveHlfVnRibCA9CnsKICBJQ09NX01TVlRBQkxFX0NPTVBBVF9EdW1teVJUVElWQUxVRQogIFN0ZFByb3h5X1F1ZXJ5SW50ZXJmYWNlLAogIFN0ZFByb3h5X0FkZFJlZiwKICBTdGRQcm94eV9SZWxlYXNlLAogIFN0ZFByb3h5X0Nvbm5lY3QsCiAgU3RkUHJveHlfRGlzY29ubmVjdAp9OwoKSFJFU1VMVCBXSU5BUEkgU3RkUHJveHlfR2V0Q2hhbm5lbChMUFZPSUQgaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFJQQ0NIQU5ORUxCVUZGRVIgKnBwQ2hhbm5lbCkKewogIElDT01fVEhJU19NVUxUSShTdGRQcm94eUltcGwsUFZ0YmwsaWZhY2UpOwogIFRSQUNFKCIoJXApLT5HZXRDaGFubmVsKCVwKSAlc1xuIixUaGlzLHBwQ2hhbm5lbCxUaGlzLT5uYW1lKTsKCiAgKnBwQ2hhbm5lbCA9IFRoaXMtPnBDaGFubmVsOwogIHJldHVybiBTX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBTdGRQcm94eV9HZXRJSUQoTFBWT0lEIGlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBJSUQgKipwcGlpZCkKewogIElDT01fVEhJU19NVUxUSShTdGRQcm94eUltcGwsUFZ0YmwsaWZhY2UpOwogIFRSQUNFKCIoJXApLT5HZXRJSUQoJXApICVzXG4iLFRoaXMscHBpaWQsVGhpcy0+bmFtZSk7CgogICpwcGlpZCA9IFRoaXMtPnBpaWQ7CiAgcmV0dXJuIFNfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlX1Byb3h5KExQVU5LTk9XTiBpZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUZJSUQgcmlpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFZPSUQgKnBwdk9iaikKewogIElDT01fVEhJU19NVUxUSShTdGRQcm94eUltcGwsUFZ0YmwsaWZhY2UpOwogIFRSQUNFKCIoJXApLT5RdWVyeUludGVyZmFjZSglcywlcCkgJXNcbiIsVGhpcyxkZWJ1Z3N0cl9ndWlkKHJpaWQpLHBwdk9iaixUaGlzLT5uYW1lKTsKICByZXR1cm4gSVVua25vd25fUXVlcnlJbnRlcmZhY2UoVGhpcy0+cFVua091dGVyLHJpaWQscHB2T2JqKTsKfQoKVUxPTkcgV0lOQVBJIElVbmtub3duX0FkZFJlZl9Qcm94eShMUFVOS05PV04gaWZhY2UpCnsKICBJQ09NX1RISVNfTVVMVEkoU3RkUHJveHlJbXBsLFBWdGJsLGlmYWNlKTsKICBUUkFDRSgiKCVwKS0+QWRkUmVmKCkgJXNcbiIsVGhpcyxUaGlzLT5uYW1lKTsKI2lmIDAgLyogaW50ZXJmYWNlIHJlZmNvdW50aW5nICovCiAgcmV0dXJuICsrKFRoaXMtPlJlZkNvdW50KTsKI2Vsc2UgLyogb2JqZWN0IHJlZmNvdW50aW5nICovCiAgcmV0dXJuIElVbmtub3duX0FkZFJlZihUaGlzLT5wVW5rT3V0ZXIpOwojZW5kaWYKfQoKVUxPTkcgV0lOQVBJIElVbmtub3duX1JlbGVhc2VfUHJveHkoTFBVTktOT1dOIGlmYWNlKQp7CiAgSUNPTV9USElTX01VTFRJKFN0ZFByb3h5SW1wbCxQVnRibCxpZmFjZSk7CiAgVFJBQ0UoIiglcCktPlJlbGVhc2UoKSAlc1xuIixUaGlzLFRoaXMtPm5hbWUpOwojaWYgMCAvKiBpbnRlcmZhY2UgcmVmY291bnRpbmcgKi8KICBpZiAoIS0tKFRoaXMtPlJlZkNvdW50KSkgewogICAgU3RkUHJveHlfRGVzdHJ1Y3QoKExQUlBDUFJPWFlCVUZGRVIpJlRoaXMtPmxwVnRibCk7CiAgICByZXR1cm4gMDsKICB9CiAgcmV0dXJuIFRoaXMtPlJlZkNvdW50OwojZWxzZSAvKiBvYmplY3QgcmVmY291bnRpbmcgKi8KICByZXR1cm4gSVVua25vd25fUmVsZWFzZShUaGlzLT5wVW5rT3V0ZXIpOwojZW5kaWYKfQoK