LyoKICAgIFNETCAtIFNpbXBsZSBEaXJlY3RNZWRpYSBMYXllcgogICAgQ29weXJpZ2h0IChDKSAxOTk3LTIwMTIgU2FtIExhbnRpbmdhCgogICAgVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogICAgbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogICAgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAgICB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KCiAgICBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICAgIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAgICBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogICAgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KCiAgICBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAgICBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAgICBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgIDAyMTEwLTEzMDEgIFVTQQoKICAgIFNhbSBMYW50aW5nYQogICAgc2xvdWtlbkBsaWJzZGwub3JnCiovCiNpbmNsdWRlICJTRExfY29uZmlnLmgiCgovKiBRdG9waWEgYmFzZWQgZnJhbWVidWZmZXIgaW1wbGVtZW50YXRpb24gKi8KCiNpbmNsdWRlIDx1bmlzdGQuaD4KCiNpbmNsdWRlIDxxYXBwbGljYXRpb24uaD4KI2luY2x1ZGUgPHFwZS9xcGVhcHBsaWNhdGlvbi5oPgoKI2luY2x1ZGUgIlNETF90aW1lci5oIgoKI2luY2x1ZGUgIlNETF9RV2luLmgiCgpleHRlcm4gIkMiIHsKCiNpbmNsdWRlICIuLi9TRExfc3lzdmlkZW8uaCIKI2luY2x1ZGUgIi4uLy4uL2V2ZW50cy9TRExfZXZlbnRzX2MuaCIKI2luY2x1ZGUgIlNETF9zeXNldmVudHNfYy5oIgojaW5jbHVkZSAiU0RMX3N5c21vdXNlX2MuaCIKI2luY2x1ZGUgIlNETF9zeXN3bV9jLmgiCiNpbmNsdWRlICJTRExfbG93dmlkZW8uaCIKCiAgLy8jZGVmaW5lIFFUT1BJQV9ERUJVRwojZGVmaW5lIFFUX0hJRERFTl9TSVpFCTMyCS8qIHN0YXJ0aW5nIGhpZGRlbiB3aW5kb3cgc2l6ZSAqLwoKICAvKiBOYW1lIG9mIHRoZSBlbnZpcm9ubWVudCB2YXJpYWJsZSB1c2VkIHRvIGludmVydCB0aGUgc2NyZWVuIHJvdGF0aW9uIG9yIG5vdDoKICAgICBQb3NzaWJsZSB2YWx1ZXM6CiAgICAgIT0wIDogU2NyZWVuIGlzIDI3MLAgcm90YXRlZAogICAgIDA6IFNjcmVlbiBpcyA5MLAgcm90YXRlZCovCiNkZWZpbmUgU0RMX1FUX1JPVEFUSU9OX0VOVl9OQU1FICJTRExfUVRfSU5WRVJUX1JPVEFUSU9OIgogIAogIC8qIEluaXRpYWxpemF0aW9uL1F1ZXJ5IGZ1bmN0aW9ucyAqLwogIHN0YXRpYyBpbnQgUVRfVmlkZW9Jbml0KF9USElTLCBTRExfUGl4ZWxGb3JtYXQgKnZmb3JtYXQpOwogIHN0YXRpYyBTRExfUmVjdCAqKlFUX0xpc3RNb2RlcyhfVEhJUywgU0RMX1BpeGVsRm9ybWF0ICpmb3JtYXQsIFVpbnQzMiBmbGFncyk7CiAgc3RhdGljIFNETF9TdXJmYWNlICpRVF9TZXRWaWRlb01vZGUoX1RISVMsIFNETF9TdXJmYWNlICpjdXJyZW50LCBpbnQgd2lkdGgsIGludCBoZWlnaHQsIGludCBicHAsIFVpbnQzMiBmbGFncyk7CiAgc3RhdGljIHZvaWQgUVRfVXBkYXRlTW91c2UoX1RISVMpOwogIHN0YXRpYyBpbnQgUVRfU2V0Q29sb3JzKF9USElTLCBpbnQgZmlyc3Rjb2xvciwgaW50IG5jb2xvcnMsIFNETF9Db2xvciAqY29sb3JzKTsKICBzdGF0aWMgdm9pZCBRVF9WaWRlb1F1aXQoX1RISVMpOwoKICAvKiBIYXJkd2FyZSBzdXJmYWNlIGZ1bmN0aW9ucyAqLwogIHN0YXRpYyBpbnQgUVRfQWxsb2NIV1N1cmZhY2UoX1RISVMsIFNETF9TdXJmYWNlICpzdXJmYWNlKTsKICBzdGF0aWMgaW50IFFUX0xvY2tIV1N1cmZhY2UoX1RISVMsIFNETF9TdXJmYWNlICpzdXJmYWNlKTsKICBzdGF0aWMgdm9pZCBRVF9VbmxvY2tIV1N1cmZhY2UoX1RISVMsIFNETF9TdXJmYWNlICpzdXJmYWNlKTsKICBzdGF0aWMgdm9pZCBRVF9GcmVlSFdTdXJmYWNlKF9USElTLCBTRExfU3VyZmFjZSAqc3VyZmFjZSk7CgogIHN0YXRpYyBpbnQgUVRfVG9nZ2xlRnVsbFNjcmVlbihfVEhJUywgaW50IGZ1bGxzY3JlZW4pOwoKICBzdGF0aWMgaW50IFFUX0ljb25pZnlXaW5kb3coX1RISVMpOwogIHN0YXRpYyBTRExfR3JhYk1vZGUgUVRfR3JhYklucHV0KF9USElTLCBTRExfR3JhYk1vZGUgbW9kZSk7CgogIC8qIEZCIGRyaXZlciBib290c3RyYXAgZnVuY3Rpb25zICovCgogIHN0YXRpYyBpbnQgUVRfQXZhaWxhYmxlKHZvaWQpCiAgewogICAgcmV0dXJuKDEpOwogIH0KCiAgc3RhdGljIHZvaWQgUVRfRGVsZXRlRGV2aWNlKFNETF9WaWRlb0RldmljZSAqZGV2aWNlKQogIHsKICAgIFNETF9mcmVlKGRldmljZS0+aGlkZGVuKTsKICAgIFNETF9mcmVlKGRldmljZSk7CiAgfQoKICBzdGF0aWMgU0RMX1ZpZGVvRGV2aWNlICpRVF9DcmVhdGVEZXZpY2UoaW50IGRldmluZGV4KQogIHsKICAgIFNETF9WaWRlb0RldmljZSAqZGV2aWNlOwoKICAgIC8qIEluaXRpYWxpemUgYWxsIHZhcmlhYmxlcyB0aGF0IHdlIGNsZWFuIG9uIHNodXRkb3duICovCiAgICBkZXZpY2UgPSAoU0RMX1ZpZGVvRGV2aWNlICopU0RMX21hbGxvYyhzaXplb2YoU0RMX1ZpZGVvRGV2aWNlKSk7CiAgICBpZiAoIGRldmljZSApIHsKICAgICAgU0RMX21lbXNldChkZXZpY2UsIDAsIChzaXplb2YgKmRldmljZSkpOwogICAgICBkZXZpY2UtPmhpZGRlbiA9IChzdHJ1Y3QgU0RMX1ByaXZhdGVWaWRlb0RhdGEgKikKCVNETF9tYWxsb2MoKHNpemVvZiAqZGV2aWNlLT5oaWRkZW4pKTsKICAgIH0KICAgIGlmICggKGRldmljZSA9PSBOVUxMKSB8fCAoZGV2aWNlLT5oaWRkZW4gPT0gTlVMTCkgKSB7CiAgICAgIFNETF9PdXRPZk1lbW9yeSgpOwogICAgICBpZiAoIGRldmljZSApIHsKCVNETF9mcmVlKGRldmljZSk7CiAgICAgIH0KICAgICAgcmV0dXJuKDApOwogICAgfQogICAgU0RMX21lbXNldChkZXZpY2UtPmhpZGRlbiwgMCwgKHNpemVvZiAqZGV2aWNlLT5oaWRkZW4pKTsKCiAgICAvKiBTZXQgdGhlIGZ1bmN0aW9uIHBvaW50ZXJzICovCiAgICBkZXZpY2UtPlZpZGVvSW5pdCA9IFFUX1ZpZGVvSW5pdDsKICAgIGRldmljZS0+TGlzdE1vZGVzID0gUVRfTGlzdE1vZGVzOwogICAgZGV2aWNlLT5TZXRWaWRlb01vZGUgPSBRVF9TZXRWaWRlb01vZGU7CiAgICBkZXZpY2UtPlVwZGF0ZU1vdXNlID0gUVRfVXBkYXRlTW91c2U7CiAgICBkZXZpY2UtPlNldENvbG9ycyA9IFFUX1NldENvbG9yczsKICAgIGRldmljZS0+VXBkYXRlUmVjdHMgPSBOVUxMOwogICAgZGV2aWNlLT5WaWRlb1F1aXQgPSBRVF9WaWRlb1F1aXQ7CiAgICBkZXZpY2UtPkFsbG9jSFdTdXJmYWNlID0gUVRfQWxsb2NIV1N1cmZhY2U7CiAgICBkZXZpY2UtPkNoZWNrSFdCbGl0ID0gTlVMTDsKICAgIGRldmljZS0+RmlsbEhXUmVjdCA9IE5VTEw7CiAgICBkZXZpY2UtPlNldEhXQ29sb3JLZXkgPSBOVUxMOwogICAgZGV2aWNlLT5TZXRIV0FscGhhID0gTlVMTDsKICAgIGRldmljZS0+TG9ja0hXU3VyZmFjZSA9IFFUX0xvY2tIV1N1cmZhY2U7CiAgICBkZXZpY2UtPlVubG9ja0hXU3VyZmFjZSA9IFFUX1VubG9ja0hXU3VyZmFjZTsKICAgIGRldmljZS0+RmxpcEhXU3VyZmFjZSA9IE5VTEw7CiAgICBkZXZpY2UtPkZyZWVIV1N1cmZhY2UgPSBRVF9GcmVlSFdTdXJmYWNlOwogICAgZGV2aWNlLT5TZXRJY29uID0gTlVMTDsKICAgIGRldmljZS0+U2V0Q2FwdGlvbiA9IFFUX1NldFdNQ2FwdGlvbjsKICAgIGRldmljZS0+SWNvbmlmeVdpbmRvdyA9IFFUX0ljb25pZnlXaW5kb3c7CiAgICBkZXZpY2UtPkdyYWJJbnB1dCA9IFFUX0dyYWJJbnB1dDsKICAgIGRldmljZS0+R2V0V01JbmZvID0gTlVMTDsKICAgIGRldmljZS0+RnJlZVdNQ3Vyc29yID0gUVRfRnJlZVdNQ3Vyc29yOwogICAgZGV2aWNlLT5DcmVhdGVXTUN1cnNvciA9IFFUX0NyZWF0ZVdNQ3Vyc29yOwogICAgZGV2aWNlLT5TaG93V01DdXJzb3IgPSBRVF9TaG93V01DdXJzb3I7CiAgICBkZXZpY2UtPldhcnBXTUN1cnNvciA9IFFUX1dhcnBXTUN1cnNvcjsKICAgIGRldmljZS0+SW5pdE9TS2V5bWFwID0gUVRfSW5pdE9TS2V5bWFwOwogICAgZGV2aWNlLT5QdW1wRXZlbnRzID0gUVRfUHVtcEV2ZW50czsKCiAgICBkZXZpY2UtPmZyZWUgPSBRVF9EZWxldGVEZXZpY2U7CiAgICBkZXZpY2UtPlRvZ2dsZUZ1bGxTY3JlZW4gPSBRVF9Ub2dnbGVGdWxsU2NyZWVuOwoKICAgIC8qIFNldCB0aGUgZHJpdmVyIGZsYWdzICovCiAgICBkZXZpY2UtPmhhbmRsZXNfYW55X3NpemUgPSAwOwoJCiAgICByZXR1cm4gZGV2aWNlOwogIH0KCiAgVmlkZW9Cb290U3RyYXAgUXRvcGlhX2Jvb3RzdHJhcCA9IHsKICAgICJxdG9waWEiLCAiUXRvcGlhIC8gUVBFIGdyYXBoaWNzIiwKICAgIFFUX0F2YWlsYWJsZSwgUVRfQ3JlYXRlRGV2aWNlCiAgfTsKCiAgLyogRnVuY3Rpb24gdG8gc29ydCB0aGUgZGlzcGxheV9saXN0ICovCiAgc3RhdGljIGludCBDb21wYXJlTW9kZXMoY29uc3Qgdm9pZCAqQSwgY29uc3Qgdm9pZCAqQikKICB7CiNpZiAwCiAgICBjb25zdCBkaXNwbGF5X21vZGUgKmEgPSAoZGlzcGxheV9tb2RlICopQTsKICAgIGNvbnN0IGRpc3BsYXlfbW9kZSAqYiA9IChkaXNwbGF5X21vZGUgKilCOwoKICAgIGlmICggYS0+c3BhY2UgPT0gYi0+c3BhY2UgKSB7CiAgICAgIHJldHVybigoYi0+dmlydHVhbF93aWR0aCpiLT52aXJ0dWFsX2hlaWdodCktCgkgICAgIChhLT52aXJ0dWFsX3dpZHRoKmEtPnZpcnR1YWxfaGVpZ2h0KSk7CiAgICB9IGVsc2UgewogICAgICByZXR1cm4oQ29sb3JTcGFjZVRvQml0c1BlclBpeGVsKGItPnNwYWNlKS0KCSAgICAgQ29sb3JTcGFjZVRvQml0c1BlclBpeGVsKGEtPnNwYWNlKSk7CiAgICB9CiNlbmRpZgogICAgcmV0dXJuIDA7CiAgfQoKICAvKiBZZXMsIHRoaXMgaXNuJ3QgdGhlIGZhc3Rlc3QgaXQgY291bGQgYmUsIGJ1dCBpdCB3b3JrcyBuaWNlbHkgKi8KICBzdGF0aWMgaW50IFFUX0FkZE1vZGUoX1RISVMsIGludCBpbmRleCwgdW5zaWduZWQgaW50IHcsIHVuc2lnbmVkIGludCBoKQogIHsKICAgIFNETF9SZWN0ICptb2RlOwogICAgaW50IGk7CiAgICBpbnQgbmV4dF9tb2RlOwoKICAgIC8qIENoZWNrIHRvIHNlZSBpZiB3ZSBhbHJlYWR5IGhhdmUgdGhpcyBtb2RlICovCiAgICBpZiAoIFNETF9udW1tb2Rlc1tpbmRleF0gPiAwICkgewogICAgICBmb3IgKCBpPVNETF9udW1tb2Rlc1tpbmRleF0tMTsgaSA+PSAwOyAtLWkgKSB7Cgltb2RlID0gU0RMX21vZGVsaXN0W2luZGV4XVtpXTsKCWlmICggKG1vZGUtPncgPT0gdykgJiYgKG1vZGUtPmggPT0gaCkgKSB7CgkgIHJldHVybigwKTsKCX0KICAgICAgfQogICAgfQoKICAgIC8qIFNldCB1cCB0aGUgbmV3IHZpZGVvIG1vZGUgcmVjdGFuZ2xlICovCiAgICBtb2RlID0gKFNETF9SZWN0ICopU0RMX21hbGxvYyhzaXplb2YgKm1vZGUpOwogICAgaWYgKCBtb2RlID09IE5VTEwgKSB7CiAgICAgIFNETF9PdXRPZk1lbW9yeSgpOwogICAgICByZXR1cm4oLTEpOwogICAgfQogICAgbW9kZS0+eCA9IDA7CiAgICBtb2RlLT55ID0gMDsKICAgIG1vZGUtPncgPSB3OwogICAgbW9kZS0+aCA9IGg7CiNpZmRlZiBRVE9QSUFfREVCVUcKICAgIGZwcmludGYoc3RkZXJyLCAiQWRkaW5nIG1vZGUgJWR4JWQgYXQgJWQgYnl0ZXMgcGVyIHBpeGVsXG4iLCB3LCBoLCBpbmRleCsxKTsKI2VuZGlmCgogICAgLyogQWxsb2NhdGUgdGhlIG5ldyBsaXN0IG9mIG1vZGVzLCBhbmQgZmlsbCBpbiB0aGUgbmV3IG1vZGUgKi8KICAgIG5leHRfbW9kZSA9IFNETF9udW1tb2Rlc1tpbmRleF07CiAgICBTRExfbW9kZWxpc3RbaW5kZXhdID0gKFNETF9SZWN0ICoqKQogICAgICBTRExfcmVhbGxvYyhTRExfbW9kZWxpc3RbaW5kZXhdLCAoMStuZXh0X21vZGUrMSkqc2l6ZW9mKFNETF9SZWN0ICopKTsKICAgIGlmICggU0RMX21vZGVsaXN0W2luZGV4XSA9PSBOVUxMICkgewogICAgICBTRExfT3V0T2ZNZW1vcnkoKTsKICAgICAgU0RMX251bW1vZGVzW2luZGV4XSA9IDA7CiAgICAgIFNETF9mcmVlKG1vZGUpOwogICAgICByZXR1cm4oLTEpOwogICAgfQogICAgU0RMX21vZGVsaXN0W2luZGV4XVtuZXh0X21vZGVdID0gbW9kZTsKICAgIFNETF9tb2RlbGlzdFtpbmRleF1bbmV4dF9tb2RlKzFdID0gTlVMTDsKICAgIFNETF9udW1tb2Rlc1tpbmRleF0rKzsKCiAgICByZXR1cm4oMCk7CiAgfQoKICBpbnQgUVRfVmlkZW9Jbml0KF9USElTLCBTRExfUGl4ZWxGb3JtYXQgKnZmb3JtYXQpCiAgewogICAgLyogSW5pdGlhbGl6ZSB0aGUgUVBFIEFwcGxpY2F0aW9uICAqLwogICAgIC8qIERldGVybWluZSB0aGUgc2NyZWVuIGRlcHRoICovCiAgICB2Zm9ybWF0LT5CaXRzUGVyUGl4ZWwgPSBRUGl4bWFwOjpkZWZhdWx0RGVwdGgoKTsKCiAgICAvLyBGb3Igbm93IHdlIGhhcmRjb2RlIHRoZSBjdXJyZW50IGRlcHRoIGJlY2F1c2UgYW55dGhpbmcgZWxzZQogICAgLy8gbWlnaHQgYXMgd2VsbCBiZSBlbXVsYXRlZCBieSBTREwgcmF0aGVyIHRoYW4gYnkgUXRvcGlhLgogICAgCiAgICBRU2l6ZSBkZXNrdG9wX3NpemUgPSBxQXBwLT5kZXNrdG9wKCktPnNpemUoKTsKICAgIFFUX0FkZE1vZGUoX3RoaXMsICgodmZvcm1hdC0+Qml0c1BlclBpeGVsKzcpLzgpLTEsCgkgICAgICAgZGVza3RvcF9zaXplLndpZHRoKCksIGRlc2t0b3Bfc2l6ZS5oZWlnaHQoKSk7CiAgICBRVF9BZGRNb2RlKF90aGlzLCAoKHZmb3JtYXQtPkJpdHNQZXJQaXhlbCs3KS84KS0xLAoJICAgICAgIGRlc2t0b3Bfc2l6ZS5oZWlnaHQoKSwgZGVza3RvcF9zaXplLndpZHRoKCkpOwoKICAgIC8qIERldGVybWluZSB0aGUgY3VycmVudCBzY3JlZW4gc2l6ZSAqLwogICAgX3RoaXMtPmluZm8uY3VycmVudF93ID0gZGVza3RvcF9zaXplLndpZHRoKCk7CiAgICBfdGhpcy0+aW5mby5jdXJyZW50X2ggPSBkZXNrdG9wX3NpemUuaGVpZ2h0KCk7CgogICAgLyogQ3JlYXRlIHRoZSB3aW5kb3cgLyB3aWRnZXQgKi8KICAgIFNETF9XaW4gPSBuZXcgU0RMX1FXaW4oUVNpemUoUVRfSElEREVOX1NJWkUsIFFUX0hJRERFTl9TSVpFKSk7CiAgICAoKFFQRUFwcGxpY2F0aW9uKilxQXBwKS0+c2hvd01haW5XaWRnZXQoU0RMX1dpbik7CiAgICAvKiBGaWxsIGluIHNvbWUgd2luZG93IG1hbmFnZXIgY2FwYWJpbGl0aWVzICovCiAgICBfdGhpcy0+aW5mby53bV9hdmFpbGFibGUgPSAwOwoKICAgIC8qIFdlJ3JlIGRvbmUhICovCiAgICByZXR1cm4oMCk7CiAgfQoKICAvKiBXZSBzdXBwb3J0IGFueSBkaW1lbnNpb24gYXQgb3VyIGJpdC1kZXB0aCAqLwogIFNETF9SZWN0ICoqUVRfTGlzdE1vZGVzKF9USElTLCBTRExfUGl4ZWxGb3JtYXQgKmZvcm1hdCwgVWludDMyIGZsYWdzKQogIHsKICAgIFNETF9SZWN0ICoqbW9kZXM7CgogICAgbW9kZXMgPSAoKFNETF9SZWN0ICoqKTApOwogICAgaWYgKCAoZmxhZ3MgJiBTRExfRlVMTFNDUkVFTikgPT0gU0RMX0ZVTExTQ1JFRU4gKSB7CiAgICAgIG1vZGVzID0gU0RMX21vZGVsaXN0WygoZm9ybWF0LT5CaXRzUGVyUGl4ZWwrNykvOCktMV07CiAgICB9IGVsc2UgewogICAgICBpZiAoIGZvcm1hdC0+Qml0c1BlclBpeGVsID09CgkgICBfdGhpcy0+c2NyZWVuLT5mb3JtYXQtPkJpdHNQZXJQaXhlbCApIHsKCW1vZGVzID0gKChTRExfUmVjdCAqKiktMSk7CiAgICAgIH0KICAgIH0KICAgIHJldHVybihtb2Rlcyk7CiAgfQoKICAvKiBWYXJpb3VzIHNjcmVlbiB1cGRhdGUgZnVuY3Rpb25zIGF2YWlsYWJsZSAqLwogIHN0YXRpYyB2b2lkIFFUX05vcm1hbFVwZGF0ZShfVEhJUywgaW50IG51bXJlY3RzLCBTRExfUmVjdCAqcmVjdHMpOwoKCiAgc3RhdGljIGludCBRVF9TZXRGdWxsU2NyZWVuKF9USElTLCBTRExfU3VyZmFjZSAqc2NyZWVuLCBpbnQgZnVsbHNjcmVlbikKICB7CiAgICByZXR1cm4gLTE7CiAgfQoKICBzdGF0aWMgaW50IFFUX1RvZ2dsZUZ1bGxTY3JlZW4oX1RISVMsIGludCBmdWxsc2NyZWVuKQogIHsKICAgIHJldHVybiAtMTsKICB9CgogIC8qIEZJWE1FOiBjaGVjayByZXR1cm4gdmFsdWVzIGFuZCBjbGVhbnVwIGhlcmUgKi8KICBTRExfU3VyZmFjZSAqUVRfU2V0VmlkZW9Nb2RlKF9USElTLCBTRExfU3VyZmFjZSAqY3VycmVudCwKCQkJICAgICAgIGludCB3aWR0aCwgaW50IGhlaWdodCwgaW50IGJwcCwgVWludDMyIGZsYWdzKQogIHsKCiAgICBRSW1hZ2UgKnFpbWFnZTsKICAgIFFTaXplIGRlc2t0b3Bfc2l6ZSA9IHFBcHAtPmRlc2t0b3AoKS0+c2l6ZSgpOwoKICAgIAogICAgY3VycmVudC0+ZmxhZ3MgPSAwOyAvL1NETF9GVUxMU0NSRUVOOyAvLyBXZSBhbHdheXMgcnVuIGZ1bGxzY3JlZW4uCgogICAgaWYod2lkdGggPD0gZGVza3RvcF9zaXplLndpZHRoKCkKCSAgICAgICYmIGhlaWdodCA8PSBkZXNrdG9wX3NpemUuaGVpZ2h0KCkpIHsKICAgICAgY3VycmVudC0+dyA9IGRlc2t0b3Bfc2l6ZS53aWR0aCgpOwogICAgICBjdXJyZW50LT5oID0gZGVza3RvcF9zaXplLmhlaWdodCgpOwogICAgfSBlbHNlIGlmKHdpZHRoIDw9IGRlc2t0b3Bfc2l6ZS5oZWlnaHQoKSAmJiBoZWlnaHQgPD0gZGVza3RvcF9zaXplLndpZHRoKCkpIHsKICAgICAgLy8gTGFuZHNjYXBlIG1vZGUKICAgICAgY2hhciAqIGVudlN0cmluZyA9IFNETF9nZXRlbnYoU0RMX1FUX1JPVEFUSU9OX0VOVl9OQU1FKTsKICAgICAgaW50IGVudlZhbHVlID0gZW52U3RyaW5nID8gYXRvaShlbnZTdHJpbmcpIDogMDsKICAgICAgc2NyZWVuUm90YXRpb24gPSBlbnZWYWx1ZSA/IFNETF9RVF9ST1RBVElPTl8yNzAgOiBTRExfUVRfUk9UQVRJT05fOTA7CiAgICAgIGN1cnJlbnQtPmggPSBkZXNrdG9wX3NpemUud2lkdGgoKTsKICAgICAgY3VycmVudC0+dyA9IGRlc2t0b3Bfc2l6ZS5oZWlnaHQoKTsKICAgIH0gZWxzZSB7CiAgICAgIFNETF9TZXRFcnJvcigiVW5zdXBwb3J0ZWQgcmVzb2x1dGlvbiwgJWR4JWRcbiIsIHdpZHRoLCBoZWlnaHQpOwogICAgfQogICAgaWYgKCBmbGFncyAmIFNETF9PUEVOR0wgKSB7CiAgICAgIFNETF9TZXRFcnJvcigiT3BlbkdMIG5vdCBzdXBwb3J0ZWQiKTsKICAgICAgcmV0dXJuKE5VTEwpOwogICAgfSAKICAgIC8qIENyZWF0ZSB0aGUgUUltYWdlIGZyYW1lYnVmZmVyICovCiAgICBxaW1hZ2UgPSBuZXcgUUltYWdlKGN1cnJlbnQtPncsIGN1cnJlbnQtPmgsIGJwcCk7CiAgICBpZiAocWltYWdlLT5pc051bGwoKSkgewogICAgICBTRExfU2V0RXJyb3IoIkNvdWxkbid0IGNyZWF0ZSBzY3JlZW4gYml0bWFwIik7CiAgICAgIGRlbGV0ZSBxaW1hZ2U7CiAgICAgIHJldHVybihOVUxMKTsKICAgIH0KICAgIGN1cnJlbnQtPnBpdGNoID0gcWltYWdlLT5ieXRlc1BlckxpbmUoKTsKICAgIGN1cnJlbnQtPnBpeGVscyA9ICh2b2lkICopcWltYWdlLT5iaXRzKCk7CiAgICBTRExfV2luLT5zZXRJbWFnZShxaW1hZ2UpOwogICAgX3RoaXMtPlVwZGF0ZVJlY3RzID0gUVRfTm9ybWFsVXBkYXRlOwogICAgU0RMX1dpbi0+c2V0RnVsbHNjcmVlbih0cnVlKTsKICAgIC8qIFdlJ3JlIGRvbmUgKi8KICAgIHJldHVybihjdXJyZW50KTsKICB9CgogIC8qIFVwZGF0ZSB0aGUgY3VycmVudCBtb3VzZSBzdGF0ZSBhbmQgcG9zaXRpb24gKi8KICB2b2lkIFFUX1VwZGF0ZU1vdXNlKF9USElTKQogIHsKICAgIFFQb2ludCBwb2ludCgtMSwgLTEpOwogICAgaWYgKCBTRExfV2luLT5pc0FjdGl2ZVdpbmRvdygpICkgewogICAgICBwb2ludCA9IFNETF9XaW4tPm1vdXNlUG9zKCk7CiAgICB9CiAgICAKICAgIGlmICggKHBvaW50LngoKSA+PSAwKSAmJiAocG9pbnQueCgpIDwgU0RMX1ZpZGVvU3VyZmFjZS0+dykgJiYKCSAocG9pbnQueSgpID49IDApICYmIChwb2ludC55KCkgPCBTRExfVmlkZW9TdXJmYWNlLT5oKSApIHsKICAgICAgU0RMX1ByaXZhdGVBcHBBY3RpdmUoMSwgU0RMX0FQUE1PVVNFRk9DVVMpOwogICAgICBTRExfUHJpdmF0ZU1vdXNlTW90aW9uKDAsIDAsCgkJCSAgICAgKFNpbnQxNilwb2ludC54KCksIChTaW50MTYpcG9pbnQueSgpKTsKICAgIH0gZWxzZSB7CiAgICAgIFNETF9Qcml2YXRlQXBwQWN0aXZlKDAsIFNETF9BUFBNT1VTRUZPQ1VTKTsKICAgIH0KICB9CgogIC8qIFdlIGRvbid0IGFjdHVhbGx5IGFsbG93IGhhcmR3YXJlIHN1cmZhY2VzIG90aGVyIHRoYW4gdGhlIG1haW4gb25lICovCiAgc3RhdGljIGludCBRVF9BbGxvY0hXU3VyZmFjZShfVEhJUywgU0RMX1N1cmZhY2UgKnN1cmZhY2UpCiAgewogICAgcmV0dXJuKC0xKTsKICB9CiAgc3RhdGljIHZvaWQgUVRfRnJlZUhXU3VyZmFjZShfVEhJUywgU0RMX1N1cmZhY2UgKnN1cmZhY2UpCiAgewogICAgcmV0dXJuOwogIH0KICBzdGF0aWMgaW50IFFUX0xvY2tIV1N1cmZhY2UoX1RISVMsIFNETF9TdXJmYWNlICpzdXJmYWNlKQogIHsKICAgIHJldHVybigwKTsKICB9CiAgc3RhdGljIHZvaWQgUVRfVW5sb2NrSFdTdXJmYWNlKF9USElTLCBTRExfU3VyZmFjZSAqc3VyZmFjZSkKICB7CiAgICByZXR1cm47CiAgfQoKICBzdGF0aWMgdm9pZCBRVF9Ob3JtYWxVcGRhdGUoX1RISVMsIGludCBudW1yZWN0cywgU0RMX1JlY3QgKnJlY3RzKQogIHsKICAgIGlmKFNETF9XaW4tPmxvY2tTY3JlZW4oKSkgewogICAgICBmb3IoaW50IGk9MDsgaTxudW1yZWN0czsgKytpICkgewoJUVJlY3QgcmVjdChyZWN0c1tpXS54LCByZWN0c1tpXS55LAoJCSAgIHJlY3RzW2ldLncsIHJlY3RzW2ldLmgpOwoJU0RMX1dpbi0+cmVwYWludFJlY3QocmVjdCk7CiAgICAgIH0KICAgICAgU0RMX1dpbi0+dW5sb2NrU2NyZWVuKCk7CiAgICB9CiAgfQogIC8qIElzIHRoZSBzeXN0ZW0gcGFsZXR0ZSBzZXR0YWJsZT8gKi8KICBpbnQgUVRfU2V0Q29sb3JzKF9USElTLCBpbnQgZmlyc3Rjb2xvciwgaW50IG5jb2xvcnMsIFNETF9Db2xvciAqY29sb3JzKQogIHsKICAgIHJldHVybiAtMTsKICB9CgogIHZvaWQgUVRfVmlkZW9RdWl0KF9USElTKQogIHsKICAgIC8vIFRoaXMgaXMgZHVtYiwgYnV0IGlmIEkgZnJlZSB0aGlzLCB0aGUgYXBwIGRvZXNuJ3QgZXhpdCBjb3JyZWN0bHkuCiAgICAvLyBPZiBjb3Vyc2UsIHRoaXMgd2lsbCBsZWFrIG1lbW9yeSBpZiBpbml0IHZpZGVvIGlzIGRvbmUgbW9yZSB0aGFuIG9uY2UuCiAgICAvLyBTdWNrcyBidXQgc3VjaCBpcyBsaWZlLgogICAgCiAgICAvLyAgICAtLSBEYXZpZCBIZWRib3IKICAgIC8vICAgIGRlbGV0ZSBTRExfV2luOyAKICAgIC8vICAgIFNETF9XaW4gPSAwOwogICAgX3RoaXMtPnNjcmVlbi0+cGl4ZWxzID0gTlVMTDsKICAgIFFUX0dyYWJJbnB1dChfdGhpcywgU0RMX0dSQUJfT0ZGKTsKICB9CgogIHN0YXRpYyBpbnQgUVRfSWNvbmlmeVdpbmRvdyhfVEhJUykgewogICAgU0RMX1dpbi0+aGlkZSgpOwogICAgCiAgICByZXR1cm4gdHJ1ZTsKICB9CgogIHN0YXRpYyBTRExfR3JhYk1vZGUgUVRfR3JhYklucHV0KF9USElTLCBTRExfR3JhYk1vZGUgbW9kZSkgewogICAgaWYobW9kZSA9PSBTRExfR1JBQl9PRkYpIHsKICAgICAgUVBFQXBwbGljYXRpb246OmdyYWJLZXlib2FyZCgpOwogICAgICBxQXBwLT5wcm9jZXNzRXZlbnRzKCk7CiAgICAgIFFQRUFwcGxpY2F0aW9uOjp1bmdyYWJLZXlib2FyZCgpOwogICAgfSBlbHNlIHsKICAgICAgUVBFQXBwbGljYXRpb246OmdyYWJLZXlib2FyZCgpOwogICAgfQogICAgcUFwcC0+cHJvY2Vzc0V2ZW50cygpOwogICAgcmV0dXJuIG1vZGU7CiAgfQogIAp9OyAvKiBFeHRlcm4gQyAqLwo=