LyoKICogQ09NIHByb3h5IGltcGxlbWVudGF0aW9uCiAqCiAqIENvcHlyaWdodCAyMDAxIE92ZSBL5XZlbiwgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKiAKICogVE9ETzogSGFuZGxlIG5vbi1pMzg2IGFyY2hpdGVjdHVyZXMKICovCgojaW5jbHVkZSA8c3RkYXJnLmg+CgojZGVmaW5lIENPQkpNQUNST1MKCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCgojaW5jbHVkZSAib2JqYmFzZS5oIgojaW5jbHVkZSAicnBjcHJveHkuaCIKCiNpbmNsdWRlICJjcHNmLmgiCiNpbmNsdWRlICJuZHJfbWlzYy5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwob2xlKTsKCnN0cnVjdCBTdHVibGVzc1RodW5rOwoKLyogSSBkb24ndCBrbm93IHdoYXQgTVMncyBzdGQgcHJveHkgc3RydWN0dXJlIGxvb2tzIGxpa2UsCiAgIHNvIHRoaXMgcHJvYmFibHkgZG9lc24ndCBtYXRjaCwgYnV0IHRoYXQgc2hvdWxkbid0IG1hdHRlciAqLwp0eXBlZGVmIHN0cnVjdCB7CiAgY29uc3QgSVJwY1Byb3h5QnVmZmVyVnRibCAqbHBWdGJsOwogIExQVk9JRCAqUFZ0Ymw7CiAgTE9ORyBSZWZDb3VudDsKICBjb25zdCBNSURMX1NUVUJMRVNTX1BST1hZX0lORk8gKnN0dWJsZXNzOwogIGNvbnN0IElJRCogcGlpZDsKICBMUFVOS05PV04gcFVua091dGVyOwogIFBDSW50ZXJmYWNlTmFtZSBuYW1lOwogIExQUFNGQUNUT1JZQlVGRkVSIHBQU0ZhY3Rvcnk7CiAgTFBSUENDSEFOTkVMQlVGRkVSIHBDaGFubmVsOwogIHN0cnVjdCBTdHVibGVzc1RodW5rICp0aHVua3M7Cn0gU3RkUHJveHlJbXBsOwoKc3RhdGljIGNvbnN0IElScGNQcm94eUJ1ZmZlclZ0YmwgU3RkUHJveHlfVnRibDsKCiNkZWZpbmUgSUNPTV9USElTX01VTFRJKGltcGwsZmllbGQsaWZhY2UpIGltcGwqIGNvbnN0IFRoaXM9KGltcGwqKSgoY2hhciopKGlmYWNlKSAtIG9mZnNldG9mKGltcGwsZmllbGQpKQoKLyogSG93IHRoZSBXaW5kb3dzIHN0dWJsZXNzIHByb3h5IHRodW5rcyB3b3JrIGlzIGV4cGxhaW5lZCBhdAogKiBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2xpYnJhcnkvZW4tdXMvZG5tc2o5OS9odG1sL2NvbTAxOTkuYXNwLAogKiBidXQgSSdsbCB1c2UgYSBzbGlnaHRseSBkaWZmZXJlbnQgbWV0aG9kLCB0byBtYWtlIGxpZmUgZWFzaWVyICovCgojaWYgZGVmaW5lZChfX2kzODZfXykKCiNpbmNsdWRlICJwc2hwYWNrMS5oIgoKc3RydWN0IFN0dWJsZXNzVGh1bmsgewogIEJZVEUgcHVzaDsKICBEV09SRCBpbmRleDsKICBCWVRFIGNhbGw7CiAgTE9ORyBoYW5kbGVyOwogIEJZVEUgcmV0OwogIFdPUkQgYnl0ZXM7CiAgQllURSBwYWRbM107Cn07CgojaW5jbHVkZSAicG9wcGFjay5oIgoKLyogYWRqdXN0IHRoZSBzdGFjayBzaXplIHNpbmNlIHdlIGRvbid0IHVzZSBXaW5kb3dzJ3MgbWV0aG9kICovCiNkZWZpbmUgU1RBQ0tfQURKVVNUIHNpemVvZihEV09SRCkKCiNkZWZpbmUgRklMTF9TVFVCTEVTUyh4LGlkeCxzdGspIFwKIHgtPnB1c2ggPSAweDY4OyAvKiBwdXNobCBbaW1tZWRpYXRlXSAqLyBcCiB4LT5pbmRleCA9IChpZHgpOyBcCiB4LT5jYWxsID0gMHhlODsgLyogY2FsbCBbbmVhcl0gKi8gXAogeC0+aGFuZGxlciA9IChjaGFyKilPYmplY3RTdHVibGVzcyAtIChjaGFyKikmeC0+cmV0OyBcCiB4LT5yZXQgPSAweGMyOyAvKiByZXQgW2ltbWVkaWF0ZV0gKi8gXAogeC0+Ynl0ZXMgPSBzdGs7IFwKIHgtPnBhZFswXSA9IDB4OGQ7IC8qIGxlYWwgKCVlc2kpLCVlc2kgKi8gXAogeC0+cGFkWzFdID0gMHg3NjsgXAogeC0+cGFkWzJdID0gMHgwMDsKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBPYmplY3RTdHVibGVzcyhEV09SRCBpbmRleCkKewogIGNoYXIgKmFyZ3MgPSAoY2hhciopKCZpbmRleCArIDIpOwogIExQVk9JRCBpZmFjZSA9ICooTFBWT0lEKilhcmdzOwoKICBJQ09NX1RISVNfTVVMVEkoU3RkUHJveHlJbXBsLFBWdGJsLGlmYWNlKTsKCiAgUEZPUk1BVF9TVFJJTkcgZnMgPSBUaGlzLT5zdHVibGVzcy0+UHJvY0Zvcm1hdFN0cmluZyArIFRoaXMtPnN0dWJsZXNzLT5Gb3JtYXRTdHJpbmdPZmZzZXRbaW5kZXhdOwogIHVuc2lnbmVkIGJ5dGVzID0gKihjb25zdCBXT1JEKikoZnMrOCkgLSBTVEFDS19BREpVU1Q7CiAgVFJBQ0UoIiglcCktPiglZCkoWyVkIGJ5dGVzXSkgcmV0PSUwOHhcbiIsIGlmYWNlLCBpbmRleCwgYnl0ZXMsICooRFdPUkQqKShhcmdzK2J5dGVzKSk7CgogIHJldHVybiBOZHJDbGllbnRDYWxsMihUaGlzLT5zdHVibGVzcy0+cFN0dWJEZXNjLCBmcywgYXJncyk7Cn0KCiNlbHNlICAvKiBfX2kzODZfXyAqLwoKLyogY2FuJ3QgZG8gdGhhdCBvbiB0aGlzIGFyY2ggKi8Kc3RydWN0IFN0dWJsZXNzVGh1bmsgeyBpbnQgZHVtbXk7IH07CiNkZWZpbmUgRklMTF9TVFVCTEVTUyh4LGlkeCxzdGspIFwKIEVSUigic3R1Ymxlc3MgcHJveGllcyBhcmUgbm90IHN1cHBvcnRlZCBvbiB0aGlzIGFyY2hpdGVjdHVyZVxuIik7CiNkZWZpbmUgU1RBQ0tfQURKVVNUIDAKCiNlbmRpZiAgLyogX19pMzg2X18gKi8KCkhSRVNVTFQgV0lOQVBJIFN0ZFByb3h5X0NvbnN0cnVjdChSRUZJSUQgcmlpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBVTktOT1dOIHBVbmtPdXRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUHJveHlGaWxlSW5mbyAqUHJveHlJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgSW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQUFNGQUNUT1JZQlVGRkVSIHBQU0ZhY3RvcnksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQUlBDUFJPWFlCVUZGRVIgKnBwUHJveHksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQVk9JRCAqcHB2T2JqKQp7CiAgU3RkUHJveHlJbXBsICpUaGlzOwogIGNvbnN0IE1JRExfU1RVQkxFU1NfUFJPWFlfSU5GTyAqc3R1Ymxlc3MgPSBOVUxMOwogIFBDSW50ZXJmYWNlTmFtZSBuYW1lID0gUHJveHlJbmZvLT5wTmFtZXNBcnJheVtJbmRleF07CiAgQ0ludGVyZmFjZVByb3h5VnRibCAqdnRibCA9IFByb3h5SW5mby0+cFByb3h5VnRibExpc3RbSW5kZXhdOwoKICBUUkFDRSgiKCVwLCVwLCVwLCVwLCVwKSAlc1xuIiwgcFVua091dGVyLCB2dGJsLCBwUFNGYWN0b3J5LCBwcFByb3h5LCBwcHZPYmosIG5hbWUpOwoKICAvKiBUYWJsZVZlcnNpb24gPSAyIG1lYW5zIGl0IGlzIHRoZSBzdHVibGVzcyB2ZXJzaW9uIG9mIENJbnRlcmZhY2VQcm94eVZ0YmwgKi8KICBpZiAoUHJveHlJbmZvLT5UYWJsZVZlcnNpb24gPiAxKSB7CiAgICBzdHVibGVzcyA9ICooY29uc3Qgdm9pZCAqKil2dGJsOwogICAgdnRibCA9IChDSW50ZXJmYWNlUHJveHlWdGJsICopKChjb25zdCB2b2lkICoqKXZ0YmwgKyAxKTsKICAgIFRSQUNFKCJzdHVibGVzcz0lcFxuIiwgc3R1Ymxlc3MpOwogIH0KCiAgVFJBQ0UoImlpZD0lc1xuIiwgZGVidWdzdHJfZ3VpZCh2dGJsLT5oZWFkZXIucGlpZCkpOwogIFRSQUNFKCJ2dGJsPSVwXG4iLCB2dGJsLT5WdGJsKTsKCiAgaWYgKCFJc0VxdWFsR1VJRCh2dGJsLT5oZWFkZXIucGlpZCwgcmlpZCkpIHsKICAgIEVSUigiSUlEIG1pc21hdGNoIGR1cmluZyBwcm94eSBjcmVhdGlvblxuIik7CiAgICByZXR1cm4gUlBDX0VfVU5FWFBFQ1RFRDsKICB9CgogIFRoaXMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSxIRUFQX1pFUk9fTUVNT1JZLHNpemVvZihTdGRQcm94eUltcGwpKTsKICBpZiAoIVRoaXMpIHJldHVybiBFX09VVE9GTUVNT1JZOwoKICBpZiAoc3R1Ymxlc3MpIHsKICAgIENJbnRlcmZhY2VTdHViVnRibCAqc3Z0YmwgPSBQcm94eUluZm8tPnBTdHViVnRibExpc3RbSW5kZXhdOwogICAgdW5zaWduZWQgbG9uZyBpLCBjb3VudCA9IHN2dGJsLT5oZWFkZXIuRGlzcGF0Y2hUYWJsZUNvdW50OwogICAgLyogTWF5YmUgdGhlIG9yaWdpbmFsIHZ0YmwgaXMganVzdCBtb2RpZmllZCBkaXJlY3RseSB0byBwb2ludCBhdAogICAgICogT2JqZWN0U3R1Ymxlc3NDbGllbnRYWFggdGh1bmtzIGluIHJlYWwgV2luZG93cywgYnV0IEkgZG9uJ3QgbGlrZSBpdAogICAgICovCiAgICBUUkFDRSgic3R1Ymxlc3MgdGh1bmtzOiBjb3VudD0lbGRcbiIsIGNvdW50KTsKICAgIFRoaXMtPnRodW5rcyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLDAsc2l6ZW9mKHN0cnVjdCBTdHVibGVzc1RodW5rKSpjb3VudCk7CiAgICBUaGlzLT5QVnRibCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLDAsc2l6ZW9mKExQVk9JRCkqY291bnQpOwogICAgZm9yIChpPTA7IGk8Y291bnQ7IGkrKykgewogICAgICBzdHJ1Y3QgU3R1Ymxlc3NUaHVuayAqdGh1bmsgPSAmVGhpcy0+dGh1bmtzW2ldOwogICAgICBpZiAodnRibC0+VnRibFtpXSA9PSAoTFBWT0lEKS0xKSB7CiAgICAgICAgUEZPUk1BVF9TVFJJTkcgZnMgPSBzdHVibGVzcy0+UHJvY0Zvcm1hdFN0cmluZyArIHN0dWJsZXNzLT5Gb3JtYXRTdHJpbmdPZmZzZXRbaV07CiAgICAgICAgdW5zaWduZWQgYnl0ZXMgPSAqKGNvbnN0IFdPUkQqKShmcys4KSAtIFNUQUNLX0FESlVTVDsKICAgICAgICBUUkFDRSgibWV0aG9kICVsZDogc3RhY2tzaXplPSVkXG4iLCBpLCBieXRlcyk7CiAgICAgICAgRklMTF9TVFVCTEVTUyh0aHVuaywgaSwgYnl0ZXMpCiAgICAgICAgVGhpcy0+UFZ0YmxbaV0gPSB0aHVuazsKICAgICAgfQogICAgICBlbHNlIHsKICAgICAgICBtZW1zZXQodGh1bmssIDAsIHNpemVvZihzdHJ1Y3QgU3R1Ymxlc3NUaHVuaykpOwogICAgICAgIFRoaXMtPlBWdGJsW2ldID0gdnRibC0+VnRibFtpXTsKICAgICAgfQogICAgfQogIH0KICBlbHNlIAogICAgVGhpcy0+UFZ0YmwgPSB2dGJsLT5WdGJsOwoKICBUaGlzLT5scFZ0YmwgPSAmU3RkUHJveHlfVnRibDsKICAvKiBvbmUgcmVmZXJlbmNlIGZvciB0aGUgcHJveHkgKi8KICBUaGlzLT5SZWZDb3VudCA9IDE7CiAgVGhpcy0+c3R1Ymxlc3MgPSBzdHVibGVzczsKICBUaGlzLT5waWlkID0gdnRibC0+aGVhZGVyLnBpaWQ7CiAgVGhpcy0+cFVua091dGVyID0gcFVua091dGVyOwogIFRoaXMtPm5hbWUgPSBuYW1lOwogIFRoaXMtPnBQU0ZhY3RvcnkgPSBwUFNGYWN0b3J5OwogIFRoaXMtPnBDaGFubmVsID0gTlVMTDsKICAqcHBQcm94eSA9IChMUFJQQ1BST1hZQlVGRkVSKSZUaGlzLT5scFZ0Ymw7CiAgKnBwdk9iaiA9ICZUaGlzLT5QVnRibDsKICAvKiBpZiB0aGVyZSBpcyBubyBvdXRlciB1bmtub3duIHRoZW4gdGhlIGNhbGxlciB3aWxsIGNvbnRyb2wgdGhlIGxpZmV0aW1lCiAgICogb2YgdGhlIHByb3h5IG9iamVjdCB0aHJvdWdoIHRoZSBwcm94eSBidWZmZXIsIHNvIG5vIG5lZWQgdG8gaW5jcmVtZW50IHRoZQogICAqIHJlZiBjb3VudCBvZiB0aGUgcHJveHkgb2JqZWN0ICovCiAgaWYgKHBVbmtPdXRlcikKICAgIElVbmtub3duX0FkZFJlZigoSVVua25vd24gKikqcHB2T2JqKTsKICBJUFNGYWN0b3J5QnVmZmVyX0FkZFJlZihwUFNGYWN0b3J5KTsKCiAgcmV0dXJuIFNfT0s7Cn0KCnN0YXRpYyB2b2lkIFdJTkFQSSBTdGRQcm94eV9EZXN0cnVjdChMUFJQQ1BST1hZQlVGRkVSIGlmYWNlKQp7CiAgSUNPTV9USElTX01VTFRJKFN0ZFByb3h5SW1wbCxscFZ0YmwsaWZhY2UpOwoKICBpZiAoVGhpcy0+cENoYW5uZWwpCiAgICBJUnBjUHJveHlCdWZmZXJfRGlzY29ubmVjdChpZmFjZSk7CgogIElQU0ZhY3RvcnlCdWZmZXJfUmVsZWFzZShUaGlzLT5wUFNGYWN0b3J5KTsKICBpZiAoVGhpcy0+dGh1bmtzKSB7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsVGhpcy0+UFZ0YmwpOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLFRoaXMtPnRodW5rcyk7CiAgfQogIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCxUaGlzKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFN0ZFByb3h5X1F1ZXJ5SW50ZXJmYWNlKExQUlBDUFJPWFlCVUZGRVIgaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFRklJRCByaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFZPSUQgKm9iaikKewogIElDT01fVEhJU19NVUxUSShTdGRQcm94eUltcGwsbHBWdGJsLGlmYWNlKTsKICBUUkFDRSgiKCVwKS0+UXVlcnlJbnRlcmZhY2UoJXMsJXApXG4iLFRoaXMsZGVidWdzdHJfZ3VpZChyaWlkKSxvYmopOwoKICBpZiAoSXNFcXVhbEdVSUQoJklJRF9JVW5rbm93bixyaWlkKSB8fAogICAgICBJc0VxdWFsR1VJRChUaGlzLT5waWlkLHJpaWQpKSB7CiAgICAqb2JqID0gJlRoaXMtPlBWdGJsOwogICAgSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPlJlZkNvdW50KTsKICAgIHJldHVybiBTX09LOwogIH0KCiAgaWYgKElzRXF1YWxHVUlEKCZJSURfSVJwY1Byb3h5QnVmZmVyLHJpaWQpKSB7CiAgICAqb2JqID0gJlRoaXMtPmxwVnRibDsKICAgIEludGVybG9ja2VkSW5jcmVtZW50KCZUaGlzLT5SZWZDb3VudCk7CiAgICByZXR1cm4gU19PSzsKICB9CgogIHJldHVybiBFX05PSU5URVJGQUNFOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIFN0ZFByb3h5X0FkZFJlZihMUFJQQ1BST1hZQlVGRkVSIGlmYWNlKQp7CiAgSUNPTV9USElTX01VTFRJKFN0ZFByb3h5SW1wbCxscFZ0YmwsaWZhY2UpOwogIFRSQUNFKCIoJXApLT5BZGRSZWYoKVxuIixUaGlzKTsKCiAgcmV0dXJuIEludGVybG9ja2VkSW5jcmVtZW50KCZUaGlzLT5SZWZDb3VudCk7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgU3RkUHJveHlfUmVsZWFzZShMUFJQQ1BST1hZQlVGRkVSIGlmYWNlKQp7CiAgVUxPTkcgcmVmczsKICBJQ09NX1RISVNfTVVMVEkoU3RkUHJveHlJbXBsLGxwVnRibCxpZmFjZSk7CiAgVFJBQ0UoIiglcCktPlJlbGVhc2UoKVxuIixUaGlzKTsKCiAgcmVmcyA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5SZWZDb3VudCk7CiAgaWYgKCFyZWZzKQogICAgU3RkUHJveHlfRGVzdHJ1Y3QoKExQUlBDUFJPWFlCVUZGRVIpJlRoaXMtPmxwVnRibCk7CiAgcmV0dXJuIHJlZnM7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBTdGRQcm94eV9Db25uZWN0KExQUlBDUFJPWFlCVUZGRVIgaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBSUENDSEFOTkVMQlVGRkVSIHBDaGFubmVsKQp7CiAgSUNPTV9USElTX01VTFRJKFN0ZFByb3h5SW1wbCxscFZ0YmwsaWZhY2UpOwogIFRSQUNFKCIoJXApLT5Db25uZWN0KCVwKVxuIixUaGlzLHBDaGFubmVsKTsKCiAgVGhpcy0+cENoYW5uZWwgPSBwQ2hhbm5lbDsKICBJUnBjQ2hhbm5lbEJ1ZmZlcl9BZGRSZWYocENoYW5uZWwpOwogIHJldHVybiBTX09LOwp9CgpzdGF0aWMgVk9JRCBXSU5BUEkgU3RkUHJveHlfRGlzY29ubmVjdChMUFJQQ1BST1hZQlVGRkVSIGlmYWNlKQp7CiAgSUNPTV9USElTX01VTFRJKFN0ZFByb3h5SW1wbCxscFZ0YmwsaWZhY2UpOwogIFRSQUNFKCIoJXApLT5EaXNjb25uZWN0KClcbiIsVGhpcyk7CgogIElScGNDaGFubmVsQnVmZmVyX1JlbGVhc2UoVGhpcy0+cENoYW5uZWwpOwogIFRoaXMtPnBDaGFubmVsID0gTlVMTDsKfQoKc3RhdGljIGNvbnN0IElScGNQcm94eUJ1ZmZlclZ0YmwgU3RkUHJveHlfVnRibCA9CnsKICBTdGRQcm94eV9RdWVyeUludGVyZmFjZSwKICBTdGRQcm94eV9BZGRSZWYsCiAgU3RkUHJveHlfUmVsZWFzZSwKICBTdGRQcm94eV9Db25uZWN0LAogIFN0ZFByb3h5X0Rpc2Nvbm5lY3QKfTsKCnN0YXRpYyB2b2lkIFN0ZFByb3h5X0dldENoYW5uZWwoTFBWT0lEIGlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQUlBDQ0hBTk5FTEJVRkZFUiAqcHBDaGFubmVsKQp7CiAgSUNPTV9USElTX01VTFRJKFN0ZFByb3h5SW1wbCxQVnRibCxpZmFjZSk7CiAgVFJBQ0UoIiglcCktPkdldENoYW5uZWwoJXApICVzXG4iLFRoaXMscHBDaGFubmVsLFRoaXMtPm5hbWUpOwoKICAqcHBDaGFubmVsID0gVGhpcy0+cENoYW5uZWw7Cn0KCnN0YXRpYyB2b2lkIFN0ZFByb3h5X0dldElJRChMUFZPSUQgaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBJSUQgKipwcGlpZCkKewogIElDT01fVEhJU19NVUxUSShTdGRQcm94eUltcGwsUFZ0YmwsaWZhY2UpOwogIFRSQUNFKCIoJXApLT5HZXRJSUQoJXApICVzXG4iLFRoaXMscHBpaWQsVGhpcy0+bmFtZSk7CgogICpwcGlpZCA9IFRoaXMtPnBpaWQ7Cn0KCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlX1Byb3h5KExQVU5LTk9XTiBpZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUZJSUQgcmlpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFZPSUQgKnBwdk9iaikKewogIElDT01fVEhJU19NVUxUSShTdGRQcm94eUltcGwsUFZ0YmwsaWZhY2UpOwogIFRSQUNFKCIoJXApLT5RdWVyeUludGVyZmFjZSglcywlcCkgJXNcbiIsVGhpcyxkZWJ1Z3N0cl9ndWlkKHJpaWQpLHBwdk9iaixUaGlzLT5uYW1lKTsKICByZXR1cm4gSVVua25vd25fUXVlcnlJbnRlcmZhY2UoVGhpcy0+cFVua091dGVyLHJpaWQscHB2T2JqKTsKfQoKVUxPTkcgV0lOQVBJIElVbmtub3duX0FkZFJlZl9Qcm94eShMUFVOS05PV04gaWZhY2UpCnsKICBJQ09NX1RISVNfTVVMVEkoU3RkUHJveHlJbXBsLFBWdGJsLGlmYWNlKTsKICBUUkFDRSgiKCVwKS0+QWRkUmVmKCkgJXNcbiIsVGhpcyxUaGlzLT5uYW1lKTsKICByZXR1cm4gSVVua25vd25fQWRkUmVmKFRoaXMtPnBVbmtPdXRlcik7Cn0KClVMT05HIFdJTkFQSSBJVW5rbm93bl9SZWxlYXNlX1Byb3h5KExQVU5LTk9XTiBpZmFjZSkKewogIElDT01fVEhJU19NVUxUSShTdGRQcm94eUltcGwsUFZ0YmwsaWZhY2UpOwogIFRSQUNFKCIoJXApLT5SZWxlYXNlKCkgJXNcbiIsVGhpcyxUaGlzLT5uYW1lKTsKICByZXR1cm4gSVVua25vd25fUmVsZWFzZShUaGlzLT5wVW5rT3V0ZXIpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5kclByb3h5SW5pdGlhbGl6ZSBbUlBDUlQ0LkBdCiAqLwp2b2lkIFdJTkFQSSBOZHJQcm94eUluaXRpYWxpemUodm9pZCAqVGhpcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUFJQQ19NRVNTQUdFIHBScGNNc2csCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBNSURMX1NUVUJfTUVTU0FHRSBwU3R1Yk1zZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUE1JRExfU1RVQl9ERVNDIHBTdHViRGVzY3JpcHRvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgaW50IFByb2NOdW0pCnsKICBUUkFDRSgiKCVwLCVwLCVwLCVwLCVkKVxuIiwgVGhpcywgcFJwY01zZywgcFN0dWJNc2csIHBTdHViRGVzY3JpcHRvciwgUHJvY051bSk7CiAgTmRyQ2xpZW50SW5pdGlhbGl6ZU5ldyhwUnBjTXNnLCBwU3R1Yk1zZywgcFN0dWJEZXNjcmlwdG9yLCBQcm9jTnVtKTsKICBTdGRQcm94eV9HZXRDaGFubmVsKFRoaXMsICZwU3R1Yk1zZy0+cFJwY0NoYW5uZWxCdWZmZXIpOwogIElScGNDaGFubmVsQnVmZmVyX0dldERlc3RDdHgocFN0dWJNc2ctPnBScGNDaGFubmVsQnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBTdHViTXNnLT5kd0Rlc3RDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBTdHViTXNnLT5wdkRlc3RDb250ZXh0KTsKICBUUkFDRSgiY2hhbm5lbD0lcFxuIiwgcFN0dWJNc2ctPnBScGNDaGFubmVsQnVmZmVyKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOZHJQcm94eUdldEJ1ZmZlciBbUlBDUlQ0LkBdCiAqLwp2b2lkIFdJTkFQSSBOZHJQcm94eUdldEJ1ZmZlcih2b2lkICpUaGlzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBNSURMX1NUVUJfTUVTU0FHRSBwU3R1Yk1zZykKewogIEhSRVNVTFQgaHI7CiAgY29uc3QgSUlEICpyaWlkID0gTlVMTDsKCiAgVFJBQ0UoIiglcCwlcClcbiIsIFRoaXMsIHBTdHViTXNnKTsKICBwU3R1Yk1zZy0+UnBjTXNnLT5CdWZmZXJMZW5ndGggPSBwU3R1Yk1zZy0+QnVmZmVyTGVuZ3RoOwogIHBTdHViTXNnLT5kd1N0dWJQaGFzZSA9IFBST1hZX0dFVEJVRkZFUjsKICBTdGRQcm94eV9HZXRJSUQoVGhpcywgJnJpaWQpOwogIGhyID0gSVJwY0NoYW5uZWxCdWZmZXJfR2V0QnVmZmVyKHBTdHViTXNnLT5wUnBjQ2hhbm5lbEJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChSUENPTEVNRVNTQUdFKilwU3R1Yk1zZy0+UnBjTXNnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmlpZCk7CiAgaWYgKEZBSUxFRChocikpCiAgewogICAgUnBjUmFpc2VFeGNlcHRpb24oaHIpOwogICAgcmV0dXJuOwogIH0KICBwU3R1Yk1zZy0+QnVmZmVyU3RhcnQgPSBwU3R1Yk1zZy0+UnBjTXNnLT5CdWZmZXI7CiAgcFN0dWJNc2ctPkJ1ZmZlckVuZCA9IHBTdHViTXNnLT5CdWZmZXJTdGFydCArIHBTdHViTXNnLT5CdWZmZXJMZW5ndGg7CiAgcFN0dWJNc2ctPkJ1ZmZlciA9IHBTdHViTXNnLT5CdWZmZXJTdGFydDsKICBwU3R1Yk1zZy0+ZHdTdHViUGhhc2UgPSBQUk9YWV9NQVJTSEFMOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5kclByb3h5U2VuZFJlY2VpdmUgW1JQQ1JUNC5AXQogKi8Kdm9pZCBXSU5BUEkgTmRyUHJveHlTZW5kUmVjZWl2ZSh2b2lkICpUaGlzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUE1JRExfU1RVQl9NRVNTQUdFIHBTdHViTXNnKQp7CiAgVUxPTkcgU3RhdHVzID0gMDsKICBIUkVTVUxUIGhyOwoKICBUUkFDRSgiKCVwLCVwKVxuIiwgVGhpcywgcFN0dWJNc2cpOwoKICBpZiAoIXBTdHViTXNnLT5wUnBjQ2hhbm5lbEJ1ZmZlcikKICB7CiAgICBXQVJOKCJUcnlpbmcgdG8gdXNlIGRpc2Nvbm5lY3RlZCBwcm94eSAlcFxuIiwgVGhpcyk7CiAgICBScGNSYWlzZUV4Y2VwdGlvbihSUENfRV9ESVNDT05ORUNURUQpOwogIH0KCiAgcFN0dWJNc2ctPmR3U3R1YlBoYXNlID0gUFJPWFlfU0VORFJFQ0VJVkU7CiAgaHIgPSBJUnBjQ2hhbm5lbEJ1ZmZlcl9TZW5kUmVjZWl2ZShwU3R1Yk1zZy0+cFJwY0NoYW5uZWxCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChSUENPTEVNRVNTQUdFKilwU3R1Yk1zZy0+UnBjTXNnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmU3RhdHVzKTsKICBwU3R1Yk1zZy0+ZHdTdHViUGhhc2UgPSBQUk9YWV9VTk1BUlNIQUw7CiAgcFN0dWJNc2ctPkJ1ZmZlckxlbmd0aCA9IHBTdHViTXNnLT5ScGNNc2ctPkJ1ZmZlckxlbmd0aDsKICBwU3R1Yk1zZy0+QnVmZmVyU3RhcnQgPSBwU3R1Yk1zZy0+UnBjTXNnLT5CdWZmZXI7CiAgcFN0dWJNc2ctPkJ1ZmZlckVuZCA9IHBTdHViTXNnLT5CdWZmZXJTdGFydCArIHBTdHViTXNnLT5CdWZmZXJMZW5ndGg7CiAgcFN0dWJNc2ctPkJ1ZmZlciA9IHBTdHViTXNnLT5CdWZmZXJTdGFydDsKCiAgLyogcmFpc2UgZXhjZXB0aW9uIGlmIGNhbGwgZmFpbGVkICovCiAgaWYgKGhyID09IFJQQ19TX0NBTExfRkFJTEVEKSBScGNSYWlzZUV4Y2VwdGlvbigqKERXT1JEKilwU3R1Yk1zZy0+QnVmZmVyKTsKICBlbHNlIGlmIChGQUlMRUQoaHIpKSBScGNSYWlzZUV4Y2VwdGlvbihocik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTmRyUHJveHlGcmVlQnVmZmVyIFtSUENSVDQuQF0KICovCnZvaWQgV0lOQVBJIE5kclByb3h5RnJlZUJ1ZmZlcih2b2lkICpUaGlzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQTUlETF9TVFVCX01FU1NBR0UgcFN0dWJNc2cpCnsKICBIUkVTVUxUIGhyOwoKICBUUkFDRSgiKCVwLCVwKVxuIiwgVGhpcywgcFN0dWJNc2cpOwogIGhyID0gSVJwY0NoYW5uZWxCdWZmZXJfRnJlZUJ1ZmZlcihwU3R1Yk1zZy0+cFJwY0NoYW5uZWxCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFJQQ09MRU1FU1NBR0UqKXBTdHViTXNnLT5ScGNNc2cpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5kclByb3h5RXJyb3JIYW5kbGVyIFtSUENSVDQuQF0KICovCkhSRVNVTFQgV0lOQVBJIE5kclByb3h5RXJyb3JIYW5kbGVyKERXT1JEIGR3RXhjZXB0aW9uQ29kZSkKewogIFdBUk4oIigweCUwOHgpOiBhIHByb3h5IGNhbGwgZmFpbGVkXG4iLCBkd0V4Y2VwdGlvbkNvZGUpOwoKICBpZiAoRkFJTEVEKGR3RXhjZXB0aW9uQ29kZSkpCiAgICByZXR1cm4gZHdFeGNlcHRpb25Db2RlOwogIGVsc2UKICAgIHJldHVybiBIUkVTVUxUX0ZST01fV0lOMzIoZHdFeGNlcHRpb25Db2RlKTsKfQoKSFJFU1VMVCBXSU5BUEkKQ3JlYXRlUHJveHlGcm9tVHlwZUluZm8oIExQVFlQRUlORk8gcFR5cGVJbmZvLCBMUFVOS05PV04gcFVua091dGVyLCBSRUZJSUQgcmlpZCwKICAgICAgICAgICAgICAgICAgICAgICAgIExQUlBDUFJPWFlCVUZGRVIgKnBwUHJveHksIExQVk9JRCAqcHB2ICkKewogICAgdHlwZWRlZiBJTlQgKFdJTkFQSSAqTWVzc2FnZUJveEEpKEhXTkQsTFBDU1RSLExQQ1NUUixVSU5UKTsKICAgIEhNT0RVTEUgaFVzZXIzMiA9IExvYWRMaWJyYXJ5QSgidXNlcjMyIik7CiAgICBNZXNzYWdlQm94QSBwTWVzc2FnZUJveEEgPSBHZXRQcm9jQWRkcmVzcyhoVXNlcjMyLCAiTWVzc2FnZUJveEEiKTsKCiAgICBGSVhNRSgiJXAgJXAgJXMgJXAgJXBcbiIsIHBUeXBlSW5mbywgcFVua091dGVyLCBkZWJ1Z3N0cl9ndWlkKHJpaWQpLCBwcFByb3h5LCBwcHYpOwogICAgaWYgKHBNZXNzYWdlQm94QSkKICAgIHsKICAgICAgICBwTWVzc2FnZUJveEEoTlVMTCwKICAgICAgICAgICAgIlRoZSBuYXRpdmUgaW1wbGVtZW50YXRpb24gb2YgT0xFQVVUMzIuRExMIGNhbm5vdCBiZSB1c2VkICIKICAgICAgICAgICAgIndpdGggV2luZSdzIFJQQ1JUNC5ETEwuIFJlbW92ZSBPTEVBVVQzMi5ETEwgYW5kIHRyeSBhZ2Fpbi5cbiIsCiAgICAgICAgICAgICJXaW5lOiBVbmltcGxlbWVudGVkIENyZWF0ZVByb3h5RnJvbVR5cGVJbmZvIiwKICAgICAgICAgICAgMHgxMCk7CiAgICAgICAgRXhpdFByb2Nlc3MoMSk7CiAgICB9CiAgICByZXR1cm4gRV9OT1RJTVBMOwp9Cg==