LyoKICogRE9TIGludGVycnVwdCAxNmggaGFuZGxlcgogKgogKiBDb3B5cmlnaHQgMTk5OCBKb3NlcGggUHJhbmV2aWNoCiAqIENvcHlyaWdodCAxOTk5IE92ZSBL5XZlbgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2lmZGVmIEhBVkVfVU5JU1REX0gKIyBpbmNsdWRlIDx1bmlzdGQuaD4KI2VuZGlmCgojaW5jbHVkZSAiZG9zZXhlLmgiCiNpbmNsdWRlICJ3aW5jb24uaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luZ2RpLmgiCiNpbmNsdWRlICJ3aW51c2VyLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChpbnQpOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJICAgIERPU1ZNX0ludDE2SGFuZGxlciAoV0lORURPUzE2LjEyMikKICoKICogSGFuZGxlciBmb3IgaW50IDE2aCAoa2V5Ym9hcmQpCiAqCiAqIE5PVEU6CiAqCiAqICAgIEtFWUIuQ09NIChET1MgPjMuMikgYWRkcyBmdW5jdGlvbnMgdG8gdGhpcyBpbnRlcnJ1cHQsIHRoZXkgYXJlCiAqICAgIG5vdCBjdXJyZW50bHkgbGlzdGVkIGhlcmUuCiAqLwoKdm9pZCBXSU5BUEkgRE9TVk1fSW50MTZIYW5kbGVyKCBDT05URVhUODYgKmNvbnRleHQgKQp7CiAgIEJJT1NEQVRBICpkYXRhID0gTlVMTDsKICAgQllURSBhc2NpaSwgc2NhbjsKCiAgIHN3aXRjaCBBSF9yZWcoY29udGV4dCkgewoKICAgY2FzZSAweDAwOiAvKiBHZXQgS2V5c3Ryb2tlICovCiAgICAgIC8qIFJldHVybnM6IEFIID0gU2NhbiBjb2RlCiAgICAgICAgICAgICAgICAgIEFMID0gQVNDSUkgY2hhcmFjdGVyICovCiAgICAgIFRSQUNFKCJHZXQgS2V5c3Ryb2tlXG4iKTsKICAgICAgRE9TVk1fSW50MTZSZWFkQ2hhcigmYXNjaWksICZzY2FuLCBjb250ZXh0KTsKICAgICAgU0VUX0FMKCBjb250ZXh0LCBhc2NpaSApOwogICAgICBTRVRfQUgoIGNvbnRleHQsIHNjYW4gKTsKICAgICAgYnJlYWs7CgogICBjYXNlIDB4MDE6IC8qIENoZWNrIGZvciBLZXlzdHJva2UgKi8KICAgICAgLyogUmV0dXJuczogWkYgc2V0IGlmIG5vIGtleXN0cm9rZSAqLwogICAgICAvKiAgICAgICAgICBBSCA9IFNjYW4gY29kZSAqLwogICAgICAvKiAgICAgICAgICBBTCA9IEFTQ0lJIGNoYXJhY3RlciAqLwogICAgICBUUkFDRSgiQ2hlY2sgZm9yIEtleXN0cm9rZVxuIik7CiAgICAgIGlmICghRE9TVk1fSW50MTZSZWFkQ2hhcigmYXNjaWksICZzY2FuLCBOVUxMKSkKICAgICAgewogICAgICAgICAgU0VUX1pGTEFHKGNvbnRleHQpOwogICAgICB9CiAgICAgIGVsc2UKICAgICAgewogICAgICAgICAgU0VUX0FMKCBjb250ZXh0LCBhc2NpaSApOwogICAgICAgICAgU0VUX0FIKCBjb250ZXh0LCBzY2FuICk7CiAgICAgICAgICBSRVNFVF9aRkxBRyhjb250ZXh0KTsKICAgICAgfQogICAgICAvKiBkb24ndCBtaXNzIHRoZSBvcHBvcnR1bml0eSB0byBicmVhayBzb21lIHRpZ2h0IHRpbWluZyBsb29wIGluIERPUwogICAgICAgKiBwcm9ncmFtcyBjYXVzaW5nIDEwMCUgQ1BVIHVzYWdlIChieSBkb2luZyBhIFNsZWVwIGhlcmUpICovCiAgICAgIFNsZWVwKDUpOwogICAgICBicmVhazsKCiAgIGNhc2UgMHgwMjogLyogR2V0IFNoaWZ0IEZsYWdzICovCgogICAgICAvKiByZWFkIHZhbHVlIGZyb20gQklPUyBkYXRhIHNlZ21lbnQncyBrZXlib2FyZCBzdGF0dXMgZmxhZ3MgZmllbGQgKi8KICAgICAgZGF0YSA9IERPU1ZNX0Jpb3NEYXRhKCk7CiAgICAgIFNFVF9BTCggY29udGV4dCwgZGF0YS0+S2JkRmxhZ3MxICk7CgogICAgICBUUkFDRSgiR2V0IFNoaWZ0IEZsYWdzOiByZXR1cm5pbmcgMHglMDJ4XG4iLCBBTF9yZWcoY29udGV4dCkpOwogICAgICBicmVhazsKCiAgIGNhc2UgMHgwMzogLyogU2V0IFR5cGVtYXRpYyBSYXRlIGFuZCBEZWxheSAqLwogICAgICBGSVhNRSgiU2V0IFR5cGVtYXRpYyBSYXRlIGFuZCBEZWxheSAtIE5vdCBTdXBwb3J0ZWRcbiIpOwogICAgICBicmVhazsKICAgICAgCiAgIGNhc2UgMHgwNTovKnNpbXVsYXRlICBLZXlzdHJva2UqLyAKICAgICAgRklYTUUoIlNpbXVsYXRpbmcgYSBrZXlzdHJva2UgaXMgbm90IHN1cHBvcnRlZCB5ZXRcbiIpOwogICAgICBicmVhazsKCiAgIGNhc2UgMHgwOTogLyogR2V0IEtleWJvYXJkIEZ1bmN0aW9uYWxpdHkgKi8KICAgICAgRklYTUUoIkdldCBLZXlib2FyZCBGdW5jdGlvbmFsaXR5IC0gTm90IFN1cHBvcnRlZFxuIik7CiAgICAgIC8qIEFzIGEgdGVtcG9yYXJ5IG1lYXN1cmUsIHNheSB0aGF0ICJub3RoaW5nIiBpcyBzdXBwb3J0ZWQuLi4gKi8KICAgICAgU0VUX0FMKCBjb250ZXh0LCAwICk7CiAgICAgIGJyZWFrOwoKICAgY2FzZSAweDBhOiAvKiBHZXQgS2V5Ym9hcmQgSUQgKi8KICAgICAgRklYTUUoIkdldCBLZXlib2FyZCBJRCAtIE5vdCBTdXBwb3J0ZWRcbiIpOwogICAgICBicmVhazsKCiAgIGNhc2UgMHgxMDogLyogR2V0IEVuaGFuY2VkIEtleXN0cm9rZSAqLwogICAgICBUUkFDRSgiR2V0IEVuaGFuY2VkIEtleXN0cm9rZSAtIFBhcnRpYWxseSBzdXBwb3J0ZWRcbiIpOwogICAgICAvKiBSZXR1cm5zOiBBSCA9IFNjYW4gY29kZQogICAgICAgICAgICAgICAgICBBTCA9IEFTQ0lJIGNoYXJhY3RlciAqLwogICAgICBET1NWTV9JbnQxNlJlYWRDaGFyKCZhc2NpaSwgJnNjYW4sIGNvbnRleHQpOwogICAgICBTRVRfQUwoIGNvbnRleHQsIGFzY2lpICk7CiAgICAgIFNFVF9BSCggY29udGV4dCwgc2NhbiApOwogICAgICBicmVhazsKCgogICBjYXNlIDB4MTE6IC8qIENoZWNrIGZvciBFbmhhbmNlZCBLZXlzdHJva2UgKi8KICAgICAgLyogUmV0dXJuczogWkYgc2V0IGlmIG5vIGtleXN0cm9rZSAqLwogICAgICAvKiAgICAgICAgICBBSCA9IFNjYW4gY29kZSAqLwogICAgICAvKiAgICAgICAgICBBTCA9IEFTQ0lJIGNoYXJhY3RlciAqLwogICAgICBUUkFDRSgiQ2hlY2sgZm9yIEVuaGFuY2VkIEtleXN0cm9rZSAtIFBhcnRpYWxseSBzdXBwb3J0ZWRcbiIpOwogICAgICBpZiAoIURPU1ZNX0ludDE2UmVhZENoYXIoJmFzY2lpLCAmc2NhbiwgTlVMTCkpCiAgICAgIHsKICAgICAgICAgIFNFVF9aRkxBRyhjb250ZXh0KTsKICAgICAgfQogICAgICBlbHNlCiAgICAgIHsKICAgICAgICAgIFNFVF9BTCggY29udGV4dCwgYXNjaWkgKTsKICAgICAgICAgIFNFVF9BSCggY29udGV4dCwgc2NhbiApOwogICAgICAgICAgUkVTRVRfWkZMQUcoY29udGV4dCk7CiAgICAgIH0KICAgICAgYnJlYWs7CgogICBjYXNlIDB4MTI6IC8qIEdldCBFeHRlbmRlZCBTaGlmdCBTdGF0ZXMgKi8KICAgICAgRklYTUUoIkdldCBFeHRlbmRlZCBTaGlmdCBTdGF0ZXMgLSBOb3QgU3VwcG9ydGVkXG4iKTsKICAgICAgYnJlYWs7CgogICBkZWZhdWx0OgogICAgICBGSVhNRSgiVW5rbm93biBJTlQgMTYgZnVuY3Rpb24gLSAweCV4XG4iLCBBSF9yZWcoY29udGV4dCkpOwogICAgICBicmVhazsKCiAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJICAgIERPU1ZNX0ludDE2UmVhZENoYXIKICoKICogRWl0aGVyIHBlZWsgaW50byBrZXlib2FyZCBidWZmZXIgb3Igd2FpdCBmb3IgbmV4dCBrZXlzdHJva2UuCiAqCiAqIElmIHdhaXRjdHggaXMgTlVMTCwgcmV0dXJuIFRSVUUgaWYgYnVmZmVyIGhhZCBrZXlzdHJva2VzIGFuZAogKiBGQUxTRSBpZiBidWZmZXIgaXMgZW1wdHkuIFJldHVybmVkIGtleXN0cm9rZSB3aWxsIGJlIGxlZnQgaW50byBidWZmZXIuCiAqIAogKiBJZiB3YWl0Y3R4IGlzIG5vbi1OVUxMLCB3YWl0IHVudGlsIGtleXN0cm9rZXMgYXJlIGF2YWlsYWJsZS4KICogUmV0dXJuIHZhbHVlIHdpbGwgYWx3YXlzIGJlIFRSVUUgYW5kIHJldHVybmVkIGtleXN0cm9rZSB3aWxsIGJlCiAqIHJlbW92ZWQgZnJvbSBidWZmZXIuCiAqLwppbnQgV0lOQVBJIERPU1ZNX0ludDE2UmVhZENoYXIoQllURSAqYXNjaWksIEJZVEUgKnNjYW4sIENPTlRFWFQ4NiAqd2FpdGN0eCkKewogICAgQklPU0RBVEEgKmRhdGEgPSBET1NWTV9CaW9zRGF0YSgpOwogICAgV09SRCBDdXJPZnMgPSBkYXRhLT5OZXh0S2JkQ2hhclB0cjsKCiAgICAvKiBjaGVjayBpZiB0aGVyZSdzIGRhdGEgaW4gYnVmZmVyICovCiAgICBpZiAod2FpdGN0eCkKICAgIHsKICAgICAgICAvKiB3YWl0IHVudGlsIGlucHV0IGlzIGF2YWlsYWJsZS4uLiAqLwogICAgICAgIHdoaWxlIChDdXJPZnMgPT0gZGF0YS0+Rmlyc3RLYmRDaGFyUHRyKQogICAgICAgICAgICBET1NWTV9XYWl0KCB3YWl0Y3R4ICk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgaWYgKEN1ck9mcyA9PSBkYXRhLT5GaXJzdEtiZENoYXJQdHIpCiAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICAvKiByZWFkIGZyb20ga2V5Ym9hcmQgcXVldWUgKi8KICAgIFRSQUNFKCAiKCVwLCVwLCVwKSAtPiAlMDJ4ICUwMnhcbiIsIGFzY2lpLCBzY2FuLCB3YWl0Y3R4LAogICAgICAgICAgICgoQllURSopZGF0YSlbQ3VyT2ZzXSwgKChCWVRFKilkYXRhKVtDdXJPZnMrMV0gKTsKCiAgICBpZiAoYXNjaWkpICphc2NpaSA9ICgoQllURSopZGF0YSlbQ3VyT2ZzXTsKICAgIGlmIChzY2FuKSAqc2NhbiA9ICgoQllURSopZGF0YSlbQ3VyT2ZzKzFdOwoKICAgIGlmICh3YWl0Y3R4KSAKICAgIHsKICAgICAgICBDdXJPZnMgKz0gMjsKICAgICAgICBpZiAoQ3VyT2ZzID49IGRhdGEtPktiZEJ1ZmZlckVuZCkgQ3VyT2ZzID0gZGF0YS0+S2JkQnVmZmVyU3RhcnQ7CiAgICAgICAgZGF0YS0+TmV4dEtiZENoYXJQdHIgPSBDdXJPZnM7CiAgICB9CgogICAgcmV0dXJuIFRSVUU7Cn0KCmludCBXSU5BUEkgRE9TVk1fSW50MTZBZGRDaGFyKEJZVEUgYXNjaWksQllURSBzY2FuKQp7CiAgQklPU0RBVEEgKmRhdGEgPSBET1NWTV9CaW9zRGF0YSgpOwogIFdPUkQgQ3VyT2ZzID0gZGF0YS0+Rmlyc3RLYmRDaGFyUHRyOwogIFdPUkQgTmV4dE9mcyA9IEN1ck9mcyArIDI7CgogIFRSQUNFKCIoJTAyeCwlMDJ4KVxuIixhc2NpaSxzY2FuKTsKICBpZiAoTmV4dE9mcyA+PSBkYXRhLT5LYmRCdWZmZXJFbmQpIE5leHRPZnMgPSBkYXRhLT5LYmRCdWZmZXJTdGFydDsKICAvKiBjaGVjayBpZiBidWZmZXIgaXMgZnVsbCAqLwogIGlmIChOZXh0T2ZzID09IGRhdGEtPk5leHRLYmRDaGFyUHRyKSByZXR1cm4gMDsKCiAgLyogb2theSwgaW5zZXJ0IGNoYXJhY3RlciBpbiByaW5nIGJ1ZmZlciAqLwogICgoQllURSopZGF0YSlbQ3VyT2ZzXSA9IGFzY2lpOwogICgoQllURSopZGF0YSlbQ3VyT2ZzKzFdID0gc2NhbjsKCiAgZGF0YS0+Rmlyc3RLYmRDaGFyUHRyID0gTmV4dE9mczsKICByZXR1cm4gMTsKfQo=