LyoKICogWE1TIHYyKyBlbXVsYXRpb24KICoKICogQ29weXJpZ2h0IDE5OTggT3ZlIEvldmVuCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKgogKiBOb3RlOiBUaGlzIFhNUyBlbXVsYXRpb24gaXMgaG9va2VkIHRocm91Z2ggdGhlIERQTUkgaW50ZXJydXB0LgogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKCiNpZmRlZiBIQVZFX1VOSVNURF9ICiMgaW5jbHVkZSA8dW5pc3RkLmg+CiNlbmRpZgojaW5jbHVkZSA8c3RkYXJnLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2luZS93aW5iYXNlMTYuaCIKI2luY2x1ZGUgImRvc2V4ZS5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoaW50MzEpOwoKI2luY2x1ZGUgInBzaHBhY2sxLmgiCgp0eXBlZGVmIHN0cnVjdCB7CiBXT1JEIEhhbmRsZTsKIERXT1JEIE9mZnNldDsKfSBNT1ZFT0ZTOwoKdHlwZWRlZiBzdHJ1Y3QgewogRFdPUkQgTGVuZ3RoOwogTU9WRU9GUyBTb3VyY2U7CiBNT1ZFT0ZTIERlc3Q7Cn0gTU9WRVNUUlVDVDsKCiNpbmNsdWRlICJwb3BwYWNrLmgiCgpzdGF0aWMgQllURSAqIFhNU19PZmZzZXQoIE1PVkVPRlMgKm9mcyApCnsKICAgIGlmIChvZnMtPkhhbmRsZSkgcmV0dXJuIChCWVRFKilHbG9iYWxMb2NrMTYob2ZzLT5IYW5kbGUpK29mcy0+T2Zmc2V0OwogICAgZWxzZSByZXR1cm4gKEJZVEUqKVBUUl9SRUFMX1RPX0xJTihTRUxFQ1RPUk9GKG9mcy0+T2Zmc2V0KSxPRkZTRVRPRihvZnMtPk9mZnNldCkpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkgICAgWE1TX0hhbmRsZXIKICovCgp2b2lkIFdJTkFQSSBYTVNfSGFuZGxlciggQ09OVEVYVDg2ICpjb250ZXh0ICkKewogICAgc3dpdGNoKEFIX3JlZyhjb250ZXh0KSkKICAgIHsKICAgIGNhc2UgMHgwMDogICAvKiBHZXQgWE1TIHZlcnNpb24gbnVtYmVyICovCiAgICAgICAgVFJBQ0UoImdldCBYTVMgdmVyc2lvbiBudW1iZXJcbiIpOwogICAgICAgIFNFVF9BWCggY29udGV4dCwgMHgwMjAwICk7IC8qIDIuMCAqLwogICAgICAgIFNFVF9CWCggY29udGV4dCwgMHgwMDAwICk7IC8qIGludGVybmFsIHJldmlzaW9uICovCiAgICAgICAgU0VUX0RYKCBjb250ZXh0LCAweDAwMDEgKTsgLyogSE1BIGV4aXN0cyAqLwogICAgICAgIGJyZWFrOwogICAgY2FzZSAweDA4OiAgIC8qIFF1ZXJ5IEZyZWUgRXh0ZW5kZWQgTWVtb3J5ICovCiAgICB7CiAgICAgICAgTUVNT1JZU1RBVFVTIHN0YXR1czsKCiAgICAgICAgVFJBQ0UoInF1ZXJ5IGZyZWUgZXh0ZW5kZWQgbWVtb3J5XG4iKTsKICAgICAgICBHbG9iYWxNZW1vcnlTdGF0dXMoICZzdGF0dXMgKTsKICAgICAgICBTRVRfRFgoIGNvbnRleHQsIHN0YXR1cy5kd0F2YWlsVmlydHVhbCA+PiAxMCApOwogICAgICAgIFNFVF9BWCggY29udGV4dCwgc3RhdHVzLmR3QXZhaWxWaXJ0dWFsID4+IDEwICk7CiAgICAgICAgVFJBQ0UoInJldHVybmluZyBsYXJnZXN0ICVkSywgdG90YWwgJWRLXG4iLCBBWF9yZWcoY29udGV4dCksIERYX3JlZyhjb250ZXh0KSk7CiAgICB9CiAgICBicmVhazsKICAgIGNhc2UgMHgwOTogICAvKiBBbGxvY2F0ZSBFeHRlbmRlZCBNZW1vcnkgQmxvY2sgKi8KICAgICAgICBUUkFDRSgiYWxsb2NhdGUgZXh0ZW5kZWQgbWVtb3J5IGJsb2NrICglZEspXG4iLAogICAgICAgICAgICBEWF9yZWcoY29udGV4dCkpOwoJU0VUX0RYKCBjb250ZXh0LCBHbG9iYWxBbGxvYzE2KEdNRU1fTU9WRUFCTEUsIChEV09SRClEWF9yZWcoY29udGV4dCk8PDEwKSApOwoJU0VUX0FYKCBjb250ZXh0LCBEWF9yZWcoY29udGV4dCkgPyAxIDogMCApOwoJaWYgKCFEWF9yZWcoY29udGV4dCkpIFNFVF9CTCggY29udGV4dCwgMHhBMCApOyAvKiBvdXQgb2YgbWVtb3J5ICovCglicmVhazsKICAgIGNhc2UgMHgwYTogICAvKiBGcmVlIEV4dGVuZGVkIE1lbW9yeSBCbG9jayAqLwoJVFJBQ0UoImZyZWUgZXh0ZW5kZWQgbWVtb3J5IGJsb2NrICUwNHhcbiIsRFhfcmVnKGNvbnRleHQpKTsKICAgICAgIGlmKCFEWF9yZWcoY29udGV4dCkgfHwgR2xvYmFsRnJlZTE2KERYX3JlZyhjb250ZXh0KSkpIHsKICAgICAgICAgU0VUX0FYKCBjb250ZXh0LCAwICk7ICAgIC8qIGZhaWx1cmUgKi8KICAgICAgICAgU0VUX0JMKCBjb250ZXh0LCAweGEyICk7IC8qIGludmFsaWQgaGFuZGxlICovCiAgICAgICB9IGVsc2UKICAgICAgICAgU0VUX0FYKCBjb250ZXh0LCAxICk7ICAgIC8qIHN1Y2Nlc3MgKi8KCWJyZWFrOwogICAgY2FzZSAweDBiOiAgIC8qIE1vdmUgRXh0ZW5kZWQgTWVtb3J5IEJsb2NrICovCiAgICB7CglNT1ZFU1RSVUNUKm1vdmU9Q1RYX1NFR19PRkZfVE9fTElOKGNvbnRleHQsCgkgICAgY29udGV4dC0+U2VnRHMsY29udGV4dC0+RXNpKTsKICAgICAgICBCWVRFKnNyYywqZHN0OwogICAgICAgIFRSQUNFKCJtb3ZlIGV4dGVuZGVkIG1lbW9yeSBibG9ja1xuIik7CiAgICAgICAgc3JjPVhNU19PZmZzZXQoJm1vdmUtPlNvdXJjZSk7CiAgICAgICAgZHN0PVhNU19PZmZzZXQoJm1vdmUtPkRlc3QpOwoJbWVtY3B5KGRzdCxzcmMsbW92ZS0+TGVuZ3RoKTsKCWlmIChtb3ZlLT5Tb3VyY2UuSGFuZGxlKSBHbG9iYWxVbmxvY2sxNihtb3ZlLT5Tb3VyY2UuSGFuZGxlKTsKCWlmIChtb3ZlLT5EZXN0LkhhbmRsZSkgR2xvYmFsVW5sb2NrMTYobW92ZS0+RGVzdC5IYW5kbGUpOwoJYnJlYWs7CiAgICB9CiAgICBjYXNlIDB4ODg6ICAgLyogUXVlcnkgQW55IEZyZWUgRXh0ZW5kZWQgTWVtb3J5ICovCiAgICB7CiAgICAgICAgTUVNT1JZU1RBVFVTIHN0YXR1czsKICAgICAgICBTWVNURU1fSU5GTyAgaW5mbzsKCiAgICAgICAgVFJBQ0UoInF1ZXJ5IGFueSBmcmVlIGV4dGVuZGVkIG1lbW9yeVxuIik7CgogICAgICAgIEdsb2JhbE1lbW9yeVN0YXR1cyggJnN0YXR1cyApOwogICAgICAgIEdldFN5c3RlbUluZm8oICZpbmZvICk7CiAgICAgICAgY29udGV4dC0+RWF4ID0gc3RhdHVzLmR3QXZhaWxWaXJ0dWFsID4+IDEwOwogICAgICAgIGNvbnRleHQtPkVkeCA9IHN0YXR1cy5kd0F2YWlsVmlydHVhbCA+PiAxMDsKICAgICAgICBjb250ZXh0LT5FY3ggPSAoRFdPUkQpaW5mby5scE1heGltdW1BcHBsaWNhdGlvbkFkZHJlc3M7CiAgICAgICAgU0VUX0JMKCBjb250ZXh0LCAwICk7IC8qIE5vIGVycm9ycy4gKi8KCiAgICAgICAgVFJBQ0UoInJldHVybmluZyBsYXJnZXN0ICVkSywgdG90YWwgJWRLLCBoaWdoZXN0IDB4JXhcbiIsCiAgICAgICAgICAgICAgY29udGV4dC0+RWF4LCBjb250ZXh0LT5FZHgsIGNvbnRleHQtPkVjeCk7CiAgICB9CiAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgICAgSU5UX0JBUkYoIGNvbnRleHQsIDB4MzEgKTsKICAgICAgICBTRVRfQVgoIGNvbnRleHQsIDB4MDAwMCApOyAvKiBmYWlsdXJlICovCiAgICAgICAgU0VUX0JMKCBjb250ZXh0LCAweDgwICk7ICAgLyogZnVuY3Rpb24gbm90IGltcGxlbWVudGVkICovCiAgICAgICAgYnJlYWs7CiAgICB9Cn0K