LyoKICoJUlBDIE1hbmFnZXIKICoKICogQ29weXJpZ2h0IDIwMDEgIE92ZSBL5XZlbiwgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzCiAqIENvcHlyaWdodCAyMDAyICBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDIwMDUgIE1pa2UgSGVhcm4sIFJvYiBTaGVhcm1hbiBmb3IgQ29kZVdlYXZlcnMKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZS9wb3J0LmgiCgojaW5jbHVkZSA8c3RkYXJnLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KCiNkZWZpbmUgQ09CSk1BQ1JPUwojZGVmaW5lIE5PTkFNRUxFU1NVTklPTgojZGVmaW5lIE5PTkFNRUxFU1NTVFJVQ1QKCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbnN2Yy5oIgojaW5jbHVkZSAib2JqYmFzZS5oIgojaW5jbHVkZSAib2xlMi5oIgojaW5jbHVkZSAicnBjLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAid2lucmVnLmgiCiNpbmNsdWRlICJ3aW5lL3VuaWNvZGUuaCIKCiNpbmNsdWRlICJjb21wb2JqX3ByaXZhdGUuaCIKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChvbGUpOwoKc3RhdGljIHZvaWQgX19SUENfU1RVQiBkaXNwYXRjaF9ycGMoUlBDX01FU1NBR0UgKm1zZyk7CgovKiB3ZSBvbmx5IHVzZSBvbmUgZnVuY3Rpb24gdG8gZGlzcGF0Y2ggY2FsbHMgZm9yIGFsbCBtZXRob2RzIC0gd2UgdXNlIHRoZQogKiBSUENfSUZfT0xFIGZsYWcgdG8gdGVsbCB0aGUgUlBDIHJ1bnRpbWUgdGhhdCB0aGlzIGlzIHRoZSBjYXNlICovCnN0YXRpYyBSUENfRElTUEFUQ0hfRlVOQ1RJT04gcnBjX2Rpc3BhdGNoX3RhYmxlWzFdID0geyBkaXNwYXRjaF9ycGMgfTsgLyogKFJPKSAqLwpzdGF0aWMgUlBDX0RJU1BBVENIX1RBQkxFIHJwY19kaXNwYXRjaCA9IHsgMSwgcnBjX2Rpc3BhdGNoX3RhYmxlIH07IC8qIChSTykgKi8KCnN0YXRpYyBzdHJ1Y3QgbGlzdCByZWdpc3RlcmVkX2ludGVyZmFjZXMgPSBMSVNUX0lOSVQocmVnaXN0ZXJlZF9pbnRlcmZhY2VzKTsgLyogKENTIGNzUmVnSWYpICovCnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OIGNzUmVnSWY7CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OX0RFQlVHIGNzUmVnSWZfZGVidWcgPQp7CiAgICAwLCAwLCAmY3NSZWdJZiwKICAgIHsgJmNzUmVnSWZfZGVidWcuUHJvY2Vzc0xvY2tzTGlzdCwgJmNzUmVnSWZfZGVidWcuUHJvY2Vzc0xvY2tzTGlzdCB9LAogICAgICAwLCAwLCB7IChEV09SRF9QVFIpKF9fRklMRV9fICI6IGRjb20gcmVnaXN0ZXJlZCBzZXJ2ZXIgaW50ZXJmYWNlcyIpIH0KfTsKc3RhdGljIENSSVRJQ0FMX1NFQ1RJT04gY3NSZWdJZiA9IHsgJmNzUmVnSWZfZGVidWcsIC0xLCAwLCAwLCAwLCAwIH07CgpzdGF0aWMgc3RydWN0IGxpc3QgY2hhbm5lbF9ob29rcyA9IExJU1RfSU5JVChjaGFubmVsX2hvb2tzKTsgLyogKENTIGNzQ2hhbm5lbEhvb2spICovCnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OIGNzQ2hhbm5lbEhvb2s7CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OX0RFQlVHIGNzQ2hhbm5lbEhvb2tfZGVidWcgPQp7CiAgICAwLCAwLCAmY3NDaGFubmVsSG9vaywKICAgIHsgJmNzQ2hhbm5lbEhvb2tfZGVidWcuUHJvY2Vzc0xvY2tzTGlzdCwgJmNzQ2hhbm5lbEhvb2tfZGVidWcuUHJvY2Vzc0xvY2tzTGlzdCB9LAogICAgICAwLCAwLCB7IChEV09SRF9QVFIpKF9fRklMRV9fICI6IGNoYW5uZWwgaG9va3MiKSB9Cn07CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OIGNzQ2hhbm5lbEhvb2sgPSB7ICZjc0NoYW5uZWxIb29rX2RlYnVnLCAtMSwgMCwgMCwgMCwgMCB9OwoKc3RhdGljIFdDSEFSIHdzelJwY1RyYW5zcG9ydFtdID0geyduJywnYycsJ2EnLCdsJywncicsJ3AnLCdjJywwfTsKCgpzdHJ1Y3QgcmVnaXN0ZXJlZF9pZgp7CiAgICBzdHJ1Y3QgbGlzdCBlbnRyeTsKICAgIERXT1JEIHJlZnM7IC8qIHJlZiBjb3VudCAqLwogICAgUlBDX1NFUlZFUl9JTlRFUkZBQ0UgSWY7IC8qIGludGVyZmFjZSByZWdpc3RlcmVkIHdpdGggdGhlIFJQQyBydW50aW1lICovCn07CgovKiBnZXQgdGhlIHBpcGUgZW5kcG9pbnQgc3BlY2lmaWVkIG9mIHRoZSBzcGVjaWZpZWQgYXBhcnRtZW50ICovCnN0YXRpYyBpbmxpbmUgdm9pZCBnZXRfcnBjX2VuZHBvaW50KExQV1NUUiBlbmRwb2ludCwgY29uc3QgT1hJRCAqb3hpZCkKewogICAgLyogRklYTUU6IHNob3VsZCBnZXQgZW5kcG9pbnQgZnJvbSBycGNzcyAqLwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHdzekVuZHBvaW50Rm9ybWF0W10gPSB7J1xcJywncCcsJ2knLCdwJywnZScsJ1xcJywnTycsJ0wnLCdFJywnXycsJyUnLCcwJywnOCcsJ2wnLCd4JywnJScsJzAnLCc4JywnbCcsJ3gnLDB9OwogICAgd3NwcmludGZXKGVuZHBvaW50LCB3c3pFbmRwb2ludEZvcm1hdCwgKERXT1JEKSgqb3hpZCA+PiAzMiksKERXT1JEKSpveGlkKTsKfQoKdHlwZWRlZiBzdHJ1Y3QKewogICAgY29uc3QgSVJwY0NoYW5uZWxCdWZmZXJWdGJsICpscFZ0Ymw7CiAgICBMT05HICAgICAgICAgICAgICAgICAgcmVmczsKfSBScGNDaGFubmVsQnVmZmVyOwoKdHlwZWRlZiBzdHJ1Y3QKewogICAgUnBjQ2hhbm5lbEJ1ZmZlciAgICAgICBzdXBlcjsgLyogc3VwZXJjbGFzcyAqLwoKICAgIFJQQ19CSU5ESU5HX0hBTkRMRSAgICAgYmluZDsgLyogaGFuZGxlIHRvIHRoZSByZW1vdGUgc2VydmVyICovCiAgICBPWElEICAgICAgICAgICAgICAgICAgIG94aWQ7IC8qIGFwYXJ0bWVudCBpbiB3aGljaCB0aGUgY2hhbm5lbCBpcyB2YWxpZCAqLwogICAgRFdPUkQgICAgICAgICAgICAgICAgICBzZXJ2ZXJfcGlkOyAvKiBpZCBvZiBzZXJ2ZXIgcHJvY2VzcyAqLwogICAgRFdPUkQgICAgICAgICAgICAgICAgICBkZXN0X2NvbnRleHQ7IC8qIHJldHVybmVkIGZyb20gR2V0RGVzdEN0eCAqLwogICAgTFBWT0lEICAgICAgICAgICAgICAgICBkZXN0X2NvbnRleHRfZGF0YTsgLyogcmV0dXJuZWQgZnJvbSBHZXREZXN0Q3R4ICovCiAgICBIQU5ETEUgICAgICAgICAgICAgICAgIGV2ZW50OyAvKiBjYWNoZWQgZXZlbnQgaGFuZGxlICovCn0gQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlcjsKCnN0cnVjdCBkaXNwYXRjaF9wYXJhbXMKewogICAgUlBDT0xFTUVTU0FHRSAgICAgKm1zZzsgLyogbWVzc2FnZSAqLwogICAgSVJwY1N0dWJCdWZmZXIgICAgKnN0dWI7IC8qIHN0dWIgYnVmZmVyLCBpZiBhcHBsaWNhYmxlICovCiAgICBJUnBjQ2hhbm5lbEJ1ZmZlciAqY2hhbjsgLyogc2VydmVyIGNoYW5uZWwgYnVmZmVyLCBpZiBhcHBsaWNhYmxlICovCiAgICBJSUQgICAgICAgICAgICAgICAgaWlkOyAvKiBJRCBvZiBpbnRlcmZhY2UgYmVpbmcgY2FsbGVkICovCiAgICBJVW5rbm93biAgICAgICAgICAqaWZhY2U7IC8qIGludGVyZmFjZSBiZWluZyBjYWxsZWQgKi8KICAgIEhBTkRMRSAgICAgICAgICAgICBoYW5kbGU7IC8qIGhhbmRsZSB0aGF0IHdpbGwgYmVjb21lIHNpZ25hbGVkIHdoZW4gY2FsbCBmaW5pc2hlcyAqLwogICAgQk9PTCAgICAgICAgICAgICAgIGJ5cGFzc19ycGNydDsgLyogYnlwYXNzIFJQQyBydW50aW1lPyAqLwogICAgUlBDX1NUQVRVUyAgICAgICAgIHN0YXR1czsgLyogc3RhdHVzIChvdXQpICovCiAgICBIUkVTVUxUICAgICAgICAgICAgaHI7IC8qIGhyZXN1bHQgKG91dCkgKi8KfTsKCnN0cnVjdCBtZXNzYWdlX3N0YXRlCnsKICAgIFJQQ19CSU5ESU5HX0hBTkRMRSBiaW5kaW5nX2hhbmRsZTsKICAgIFVMT05HIHByZWZpeF9kYXRhX2xlbjsKICAgIFNDaGFubmVsSG9va0NhbGxJbmZvIGNoYW5uZWxfaG9va19pbmZvOwogICAgQk9PTCBieXBhc3NfcnBjcnQ7CgogICAgLyogY2xpZW50IG9ubHkgKi8KICAgIEhXTkQgdGFyZ2V0X2h3bmQ7CiAgICBEV09SRCB0YXJnZXRfdGlkOwogICAgc3RydWN0IGRpc3BhdGNoX3BhcmFtcyBwYXJhbXM7Cn07Cgp0eXBlZGVmIHN0cnVjdAp7CiAgICBVTE9ORyBjb25mb3JtYW5jZTsgLyogTkRSICovCiAgICBHVUlEIGlkOwogICAgVUxPTkcgc2l6ZTsKICAgIC8qIFtzaXplX2lzKChzaXplKzcpJn43KV0gKi8gdW5zaWduZWQgY2hhciBkYXRhWzFdOwp9IFdJUkVfT1JQQ19FWFRFTlQ7CgpzdHJ1Y3QgY2hhbm5lbF9ob29rX2VudHJ5CnsKICAgIHN0cnVjdCBsaXN0IGVudHJ5OwogICAgR1VJRCBpZDsKICAgIElDaGFubmVsSG9vayAqaG9vazsKfTsKCnN0cnVjdCBjaGFubmVsX2hvb2tfYnVmZmVyX2RhdGEKewogICAgR1VJRCBpZDsKICAgIFVMT05HIGV4dGVuc2lvbl9zaXplOwp9OwoKCnN0YXRpYyBIUkVTVUxUIHVubWFyc2hhbF9PUlBDVEhBVChSUENfTUVTU0FHRSAqbXNnLCBPUlBDVEhBVCAqb3JwY3RoYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPUlBDX0VYVEVOVF9BUlJBWSAqb3JwY19leHRfYXJyYXksIFdJUkVfT1JQQ19FWFRFTlQgKipmaXJzdF93aXJlX29ycGNfZXh0ZW50KTsKCi8qIENoYW5uZWwgSG9vayBGdW5jdGlvbnMgKi8KCnN0YXRpYyBVTE9ORyBDaGFubmVsSG9va3NfQ2xpZW50R2V0U2l6ZShTQ2hhbm5lbEhvb2tDYWxsSW5mbyAqaW5mbywKICAgIHN0cnVjdCBjaGFubmVsX2hvb2tfYnVmZmVyX2RhdGEgKipkYXRhLCB1bnNpZ25lZCBpbnQgKmhvb2tfY291bnQsCiAgICBVTE9ORyAqZXh0ZW5zaW9uX2NvdW50KQp7CiAgICBzdHJ1Y3QgY2hhbm5lbF9ob29rX2VudHJ5ICplbnRyeTsKICAgIFVMT05HIHRvdGFsX3NpemUgPSAwOwogICAgdW5zaWduZWQgaW50IGhvb2tfaW5kZXggPSAwOwoKICAgICpob29rX2NvdW50ID0gMDsKICAgICpleHRlbnNpb25fY291bnQgPSAwOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZjc0NoYW5uZWxIb29rKTsKCiAgICBMSVNUX0ZPUl9FQUNIX0VOVFJZKGVudHJ5LCAmY2hhbm5lbF9ob29rcywgc3RydWN0IGNoYW5uZWxfaG9va19lbnRyeSwgZW50cnkpCiAgICAgICAgKCpob29rX2NvdW50KSsrOwoKICAgIGlmICgqaG9va19jb3VudCkKICAgICAgICAqZGF0YSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCAqaG9va19jb3VudCAqIHNpemVvZihzdHJ1Y3QgY2hhbm5lbF9ob29rX2J1ZmZlcl9kYXRhKSk7CiAgICBlbHNlCiAgICAgICAgKmRhdGEgPSBOVUxMOwoKICAgIExJU1RfRk9SX0VBQ0hfRU5UUlkoZW50cnksICZjaGFubmVsX2hvb2tzLCBzdHJ1Y3QgY2hhbm5lbF9ob29rX2VudHJ5LCBlbnRyeSkKICAgIHsKICAgICAgICBVTE9ORyBleHRlbnNpb25fc2l6ZSA9IDA7CgogICAgICAgIElDaGFubmVsSG9va19DbGllbnRHZXRTaXplKGVudHJ5LT5ob29rLCAmZW50cnktPmlkLCAmaW5mby0+aWlkLCAmZXh0ZW5zaW9uX3NpemUpOwoKICAgICAgICBUUkFDRSgiJXM6IGV4dGVuc2lvbl9zaXplID0gJXVcbiIsIGRlYnVnc3RyX2d1aWQoJmVudHJ5LT5pZCksIGV4dGVuc2lvbl9zaXplKTsKCiAgICAgICAgZXh0ZW5zaW9uX3NpemUgPSAoZXh0ZW5zaW9uX3NpemUrNykmfjc7CiAgICAgICAgKCpkYXRhKVtob29rX2luZGV4XS5pZCA9IGVudHJ5LT5pZDsKICAgICAgICAoKmRhdGEpW2hvb2tfaW5kZXhdLmV4dGVuc2lvbl9zaXplID0gZXh0ZW5zaW9uX3NpemU7CgogICAgICAgIC8qIGFuIGV4dGVuc2lvbiBpcyBvbmx5IHB1dCBvbnRvIHRoZSB3aXJlIGlmIGl0IGhhcyBkYXRhIHRvIHdyaXRlICovCiAgICAgICAgaWYgKGV4dGVuc2lvbl9zaXplKQogICAgICAgIHsKICAgICAgICAgICAgdG90YWxfc2l6ZSArPSBGSUVMRF9PRkZTRVQoV0lSRV9PUlBDX0VYVEVOVCwgZGF0YVtleHRlbnNpb25fc2l6ZV0pOwogICAgICAgICAgICAoKmV4dGVuc2lvbl9jb3VudCkrKzsKICAgICAgICB9CgogICAgICAgIGhvb2tfaW5kZXgrKzsKICAgIH0KCiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmY3NDaGFubmVsSG9vayk7CgogICAgcmV0dXJuIHRvdGFsX3NpemU7Cn0KCnN0YXRpYyB1bnNpZ25lZCBjaGFyICogQ2hhbm5lbEhvb2tzX0NsaWVudEZpbGxCdWZmZXIoU0NoYW5uZWxIb29rQ2FsbEluZm8gKmluZm8sCiAgICB1bnNpZ25lZCBjaGFyICpidWZmZXIsIHN0cnVjdCBjaGFubmVsX2hvb2tfYnVmZmVyX2RhdGEgKmRhdGEsCiAgICB1bnNpZ25lZCBpbnQgaG9va19jb3VudCkKewogICAgc3RydWN0IGNoYW5uZWxfaG9va19lbnRyeSAqZW50cnk7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmNzQ2hhbm5lbEhvb2spOwoKICAgIExJU1RfRk9SX0VBQ0hfRU5UUlkoZW50cnksICZjaGFubmVsX2hvb2tzLCBzdHJ1Y3QgY2hhbm5lbF9ob29rX2VudHJ5LCBlbnRyeSkKICAgIHsKICAgICAgICB1bnNpZ25lZCBpbnQgaTsKICAgICAgICBVTE9ORyBleHRlbnNpb25fc2l6ZSA9IDA7CiAgICAgICAgV0lSRV9PUlBDX0VYVEVOVCAqd2lyZV9vcnBjX2V4dGVudCA9IChXSVJFX09SUENfRVhURU5UICopYnVmZmVyOwoKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgaG9va19jb3VudDsgaSsrKQogICAgICAgICAgICBpZiAoSXNFcXVhbEdVSUQoJmVudHJ5LT5pZCwgJmRhdGFbaV0uaWQpKQogICAgICAgICAgICAgICAgZXh0ZW5zaW9uX3NpemUgPSBkYXRhW2ldLmV4dGVuc2lvbl9zaXplOwoKICAgICAgICAvKiBhbiBleHRlbnNpb24gaXMgb25seSBwdXQgb250byB0aGUgd2lyZSBpZiBpdCBoYXMgZGF0YSB0byB3cml0ZSAqLwogICAgICAgIGlmICghZXh0ZW5zaW9uX3NpemUpCiAgICAgICAgICAgIGNvbnRpbnVlOwoKICAgICAgICBJQ2hhbm5lbEhvb2tfQ2xpZW50RmlsbEJ1ZmZlcihlbnRyeS0+aG9vaywgJmVudHJ5LT5pZCwgJmluZm8tPmlpZCwKICAgICAgICAgICAgJmV4dGVuc2lvbl9zaXplLCBidWZmZXIgKyBGSUVMRF9PRkZTRVQoV0lSRV9PUlBDX0VYVEVOVCwgZGF0YVswXSkpOwoKICAgICAgICBUUkFDRSgiJXM6IGV4dGVuc2lvbl9zaXplID0gJXVcbiIsIGRlYnVnc3RyX2d1aWQoJmVudHJ5LT5pZCksIGV4dGVuc2lvbl9zaXplKTsKCiAgICAgICAgLyogRklYTUU6IHNldCB1bnVzZWQgcG9ydGlvbiBvZiB3aXJlX29ycGNfZXh0ZW50LT5kYXRhIHRvIDA/ICovCgogICAgICAgIHdpcmVfb3JwY19leHRlbnQtPmNvbmZvcm1hbmNlID0gKGV4dGVuc2lvbl9zaXplKzcpJn43OwogICAgICAgIHdpcmVfb3JwY19leHRlbnQtPnNpemUgPSBleHRlbnNpb25fc2l6ZTsKICAgICAgICB3aXJlX29ycGNfZXh0ZW50LT5pZCA9IGVudHJ5LT5pZDsKICAgICAgICBidWZmZXIgKz0gRklFTERfT0ZGU0VUKFdJUkVfT1JQQ19FWFRFTlQsIGRhdGFbd2lyZV9vcnBjX2V4dGVudC0+Y29uZm9ybWFuY2VdKTsKICAgIH0KCiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmY3NDaGFubmVsSG9vayk7CgogICAgcmV0dXJuIGJ1ZmZlcjsKfQoKc3RhdGljIHZvaWQgQ2hhbm5lbEhvb2tzX1NlcnZlck5vdGlmeShTQ2hhbm5lbEhvb2tDYWxsSW5mbyAqaW5mbywKICAgIERXT1JEIGxEYXRhUmVwLCBXSVJFX09SUENfRVhURU5UICpmaXJzdF93aXJlX29ycGNfZXh0ZW50LAogICAgVUxPTkcgZXh0ZW5zaW9uX2NvdW50KQp7CiAgICBzdHJ1Y3QgY2hhbm5lbF9ob29rX2VudHJ5ICplbnRyeTsKICAgIFVMT05HIGk7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmNzQ2hhbm5lbEhvb2spOwoKICAgIExJU1RfRk9SX0VBQ0hfRU5UUlkoZW50cnksICZjaGFubmVsX2hvb2tzLCBzdHJ1Y3QgY2hhbm5lbF9ob29rX2VudHJ5LCBlbnRyeSkKICAgIHsKICAgICAgICBXSVJFX09SUENfRVhURU5UICp3aXJlX29ycGNfZXh0ZW50OwogICAgICAgIGZvciAoaSA9IDAsIHdpcmVfb3JwY19leHRlbnQgPSBmaXJzdF93aXJlX29ycGNfZXh0ZW50OwogICAgICAgICAgICAgaSA8IGV4dGVuc2lvbl9jb3VudDsKICAgICAgICAgICAgIGkrKywgd2lyZV9vcnBjX2V4dGVudCA9IChXSVJFX09SUENfRVhURU5UICopJndpcmVfb3JwY19leHRlbnQtPmRhdGFbd2lyZV9vcnBjX2V4dGVudC0+Y29uZm9ybWFuY2VdKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKElzRXF1YWxHVUlEKCZlbnRyeS0+aWQsICZ3aXJlX29ycGNfZXh0ZW50LT5pZCkpCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgaWYgKGkgPT0gZXh0ZW5zaW9uX2NvdW50KSB3aXJlX29ycGNfZXh0ZW50ID0gTlVMTDsKCiAgICAgICAgSUNoYW5uZWxIb29rX1NlcnZlck5vdGlmeShlbnRyeS0+aG9vaywgJmVudHJ5LT5pZCwgJmluZm8tPmlpZCwKICAgICAgICAgICAgd2lyZV9vcnBjX2V4dGVudCA/IHdpcmVfb3JwY19leHRlbnQtPnNpemUgOiAwLAogICAgICAgICAgICB3aXJlX29ycGNfZXh0ZW50ID8gd2lyZV9vcnBjX2V4dGVudC0+ZGF0YSA6IE5VTEwsCiAgICAgICAgICAgIGxEYXRhUmVwKTsKICAgIH0KCiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmY3NDaGFubmVsSG9vayk7Cn0KCnN0YXRpYyBVTE9ORyBDaGFubmVsSG9va3NfU2VydmVyR2V0U2l6ZShTQ2hhbm5lbEhvb2tDYWxsSW5mbyAqaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCBjaGFubmVsX2hvb2tfYnVmZmVyX2RhdGEgKipkYXRhLCB1bnNpZ25lZCBpbnQgKmhvb2tfY291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVTE9ORyAqZXh0ZW5zaW9uX2NvdW50KQp7CiAgICBzdHJ1Y3QgY2hhbm5lbF9ob29rX2VudHJ5ICplbnRyeTsKICAgIFVMT05HIHRvdGFsX3NpemUgPSAwOwogICAgdW5zaWduZWQgaW50IGhvb2tfaW5kZXggPSAwOwoKICAgICpob29rX2NvdW50ID0gMDsKICAgICpleHRlbnNpb25fY291bnQgPSAwOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZjc0NoYW5uZWxIb29rKTsKCiAgICBMSVNUX0ZPUl9FQUNIX0VOVFJZKGVudHJ5LCAmY2hhbm5lbF9ob29rcywgc3RydWN0IGNoYW5uZWxfaG9va19lbnRyeSwgZW50cnkpCiAgICAgICAgKCpob29rX2NvdW50KSsrOwoKICAgIGlmICgqaG9va19jb3VudCkKICAgICAgICAqZGF0YSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCAqaG9va19jb3VudCAqIHNpemVvZihzdHJ1Y3QgY2hhbm5lbF9ob29rX2J1ZmZlcl9kYXRhKSk7CiAgICBlbHNlCiAgICAgICAgKmRhdGEgPSBOVUxMOwoKICAgIExJU1RfRk9SX0VBQ0hfRU5UUlkoZW50cnksICZjaGFubmVsX2hvb2tzLCBzdHJ1Y3QgY2hhbm5lbF9ob29rX2VudHJ5LCBlbnRyeSkKICAgIHsKICAgICAgICBVTE9ORyBleHRlbnNpb25fc2l6ZSA9IDA7CgogICAgICAgIElDaGFubmVsSG9va19TZXJ2ZXJHZXRTaXplKGVudHJ5LT5ob29rLCAmZW50cnktPmlkLCAmaW5mby0+aWlkLCBTX09LLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZleHRlbnNpb25fc2l6ZSk7CgogICAgICAgIFRSQUNFKCIlczogZXh0ZW5zaW9uX3NpemUgPSAldVxuIiwgZGVidWdzdHJfZ3VpZCgmZW50cnktPmlkKSwgZXh0ZW5zaW9uX3NpemUpOwoKICAgICAgICBleHRlbnNpb25fc2l6ZSA9IChleHRlbnNpb25fc2l6ZSs3KSZ+NzsKICAgICAgICAoKmRhdGEpW2hvb2tfaW5kZXhdLmlkID0gZW50cnktPmlkOwogICAgICAgICgqZGF0YSlbaG9va19pbmRleF0uZXh0ZW5zaW9uX3NpemUgPSBleHRlbnNpb25fc2l6ZTsKCiAgICAgICAgLyogYW4gZXh0ZW5zaW9uIGlzIG9ubHkgcHV0IG9udG8gdGhlIHdpcmUgaWYgaXQgaGFzIGRhdGEgdG8gd3JpdGUgKi8KICAgICAgICBpZiAoZXh0ZW5zaW9uX3NpemUpCiAgICAgICAgewogICAgICAgICAgICB0b3RhbF9zaXplICs9IEZJRUxEX09GRlNFVChXSVJFX09SUENfRVhURU5ULCBkYXRhW2V4dGVuc2lvbl9zaXplXSk7CiAgICAgICAgICAgICgqZXh0ZW5zaW9uX2NvdW50KSsrOwogICAgICAgIH0KCiAgICAgICAgaG9va19pbmRleCsrOwogICAgfQoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZjc0NoYW5uZWxIb29rKTsKCiAgICByZXR1cm4gdG90YWxfc2l6ZTsKfQoKc3RhdGljIHVuc2lnbmVkIGNoYXIgKiBDaGFubmVsSG9va3NfU2VydmVyRmlsbEJ1ZmZlcihTQ2hhbm5lbEhvb2tDYWxsSW5mbyAqaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyICpidWZmZXIsIHN0cnVjdCBjaGFubmVsX2hvb2tfYnVmZmVyX2RhdGEgKmRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgaW50IGhvb2tfY291bnQpCnsKICAgIHN0cnVjdCBjaGFubmVsX2hvb2tfZW50cnkgKmVudHJ5OwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZjc0NoYW5uZWxIb29rKTsKCiAgICBMSVNUX0ZPUl9FQUNIX0VOVFJZKGVudHJ5LCAmY2hhbm5lbF9ob29rcywgc3RydWN0IGNoYW5uZWxfaG9va19lbnRyeSwgZW50cnkpCiAgICB7CiAgICAgICAgdW5zaWduZWQgaW50IGk7CiAgICAgICAgVUxPTkcgZXh0ZW5zaW9uX3NpemUgPSAwOwogICAgICAgIFdJUkVfT1JQQ19FWFRFTlQgKndpcmVfb3JwY19leHRlbnQgPSAoV0lSRV9PUlBDX0VYVEVOVCAqKWJ1ZmZlcjsKCiAgICAgICAgZm9yIChpID0gMDsgaSA8IGhvb2tfY291bnQ7IGkrKykKICAgICAgICAgICAgaWYgKElzRXF1YWxHVUlEKCZlbnRyeS0+aWQsICZkYXRhW2ldLmlkKSkKICAgICAgICAgICAgICAgIGV4dGVuc2lvbl9zaXplID0gZGF0YVtpXS5leHRlbnNpb25fc2l6ZTsKCiAgICAgICAgLyogYW4gZXh0ZW5zaW9uIGlzIG9ubHkgcHV0IG9udG8gdGhlIHdpcmUgaWYgaXQgaGFzIGRhdGEgdG8gd3JpdGUgKi8KICAgICAgICBpZiAoIWV4dGVuc2lvbl9zaXplKQogICAgICAgICAgICBjb250aW51ZTsKCiAgICAgICAgSUNoYW5uZWxIb29rX1NlcnZlckZpbGxCdWZmZXIoZW50cnktPmhvb2ssICZlbnRyeS0+aWQsICZpbmZvLT5paWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmV4dGVuc2lvbl9zaXplLCBidWZmZXIgKyBGSUVMRF9PRkZTRVQoV0lSRV9PUlBDX0VYVEVOVCwgZGF0YVswXSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU19PSyk7CgogICAgICAgIFRSQUNFKCIlczogZXh0ZW5zaW9uX3NpemUgPSAldVxuIiwgZGVidWdzdHJfZ3VpZCgmZW50cnktPmlkKSwgZXh0ZW5zaW9uX3NpemUpOwoKICAgICAgICAvKiBGSVhNRTogc2V0IHVudXNlZCBwb3J0aW9uIG9mIHdpcmVfb3JwY19leHRlbnQtPmRhdGEgdG8gMD8gKi8KCiAgICAgICAgd2lyZV9vcnBjX2V4dGVudC0+Y29uZm9ybWFuY2UgPSAoZXh0ZW5zaW9uX3NpemUrNykmfjc7CiAgICAgICAgd2lyZV9vcnBjX2V4dGVudC0+c2l6ZSA9IGV4dGVuc2lvbl9zaXplOwogICAgICAgIHdpcmVfb3JwY19leHRlbnQtPmlkID0gZW50cnktPmlkOwogICAgICAgIGJ1ZmZlciArPSBGSUVMRF9PRkZTRVQoV0lSRV9PUlBDX0VYVEVOVCwgZGF0YVt3aXJlX29ycGNfZXh0ZW50LT5jb25mb3JtYW5jZV0pOwogICAgfQoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZjc0NoYW5uZWxIb29rKTsKCiAgICByZXR1cm4gYnVmZmVyOwp9CgpzdGF0aWMgdm9pZCBDaGFubmVsSG9va3NfQ2xpZW50Tm90aWZ5KFNDaGFubmVsSG9va0NhbGxJbmZvICppbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGxEYXRhUmVwLCBXSVJFX09SUENfRVhURU5UICpmaXJzdF93aXJlX29ycGNfZXh0ZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVMT05HIGV4dGVuc2lvbl9jb3VudCwgSFJFU1VMVCBockZhdWx0KQp7CiAgICBzdHJ1Y3QgY2hhbm5lbF9ob29rX2VudHJ5ICplbnRyeTsKICAgIFVMT05HIGk7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmNzQ2hhbm5lbEhvb2spOwoKICAgIExJU1RfRk9SX0VBQ0hfRU5UUlkoZW50cnksICZjaGFubmVsX2hvb2tzLCBzdHJ1Y3QgY2hhbm5lbF9ob29rX2VudHJ5LCBlbnRyeSkKICAgIHsKICAgICAgICBXSVJFX09SUENfRVhURU5UICp3aXJlX29ycGNfZXh0ZW50OwogICAgICAgIGZvciAoaSA9IDAsIHdpcmVfb3JwY19leHRlbnQgPSBmaXJzdF93aXJlX29ycGNfZXh0ZW50OwogICAgICAgICAgICAgaSA8IGV4dGVuc2lvbl9jb3VudDsKICAgICAgICAgICAgIGkrKywgd2lyZV9vcnBjX2V4dGVudCA9IChXSVJFX09SUENfRVhURU5UICopJndpcmVfb3JwY19leHRlbnQtPmRhdGFbd2lyZV9vcnBjX2V4dGVudC0+Y29uZm9ybWFuY2VdKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKElzRXF1YWxHVUlEKCZlbnRyeS0+aWQsICZ3aXJlX29ycGNfZXh0ZW50LT5pZCkpCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgaWYgKGkgPT0gZXh0ZW5zaW9uX2NvdW50KSB3aXJlX29ycGNfZXh0ZW50ID0gTlVMTDsKCiAgICAgICAgSUNoYW5uZWxIb29rX0NsaWVudE5vdGlmeShlbnRyeS0+aG9vaywgJmVudHJ5LT5pZCwgJmluZm8tPmlpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpcmVfb3JwY19leHRlbnQgPyB3aXJlX29ycGNfZXh0ZW50LT5zaXplIDogMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpcmVfb3JwY19leHRlbnQgPyB3aXJlX29ycGNfZXh0ZW50LT5kYXRhIDogTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxEYXRhUmVwLCBockZhdWx0KTsKICAgIH0KCiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmY3NDaGFubmVsSG9vayk7Cn0KCkhSRVNVTFQgUlBDX1JlZ2lzdGVyQ2hhbm5lbEhvb2soUkVGR1VJRCByZ3VpZCwgSUNoYW5uZWxIb29rICpob29rKQp7CiAgICBzdHJ1Y3QgY2hhbm5lbF9ob29rX2VudHJ5ICplbnRyeTsKCiAgICBUUkFDRSgiKCVzLCAlcClcbiIsIGRlYnVnc3RyX2d1aWQocmd1aWQpLCBob29rKTsKCiAgICBlbnRyeSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoKmVudHJ5KSk7CiAgICBpZiAoIWVudHJ5KQogICAgICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwoKICAgIGVudHJ5LT5pZCA9ICpyZ3VpZDsKICAgIGVudHJ5LT5ob29rID0gaG9vazsKICAgIElDaGFubmVsSG9va19BZGRSZWYoaG9vayk7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmNzQ2hhbm5lbEhvb2spOwogICAgbGlzdF9hZGRfdGFpbCgmY2hhbm5lbF9ob29rcywgJmVudHJ5LT5lbnRyeSk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmY3NDaGFubmVsSG9vayk7CgogICAgcmV0dXJuIFNfT0s7Cn0KCnZvaWQgUlBDX1VucmVnaXN0ZXJBbGxDaGFubmVsSG9va3Modm9pZCkKewogICAgc3RydWN0IGNoYW5uZWxfaG9va19lbnRyeSAqY3Vyc29yOwogICAgc3RydWN0IGNoYW5uZWxfaG9va19lbnRyeSAqY3Vyc29yMjsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmY3NDaGFubmVsSG9vayk7CiAgICBMSVNUX0ZPUl9FQUNIX0VOVFJZX1NBRkUoY3Vyc29yLCBjdXJzb3IyLCAmY2hhbm5lbF9ob29rcywgc3RydWN0IGNoYW5uZWxfaG9va19lbnRyeSwgZW50cnkpCiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgY3Vyc29yKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZjc0NoYW5uZWxIb29rKTsKfQoKLyogUlBDIENoYW5uZWwgQnVmZmVyIEZ1bmN0aW9ucyAqLwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFJwY0NoYW5uZWxCdWZmZXJfUXVlcnlJbnRlcmZhY2UoTFBSUENDSEFOTkVMQlVGRkVSIGlmYWNlLCBSRUZJSUQgcmlpZCwgTFBWT0lEICpwcHYpCnsKICAgICpwcHYgPSBOVUxMOwogICAgaWYgKElzRXF1YWxJSUQocmlpZCwmSUlEX0lScGNDaGFubmVsQnVmZmVyKSB8fCBJc0VxdWFsSUlEKHJpaWQsJklJRF9JVW5rbm93bikpCiAgICB7CiAgICAgICAgKnBwdiA9IChMUFZPSUQpaWZhY2U7CiAgICAgICAgSVVua25vd25fQWRkUmVmKGlmYWNlKTsKICAgICAgICByZXR1cm4gU19PSzsKICAgIH0KICAgIHJldHVybiBFX05PSU5URVJGQUNFOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIFJwY0NoYW5uZWxCdWZmZXJfQWRkUmVmKExQUlBDQ0hBTk5FTEJVRkZFUiBpZmFjZSkKewogICAgUnBjQ2hhbm5lbEJ1ZmZlciAqVGhpcyA9IChScGNDaGFubmVsQnVmZmVyICopaWZhY2U7CiAgICByZXR1cm4gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPnJlZnMpOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIFNlcnZlclJwY0NoYW5uZWxCdWZmZXJfUmVsZWFzZShMUFJQQ0NIQU5ORUxCVUZGRVIgaWZhY2UpCnsKICAgIFJwY0NoYW5uZWxCdWZmZXIgKlRoaXMgPSAoUnBjQ2hhbm5lbEJ1ZmZlciAqKWlmYWNlOwogICAgVUxPTkcgcmVmOwoKICAgIHJlZiA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5yZWZzKTsKICAgIGlmIChyZWYpCiAgICAgICAgcmV0dXJuIHJlZjsKCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzKTsKICAgIHJldHVybiAwOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIENsaWVudFJwY0NoYW5uZWxCdWZmZXJfUmVsZWFzZShMUFJQQ0NIQU5ORUxCVUZGRVIgaWZhY2UpCnsKICAgIENsaWVudFJwY0NoYW5uZWxCdWZmZXIgKlRoaXMgPSAoQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlciAqKWlmYWNlOwogICAgVUxPTkcgcmVmOwoKICAgIHJlZiA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5zdXBlci5yZWZzKTsKICAgIGlmIChyZWYpCiAgICAgICAgcmV0dXJuIHJlZjsKCiAgICBpZiAoVGhpcy0+ZXZlbnQpIENsb3NlSGFuZGxlKFRoaXMtPmV2ZW50KTsKICAgIFJwY0JpbmRpbmdGcmVlKCZUaGlzLT5iaW5kKTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMpOwogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBTZXJ2ZXJScGNDaGFubmVsQnVmZmVyX0dldEJ1ZmZlcihMUFJQQ0NIQU5ORUxCVUZGRVIgaWZhY2UsIFJQQ09MRU1FU1NBR0UqIG9sZW1zZywgUkVGSUlEIHJpaWQpCnsKICAgIFJwY0NoYW5uZWxCdWZmZXIgKlRoaXMgPSAoUnBjQ2hhbm5lbEJ1ZmZlciAqKWlmYWNlOwogICAgUlBDX01FU1NBR0UgKm1zZyA9IChSUENfTUVTU0FHRSAqKW9sZW1zZzsKICAgIFJQQ19TVEFUVVMgc3RhdHVzOwogICAgT1JQQ1RIQVQgKm9ycGN0aGF0OwogICAgc3RydWN0IG1lc3NhZ2Vfc3RhdGUgKm1lc3NhZ2Vfc3RhdGU7CiAgICBVTE9ORyBleHRlbnNpb25zX3NpemU7CiAgICBzdHJ1Y3QgY2hhbm5lbF9ob29rX2J1ZmZlcl9kYXRhICpjaGFubmVsX2hvb2tfZGF0YTsKICAgIHVuc2lnbmVkIGludCBjaGFubmVsX2hvb2tfY291bnQ7CiAgICBVTE9ORyBleHRlbnNpb25fY291bnQ7CgogICAgVFJBQ0UoIiglcCktPiglcCwlcylcbiIsIFRoaXMsIG9sZW1zZywgZGVidWdzdHJfZ3VpZChyaWlkKSk7CgogICAgbWVzc2FnZV9zdGF0ZSA9IChzdHJ1Y3QgbWVzc2FnZV9zdGF0ZSAqKW1zZy0+SGFuZGxlOwogICAgLyogcmVzdG9yZSB0aGUgYmluZGluZyBoYW5kbGUgYW5kIHRoZSByZWFsIHN0YXJ0IG9mIGRhdGEgKi8KICAgIG1zZy0+SGFuZGxlID0gbWVzc2FnZV9zdGF0ZS0+YmluZGluZ19oYW5kbGU7CiAgICBtc2ctPkJ1ZmZlciA9IChjaGFyICopbXNnLT5CdWZmZXIgLSBtZXNzYWdlX3N0YXRlLT5wcmVmaXhfZGF0YV9sZW47CgogICAgZXh0ZW5zaW9uc19zaXplID0gQ2hhbm5lbEhvb2tzX1NlcnZlckdldFNpemUoJm1lc3NhZ2Vfc3RhdGUtPmNoYW5uZWxfaG9va19pbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmNoYW5uZWxfaG9va19kYXRhLCAmY2hhbm5lbF9ob29rX2NvdW50LCAmZXh0ZW5zaW9uX2NvdW50KTsKCiAgICBtc2ctPkJ1ZmZlckxlbmd0aCArPSBGSUVMRF9PRkZTRVQoT1JQQ1RIQVQsIGV4dGVuc2lvbnMpICsgNDsKICAgIGlmIChleHRlbnNpb25zX3NpemUpCiAgICB7CiAgICAgICAgbXNnLT5CdWZmZXJMZW5ndGggKz0gRklFTERfT0ZGU0VUKE9SUENfRVhURU5UX0FSUkFZLCBleHRlbnQpICsgMipzaXplb2YoRFdPUkQpICsgZXh0ZW5zaW9uc19zaXplOwogICAgICAgIGlmIChleHRlbnNpb25fY291bnQgJiAxKQogICAgICAgICAgICBtc2ctPkJ1ZmZlckxlbmd0aCArPSBGSUVMRF9PRkZTRVQoV0lSRV9PUlBDX0VYVEVOVCwgZGF0YVswXSk7CiAgICB9CgogICAgaWYgKG1lc3NhZ2Vfc3RhdGUtPmJ5cGFzc19ycGNydCkKICAgIHsKICAgICAgICBtc2ctPkJ1ZmZlciA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBtc2ctPkJ1ZmZlckxlbmd0aCk7CiAgICAgICAgaWYgKG1zZy0+QnVmZmVyKQogICAgICAgICAgICBzdGF0dXMgPSBSUENfU19PSzsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHN0YXR1cyA9IEVSUk9SX09VVE9GTUVNT1JZOwogICAgfQogICAgZWxzZQogICAgICAgIHN0YXR1cyA9IElfUnBjR2V0QnVmZmVyKG1zZyk7CgogICAgb3JwY3RoYXQgPSAoT1JQQ1RIQVQgKiltc2ctPkJ1ZmZlcjsKICAgIG1zZy0+QnVmZmVyID0gKGNoYXIgKiltc2ctPkJ1ZmZlciArIEZJRUxEX09GRlNFVChPUlBDVEhBVCwgZXh0ZW5zaW9ucyk7CgogICAgb3JwY3RoYXQtPmZsYWdzID0gT1JQQ0ZfTlVMTCAvKiBGSVhNRT8gKi87CgogICAgLyogTkRSIHJlcHJlc2VudGF0aW9uIG9mIG9ycGN0aGF0LT5leHRlbnNpb25zICovCiAgICAqKERXT1JEICopbXNnLT5CdWZmZXIgPSBleHRlbnNpb25zX3NpemUgPyAxIDogMDsKICAgIG1zZy0+QnVmZmVyID0gKGNoYXIgKiltc2ctPkJ1ZmZlciArIHNpemVvZihEV09SRCk7CgogICAgaWYgKGV4dGVuc2lvbnNfc2l6ZSkKICAgIHsKICAgICAgICBPUlBDX0VYVEVOVF9BUlJBWSAqb3JwY19leHRlbnRfYXJyYXkgPSBtc2ctPkJ1ZmZlcjsKICAgICAgICBvcnBjX2V4dGVudF9hcnJheS0+c2l6ZSA9IGV4dGVuc2lvbl9jb3VudDsKICAgICAgICBvcnBjX2V4dGVudF9hcnJheS0+cmVzZXJ2ZWQgPSAwOwogICAgICAgIG1zZy0+QnVmZmVyID0gKGNoYXIgKiltc2ctPkJ1ZmZlciArIEZJRUxEX09GRlNFVChPUlBDX0VYVEVOVF9BUlJBWSwgZXh0ZW50KTsKICAgICAgICAvKiBORFIgcmVwcmVzZW50YXRpb24gb2Ygb3JwY19leHRlbnRfYXJyYXktPmV4dGVudCAqLwogICAgICAgICooRFdPUkQgKiltc2ctPkJ1ZmZlciA9IDE7CiAgICAgICAgbXNnLT5CdWZmZXIgPSAoY2hhciAqKW1zZy0+QnVmZmVyICsgc2l6ZW9mKERXT1JEKTsKICAgICAgICAvKiBORFIgcmVwcmVzZW50YXRpb24gb2YgW3NpemVfaXNdIGF0dHJpYnV0ZSBvZiBvcnBjX2V4dGVudF9hcnJheS0+ZXh0ZW50ICovCiAgICAgICAgKihEV09SRCAqKW1zZy0+QnVmZmVyID0gKGV4dGVuc2lvbl9jb3VudCArIDEpICYgfjE7CiAgICAgICAgbXNnLT5CdWZmZXIgPSAoY2hhciAqKW1zZy0+QnVmZmVyICsgc2l6ZW9mKERXT1JEKTsKCiAgICAgICAgbXNnLT5CdWZmZXIgPSBDaGFubmVsSG9va3NfU2VydmVyRmlsbEJ1ZmZlcigmbWVzc2FnZV9zdGF0ZS0+Y2hhbm5lbF9ob29rX2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtc2ctPkJ1ZmZlciwgY2hhbm5lbF9ob29rX2RhdGEsIGNoYW5uZWxfaG9va19jb3VudCk7CgogICAgICAgIC8qIHdlIG11c3QgYWRkIGEgZHVtbXkgZXh0ZW5zaW9uIGlmIHRoZXJlIGlzIGFuIG9kZCBleHRlbnNpb24KICAgICAgICAgKiBjb3VudCB0byBtZWV0IHRoZSBjb250cmFjdCBzcGVjaWZpZWQgYnkgdGhlIHNpemVfaXMgYXR0cmlidXRlICovCiAgICAgICAgaWYgKGV4dGVuc2lvbl9jb3VudCAmIDEpCiAgICAgICAgewogICAgICAgICAgICBXSVJFX09SUENfRVhURU5UICp3aXJlX29ycGNfZXh0ZW50ID0gbXNnLT5CdWZmZXI7CiAgICAgICAgICAgIHdpcmVfb3JwY19leHRlbnQtPmNvbmZvcm1hbmNlID0gMDsKICAgICAgICAgICAgd2lyZV9vcnBjX2V4dGVudC0+aWQgPSBHVUlEX05VTEw7CiAgICAgICAgICAgIHdpcmVfb3JwY19leHRlbnQtPnNpemUgPSAwOwogICAgICAgICAgICBtc2ctPkJ1ZmZlciA9IChjaGFyICopbXNnLT5CdWZmZXIgKyBGSUVMRF9PRkZTRVQoV0lSRV9PUlBDX0VYVEVOVCwgZGF0YVswXSk7CiAgICAgICAgfQogICAgfQoKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGNoYW5uZWxfaG9va19kYXRhKTsKCiAgICAvKiBzdG9yZSB0aGUgcHJlZml4ZWQgZGF0YSBsZW5ndGggc28gdGhhdCB3ZSBjYW4gcmVzdG9yZSB0aGUgcmVhbCBidWZmZXIKICAgICAqIGxhdGVyICovCiAgICBtZXNzYWdlX3N0YXRlLT5wcmVmaXhfZGF0YV9sZW4gPSAoY2hhciAqKW1zZy0+QnVmZmVyIC0gKGNoYXIgKilvcnBjdGhhdDsKICAgIG1zZy0+QnVmZmVyTGVuZ3RoIC09IG1lc3NhZ2Vfc3RhdGUtPnByZWZpeF9kYXRhX2xlbjsKICAgIC8qIHNhdmUgYXdheSB0aGUgbWVzc2FnZSBzdGF0ZSBhZ2FpbiAqLwogICAgbXNnLT5IYW5kbGUgPSBtZXNzYWdlX3N0YXRlOwoKICAgIFRSQUNFKCItLSAlbGRcbiIsIHN0YXR1cyk7CgogICAgcmV0dXJuIEhSRVNVTFRfRlJPTV9XSU4zMihzdGF0dXMpOwp9CgpzdGF0aWMgSEFORExFIENsaWVudFJwY0NoYW5uZWxCdWZmZXJfR2V0RXZlbnRIYW5kbGUoQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlciAqVGhpcykKewogICAgSEFORExFIGV2ZW50ID0gSW50ZXJsb2NrZWRFeGNoYW5nZVBvaW50ZXIoJlRoaXMtPmV2ZW50LCBOVUxMKTsKCiAgICAvKiBOb3RlOiBtdXN0IGJlIGF1dG8tcmVzZXQgZXZlbnQgc28gd2UgY2FuIHJldXNlIGl0IHdpdGhvdXQgYSBjYWxsCiAgICAqIHRvIFJlc2V0RXZlbnQgKi8KICAgIGlmICghZXZlbnQpIGV2ZW50ID0gQ3JlYXRlRXZlbnRXKE5VTEwsIEZBTFNFLCBGQUxTRSwgTlVMTCk7CgogICAgcmV0dXJuIGV2ZW50Owp9CgpzdGF0aWMgdm9pZCBDbGllbnRScGNDaGFubmVsQnVmZmVyX1JlbGVhc2VFdmVudEhhbmRsZShDbGllbnRScGNDaGFubmVsQnVmZmVyICpUaGlzLCBIQU5ETEUgZXZlbnQpCnsKICAgIGlmIChJbnRlcmxvY2tlZENvbXBhcmVFeGNoYW5nZVBvaW50ZXIoJlRoaXMtPmV2ZW50LCBldmVudCwgTlVMTCkpCiAgICAgICAgLyogYWxyZWFkeSBhIGhhbmRsZSBjYWNoZWQgaW4gVGhpcyAqLwogICAgICAgIENsb3NlSGFuZGxlKGV2ZW50KTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIENsaWVudFJwY0NoYW5uZWxCdWZmZXJfR2V0QnVmZmVyKExQUlBDQ0hBTk5FTEJVRkZFUiBpZmFjZSwgUlBDT0xFTUVTU0FHRSogb2xlbXNnLCBSRUZJSUQgcmlpZCkKewogICAgQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlciAqVGhpcyA9IChDbGllbnRScGNDaGFubmVsQnVmZmVyICopaWZhY2U7CiAgICBSUENfTUVTU0FHRSAqbXNnID0gKFJQQ19NRVNTQUdFICopb2xlbXNnOwogICAgUlBDX0NMSUVOVF9JTlRFUkZBQ0UgKmNpZjsKICAgIFJQQ19TVEFUVVMgc3RhdHVzOwogICAgT1JQQ1RISVMgKm9ycGN0aGlzOwogICAgc3RydWN0IG1lc3NhZ2Vfc3RhdGUgKm1lc3NhZ2Vfc3RhdGU7CiAgICBVTE9ORyBleHRlbnNpb25zX3NpemU7CiAgICBzdHJ1Y3QgY2hhbm5lbF9ob29rX2J1ZmZlcl9kYXRhICpjaGFubmVsX2hvb2tfZGF0YTsKICAgIHVuc2lnbmVkIGludCBjaGFubmVsX2hvb2tfY291bnQ7CiAgICBVTE9ORyBleHRlbnNpb25fY291bnQ7CiAgICBJUElEIGlwaWQ7CiAgICBIUkVTVUxUIGhyOwogICAgQVBBUlRNRU5UICphcHQgPSBOVUxMOwoKICAgIFRSQUNFKCIoJXApLT4oJXAsJXMpXG4iLCBUaGlzLCBvbGVtc2csIGRlYnVnc3RyX2d1aWQocmlpZCkpOwoKICAgIGNpZiA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoUlBDX0NMSUVOVF9JTlRFUkZBQ0UpKTsKICAgIGlmICghY2lmKQogICAgICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwoKICAgIG1lc3NhZ2Vfc3RhdGUgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKCptZXNzYWdlX3N0YXRlKSk7CiAgICBpZiAoIW1lc3NhZ2Vfc3RhdGUpCiAgICB7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgY2lmKTsKICAgICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKICAgIH0KCiAgICBjaWYtPkxlbmd0aCA9IHNpemVvZihSUENfQ0xJRU5UX0lOVEVSRkFDRSk7CiAgICAvKiBSUEMgaW50ZXJmYWNlIElEID0gQ09NIGludGVyZmFjZSBJRCAqLwogICAgY2lmLT5JbnRlcmZhY2VJZC5TeW50YXhHVUlEID0gKnJpaWQ7CiAgICAvKiBDT00gb2JqZWN0cyBhbHdheXMgaGF2ZSBhIHZlcnNpb24gb2YgMC4wICovCiAgICBjaWYtPkludGVyZmFjZUlkLlN5bnRheFZlcnNpb24uTWFqb3JWZXJzaW9uID0gMDsKICAgIGNpZi0+SW50ZXJmYWNlSWQuU3ludGF4VmVyc2lvbi5NaW5vclZlcnNpb24gPSAwOwogICAgbXNnLT5IYW5kbGUgPSBUaGlzLT5iaW5kOwogICAgbXNnLT5ScGNJbnRlcmZhY2VJbmZvcm1hdGlvbiA9IGNpZjsKCiAgICBtZXNzYWdlX3N0YXRlLT5wcmVmaXhfZGF0YV9sZW4gPSAwOwogICAgbWVzc2FnZV9zdGF0ZS0+YmluZGluZ19oYW5kbGUgPSBUaGlzLT5iaW5kOwoKICAgIG1lc3NhZ2Vfc3RhdGUtPmNoYW5uZWxfaG9va19pbmZvLmlpZCA9ICpyaWlkOwogICAgbWVzc2FnZV9zdGF0ZS0+Y2hhbm5lbF9ob29rX2luZm8uY2JTaXplID0gc2l6ZW9mKG1lc3NhZ2Vfc3RhdGUtPmNoYW5uZWxfaG9va19pbmZvKTsKICAgIG1lc3NhZ2Vfc3RhdGUtPmNoYW5uZWxfaG9va19pbmZvLnVDYXVzYWxpdHkgPSBDT01fQ3VycmVudENhdXNhbGl0eUlkKCk7CiAgICBtZXNzYWdlX3N0YXRlLT5jaGFubmVsX2hvb2tfaW5mby5kd1NlcnZlclBpZCA9IFRoaXMtPnNlcnZlcl9waWQ7CiAgICBtZXNzYWdlX3N0YXRlLT5jaGFubmVsX2hvb2tfaW5mby5pTWV0aG9kID0gbXNnLT5Qcm9jTnVtOwogICAgbWVzc2FnZV9zdGF0ZS0+Y2hhbm5lbF9ob29rX2luZm8ucE9iamVjdCA9IE5VTEw7IC8qIG9ubHkgcHJlc2VudCBvbiBzZXJ2ZXItc2lkZSAqLwogICAgbWVzc2FnZV9zdGF0ZS0+dGFyZ2V0X2h3bmQgPSBOVUxMOwogICAgbWVzc2FnZV9zdGF0ZS0+dGFyZ2V0X3RpZCA9IDA7CiAgICBtZW1zZXQoJm1lc3NhZ2Vfc3RhdGUtPnBhcmFtcywgMCwgc2l6ZW9mKG1lc3NhZ2Vfc3RhdGUtPnBhcmFtcykpOwoKICAgIGV4dGVuc2lvbnNfc2l6ZSA9IENoYW5uZWxIb29rc19DbGllbnRHZXRTaXplKCZtZXNzYWdlX3N0YXRlLT5jaGFubmVsX2hvb2tfaW5mbywKICAgICAgICAmY2hhbm5lbF9ob29rX2RhdGEsICZjaGFubmVsX2hvb2tfY291bnQsICZleHRlbnNpb25fY291bnQpOwoKICAgIG1zZy0+QnVmZmVyTGVuZ3RoICs9IEZJRUxEX09GRlNFVChPUlBDVEhJUywgZXh0ZW5zaW9ucykgKyA0OwogICAgaWYgKGV4dGVuc2lvbnNfc2l6ZSkKICAgIHsKICAgICAgICBtc2ctPkJ1ZmZlckxlbmd0aCArPSBGSUVMRF9PRkZTRVQoT1JQQ19FWFRFTlRfQVJSQVksIGV4dGVudCkgKyAyKnNpemVvZihEV09SRCkgKyBleHRlbnNpb25zX3NpemU7CiAgICAgICAgaWYgKGV4dGVuc2lvbl9jb3VudCAmIDEpCiAgICAgICAgICAgIG1zZy0+QnVmZmVyTGVuZ3RoICs9IEZJRUxEX09GRlNFVChXSVJFX09SUENfRVhURU5ULCBkYXRhWzBdKTsKICAgIH0KCiAgICBScGNCaW5kaW5nSW5xT2JqZWN0KG1lc3NhZ2Vfc3RhdGUtPmJpbmRpbmdfaGFuZGxlLCAmaXBpZCk7CiAgICBociA9IGlwaWRfZ2V0X2Rpc3BhdGNoX3BhcmFtcygmaXBpZCwgJmFwdCwgJm1lc3NhZ2Vfc3RhdGUtPnBhcmFtcy5zdHViLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJm1lc3NhZ2Vfc3RhdGUtPnBhcmFtcy5jaGFuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJm1lc3NhZ2Vfc3RhdGUtPnBhcmFtcy5paWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbWVzc2FnZV9zdGF0ZS0+cGFyYW1zLmlmYWNlKTsKICAgIGlmIChociA9PSBTX09LKQogICAgewogICAgICAgIC8qIHN0dWIsIGNoYW4sIGlmYWNlIGFuZCBpaWQgYXJlIHVubmVlZGVkIGluIG11bHRpLXRocmVhZGVkIGNhc2UgYXMgd2UgZ28KICAgICAgICAgKiB2aWEgdGhlIFJQQyBydW50aW1lICovCiAgICAgICAgaWYgKGFwdC0+bXVsdGlfdGhyZWFkZWQpCiAgICAgICAgewogICAgICAgICAgICBJUnBjU3R1YkJ1ZmZlcl9SZWxlYXNlKG1lc3NhZ2Vfc3RhdGUtPnBhcmFtcy5zdHViKTsKICAgICAgICAgICAgbWVzc2FnZV9zdGF0ZS0+cGFyYW1zLnN0dWIgPSBOVUxMOwogICAgICAgICAgICBJUnBjQ2hhbm5lbEJ1ZmZlcl9SZWxlYXNlKG1lc3NhZ2Vfc3RhdGUtPnBhcmFtcy5jaGFuKTsKICAgICAgICAgICAgbWVzc2FnZV9zdGF0ZS0+cGFyYW1zLmNoYW4gPSBOVUxMOwogICAgICAgICAgICBtZXNzYWdlX3N0YXRlLT5wYXJhbXMuaWZhY2UgPSBOVUxMOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBtZXNzYWdlX3N0YXRlLT5wYXJhbXMuYnlwYXNzX3JwY3J0ID0gVFJVRTsKICAgICAgICAgICAgbWVzc2FnZV9zdGF0ZS0+dGFyZ2V0X2h3bmQgPSBhcGFydG1lbnRfZ2V0d2luZG93KGFwdCk7CiAgICAgICAgICAgIG1lc3NhZ2Vfc3RhdGUtPnRhcmdldF90aWQgPSBhcHQtPnRpZDsKICAgICAgICAgICAgLyogd2UgYXNzdW1lIGxhdGVyIG9uIHRoYXQgdGhpcyBiZWluZyBub24tTlVMTCBpcyB0aGUgaW5kaWNhdG9yIHRoYXQKICAgICAgICAgICAgICogbWVhbnMgY2FsbCBkaXJlY3RseSBpbnN0ZWFkIG9mIGdvaW5nIHRocm91Z2ggUlBDIHJ1bnRpbWUgKi8KICAgICAgICAgICAgaWYgKCFtZXNzYWdlX3N0YXRlLT50YXJnZXRfaHduZCkKICAgICAgICAgICAgICAgIEVSUigid2luZG93IGZvciBhcGFydG1lbnQgJXMgaXMgTlVMTFxuIiwgd2luZV9kYmdzdHJfbG9uZ2xvbmcoYXB0LT5veGlkKSk7CiAgICAgICAgfQogICAgfQogICAgaWYgKGFwdCkgYXBhcnRtZW50X3JlbGVhc2UoYXB0KTsKICAgIG1lc3NhZ2Vfc3RhdGUtPnBhcmFtcy5oYW5kbGUgPSBDbGllbnRScGNDaGFubmVsQnVmZmVyX0dldEV2ZW50SGFuZGxlKFRoaXMpOwogICAgLyogTm90ZTogbWVzc2FnZV9zdGF0ZS0+cGFyYW1zLm1zZyBpcyBpbml0aWFsaXNlZCBpbgogICAgICogQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlcl9TZW5kUmVjZWl2ZSAqLwoKICAgIC8qIHNob3J0Y3V0IHRoZSBSUEMgcnVudGltZSAqLwogICAgaWYgKG1lc3NhZ2Vfc3RhdGUtPnRhcmdldF9od25kKQogICAgewogICAgICAgIG1zZy0+QnVmZmVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIG1zZy0+QnVmZmVyTGVuZ3RoKTsKICAgICAgICBpZiAobXNnLT5CdWZmZXIpCiAgICAgICAgICAgIHN0YXR1cyA9IFJQQ19TX09LOwogICAgICAgIGVsc2UKICAgICAgICAgICAgc3RhdHVzID0gRVJST1JfT1VUT0ZNRU1PUlk7CiAgICB9CiAgICBlbHNlCiAgICAgICAgc3RhdHVzID0gSV9ScGNHZXRCdWZmZXIobXNnKTsKCiAgICBtc2ctPkhhbmRsZSA9IG1lc3NhZ2Vfc3RhdGU7CgogICAgaWYgKHN0YXR1cyA9PSBSUENfU19PSykKICAgIHsKICAgICAgICBvcnBjdGhpcyA9IChPUlBDVEhJUyAqKW1zZy0+QnVmZmVyOwogICAgICAgIG1zZy0+QnVmZmVyID0gKGNoYXIgKiltc2ctPkJ1ZmZlciArIEZJRUxEX09GRlNFVChPUlBDVEhJUywgZXh0ZW5zaW9ucyk7CgogICAgICAgIG9ycGN0aGlzLT52ZXJzaW9uLk1ham9yVmVyc2lvbiA9IENPTV9NQUpPUl9WRVJTSU9OOwogICAgICAgIG9ycGN0aGlzLT52ZXJzaW9uLk1pbm9yVmVyc2lvbiA9IENPTV9NSU5PUl9WRVJTSU9OOwogICAgICAgIG9ycGN0aGlzLT5mbGFncyA9IG1lc3NhZ2Vfc3RhdGUtPmNoYW5uZWxfaG9va19pbmZvLmR3U2VydmVyUGlkID8gT1JQQ0ZfTE9DQUwgOiBPUlBDRl9OVUxMOwogICAgICAgIG9ycGN0aGlzLT5yZXNlcnZlZDEgPSAwOwogICAgICAgIG9ycGN0aGlzLT5jaWQgPSBtZXNzYWdlX3N0YXRlLT5jaGFubmVsX2hvb2tfaW5mby51Q2F1c2FsaXR5OwoKICAgICAgICAvKiBORFIgcmVwcmVzZW50YXRpb24gb2Ygb3JwY3RoaXMtPmV4dGVuc2lvbnMgKi8KICAgICAgICAqKERXT1JEICopbXNnLT5CdWZmZXIgPSBleHRlbnNpb25zX3NpemUgPyAxIDogMDsKICAgICAgICBtc2ctPkJ1ZmZlciA9IChjaGFyICopbXNnLT5CdWZmZXIgKyBzaXplb2YoRFdPUkQpOwoKICAgICAgICBpZiAoZXh0ZW5zaW9uc19zaXplKQogICAgICAgIHsKICAgICAgICAgICAgT1JQQ19FWFRFTlRfQVJSQVkgKm9ycGNfZXh0ZW50X2FycmF5ID0gbXNnLT5CdWZmZXI7CiAgICAgICAgICAgIG9ycGNfZXh0ZW50X2FycmF5LT5zaXplID0gZXh0ZW5zaW9uX2NvdW50OwogICAgICAgICAgICBvcnBjX2V4dGVudF9hcnJheS0+cmVzZXJ2ZWQgPSAwOwogICAgICAgICAgICBtc2ctPkJ1ZmZlciA9IChjaGFyICopbXNnLT5CdWZmZXIgKyBGSUVMRF9PRkZTRVQoT1JQQ19FWFRFTlRfQVJSQVksIGV4dGVudCk7CiAgICAgICAgICAgIC8qIE5EUiByZXByZXNlbnRhdGlvbiBvZiBvcnBjX2V4dGVudF9hcnJheS0+ZXh0ZW50ICovCiAgICAgICAgICAgICooRFdPUkQgKiltc2ctPkJ1ZmZlciA9IDE7CiAgICAgICAgICAgIG1zZy0+QnVmZmVyID0gKGNoYXIgKiltc2ctPkJ1ZmZlciArIHNpemVvZihEV09SRCk7CiAgICAgICAgICAgIC8qIE5EUiByZXByZXNlbnRhdGlvbiBvZiBbc2l6ZV9pc10gYXR0cmlidXRlIG9mIG9ycGNfZXh0ZW50X2FycmF5LT5leHRlbnQgKi8KICAgICAgICAgICAgKihEV09SRCAqKW1zZy0+QnVmZmVyID0gKGV4dGVuc2lvbl9jb3VudCArIDEpICYgfjE7CiAgICAgICAgICAgIG1zZy0+QnVmZmVyID0gKGNoYXIgKiltc2ctPkJ1ZmZlciArIHNpemVvZihEV09SRCk7CgogICAgICAgICAgICBtc2ctPkJ1ZmZlciA9IENoYW5uZWxIb29rc19DbGllbnRGaWxsQnVmZmVyKCZtZXNzYWdlX3N0YXRlLT5jaGFubmVsX2hvb2tfaW5mbywKICAgICAgICAgICAgICAgIG1zZy0+QnVmZmVyLCBjaGFubmVsX2hvb2tfZGF0YSwgY2hhbm5lbF9ob29rX2NvdW50KTsKCiAgICAgICAgICAgIC8qIHdlIG11c3QgYWRkIGEgZHVtbXkgZXh0ZW5zaW9uIGlmIHRoZXJlIGlzIGFuIG9kZCBleHRlbnNpb24KICAgICAgICAgICAgICogY291bnQgdG8gbWVldCB0aGUgY29udHJhY3Qgc3BlY2lmaWVkIGJ5IHRoZSBzaXplX2lzIGF0dHJpYnV0ZSAqLwogICAgICAgICAgICBpZiAoZXh0ZW5zaW9uX2NvdW50ICYgMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgV0lSRV9PUlBDX0VYVEVOVCAqd2lyZV9vcnBjX2V4dGVudCA9IG1zZy0+QnVmZmVyOwogICAgICAgICAgICAgICAgd2lyZV9vcnBjX2V4dGVudC0+Y29uZm9ybWFuY2UgPSAwOwogICAgICAgICAgICAgICAgd2lyZV9vcnBjX2V4dGVudC0+aWQgPSBHVUlEX05VTEw7CiAgICAgICAgICAgICAgICB3aXJlX29ycGNfZXh0ZW50LT5zaXplID0gMDsKICAgICAgICAgICAgICAgIG1zZy0+QnVmZmVyID0gKGNoYXIgKiltc2ctPkJ1ZmZlciArIEZJRUxEX09GRlNFVChXSVJFX09SUENfRVhURU5ULCBkYXRhWzBdKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyogc3RvcmUgdGhlIHByZWZpeGVkIGRhdGEgbGVuZ3RoIHNvIHRoYXQgd2UgY2FuIHJlc3RvcmUgdGhlIHJlYWwgYnVmZmVyCiAgICAgICAgICogcG9pbnRlciBpbiBDbGllbnRScGNDaGFubmVsQnVmZmVyX1NlbmRSZWNlaXZlLiAqLwogICAgICAgIG1lc3NhZ2Vfc3RhdGUtPnByZWZpeF9kYXRhX2xlbiA9IChjaGFyICopbXNnLT5CdWZmZXIgLSAoY2hhciAqKW9ycGN0aGlzOwogICAgICAgIG1zZy0+QnVmZmVyTGVuZ3RoIC09IG1lc3NhZ2Vfc3RhdGUtPnByZWZpeF9kYXRhX2xlbjsKICAgIH0KCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBjaGFubmVsX2hvb2tfZGF0YSk7CgogICAgVFJBQ0UoIi0tICVsZFxuIiwgc3RhdHVzKTsKCiAgICByZXR1cm4gSFJFU1VMVF9GUk9NX1dJTjMyKHN0YXR1cyk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBTZXJ2ZXJScGNDaGFubmVsQnVmZmVyX1NlbmRSZWNlaXZlKExQUlBDQ0hBTk5FTEJVRkZFUiBpZmFjZSwgUlBDT0xFTUVTU0FHRSAqb2xlbXNnLCBVTE9ORyAqcHN0YXR1cykKewogICAgRklYTUUoInN0dWJcbiIpOwogICAgcmV0dXJuIEVfTk9USU1QTDsKfQoKLyogdGhpcyB0aHJlYWQgcnVucyBhbiBvdXRnb2luZyBSUEMgKi8Kc3RhdGljIERXT1JEIFdJTkFQSSBycGNfc2VuZHJlY2VpdmVfdGhyZWFkKExQVk9JRCBwYXJhbSkKewogICAgc3RydWN0IGRpc3BhdGNoX3BhcmFtcyAqZGF0YSA9IChzdHJ1Y3QgZGlzcGF0Y2hfcGFyYW1zICopIHBhcmFtOwoKICAgIC8qIE5vdGU6IElfUnBjU2VuZFJlY2VpdmUgZG9lc24ndCByYWlzZSBleGNlcHRpb25zIGxpa2UgdGhlIGhpZ2hlci1sZXZlbAogICAgICogUlBDIGZ1bmN0aW9ucyBkbyAqLwogICAgZGF0YS0+c3RhdHVzID0gSV9ScGNTZW5kUmVjZWl2ZSgoUlBDX01FU1NBR0UgKilkYXRhLT5tc2cpOwoKICAgIFRSQUNFKCJjb21wbGV0ZWQgd2l0aCBzdGF0dXMgMHglbHhcbiIsIGRhdGEtPnN0YXR1cyk7CgogICAgU2V0RXZlbnQoZGF0YS0+aGFuZGxlKTsKCiAgICByZXR1cm4gMDsKfQoKc3RhdGljIGlubGluZSBIUkVTVUxUIENsaWVudFJwY0NoYW5uZWxCdWZmZXJfSXNDb3JyZWN0QXBhcnRtZW50KENsaWVudFJwY0NoYW5uZWxCdWZmZXIgKlRoaXMsIEFQQVJUTUVOVCAqYXB0KQp7CiAgICBPWElEIG94aWQ7CiAgICBpZiAoIWFwdCkKICAgICAgICByZXR1cm4gU19GQUxTRTsKICAgIGlmIChhcGFydG1lbnRfZ2V0b3hpZChhcHQsICZveGlkKSAhPSBTX09LKQogICAgICAgIHJldHVybiBTX0ZBTFNFOwogICAgaWYgKFRoaXMtPm94aWQgIT0gb3hpZCkKICAgICAgICByZXR1cm4gU19GQUxTRTsKICAgIHJldHVybiBTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlcl9TZW5kUmVjZWl2ZShMUFJQQ0NIQU5ORUxCVUZGRVIgaWZhY2UsIFJQQ09MRU1FU1NBR0UgKm9sZW1zZywgVUxPTkcgKnBzdGF0dXMpCnsKICAgIENsaWVudFJwY0NoYW5uZWxCdWZmZXIgKlRoaXMgPSAoQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlciAqKWlmYWNlOwogICAgSFJFU1VMVCBocjsKICAgIFJQQ19NRVNTQUdFICptc2cgPSAoUlBDX01FU1NBR0UgKilvbGVtc2c7CiAgICBSUENfU1RBVFVTIHN0YXR1czsKICAgIERXT1JEIGluZGV4OwogICAgc3RydWN0IG1lc3NhZ2Vfc3RhdGUgKm1lc3NhZ2Vfc3RhdGU7CiAgICBPUlBDVEhBVCBvcnBjdGhhdDsKICAgIE9SUENfRVhURU5UX0FSUkFZIG9ycGNfZXh0X2FycmF5OwogICAgV0lSRV9PUlBDX0VYVEVOVCAqZmlyc3Rfd2lyZV9vcnBjX2V4dGVudCA9IE5VTEw7CiAgICBIUkVTVUxUIGhyRmF1bHQgPSBTX09LOwoKICAgIFRSQUNFKCIoJXApIGlNZXRob2Q9JWRcbiIsIG9sZW1zZywgb2xlbXNnLT5pTWV0aG9kKTsKCiAgICBociA9IENsaWVudFJwY0NoYW5uZWxCdWZmZXJfSXNDb3JyZWN0QXBhcnRtZW50KFRoaXMsIENPTV9DdXJyZW50QXB0KCkpOwogICAgaWYgKGhyICE9IFNfT0spCiAgICB7CiAgICAgICAgRVJSKCJjYWxsZWQgZnJvbSB3cm9uZyBhcGFydG1lbnQsIHNob3VsZCBoYXZlIGJlZW4gMHglc1xuIiwKICAgICAgICAgICAgd2luZV9kYmdzdHJfbG9uZ2xvbmcoVGhpcy0+b3hpZCkpOwogICAgICAgIHJldHVybiBSUENfRV9XUk9OR19USFJFQUQ7CiAgICB9CiAgICAvKiBUaGlzIHNpdHVhdGlvbiBzaG91bGQgYmUgaW1wb3NzaWJsZSBpbiBtdWx0aS10aHJlYWRlZCBhcGFydG1lbnRzLAogICAgICogYmVjYXVzZSB0aGUgY2FsbGluZyB0aHJlYWQgaXNuJ3QgcmUtZW50ZXJhYmxlLgogICAgICogTm90ZTogZG9pbmcgYSBDT00gY2FsbCBkdXJpbmcgdGhlIHByb2Nlc3Npbmcgb2YgYSBzZW50IG1lc3NhZ2UgaXMKICAgICAqIG9ubHkgZGlzYWxsb3dlZCBpZiBhIGNsaWVudCBjYWxsIGlzIGFscmVhZHkgYmVpbmcgd2FpdGVkIGZvcgogICAgICogY29tcGxldGlvbiAqLwogICAgaWYgKCFDT01fQ3VycmVudEFwdCgpLT5tdWx0aV90aHJlYWRlZCAmJgogICAgICAgIENPTV9DdXJyZW50SW5mbygpLT5wZW5kaW5nX2NhbGxfY291bnRfY2xpZW50ICYmCiAgICAgICAgSW5TZW5kTWVzc2FnZSgpKQogICAgewogICAgICAgIEVSUigiY2FuJ3QgbWFrZSBhbiBvdXRnb2luZyBDT00gY2FsbCBpbiByZXNwb25zZSB0byBhIHNlbnQgbWVzc2FnZVxuIik7CiAgICAgICAgcmV0dXJuIFJQQ19FX0NBTlRDQUxMT1VUX0lOSU5QVVRTWU5DQ0FMTDsKICAgIH0KCiAgICBtZXNzYWdlX3N0YXRlID0gKHN0cnVjdCBtZXNzYWdlX3N0YXRlICopbXNnLT5IYW5kbGU7CiAgICAvKiByZXN0b3JlIHRoZSBiaW5kaW5nIGhhbmRsZSBhbmQgdGhlIHJlYWwgc3RhcnQgb2YgZGF0YSAqLwogICAgbXNnLT5IYW5kbGUgPSBtZXNzYWdlX3N0YXRlLT5iaW5kaW5nX2hhbmRsZTsKICAgIG1zZy0+QnVmZmVyID0gKGNoYXIgKiltc2ctPkJ1ZmZlciAtIG1lc3NhZ2Vfc3RhdGUtPnByZWZpeF9kYXRhX2xlbjsKICAgIG1zZy0+QnVmZmVyTGVuZ3RoICs9IG1lc3NhZ2Vfc3RhdGUtPnByZWZpeF9kYXRhX2xlbjsKCiAgICAvKiBOb3RlOiB0aGlzIGlzIGFuIG9wdGltaXphdGlvbiBpbiB0aGUgTWljcm9zb2Z0IE9MRSBydW50aW1lIHRoYXQgd2UgbmVlZAogICAgICogdG8gY29weSwgYXMgc2hvd24gYnkgdGhlIHRlc3Rfbm9fY291bmluaXRpYWxpemVfY2xpZW50IHRlc3QuIHdpdGhvdXQKICAgICAqIHNob3J0LWNpcmN1aXRpbmcgdGhlIFJQQyBydW50aW1lIGluIHRoZSBjYXNlIGJlbG93LCB0aGUgdGVzdCB3aWxsCiAgICAgKiBkZWFkbG9jayBvbiB0aGUgbG9hZGVyIGxvY2sgZHVlIHRvIHRoZSBSUEMgcnVudGltZSBuZWVkaW5nIHRvIGNyZWF0ZQogICAgICogYSB0aHJlYWQgdG8gcHJvY2VzcyB0aGUgUlBDIHdoZW4gdGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgaW5kaXJlY3RseQogICAgICogZnJvbSBEbGxNYWluICovCgogICAgbWVzc2FnZV9zdGF0ZS0+cGFyYW1zLm1zZyA9IG9sZW1zZzsKICAgIGlmIChtZXNzYWdlX3N0YXRlLT5wYXJhbXMuYnlwYXNzX3JwY3J0KQogICAgewogICAgICAgIFRSQUNFKCJDYWxsaW5nIGFwYXJ0bWVudCB0aHJlYWQgMHglMDh4Li4uXG4iLCBtZXNzYWdlX3N0YXRlLT50YXJnZXRfdGlkKTsKCiAgICAgICAgbXNnLT5Qcm9jTnVtICY9IH5SUENfRkxBR1NfVkFMSURfQklUOwoKICAgICAgICBpZiAoIVBvc3RNZXNzYWdlVyhtZXNzYWdlX3N0YXRlLT50YXJnZXRfaHduZCwgRE1fRVhFQ1VURVJQQywgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBBUkFNKSZtZXNzYWdlX3N0YXRlLT5wYXJhbXMpKQogICAgICAgIHsKICAgICAgICAgICAgRVJSKCJQb3N0TWVzc2FnZSBmYWlsZWQgd2l0aCBlcnJvciAldVxuIiwgR2V0TGFzdEVycm9yKCkpOwoKICAgICAgICAgICAgLyogTm90ZTogbWVzc2FnZV9zdGF0ZS0+cGFyYW1zLmlmYWNlIGRvZXNuJ3QgaGF2ZSBhIHJlZmVyZW5jZSBhbmQKICAgICAgICAgICAgICogc28gZG9lc24ndCBuZWVkIHRvIGJlIHJlbGVhc2VkICovCgogICAgICAgICAgICBociA9IEhSRVNVTFRfRlJPTV9XSU4zMihHZXRMYXN0RXJyb3IoKSk7CiAgICAgICAgfQogICAgfQogICAgZWxzZQogICAgewogICAgICAgIC8qIHdlIHVzZSBhIHNlcGFyYXRlIHRocmVhZCBoZXJlIGJlY2F1c2Ugd2UgbmVlZCB0byBiZSBhYmxlIHRvCiAgICAgICAgICogcHVtcCB0aGUgbWVzc2FnZSBsb29wIGluIHRoZSBhcHBsaWNhdGlvbiB0aHJlYWQ6IGlmIHdlIGRvIG5vdCwKICAgICAgICAgKiBhbnkgd2luZG93cyBjcmVhdGVkIGJ5IHRoaXMgdGhyZWFkIHdpbGwgaGFuZyBhbmQgUlBDcyB0aGF0IHRyeQogICAgICAgICAqIGFuZCByZS1lbnRlciB0aGlzIFNUQSBmcm9tIGFuIGluY29taW5nIHNlcnZlciB0aHJlYWQgd2lsbAogICAgICAgICAqIGRlYWRsb2NrLiBJbnN0YWxsU2hpZWxkIGlzIGFuIGV4YW1wbGUgb2YgdGhhdC4KICAgICAgICAgKi8KICAgICAgICBpZiAoIVF1ZXVlVXNlcldvcmtJdGVtKHJwY19zZW5kcmVjZWl2ZV90aHJlYWQsICZtZXNzYWdlX3N0YXRlLT5wYXJhbXMsIFdUX0VYRUNVVEVERUZBVUxUKSkKICAgICAgICB7CiAgICAgICAgICAgIEVSUigiUXVldWVVc2VyV29ya0l0ZW0gZmFpbGVkIHdpdGggZXJyb3IgJXVcbiIsIEdldExhc3RFcnJvcigpKTsKICAgICAgICAgICAgaHIgPSBFX1VORVhQRUNURUQ7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICAgICAgaHIgPSBTX09LOwogICAgfQoKICAgIGlmIChociA9PSBTX09LKQogICAgewogICAgICAgIGlmIChXYWl0Rm9yU2luZ2xlT2JqZWN0KG1lc3NhZ2Vfc3RhdGUtPnBhcmFtcy5oYW5kbGUsIDApKQogICAgICAgIHsKICAgICAgICAgICAgQ09NX0N1cnJlbnRJbmZvKCktPnBlbmRpbmdfY2FsbF9jb3VudF9jbGllbnQrKzsKICAgICAgICAgICAgaHIgPSBDb1dhaXRGb3JNdWx0aXBsZUhhbmRsZXMoMCwgSU5GSU5JVEUsIDEsICZtZXNzYWdlX3N0YXRlLT5wYXJhbXMuaGFuZGxlLCAmaW5kZXgpOwogICAgICAgICAgICBDT01fQ3VycmVudEluZm8oKS0+cGVuZGluZ19jYWxsX2NvdW50X2NsaWVudC0tOwogICAgICAgIH0KICAgIH0KICAgIENsaWVudFJwY0NoYW5uZWxCdWZmZXJfUmVsZWFzZUV2ZW50SGFuZGxlKFRoaXMsIG1lc3NhZ2Vfc3RhdGUtPnBhcmFtcy5oYW5kbGUpOwoKICAgIC8qIGZvciBXTSBzaG9ydGN1dCwgZmF1bHRzIGFyZSByZXR1cm5lZCBpbiBwYXJhbXMtPmhyICovCiAgICBpZiAoaHIgPT0gU19PSykKICAgICAgICBockZhdWx0ID0gbWVzc2FnZV9zdGF0ZS0+cGFyYW1zLmhyOwoKICAgIHN0YXR1cyA9IG1lc3NhZ2Vfc3RhdGUtPnBhcmFtcy5zdGF0dXM7CgogICAgb3JwY3RoYXQuZmxhZ3MgPSBPUlBDRl9OVUxMOwogICAgb3JwY3RoYXQuZXh0ZW5zaW9ucyA9IE5VTEw7CgogICAgVFJBQ0UoIlJQQyBjYWxsIHN0YXR1czogMHglbHhcbiIsIHN0YXR1cyk7CiAgICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKQogICAgICAgIGhyID0gSFJFU1VMVF9GUk9NX1dJTjMyKHN0YXR1cyk7CgogICAgVFJBQ0UoImhyRmF1bHQgPSAweCUwOHhcbiIsIGhyRmF1bHQpOwoKICAgIC8qIEZJWE1FOiB0aGlzIGNvbmRpdGlvbiBzaG91bGQgYmUKICAgICAqICJociA9PSBTX09LICYmICghaHJGYXVsdCB8fCBtc2ctPkJ1ZmZlckxlbmd0aCA+IEZJRUxEX09GRlNFVChPUlBDVEhBVCwgZXh0ZW5zaW9ucykgKyA0KSIKICAgICAqIGJ1dCB3ZSBkb24ndCBjdXJyZW50bHkgcmVzZXQgdGhlIG1lc3NhZ2UgbGVuZ3RoIGZvciBQb3N0TWVzc2FnZQogICAgICogZGlzcGF0Y2hlZCBjYWxscyAqLwogICAgaWYgKGhyID09IFNfT0sgJiYgaHJGYXVsdCA9PSBTX09LKQogICAgewogICAgICAgIEhSRVNVTFQgaHIyOwogICAgICAgIGNoYXIgKm9yaWdpbmFsX2J1ZmZlciA9IG1zZy0+QnVmZmVyOwoKICAgICAgICAvKiBoYW5kbGUgT1JQQ1RIQVQgYW5kIGNsaWVudCBleHRlbnNpb25zICovCgogICAgICAgIGhyMiA9IHVubWFyc2hhbF9PUlBDVEhBVChtc2csICZvcnBjdGhhdCwgJm9ycGNfZXh0X2FycmF5LCAmZmlyc3Rfd2lyZV9vcnBjX2V4dGVudCk7CiAgICAgICAgaWYgKEZBSUxFRChocjIpKQogICAgICAgICAgICBociA9IGhyMjsKCiAgICAgICAgbWVzc2FnZV9zdGF0ZS0+cHJlZml4X2RhdGFfbGVuID0gKGNoYXIgKiltc2ctPkJ1ZmZlciAtIG9yaWdpbmFsX2J1ZmZlcjsKICAgICAgICBtc2ctPkJ1ZmZlckxlbmd0aCAtPSBtZXNzYWdlX3N0YXRlLT5wcmVmaXhfZGF0YV9sZW47CiAgICB9CiAgICBlbHNlCiAgICAgICAgbWVzc2FnZV9zdGF0ZS0+cHJlZml4X2RhdGFfbGVuID0gMDsKCiAgICBpZiAoaHIgPT0gU19PSykKICAgIHsKICAgICAgICBDaGFubmVsSG9va3NfQ2xpZW50Tm90aWZ5KCZtZXNzYWdlX3N0YXRlLT5jaGFubmVsX2hvb2tfaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1zZy0+RGF0YVJlcHJlc2VudGF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3Rfd2lyZV9vcnBjX2V4dGVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ycGN0aGF0LmV4dGVuc2lvbnMgJiYgZmlyc3Rfd2lyZV9vcnBjX2V4dGVudCA/IG9ycGN0aGF0LmV4dGVuc2lvbnMtPnNpemUgOiAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaHJGYXVsdCk7CiAgICB9CgogICAgLyogc2F2ZSBhd2F5IHRoZSBtZXNzYWdlIHN0YXRlIGFnYWluICovCiAgICBtc2ctPkhhbmRsZSA9IG1lc3NhZ2Vfc3RhdGU7CgogICAgaWYgKHBzdGF0dXMpICpwc3RhdHVzID0gc3RhdHVzOwoKICAgIGlmIChociA9PSBTX09LKQogICAgICAgIGhyID0gaHJGYXVsdDsKCiAgICBUUkFDRSgiLS0gMHglMDh4XG4iLCBocik7CgogICAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgU2VydmVyUnBjQ2hhbm5lbEJ1ZmZlcl9GcmVlQnVmZmVyKExQUlBDQ0hBTk5FTEJVRkZFUiBpZmFjZSwgUlBDT0xFTUVTU0FHRSogb2xlbXNnKQp7CiAgICBSUENfTUVTU0FHRSAqbXNnID0gKFJQQ19NRVNTQUdFICopb2xlbXNnOwogICAgUlBDX1NUQVRVUyBzdGF0dXM7CiAgICBzdHJ1Y3QgbWVzc2FnZV9zdGF0ZSAqbWVzc2FnZV9zdGF0ZTsKCiAgICBUUkFDRSgiKCVwKVxuIiwgbXNnKTsKCiAgICBtZXNzYWdlX3N0YXRlID0gKHN0cnVjdCBtZXNzYWdlX3N0YXRlICopbXNnLT5IYW5kbGU7CiAgICAvKiByZXN0b3JlIHRoZSBiaW5kaW5nIGhhbmRsZSBhbmQgdGhlIHJlYWwgc3RhcnQgb2YgZGF0YSAqLwogICAgbXNnLT5IYW5kbGUgPSBtZXNzYWdlX3N0YXRlLT5iaW5kaW5nX2hhbmRsZTsKICAgIG1zZy0+QnVmZmVyID0gKGNoYXIgKiltc2ctPkJ1ZmZlciAtIG1lc3NhZ2Vfc3RhdGUtPnByZWZpeF9kYXRhX2xlbjsKICAgIG1zZy0+QnVmZmVyTGVuZ3RoICs9IG1lc3NhZ2Vfc3RhdGUtPnByZWZpeF9kYXRhX2xlbjsKICAgIG1lc3NhZ2Vfc3RhdGUtPnByZWZpeF9kYXRhX2xlbiA9IDA7CgogICAgaWYgKG1lc3NhZ2Vfc3RhdGUtPmJ5cGFzc19ycGNydCkKICAgIHsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBtc2ctPkJ1ZmZlcik7CiAgICAgICAgc3RhdHVzID0gUlBDX1NfT0s7CiAgICB9CiAgICBlbHNlCiAgICAgICAgc3RhdHVzID0gSV9ScGNGcmVlQnVmZmVyKG1zZyk7CgogICAgbXNnLT5IYW5kbGUgPSBtZXNzYWdlX3N0YXRlOwoKICAgIFRSQUNFKCItLSAlbGRcbiIsIHN0YXR1cyk7CgogICAgcmV0dXJuIEhSRVNVTFRfRlJPTV9XSU4zMihzdGF0dXMpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlcl9GcmVlQnVmZmVyKExQUlBDQ0hBTk5FTEJVRkZFUiBpZmFjZSwgUlBDT0xFTUVTU0FHRSogb2xlbXNnKQp7CiAgICBSUENfTUVTU0FHRSAqbXNnID0gKFJQQ19NRVNTQUdFICopb2xlbXNnOwogICAgUlBDX1NUQVRVUyBzdGF0dXM7CiAgICBzdHJ1Y3QgbWVzc2FnZV9zdGF0ZSAqbWVzc2FnZV9zdGF0ZTsKCiAgICBUUkFDRSgiKCVwKVxuIiwgbXNnKTsKCiAgICBtZXNzYWdlX3N0YXRlID0gKHN0cnVjdCBtZXNzYWdlX3N0YXRlICopbXNnLT5IYW5kbGU7CiAgICAvKiByZXN0b3JlIHRoZSBiaW5kaW5nIGhhbmRsZSBhbmQgdGhlIHJlYWwgc3RhcnQgb2YgZGF0YSAqLwogICAgbXNnLT5IYW5kbGUgPSBtZXNzYWdlX3N0YXRlLT5iaW5kaW5nX2hhbmRsZTsKICAgIG1zZy0+QnVmZmVyID0gKGNoYXIgKiltc2ctPkJ1ZmZlciAtIG1lc3NhZ2Vfc3RhdGUtPnByZWZpeF9kYXRhX2xlbjsKICAgIG1zZy0+QnVmZmVyTGVuZ3RoICs9IG1lc3NhZ2Vfc3RhdGUtPnByZWZpeF9kYXRhX2xlbjsKCiAgICBpZiAobWVzc2FnZV9zdGF0ZS0+cGFyYW1zLmJ5cGFzc19ycGNydCkKICAgIHsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBtc2ctPkJ1ZmZlcik7CiAgICAgICAgc3RhdHVzID0gUlBDX1NfT0s7CiAgICB9CiAgICBlbHNlCiAgICAgICAgc3RhdHVzID0gSV9ScGNGcmVlQnVmZmVyKG1zZyk7CgogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbXNnLT5ScGNJbnRlcmZhY2VJbmZvcm1hdGlvbik7CiAgICBtc2ctPlJwY0ludGVyZmFjZUluZm9ybWF0aW9uID0gTlVMTDsKCiAgICBpZiAobWVzc2FnZV9zdGF0ZS0+cGFyYW1zLnN0dWIpCiAgICAgICAgSVJwY1N0dWJCdWZmZXJfUmVsZWFzZShtZXNzYWdlX3N0YXRlLT5wYXJhbXMuc3R1Yik7CiAgICBpZiAobWVzc2FnZV9zdGF0ZS0+cGFyYW1zLmNoYW4pCiAgICAgICAgSVJwY0NoYW5uZWxCdWZmZXJfUmVsZWFzZShtZXNzYWdlX3N0YXRlLT5wYXJhbXMuY2hhbik7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBtZXNzYWdlX3N0YXRlKTsKCiAgICBUUkFDRSgiLS0gJWxkXG4iLCBzdGF0dXMpOwoKICAgIHJldHVybiBIUkVTVUxUX0ZST01fV0lOMzIoc3RhdHVzKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIENsaWVudFJwY0NoYW5uZWxCdWZmZXJfR2V0RGVzdEN0eChMUFJQQ0NIQU5ORUxCVUZGRVIgaWZhY2UsIERXT1JEKiBwZHdEZXN0Q29udGV4dCwgdm9pZCoqIHBwdkRlc3RDb250ZXh0KQp7CiAgICBDbGllbnRScGNDaGFubmVsQnVmZmVyICpUaGlzID0gKENsaWVudFJwY0NoYW5uZWxCdWZmZXIgKilpZmFjZTsKCiAgICBUUkFDRSgiKCVwLCVwKVxuIiwgcGR3RGVzdENvbnRleHQsIHBwdkRlc3RDb250ZXh0KTsKCiAgICAqcGR3RGVzdENvbnRleHQgPSBUaGlzLT5kZXN0X2NvbnRleHQ7CiAgICAqcHB2RGVzdENvbnRleHQgPSBUaGlzLT5kZXN0X2NvbnRleHRfZGF0YTsKCiAgICByZXR1cm4gU19PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFNlcnZlclJwY0NoYW5uZWxCdWZmZXJfR2V0RGVzdEN0eChMUFJQQ0NIQU5ORUxCVUZGRVIgaWZhY2UsIERXT1JEKiBwZHdEZXN0Q29udGV4dCwgdm9pZCoqIHBwdkRlc3RDb250ZXh0KQp7CiAgICBXQVJOKCIoJXAsJXApLCBzdHViIVxuIiwgcGR3RGVzdENvbnRleHQsIHBwdkRlc3RDb250ZXh0KTsKCiAgICAvKiBGSVhNRTogaW1wbGVtZW50IHRoaXMgYnkgc3RvcmluZyB0aGUgZHdEZXN0Q29udGV4dCBhbmQgcHZEZXN0Q29udGV4dAogICAgICogdmFsdWVzIHBhc3NlZCBpbnRvIElNYXJzaGFsX01hcnNoYWxJbnRlcmZhY2UgYW5kIHJldHVybmluZyB0aGVtIGhlcmUgKi8KICAgICpwZHdEZXN0Q29udGV4dCA9IE1TSENUWF9ESUZGRVJFTlRNQUNISU5FOwogICAgKnBwdkRlc3RDb250ZXh0ID0gTlVMTDsKICAgIHJldHVybiBTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgUnBjQ2hhbm5lbEJ1ZmZlcl9Jc0Nvbm5lY3RlZChMUFJQQ0NIQU5ORUxCVUZGRVIgaWZhY2UpCnsKICAgIFRSQUNFKCIoKVxuIik7CiAgICAvKiBuYXRpdmUgZG9lcyBub3RoaW5nIHRvbyAqLwogICAgcmV0dXJuIFNfT0s7Cn0KCnN0YXRpYyBjb25zdCBJUnBjQ2hhbm5lbEJ1ZmZlclZ0YmwgQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlclZ0YmwgPQp7CiAgICBScGNDaGFubmVsQnVmZmVyX1F1ZXJ5SW50ZXJmYWNlLAogICAgUnBjQ2hhbm5lbEJ1ZmZlcl9BZGRSZWYsCiAgICBDbGllbnRScGNDaGFubmVsQnVmZmVyX1JlbGVhc2UsCiAgICBDbGllbnRScGNDaGFubmVsQnVmZmVyX0dldEJ1ZmZlciwKICAgIENsaWVudFJwY0NoYW5uZWxCdWZmZXJfU2VuZFJlY2VpdmUsCiAgICBDbGllbnRScGNDaGFubmVsQnVmZmVyX0ZyZWVCdWZmZXIsCiAgICBDbGllbnRScGNDaGFubmVsQnVmZmVyX0dldERlc3RDdHgsCiAgICBScGNDaGFubmVsQnVmZmVyX0lzQ29ubmVjdGVkCn07CgpzdGF0aWMgY29uc3QgSVJwY0NoYW5uZWxCdWZmZXJWdGJsIFNlcnZlclJwY0NoYW5uZWxCdWZmZXJWdGJsID0KewogICAgUnBjQ2hhbm5lbEJ1ZmZlcl9RdWVyeUludGVyZmFjZSwKICAgIFJwY0NoYW5uZWxCdWZmZXJfQWRkUmVmLAogICAgU2VydmVyUnBjQ2hhbm5lbEJ1ZmZlcl9SZWxlYXNlLAogICAgU2VydmVyUnBjQ2hhbm5lbEJ1ZmZlcl9HZXRCdWZmZXIsCiAgICBTZXJ2ZXJScGNDaGFubmVsQnVmZmVyX1NlbmRSZWNlaXZlLAogICAgU2VydmVyUnBjQ2hhbm5lbEJ1ZmZlcl9GcmVlQnVmZmVyLAogICAgU2VydmVyUnBjQ2hhbm5lbEJ1ZmZlcl9HZXREZXN0Q3R4LAogICAgUnBjQ2hhbm5lbEJ1ZmZlcl9Jc0Nvbm5lY3RlZAp9OwoKLyogcmV0dXJucyBhIGNoYW5uZWwgYnVmZmVyIGZvciBwcm94aWVzICovCkhSRVNVTFQgUlBDX0NyZWF0ZUNsaWVudENoYW5uZWwoY29uc3QgT1hJRCAqb3hpZCwgY29uc3QgSVBJRCAqaXBpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBPWElEX0lORk8gKm94aWRfaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkZXN0X2NvbnRleHQsIHZvaWQgKmRlc3RfY29udGV4dF9kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElScGNDaGFubmVsQnVmZmVyICoqY2hhbikKewogICAgQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlciAqVGhpczsKICAgIFdDSEFSICAgICAgICAgICAgICAgICAgIGVuZHBvaW50WzIwMF07CiAgICBSUENfQklORElOR19IQU5ETEUgICAgICBiaW5kOwogICAgUlBDX1NUQVRVUyAgICAgICAgICAgICAgc3RhdHVzOwogICAgTFBXU1RSICAgICAgICAgICAgICAgICAgc3RyaW5nX2JpbmRpbmc7CgogICAgLyogRklYTUU6IGdldCB0aGUgZW5kcG9pbnQgZnJvbSBveGlkX2luZm8tPnBzYSBpbnN0ZWFkICovCiAgICBnZXRfcnBjX2VuZHBvaW50KGVuZHBvaW50LCBveGlkKTsKCiAgICBUUkFDRSgicHJveHkgcGlwZTogY29ubmVjdGluZyB0byBlbmRwb2ludDogJXNcbiIsIGRlYnVnc3RyX3coZW5kcG9pbnQpKTsKCiAgICBzdGF0dXMgPSBScGNTdHJpbmdCaW5kaW5nQ29tcG9zZVcoCiAgICAgICAgTlVMTCwKICAgICAgICB3c3pScGNUcmFuc3BvcnQsCiAgICAgICAgTlVMTCwKICAgICAgICBlbmRwb2ludCwKICAgICAgICBOVUxMLAogICAgICAgICZzdHJpbmdfYmluZGluZyk7CiAgICAgICAgCiAgICBpZiAoc3RhdHVzID09IFJQQ19TX09LKQogICAgewogICAgICAgIHN0YXR1cyA9IFJwY0JpbmRpbmdGcm9tU3RyaW5nQmluZGluZ1coc3RyaW5nX2JpbmRpbmcsICZiaW5kKTsKCiAgICAgICAgaWYgKHN0YXR1cyA9PSBSUENfU19PSykKICAgICAgICB7CiAgICAgICAgICAgIElQSUQgaXBpZDIgPSAqaXBpZDsgLyogd2h5IGNhbid0IFJwY0JpbmRpbmdTZXRPYmplY3QgdGFrZSBhIGNvbnN0PyAqLwogICAgICAgICAgICBzdGF0dXMgPSBScGNCaW5kaW5nU2V0T2JqZWN0KGJpbmQsICZpcGlkMik7CiAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gUlBDX1NfT0spCiAgICAgICAgICAgICAgICBScGNCaW5kaW5nRnJlZSgmYmluZCk7CiAgICAgICAgfQoKICAgICAgICBScGNTdHJpbmdGcmVlVygmc3RyaW5nX2JpbmRpbmcpOwogICAgfQoKICAgIGlmIChzdGF0dXMgIT0gUlBDX1NfT0spCiAgICB7CiAgICAgICAgRVJSKCJDb3VsZG4ndCBnZXQgYmluZGluZyBmb3IgZW5kcG9pbnQgJXMsIHN0YXR1cyA9ICVsZFxuIiwgZGVidWdzdHJfdyhlbmRwb2ludCksIHN0YXR1cyk7CiAgICAgICAgcmV0dXJuIEhSRVNVTFRfRlJPTV9XSU4zMihzdGF0dXMpOwogICAgfQoKICAgIFRoaXMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKCpUaGlzKSk7CiAgICBpZiAoIVRoaXMpCiAgICB7CiAgICAgICAgUnBjQmluZGluZ0ZyZWUoJmJpbmQpOwogICAgICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwogICAgfQoKICAgIFRoaXMtPnN1cGVyLmxwVnRibCA9ICZDbGllbnRScGNDaGFubmVsQnVmZmVyVnRibDsKICAgIFRoaXMtPnN1cGVyLnJlZnMgPSAxOwogICAgVGhpcy0+YmluZCA9IGJpbmQ7CiAgICBhcGFydG1lbnRfZ2V0b3hpZChDT01fQ3VycmVudEFwdCgpLCAmVGhpcy0+b3hpZCk7CiAgICBUaGlzLT5zZXJ2ZXJfcGlkID0gb3hpZF9pbmZvLT5kd1BpZDsKICAgIFRoaXMtPmRlc3RfY29udGV4dCA9IGRlc3RfY29udGV4dDsKICAgIFRoaXMtPmRlc3RfY29udGV4dF9kYXRhID0gZGVzdF9jb250ZXh0X2RhdGE7CiAgICBUaGlzLT5ldmVudCA9IE5VTEw7CgogICAgKmNoYW4gPSAoSVJwY0NoYW5uZWxCdWZmZXIqKVRoaXM7CgogICAgcmV0dXJuIFNfT0s7Cn0KCkhSRVNVTFQgUlBDX0NyZWF0ZVNlcnZlckNoYW5uZWwoSVJwY0NoYW5uZWxCdWZmZXIgKipjaGFuKQp7CiAgICBScGNDaGFubmVsQnVmZmVyICpUaGlzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZigqVGhpcykpOwogICAgaWYgKCFUaGlzKQogICAgICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwoKICAgIFRoaXMtPmxwVnRibCA9ICZTZXJ2ZXJScGNDaGFubmVsQnVmZmVyVnRibDsKICAgIFRoaXMtPnJlZnMgPSAxOwogICAgCiAgICAqY2hhbiA9IChJUnBjQ2hhbm5lbEJ1ZmZlciopVGhpczsKCiAgICByZXR1cm4gU19PSzsKfQoKLyogdW5tYXJzaGFscyBPUlBDX0VYVEVOVF9BUlJBWSBhY2NvcmRpbmcgdG8gTkRSIHJ1bGVzLCBidXQgZG9lc24ndCBhbGxvY2F0ZQogKiBhbnkgbWVtb3J5ICovCnN0YXRpYyBIUkVTVUxUIHVubWFyc2hhbF9PUlBDX0VYVEVOVF9BUlJBWShSUENfTUVTU0FHRSAqbXNnLCBjb25zdCBjaGFyICplbmQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPUlBDX0VYVEVOVF9BUlJBWSAqZXh0ZW5zaW9ucywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJUkVfT1JQQ19FWFRFTlQgKipmaXJzdF93aXJlX29ycGNfZXh0ZW50KQp7CiAgICBEV09SRCBwb2ludGVyX2lkOwogICAgRFdPUkQgaTsKCiAgICBtZW1jcHkoZXh0ZW5zaW9ucywgbXNnLT5CdWZmZXIsIEZJRUxEX09GRlNFVChPUlBDX0VYVEVOVF9BUlJBWSwgZXh0ZW50KSk7CiAgICBtc2ctPkJ1ZmZlciA9IChjaGFyICopbXNnLT5CdWZmZXIgKyBGSUVMRF9PRkZTRVQoT1JQQ19FWFRFTlRfQVJSQVksIGV4dGVudCk7CgogICAgaWYgKChjb25zdCBjaGFyICopbXNnLT5CdWZmZXIgKyAyICogc2l6ZW9mKERXT1JEKSA+IGVuZCkKICAgICAgICByZXR1cm4gUlBDX0VfSU5WQUxJRF9IRUFERVI7CgogICAgcG9pbnRlcl9pZCA9ICooRFdPUkQgKiltc2ctPkJ1ZmZlcjsKICAgIG1zZy0+QnVmZmVyID0gKGNoYXIgKiltc2ctPkJ1ZmZlciArIHNpemVvZihEV09SRCk7CiAgICBleHRlbnNpb25zLT5leHRlbnQgPSBOVUxMOwoKICAgIGlmIChwb2ludGVyX2lkKQogICAgewogICAgICAgIFdJUkVfT1JQQ19FWFRFTlQgKndpcmVfb3JwY19leHRlbnQ7CgogICAgICAgIC8qIGNvbmZvcm1hbmNlICovCiAgICAgICAgaWYgKCooRFdPUkQgKiltc2ctPkJ1ZmZlciAhPSAoKGV4dGVuc2lvbnMtPnNpemUrMSkmfjEpKQogICAgICAgICAgICByZXR1cm4gUlBDX1NfSU5WQUxJRF9CT1VORDsKCiAgICAgICAgbXNnLT5CdWZmZXIgPSAoY2hhciAqKW1zZy0+QnVmZmVyICsgc2l6ZW9mKERXT1JEKTsKCiAgICAgICAgLyogYXJiaXRyYXJ5IGxpbWl0IGZvciBzZWN1cml0eSAoZG9uJ3Qga25vdyB3aGF0IG5hdGl2ZSBkb2VzKSAqLwogICAgICAgIGlmIChleHRlbnNpb25zLT5zaXplID4gMjU2KQogICAgICAgIHsKICAgICAgICAgICAgRVJSKCJ0b28gbWFueSBleHRlbnNpb25zOiAlbGRcbiIsIGV4dGVuc2lvbnMtPnNpemUpOwogICAgICAgICAgICByZXR1cm4gUlBDX1NfSU5WQUxJRF9CT1VORDsKICAgICAgICB9CgogICAgICAgICpmaXJzdF93aXJlX29ycGNfZXh0ZW50ID0gd2lyZV9vcnBjX2V4dGVudCA9IChXSVJFX09SUENfRVhURU5UICopbXNnLT5CdWZmZXI7CiAgICAgICAgZm9yIChpID0gMDsgaSA8ICgoZXh0ZW5zaW9ucy0+c2l6ZSsxKSZ+MSk7IGkrKykKICAgICAgICB7CiAgICAgICAgICAgIGlmICgoY29uc3QgY2hhciAqKSZ3aXJlX29ycGNfZXh0ZW50LT5kYXRhWzBdID4gZW5kKQogICAgICAgICAgICAgICAgcmV0dXJuIFJQQ19TX0lOVkFMSURfQk9VTkQ7CiAgICAgICAgICAgIGlmICh3aXJlX29ycGNfZXh0ZW50LT5jb25mb3JtYW5jZSAhPSAoKHdpcmVfb3JwY19leHRlbnQtPnNpemUrNykmfjcpKQogICAgICAgICAgICAgICAgcmV0dXJuIFJQQ19TX0lOVkFMSURfQk9VTkQ7CiAgICAgICAgICAgIGlmICgoY29uc3QgY2hhciAqKSZ3aXJlX29ycGNfZXh0ZW50LT5kYXRhW3dpcmVfb3JwY19leHRlbnQtPmNvbmZvcm1hbmNlXSA+IGVuZCkKICAgICAgICAgICAgICAgIHJldHVybiBSUENfU19JTlZBTElEX0JPVU5EOwogICAgICAgICAgICBUUkFDRSgic2l6ZSAldSwgZ3VpZCAlc1xuIiwgd2lyZV9vcnBjX2V4dGVudC0+c2l6ZSwgZGVidWdzdHJfZ3VpZCgmd2lyZV9vcnBjX2V4dGVudC0+aWQpKTsKICAgICAgICAgICAgd2lyZV9vcnBjX2V4dGVudCA9IChXSVJFX09SUENfRVhURU5UICopJndpcmVfb3JwY19leHRlbnQtPmRhdGFbd2lyZV9vcnBjX2V4dGVudC0+Y29uZm9ybWFuY2VdOwogICAgICAgIH0KICAgICAgICBtc2ctPkJ1ZmZlciA9IHdpcmVfb3JwY19leHRlbnQ7CiAgICB9CgogICAgcmV0dXJuIFNfT0s7Cn0KCi8qIHVubWFyc2hhbHMgT1JQQ1RISVMgYWNjb3JkaW5nIHRvIE5EUiBydWxlcywgYnV0IGRvZXNuJ3QgYWxsb2NhdGUgYW55IG1lbW9yeSAqLwpzdGF0aWMgSFJFU1VMVCB1bm1hcnNoYWxfT1JQQ1RISVMoUlBDX01FU1NBR0UgKm1zZywgT1JQQ1RISVMgKm9ycGN0aGlzLAogICAgT1JQQ19FWFRFTlRfQVJSQVkgKm9ycGNfZXh0X2FycmF5LCBXSVJFX09SUENfRVhURU5UICoqZmlyc3Rfd2lyZV9vcnBjX2V4dGVudCkKewogICAgY29uc3QgY2hhciAqZW5kID0gKGNoYXIgKiltc2ctPkJ1ZmZlciArIG1zZy0+QnVmZmVyTGVuZ3RoOwoKICAgICpmaXJzdF93aXJlX29ycGNfZXh0ZW50ID0gTlVMTDsKCiAgICBpZiAobXNnLT5CdWZmZXJMZW5ndGggPCBGSUVMRF9PRkZTRVQoT1JQQ1RISVMsIGV4dGVuc2lvbnMpICsgNCkKICAgIHsKICAgICAgICBFUlIoImludmFsaWQgYnVmZmVyIGxlbmd0aFxuIik7CiAgICAgICAgcmV0dXJuIFJQQ19FX0lOVkFMSURfSEVBREVSOwogICAgfQoKICAgIG1lbWNweShvcnBjdGhpcywgbXNnLT5CdWZmZXIsIEZJRUxEX09GRlNFVChPUlBDVEhJUywgZXh0ZW5zaW9ucykpOwogICAgbXNnLT5CdWZmZXIgPSAoY2hhciAqKW1zZy0+QnVmZmVyICsgRklFTERfT0ZGU0VUKE9SUENUSElTLCBleHRlbnNpb25zKTsKCiAgICBpZiAoKGNvbnN0IGNoYXIgKiltc2ctPkJ1ZmZlciArIHNpemVvZihEV09SRCkgPiBlbmQpCiAgICAgICAgcmV0dXJuIFJQQ19FX0lOVkFMSURfSEVBREVSOwoKICAgIGlmICgqKERXT1JEICopbXNnLT5CdWZmZXIpCiAgICAgICAgb3JwY3RoaXMtPmV4dGVuc2lvbnMgPSBvcnBjX2V4dF9hcnJheTsKICAgIGVsc2UKICAgICAgICBvcnBjdGhpcy0+ZXh0ZW5zaW9ucyA9IE5VTEw7CgogICAgbXNnLT5CdWZmZXIgPSAoY2hhciAqKW1zZy0+QnVmZmVyICsgc2l6ZW9mKERXT1JEKTsKCiAgICBpZiAob3JwY3RoaXMtPmV4dGVuc2lvbnMpCiAgICB7CiAgICAgICAgSFJFU1VMVCBociA9IHVubWFyc2hhbF9PUlBDX0VYVEVOVF9BUlJBWShtc2csIGVuZCwgb3JwY19leHRfYXJyYXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaXJzdF93aXJlX29ycGNfZXh0ZW50KTsKICAgICAgICBpZiAoRkFJTEVEKGhyKSkKICAgICAgICAgICAgcmV0dXJuIGhyOwogICAgfQoKICAgIGlmICgob3JwY3RoaXMtPnZlcnNpb24uTWFqb3JWZXJzaW9uICE9IENPTV9NQUpPUl9WRVJTSU9OKSB8fAogICAgICAgIChvcnBjdGhpcy0+dmVyc2lvbi5NaW5vclZlcnNpb24gPiBDT01fTUlOT1JfVkVSU0lPTikpCiAgICB7CiAgICAgICAgRVJSKCJDT00gdmVyc2lvbiB7JWQsICVkfSBub3Qgc3VwcG9ydGVkXG4iLAogICAgICAgICAgICBvcnBjdGhpcy0+dmVyc2lvbi5NYWpvclZlcnNpb24sIG9ycGN0aGlzLT52ZXJzaW9uLk1pbm9yVmVyc2lvbik7CiAgICAgICAgcmV0dXJuIFJQQ19FX1ZFUlNJT05fTUlTTUFUQ0g7CiAgICB9CgogICAgaWYgKG9ycGN0aGlzLT5mbGFncyAmIH4oT1JQQ0ZfTE9DQUx8T1JQQ0ZfUkVTRVJWRUQxfE9SUENGX1JFU0VSVkVEMnxPUlBDRl9SRVNFUlZFRDN8T1JQQ0ZfUkVTRVJWRUQ0KSkKICAgIHsKICAgICAgICBFUlIoImludmFsaWQgZmxhZ3MgMHglbHhcbiIsIG9ycGN0aGlzLT5mbGFncyAmIH4oT1JQQ0ZfTE9DQUx8T1JQQ0ZfUkVTRVJWRUQxfE9SUENGX1JFU0VSVkVEMnxPUlBDRl9SRVNFUlZFRDN8T1JQQ0ZfUkVTRVJWRUQ0KSk7CiAgICAgICAgcmV0dXJuIFJQQ19FX0lOVkFMSURfSEVBREVSOwogICAgfQoKICAgIHJldHVybiBTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCB1bm1hcnNoYWxfT1JQQ1RIQVQoUlBDX01FU1NBR0UgKm1zZywgT1JQQ1RIQVQgKm9ycGN0aGF0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT1JQQ19FWFRFTlRfQVJSQVkgKm9ycGNfZXh0X2FycmF5LCBXSVJFX09SUENfRVhURU5UICoqZmlyc3Rfd2lyZV9vcnBjX2V4dGVudCkKewogICAgY29uc3QgY2hhciAqZW5kID0gKGNoYXIgKiltc2ctPkJ1ZmZlciArIG1zZy0+QnVmZmVyTGVuZ3RoOwoKICAgICpmaXJzdF93aXJlX29ycGNfZXh0ZW50ID0gTlVMTDsKCiAgICBpZiAobXNnLT5CdWZmZXJMZW5ndGggPCBGSUVMRF9PRkZTRVQoT1JQQ1RIQVQsIGV4dGVuc2lvbnMpICsgNCkKICAgIHsKICAgICAgICBFUlIoImludmFsaWQgYnVmZmVyIGxlbmd0aFxuIik7CiAgICAgICAgcmV0dXJuIFJQQ19FX0lOVkFMSURfSEVBREVSOwogICAgfQoKICAgIG1lbWNweShvcnBjdGhhdCwgbXNnLT5CdWZmZXIsIEZJRUxEX09GRlNFVChPUlBDVEhBVCwgZXh0ZW5zaW9ucykpOwogICAgbXNnLT5CdWZmZXIgPSAoY2hhciAqKW1zZy0+QnVmZmVyICsgRklFTERfT0ZGU0VUKE9SUENUSEFULCBleHRlbnNpb25zKTsKCiAgICBpZiAoKGNvbnN0IGNoYXIgKiltc2ctPkJ1ZmZlciArIHNpemVvZihEV09SRCkgPiBlbmQpCiAgICAgICAgcmV0dXJuIFJQQ19FX0lOVkFMSURfSEVBREVSOwoKICAgIGlmICgqKERXT1JEICopbXNnLT5CdWZmZXIpCiAgICAgICAgb3JwY3RoYXQtPmV4dGVuc2lvbnMgPSBvcnBjX2V4dF9hcnJheTsKICAgIGVsc2UKICAgICAgICBvcnBjdGhhdC0+ZXh0ZW5zaW9ucyA9IE5VTEw7CgogICAgbXNnLT5CdWZmZXIgPSAoY2hhciAqKW1zZy0+QnVmZmVyICsgc2l6ZW9mKERXT1JEKTsKCiAgICBpZiAob3JwY3RoYXQtPmV4dGVuc2lvbnMpCiAgICB7CiAgICAgICAgSFJFU1VMVCBociA9IHVubWFyc2hhbF9PUlBDX0VYVEVOVF9BUlJBWShtc2csIGVuZCwgb3JwY19leHRfYXJyYXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaXJzdF93aXJlX29ycGNfZXh0ZW50KTsKICAgICAgICBpZiAoRkFJTEVEKGhyKSkKICAgICAgICAgICAgcmV0dXJuIGhyOwogICAgfQoKICAgIGlmIChvcnBjdGhhdC0+ZmxhZ3MgJiB+KE9SUENGX0xPQ0FMfE9SUENGX1JFU0VSVkVEMXxPUlBDRl9SRVNFUlZFRDJ8T1JQQ0ZfUkVTRVJWRUQzfE9SUENGX1JFU0VSVkVENCkpCiAgICB7CiAgICAgICAgRVJSKCJpbnZhbGlkIGZsYWdzIDB4JWx4XG4iLCBvcnBjdGhhdC0+ZmxhZ3MgJiB+KE9SUENGX0xPQ0FMfE9SUENGX1JFU0VSVkVEMXxPUlBDRl9SRVNFUlZFRDJ8T1JQQ0ZfUkVTRVJWRUQzfE9SUENGX1JFU0VSVkVENCkpOwogICAgICAgIHJldHVybiBSUENfRV9JTlZBTElEX0hFQURFUjsKICAgIH0KCiAgICByZXR1cm4gU19PSzsKfQoKdm9pZCBSUENfRXhlY3V0ZUNhbGwoc3RydWN0IGRpc3BhdGNoX3BhcmFtcyAqcGFyYW1zKQp7CiAgICBzdHJ1Y3QgbWVzc2FnZV9zdGF0ZSAqbWVzc2FnZV9zdGF0ZSA9IE5VTEw7CiAgICBSUENfTUVTU0FHRSAqbXNnID0gKFJQQ19NRVNTQUdFICopcGFyYW1zLT5tc2c7CiAgICBjaGFyICpvcmlnaW5hbF9idWZmZXIgPSBtc2ctPkJ1ZmZlcjsKICAgIE9SUENUSElTIG9ycGN0aGlzOwogICAgT1JQQ19FWFRFTlRfQVJSQVkgb3JwY19leHRfYXJyYXk7CiAgICBXSVJFX09SUENfRVhURU5UICpmaXJzdF93aXJlX29ycGNfZXh0ZW50OwogICAgR1VJRCBvbGRfY2F1c2FsaXR5X2lkOwoKICAgIC8qIGhhbmRsZSBPUlBDVEhJUyBhbmQgc2VydmVyIGV4dGVuc2lvbnMgKi8KCiAgICBwYXJhbXMtPmhyID0gdW5tYXJzaGFsX09SUENUSElTKG1zZywgJm9ycGN0aGlzLCAmb3JwY19leHRfYXJyYXksICZmaXJzdF93aXJlX29ycGNfZXh0ZW50KTsKICAgIGlmIChwYXJhbXMtPmhyICE9IFNfT0spCiAgICB7CiAgICAgICAgbXNnLT5CdWZmZXIgPSBvcmlnaW5hbF9idWZmZXI7CiAgICAgICAgZ290byBleGl0OwogICAgfQoKICAgIG1lc3NhZ2Vfc3RhdGUgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKCptZXNzYWdlX3N0YXRlKSk7CiAgICBpZiAoIW1lc3NhZ2Vfc3RhdGUpCiAgICB7CiAgICAgICAgcGFyYW1zLT5ociA9IEVfT1VUT0ZNRU1PUlk7CiAgICAgICAgbXNnLT5CdWZmZXIgPSBvcmlnaW5hbF9idWZmZXI7CiAgICAgICAgZ290byBleGl0OwogICAgfQoKICAgIG1lc3NhZ2Vfc3RhdGUtPnByZWZpeF9kYXRhX2xlbiA9IChjaGFyICopbXNnLT5CdWZmZXIgLSBvcmlnaW5hbF9idWZmZXI7CiAgICBtZXNzYWdlX3N0YXRlLT5iaW5kaW5nX2hhbmRsZSA9IG1zZy0+SGFuZGxlOwogICAgbWVzc2FnZV9zdGF0ZS0+YnlwYXNzX3JwY3J0ID0gcGFyYW1zLT5ieXBhc3NfcnBjcnQ7CgogICAgbWVzc2FnZV9zdGF0ZS0+Y2hhbm5lbF9ob29rX2luZm8uaWlkID0gcGFyYW1zLT5paWQ7CiAgICBtZXNzYWdlX3N0YXRlLT5jaGFubmVsX2hvb2tfaW5mby5jYlNpemUgPSBzaXplb2YobWVzc2FnZV9zdGF0ZS0+Y2hhbm5lbF9ob29rX2luZm8pOwogICAgbWVzc2FnZV9zdGF0ZS0+Y2hhbm5lbF9ob29rX2luZm8udUNhdXNhbGl0eSA9IG9ycGN0aGlzLmNpZDsKICAgIG1lc3NhZ2Vfc3RhdGUtPmNoYW5uZWxfaG9va19pbmZvLmR3U2VydmVyUGlkID0gR2V0Q3VycmVudFByb2Nlc3NJZCgpOwogICAgbWVzc2FnZV9zdGF0ZS0+Y2hhbm5lbF9ob29rX2luZm8uaU1ldGhvZCA9IG1zZy0+UHJvY051bTsKICAgIG1lc3NhZ2Vfc3RhdGUtPmNoYW5uZWxfaG9va19pbmZvLnBPYmplY3QgPSBwYXJhbXMtPmlmYWNlOwoKICAgIGlmIChvcnBjdGhpcy5leHRlbnNpb25zICYmIGZpcnN0X3dpcmVfb3JwY19leHRlbnQgJiYKICAgICAgICBvcnBjdGhpcy5leHRlbnNpb25zLT5zaXplKQogICAgICAgIENoYW5uZWxIb29rc19TZXJ2ZXJOb3RpZnkoJm1lc3NhZ2Vfc3RhdGUtPmNoYW5uZWxfaG9va19pbmZvLCBtc2ctPkRhdGFSZXByZXNlbnRhdGlvbiwgZmlyc3Rfd2lyZV9vcnBjX2V4dGVudCwgb3JwY3RoaXMuZXh0ZW5zaW9ucy0+c2l6ZSk7CgogICAgbXNnLT5IYW5kbGUgPSBtZXNzYWdlX3N0YXRlOwogICAgbXNnLT5CdWZmZXJMZW5ndGggLT0gbWVzc2FnZV9zdGF0ZS0+cHJlZml4X2RhdGFfbGVuOwoKICAgIC8qIGNhbGwgbWVzc2FnZSBmaWx0ZXIgKi8KCiAgICBpZiAoQ09NX0N1cnJlbnRBcHQoKS0+ZmlsdGVyKQogICAgewogICAgICAgIERXT1JEIGhhbmRsZWNhbGw7CiAgICAgICAgSU5URVJGQUNFSU5GTyBpbnRlcmZhY2VfaW5mbzsKICAgICAgICBDQUxMVFlQRSBjYWxsdHlwZTsKCiAgICAgICAgaW50ZXJmYWNlX2luZm8ucFVuayA9IHBhcmFtcy0+aWZhY2U7CiAgICAgICAgaW50ZXJmYWNlX2luZm8uaWlkID0gcGFyYW1zLT5paWQ7CiAgICAgICAgaW50ZXJmYWNlX2luZm8ud01ldGhvZCA9IG1zZy0+UHJvY051bTsKCiAgICAgICAgaWYgKElzRXF1YWxHVUlEKCZvcnBjdGhpcy5jaWQsICZDT01fQ3VycmVudEluZm8oKS0+Y2F1c2FsaXR5X2lkKSkKICAgICAgICAgICAgY2FsbHR5cGUgPSBDQUxMVFlQRV9ORVNURUQ7CiAgICAgICAgZWxzZSBpZiAoQ09NX0N1cnJlbnRJbmZvKCktPnBlbmRpbmdfY2FsbF9jb3VudF9zZXJ2ZXIgPT0gMCkKICAgICAgICAgICAgY2FsbHR5cGUgPSBDQUxMVFlQRV9UT1BMRVZFTDsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGNhbGx0eXBlID0gQ0FMTFRZUEVfVE9QTEVWRUxfQ0FMTFBFTkRJTkc7CgogICAgICAgIGhhbmRsZWNhbGwgPSBJTWVzc2FnZUZpbHRlcl9IYW5kbGVJbkNvbWluZ0NhbGwoQ09NX0N1cnJlbnRBcHQoKS0+ZmlsdGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbHR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoSFRBU0spR2V0Q3VycmVudFByb2Nlc3NJZCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCAvKiBGSVhNRSAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZpbnRlcmZhY2VfaW5mbyk7CiAgICAgICAgVFJBQ0UoIklNZXNzYWdlRmlsdGVyX0hhbmRsZUluQ29taW5nQ2FsbCByZXR1cm5lZCAlZFxuIiwgaGFuZGxlY2FsbCk7CiAgICAgICAgc3dpdGNoIChoYW5kbGVjYWxsKQogICAgICAgIHsKICAgICAgICBjYXNlIFNFUlZFUkNBTExfUkVKRUNURUQ6CiAgICAgICAgICAgIHBhcmFtcy0+aHIgPSBSUENfRV9DQUxMX1JFSkVDVEVEOwogICAgICAgICAgICBnb3RvIGV4aXRfcmVzZXRfc3RhdGU7CiAgICAgICAgY2FzZSBTRVJWRVJDQUxMX1JFVFJZTEFURVI6CiNpZiAwIC8qIEZJWE1FOiBoYW5kbGUgcmV0cmllcyBvbiB0aGUgY2xpZW50IHNpZGUgYmVmb3JlIGVuYWJsaW5nIHRoaXMgY29kZSAqLwogICAgICAgICAgICBwYXJhbXMtPmhyID0gUlBDX0VfUkVUUlk7CiAgICAgICAgICAgIGdvdG8gZXhpdF9yZXNldF9zdGF0ZTsKI2Vsc2UKICAgICAgICAgICAgRklYTUUoInJldHJ5IGNhbGwgbGF0ZXIgbm90IGltcGxlbWVudGVkXG4iKTsKICAgICAgICAgICAgYnJlYWs7CiNlbmRpZgogICAgICAgIGNhc2UgU0VSVkVSQ0FMTF9JU0hBTkRMRUQ6CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQoKICAgIC8qIGludm9rZSB0aGUgbWV0aG9kICovCgogICAgLyogc2F2ZSB0aGUgb2xkIGNhdXNhbGl0eSBJRCAtIG5vdGU6IGFueSBjYWxscyBleGVjdXRlZCB3aGlsZSBwcm9jZXNzaW5nCiAgICAgKiBtZXNzYWdlcyByZWNlaXZlZCBkdXJpbmcgdGhlIFNlbmRSZWNlaXZlIHdpbGwgYXBwZWFyIHRvIG9yaWdpbmF0ZSBmcm9tCiAgICAgKiB0aGlzIGNhbGwgLSB0aGlzIHNob3VsZCBiZSBjaGVja2VkIHdpdGggd2hhdCBXaW5kb3dzIGRvZXMgKi8KICAgIG9sZF9jYXVzYWxpdHlfaWQgPSBDT01fQ3VycmVudEluZm8oKS0+Y2F1c2FsaXR5X2lkOwogICAgQ09NX0N1cnJlbnRJbmZvKCktPmNhdXNhbGl0eV9pZCA9IG9ycGN0aGlzLmNpZDsKICAgIENPTV9DdXJyZW50SW5mbygpLT5wZW5kaW5nX2NhbGxfY291bnRfc2VydmVyKys7CiAgICBwYXJhbXMtPmhyID0gSVJwY1N0dWJCdWZmZXJfSW52b2tlKHBhcmFtcy0+c3R1YiwgcGFyYW1zLT5tc2csIHBhcmFtcy0+Y2hhbik7CiAgICBDT01fQ3VycmVudEluZm8oKS0+cGVuZGluZ19jYWxsX2NvdW50X3NlcnZlci0tOwogICAgQ09NX0N1cnJlbnRJbmZvKCktPmNhdXNhbGl0eV9pZCA9IG9sZF9jYXVzYWxpdHlfaWQ7CgogICAgLyogdGhlIGludm9rZSBhbGxvY2F0ZWQgYSBuZXcgYnVmZmVyLCBzbyBmcmVlIHRoZSBvbGQgb25lICovCiAgICBpZiAobWVzc2FnZV9zdGF0ZS0+YnlwYXNzX3JwY3J0ICYmIG9yaWdpbmFsX2J1ZmZlciAhPSBtc2ctPkJ1ZmZlcikKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBvcmlnaW5hbF9idWZmZXIpOwoKZXhpdF9yZXNldF9zdGF0ZToKICAgIG1lc3NhZ2Vfc3RhdGUgPSAoc3RydWN0IG1lc3NhZ2Vfc3RhdGUgKiltc2ctPkhhbmRsZTsKICAgIG1zZy0+SGFuZGxlID0gbWVzc2FnZV9zdGF0ZS0+YmluZGluZ19oYW5kbGU7CiAgICBtc2ctPkJ1ZmZlciA9IChjaGFyICopbXNnLT5CdWZmZXIgLSBtZXNzYWdlX3N0YXRlLT5wcmVmaXhfZGF0YV9sZW47CiAgICBtc2ctPkJ1ZmZlckxlbmd0aCArPSBtZXNzYWdlX3N0YXRlLT5wcmVmaXhfZGF0YV9sZW47CgpleGl0OgogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbWVzc2FnZV9zdGF0ZSk7CiAgICBpZiAocGFyYW1zLT5oYW5kbGUpIFNldEV2ZW50KHBhcmFtcy0+aGFuZGxlKTsKfQoKc3RhdGljIHZvaWQgX19SUENfU1RVQiBkaXNwYXRjaF9ycGMoUlBDX01FU1NBR0UgKm1zZykKewogICAgc3RydWN0IGRpc3BhdGNoX3BhcmFtcyAqcGFyYW1zOwogICAgQVBBUlRNRU5UICphcHQ7CiAgICBJUElEIGlwaWQ7CiAgICBIUkVTVUxUIGhyOwoKICAgIFJwY0JpbmRpbmdJbnFPYmplY3QobXNnLT5IYW5kbGUsICZpcGlkKTsKCiAgICBUUkFDRSgiaXBpZCA9ICVzLCBpTWV0aG9kID0gJWRcbiIsIGRlYnVnc3RyX2d1aWQoJmlwaWQpLCBtc2ctPlByb2NOdW0pOwoKICAgIHBhcmFtcyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoKnBhcmFtcykpOwogICAgaWYgKCFwYXJhbXMpCiAgICB7CiAgICAgICAgUnBjUmFpc2VFeGNlcHRpb24oRV9PVVRPRk1FTU9SWSk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGhyID0gaXBpZF9nZXRfZGlzcGF0Y2hfcGFyYW1zKCZpcGlkLCAmYXB0LCAmcGFyYW1zLT5zdHViLCAmcGFyYW1zLT5jaGFuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBhcmFtcy0+aWlkLCAmcGFyYW1zLT5pZmFjZSk7CiAgICBpZiAoaHIgIT0gU19PSykKICAgIHsKICAgICAgICBFUlIoIm5vIGFwYXJ0bWVudCBmb3VuZCBmb3IgaXBpZCAlc1xuIiwgZGVidWdzdHJfZ3VpZCgmaXBpZCkpOwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBhcmFtcyk7CiAgICAgICAgUnBjUmFpc2VFeGNlcHRpb24oaHIpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBwYXJhbXMtPm1zZyA9IChSUENPTEVNRVNTQUdFICopbXNnOwogICAgcGFyYW1zLT5zdGF0dXMgPSBSUENfU19PSzsKICAgIHBhcmFtcy0+aHIgPSBTX09LOwogICAgcGFyYW1zLT5oYW5kbGUgPSBOVUxMOwogICAgcGFyYW1zLT5ieXBhc3NfcnBjcnQgPSBGQUxTRTsKCiAgICAvKiBOb3RlOiB0aGlzIGlzIHRoZSBpbXBvcnRhbnQgZGlmZmVyZW5jZSBiZXR3ZWVuIFNUQXMgYW5kIE1UQXMgLSB3ZQogICAgICogYWx3YXlzIGV4ZWN1dGUgUlBDcyB0byBTVEFzIGluIHRoZSB0aHJlYWQgdGhhdCBvcmlnaW5hbGx5IGNyZWF0ZWQgdGhlCiAgICAgKiBhcGFydG1lbnQgKGkuZS4gdGhlIG9uZSB0aGF0IHB1bXBzIG1lc3NhZ2VzIHRvIHRoZSB3aW5kb3cpICovCiAgICBpZiAoIWFwdC0+bXVsdGlfdGhyZWFkZWQpCiAgICB7CiAgICAgICAgcGFyYW1zLT5oYW5kbGUgPSBDcmVhdGVFdmVudFcoTlVMTCwgRkFMU0UsIEZBTFNFLCBOVUxMKTsKCiAgICAgICAgVFJBQ0UoIkNhbGxpbmcgYXBhcnRtZW50IHRocmVhZCAweCUwOHguLi5cbiIsIGFwdC0+dGlkKTsKCiAgICAgICAgaWYgKFBvc3RNZXNzYWdlVyhhcGFydG1lbnRfZ2V0d2luZG93KGFwdCksIERNX0VYRUNVVEVSUEMsIDAsIChMUEFSQU0pcGFyYW1zKSkKICAgICAgICAgICAgV2FpdEZvclNpbmdsZU9iamVjdChwYXJhbXMtPmhhbmRsZSwgSU5GSU5JVEUpOwogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIEVSUigiUG9zdE1lc3NhZ2UgZmFpbGVkIHdpdGggZXJyb3IgJXVcbiIsIEdldExhc3RFcnJvcigpKTsKICAgICAgICAgICAgSVJwY0NoYW5uZWxCdWZmZXJfUmVsZWFzZShwYXJhbXMtPmNoYW4pOwogICAgICAgICAgICBJUnBjU3R1YkJ1ZmZlcl9SZWxlYXNlKHBhcmFtcy0+c3R1Yik7CiAgICAgICAgfQogICAgICAgIENsb3NlSGFuZGxlKHBhcmFtcy0+aGFuZGxlKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBCT09MIGpvaW5lZCA9IEZBTFNFOwogICAgICAgIGlmICghQ09NX0N1cnJlbnRJbmZvKCktPmFwdCkKICAgICAgICB7CiAgICAgICAgICAgIGFwYXJ0bWVudF9qb2lubXRhKCk7CiAgICAgICAgICAgIGpvaW5lZCA9IFRSVUU7CiAgICAgICAgfQogICAgICAgIFJQQ19FeGVjdXRlQ2FsbChwYXJhbXMpOwogICAgICAgIGlmIChqb2luZWQpCiAgICAgICAgewogICAgICAgICAgICBhcGFydG1lbnRfcmVsZWFzZShDT01fQ3VycmVudEluZm8oKS0+YXB0KTsKICAgICAgICAgICAgQ09NX0N1cnJlbnRJbmZvKCktPmFwdCA9IE5VTEw7CiAgICAgICAgfQogICAgfQoKICAgIGhyID0gcGFyYW1zLT5ocjsKICAgIGlmIChwYXJhbXMtPmNoYW4pCiAgICAgICAgSVJwY0NoYW5uZWxCdWZmZXJfUmVsZWFzZShwYXJhbXMtPmNoYW4pOwogICAgaWYgKHBhcmFtcy0+c3R1YikKICAgICAgICBJUnBjU3R1YkJ1ZmZlcl9SZWxlYXNlKHBhcmFtcy0+c3R1Yik7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwYXJhbXMpOwoKICAgIGFwYXJ0bWVudF9yZWxlYXNlKGFwdCk7CgogICAgLyogaWYgSVJwY1N0dWJCdWZmZXJfSW52b2tlIGZhaWxzLCB3ZSBzaG91bGQgcmFpc2UgYW4gZXhjZXB0aW9uIHRvIHRlbGwKICAgICAqIHRoZSBSUEMgcnVudGltZSB0aGF0IHRoZSBjYWxsIGZhaWxlZCAqLwogICAgaWYgKGhyKSBScGNSYWlzZUV4Y2VwdGlvbihocik7Cn0KCi8qIHN0dWIgcmVnaXN0cmF0aW9uICovCkhSRVNVTFQgUlBDX1JlZ2lzdGVySW50ZXJmYWNlKFJFRklJRCByaWlkKQp7CiAgICBzdHJ1Y3QgcmVnaXN0ZXJlZF9pZiAqcmlmOwogICAgQk9PTCBmb3VuZCA9IEZBTFNFOwogICAgSFJFU1VMVCBociA9IFNfT0s7CiAgICAKICAgIFRSQUNFKCIoJXMpXG4iLCBkZWJ1Z3N0cl9ndWlkKHJpaWQpKTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmY3NSZWdJZik7CiAgICBMSVNUX0ZPUl9FQUNIX0VOVFJZKHJpZiwgJnJlZ2lzdGVyZWRfaW50ZXJmYWNlcywgc3RydWN0IHJlZ2lzdGVyZWRfaWYsIGVudHJ5KQogICAgewogICAgICAgIGlmIChJc0VxdWFsR1VJRCgmcmlmLT5JZi5JbnRlcmZhY2VJZC5TeW50YXhHVUlELCByaWlkKSkKICAgICAgICB7CiAgICAgICAgICAgIHJpZi0+cmVmcysrOwogICAgICAgICAgICBmb3VuZCA9IFRSVUU7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KICAgIGlmICghZm91bmQpCiAgICB7CiAgICAgICAgVFJBQ0UoIkNyZWF0aW5nIG5ldyBpbnRlcmZhY2VcbiIpOwoKICAgICAgICByaWYgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKCpyaWYpKTsKICAgICAgICBpZiAocmlmKQogICAgICAgIHsKICAgICAgICAgICAgUlBDX1NUQVRVUyBzdGF0dXM7CgogICAgICAgICAgICByaWYtPnJlZnMgPSAxOwogICAgICAgICAgICByaWYtPklmLkxlbmd0aCA9IHNpemVvZihSUENfU0VSVkVSX0lOVEVSRkFDRSk7CiAgICAgICAgICAgIC8qIFJQQyBpbnRlcmZhY2UgSUQgPSBDT00gaW50ZXJmYWNlIElEICovCiAgICAgICAgICAgIHJpZi0+SWYuSW50ZXJmYWNlSWQuU3ludGF4R1VJRCA9ICpyaWlkOwogICAgICAgICAgICByaWYtPklmLkRpc3BhdGNoVGFibGUgPSAmcnBjX2Rpc3BhdGNoOwogICAgICAgICAgICAvKiBhbGwgb3RoZXIgZmllbGRzIGFyZSAwLCBpbmNsdWRpbmcgdGhlIHZlcnNpb24gYXNDT00gb2JqZWN0cwogICAgICAgICAgICAgKiBhbHdheXMgaGF2ZSBhIHZlcnNpb24gb2YgMC4wICovCiAgICAgICAgICAgIHN0YXR1cyA9IFJwY1NlcnZlclJlZ2lzdGVySWZFeCgKICAgICAgICAgICAgICAgIChSUENfSUZfSEFORExFKSZyaWYtPklmLAogICAgICAgICAgICAgICAgTlVMTCwgTlVMTCwKICAgICAgICAgICAgICAgIFJQQ19JRl9PTEUgfCBSUENfSUZfQVVUT0xJU1RFTiwKICAgICAgICAgICAgICAgIFJQQ19DX0xJU1RFTl9NQVhfQ0FMTFNfREVGQVVMVCwKICAgICAgICAgICAgICAgIE5VTEwpOwogICAgICAgICAgICBpZiAoc3RhdHVzID09IFJQQ19TX09LKQogICAgICAgICAgICAgICAgbGlzdF9hZGRfdGFpbCgmcmVnaXN0ZXJlZF9pbnRlcmZhY2VzLCAmcmlmLT5lbnRyeSk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgRVJSKCJScGNTZXJ2ZXJSZWdpc3RlcklmRXggZmFpbGVkIHdpdGggZXJyb3IgJWxkXG4iLCBzdGF0dXMpOwogICAgICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcmlmKTsKICAgICAgICAgICAgICAgIGhyID0gSFJFU1VMVF9GUk9NX1dJTjMyKHN0YXR1cyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgICAgICBociA9IEVfT1VUT0ZNRU1PUlk7CiAgICB9CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmY3NSZWdJZik7CiAgICByZXR1cm4gaHI7Cn0KCi8qIHN0dWIgdW5yZWdpc3RyYXRpb24gKi8Kdm9pZCBSUENfVW5yZWdpc3RlckludGVyZmFjZShSRUZJSUQgcmlpZCkKewogICAgc3RydWN0IHJlZ2lzdGVyZWRfaWYgKnJpZjsKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZjc1JlZ0lmKTsKICAgIExJU1RfRk9SX0VBQ0hfRU5UUlkocmlmLCAmcmVnaXN0ZXJlZF9pbnRlcmZhY2VzLCBzdHJ1Y3QgcmVnaXN0ZXJlZF9pZiwgZW50cnkpCiAgICB7CiAgICAgICAgaWYgKElzRXF1YWxHVUlEKCZyaWYtPklmLkludGVyZmFjZUlkLlN5bnRheEdVSUQsIHJpaWQpKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCEtLXJpZi0+cmVmcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgUnBjU2VydmVyVW5yZWdpc3RlcklmKChSUENfSUZfSEFORExFKSZyaWYtPklmLCBOVUxMLCBUUlVFKTsKICAgICAgICAgICAgICAgIGxpc3RfcmVtb3ZlKCZyaWYtPmVudHJ5KTsKICAgICAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHJpZik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmNzUmVnSWYpOwp9CgovKiBnZXQgdGhlIGluZm8gZm9yIGFuIE9YSUQsIGluY2x1ZGluZyB0aGUgSVBJRCBmb3IgdGhlIHJlbSB1bmtub3duIGludGVyZmFjZQogKiBhbmQgdGhlIHN0cmluZyBiaW5kaW5nICovCkhSRVNVTFQgUlBDX1Jlc29sdmVPeGlkKE9YSUQgb3hpZCwgT1hJRF9JTkZPICpveGlkX2luZm8pCnsKICAgIFRSQUNFKCIlc1xuIiwgd2luZV9kYmdzdHJfbG9uZ2xvbmcob3hpZCkpOwoKICAgIG94aWRfaW5mby0+ZHdUaWQgPSAwOwogICAgb3hpZF9pbmZvLT5kd1BpZCA9IDA7CiAgICBveGlkX2luZm8tPmR3QXV0aG5IaW50ID0gUlBDX0NfQVVUSE5fTEVWRUxfTk9ORTsKICAgIC8qIEZJWE1FOiB0aGlzIGlzIGEgaGFjayBhcm91bmQgbm90IGhhdmluZyBhbiBPWElEIHJlc29sdmVyIHlldCAtCiAgICAgKiB0aGlzIGZ1bmN0aW9uIHNob3VsZCBjb250YWN0IHRoZSBtYWNoaW5lJ3MgT1hJRCByZXNvbHZlciBhbmQgdGhlbiBpdAogICAgICogc2hvdWxkIGdpdmUgdXMgdGhlIElQSUQgb2YgdGhlIElSZW1Vbmtub3duIGludGVyZmFjZSAqLwogICAgb3hpZF9pbmZvLT5pcGlkUmVtVW5rbm93bi5EYXRhMSA9IDB4ZmZmZmZmZmY7CiAgICBveGlkX2luZm8tPmlwaWRSZW1Vbmtub3duLkRhdGEyID0gMHhmZmZmOwogICAgb3hpZF9pbmZvLT5pcGlkUmVtVW5rbm93bi5EYXRhMyA9IDB4ZmZmZjsKICAgIG1lbWNweSgmb3hpZF9pbmZvLT5pcGlkUmVtVW5rbm93bi5EYXRhNCwgJm94aWQsIHNpemVvZihPWElEKSk7CiAgICBveGlkX2luZm8tPnBzYSA9IE5VTEwgLyogRklYTUUgKi87CgogICAgcmV0dXJuIFNfT0s7Cn0KCi8qIG1ha2UgdGhlIGFwYXJ0bWVudCByZWFjaGFibGUgYnkgb3RoZXIgdGhyZWFkcyBhbmQgcHJvY2Vzc2VzIGFuZCBjcmVhdGUgdGhlCiAqIElSZW1Vbmtub3duIG9iamVjdCAqLwp2b2lkIFJQQ19TdGFydFJlbW90aW5nKHN0cnVjdCBhcGFydG1lbnQgKmFwdCkKewogICAgaWYgKCFJbnRlcmxvY2tlZEV4Y2hhbmdlKCZhcHQtPnJlbW90aW5nX3N0YXJ0ZWQsIFRSVUUpKQogICAgewogICAgICAgIFdDSEFSIGVuZHBvaW50WzIwMF07CiAgICAgICAgUlBDX1NUQVRVUyBzdGF0dXM7CgogICAgICAgIGdldF9ycGNfZW5kcG9pbnQoZW5kcG9pbnQsICZhcHQtPm94aWQpOwogICAgCiAgICAgICAgc3RhdHVzID0gUnBjU2VydmVyVXNlUHJvdHNlcUVwVygKICAgICAgICAgICAgd3N6UnBjVHJhbnNwb3J0LAogICAgICAgICAgICBSUENfQ19QUk9UU0VRX01BWF9SRVFTX0RFRkFVTFQsCiAgICAgICAgICAgIGVuZHBvaW50LAogICAgICAgICAgICBOVUxMKTsKICAgICAgICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKQogICAgICAgICAgICBFUlIoIkNvdWxkbid0IHJlZ2lzdGVyIGVuZHBvaW50ICVzXG4iLCBkZWJ1Z3N0cl93KGVuZHBvaW50KSk7CgogICAgICAgIC8qIEZJWE1FOiBtb3ZlIHJlbW90ZSB1bmtub3duIGV4cG9ydGluZyBpbnRvIHRoaXMgZnVuY3Rpb24gKi8KICAgIH0KICAgIHN0YXJ0X2FwYXJ0bWVudF9yZW1vdGVfdW5rbm93bigpOwp9CgoKc3RhdGljIEhSRVNVTFQgY3JlYXRlX3NlcnZlcihSRUZDTFNJRCByY2xzaWQpCnsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiAgd3N6TG9jYWxTZXJ2ZXIzMltdID0geyAnTCcsJ28nLCdjJywnYScsJ2wnLCdTJywnZScsJ3InLCd2JywnZScsJ3InLCczJywnMicsMCB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSICBlbWJlZGRpbmdbXSA9IHsgJyAnLCAnLScsJ0UnLCdtJywnYicsJ2UnLCdkJywnZCcsJ2knLCduJywnZycsMCB9OwogICAgSEtFWSAgICAgICAgICAgICAgICBrZXk7CiAgICBIUkVTVUxUICAgICAgICAgICAgIGhyZXM7CiAgICBXQ0hBUiAgICAgICAgICAgICAgIGNvbW1hbmRbTUFYX1BBVEgrc2l6ZW9mKGVtYmVkZGluZykvc2l6ZW9mKFdDSEFSKV07CiAgICBEV09SRCAgICAgICAgICAgICAgIHNpemUgPSAoTUFYX1BBVEgrMSkgKiBzaXplb2YoV0NIQVIpOwogICAgU1RBUlRVUElORk9XICAgICAgICBzaW5mbzsKICAgIFBST0NFU1NfSU5GT1JNQVRJT04gcGluZm87CgogICAgaHJlcyA9IENPTV9PcGVuS2V5Rm9yQ0xTSUQocmNsc2lkLCB3c3pMb2NhbFNlcnZlcjMyLCBLRVlfUkVBRCwgJmtleSk7CiAgICBpZiAoRkFJTEVEKGhyZXMpKSB7CiAgICAgICAgRVJSKCJjbGFzcyAlcyBub3QgcmVnaXN0ZXJlZFxuIiwgZGVidWdzdHJfZ3VpZChyY2xzaWQpKTsKICAgICAgICByZXR1cm4gaHJlczsKICAgIH0KCiAgICBocmVzID0gUmVnUXVlcnlWYWx1ZUV4VyhrZXksIE5VTEwsIE5VTEwsIE5VTEwsIChMUEJZVEUpY29tbWFuZCwgJnNpemUpOwogICAgUmVnQ2xvc2VLZXkoa2V5KTsKICAgIGlmIChocmVzKSB7CiAgICAgICAgV0FSTigiTm8gZGVmYXVsdCB2YWx1ZSBmb3IgTG9jYWxTZXJ2ZXIzMiBrZXlcbiIpOwogICAgICAgIHJldHVybiBSRUdEQl9FX0NMQVNTTk9UUkVHOyAvKiBGSVhNRTogY2hlY2sgcmV0dmFsICovCiAgICB9CgogICAgbWVtc2V0KCZzaW5mbywwLHNpemVvZihzaW5mbykpOwogICAgc2luZm8uY2IgPSBzaXplb2Yoc2luZm8pOwoKICAgIC8qIEVYRSBzZXJ2ZXJzIGFyZSBzdGFydGVkIHdpdGggdGhlIC1FbWJlZGRpbmcgc3dpdGNoLiAqLwoKICAgIHN0cmNhdFcoY29tbWFuZCwgZW1iZWRkaW5nKTsKCiAgICBUUkFDRSgiYWN0aXZhdGluZyBsb2NhbCBzZXJ2ZXIgJXMgZm9yICVzXG4iLCBkZWJ1Z3N0cl93KGNvbW1hbmQpLCBkZWJ1Z3N0cl9ndWlkKHJjbHNpZCkpOwoKICAgIC8qIEZJWE1FOiBXaW4yMDAzIHN1cHBvcnRzIGEgU2VydmVyRXhlY3V0YWJsZSB2YWx1ZSB0aGF0IGlzIHBhc3NlZCBpbnRvCiAgICAgKiBDcmVhdGVQcm9jZXNzICovCiAgICBpZiAoIUNyZWF0ZVByb2Nlc3NXKE5VTEwsIGNvbW1hbmQsIE5VTEwsIE5VTEwsIEZBTFNFLCAwLCBOVUxMLCBOVUxMLCAmc2luZm8sICZwaW5mbykpIHsKICAgICAgICBXQVJOKCJmYWlsZWQgdG8gcnVuIGxvY2FsIHNlcnZlciAlc1xuIiwgZGVidWdzdHJfdyhjb21tYW5kKSk7CiAgICAgICAgcmV0dXJuIEhSRVNVTFRfRlJPTV9XSU4zMihHZXRMYXN0RXJyb3IoKSk7CiAgICB9CiAgICBDbG9zZUhhbmRsZShwaW5mby5oUHJvY2Vzcyk7CiAgICBDbG9zZUhhbmRsZShwaW5mby5oVGhyZWFkKTsKCiAgICByZXR1cm4gU19PSzsKfQoKLyoKICogc3RhcnRfbG9jYWxfc2VydmljZSgpICAtIHN0YXJ0IGEgc2VydmljZSBnaXZlbiBpdHMgbmFtZSBhbmQgcGFyYW1ldGVycwogKi8Kc3RhdGljIERXT1JEIHN0YXJ0X2xvY2FsX3NlcnZpY2UoTFBDV1NUUiBuYW1lLCBEV09SRCBudW0sIExQQ1dTVFIgKnBhcmFtcykKewogICAgU0NfSEFORExFIGhhbmRsZSwgaHN2YzsKICAgIERXT1JEICAgICByID0gRVJST1JfRlVOQ1RJT05fRkFJTEVEOwoKICAgIFRSQUNFKCJTdGFydGluZyBzZXJ2aWNlICVzICVkIHBhcmFtc1xuIiwgZGVidWdzdHJfdyhuYW1lKSwgbnVtKTsKCiAgICBoYW5kbGUgPSBPcGVuU0NNYW5hZ2VyVyhOVUxMLCBOVUxMLCBTQ19NQU5BR0VSX0NPTk5FQ1QpOwogICAgaWYgKCFoYW5kbGUpCiAgICAgICAgcmV0dXJuIHI7CiAgICBoc3ZjID0gT3BlblNlcnZpY2VXKGhhbmRsZSwgbmFtZSwgU0VSVklDRV9TVEFSVCk7CiAgICBpZiAoaHN2YykKICAgIHsKICAgICAgICBpZihTdGFydFNlcnZpY2VXKGhzdmMsIG51bSwgcGFyYW1zKSkKICAgICAgICAgICAgciA9IEVSUk9SX1NVQ0NFU1M7CiAgICAgICAgZWxzZQogICAgICAgICAgICByID0gR2V0TGFzdEVycm9yKCk7CiAgICAgICAgaWYgKHIgPT0gRVJST1JfU0VSVklDRV9BTFJFQURZX1JVTk5JTkcpCiAgICAgICAgICAgIHIgPSBFUlJPUl9TVUNDRVNTOwogICAgICAgIENsb3NlU2VydmljZUhhbmRsZShoc3ZjKTsKICAgIH0KICAgIGVsc2UKICAgICAgICByID0gR2V0TGFzdEVycm9yKCk7CiAgICBDbG9zZVNlcnZpY2VIYW5kbGUoaGFuZGxlKTsKCiAgICBUUkFDRSgiU3RhcnRTZXJ2aWNlIHJldHVybmVkIGVycm9yICV1ICglcylcbiIsIHIsIChyID09IEVSUk9SX1NVQ0NFU1MpID8gIm9rIjoiZmFpbGVkIik7CgogICAgcmV0dXJuIHI7Cn0KCi8qCiAqIGNyZWF0ZV9sb2NhbF9zZXJ2aWNlKCkgIC0gc3RhcnQgYSBDT00gc2VydmVyIGluIGEgc2VydmljZQogKgogKiAgIFRvIHN0YXJ0IGEgTG9jYWwgU2VydmljZSwgd2UgcmVhZCB0aGUgQXBwSUQgdmFsdWUgdW5kZXIKICogdGhlIGNsYXNzJ3MgQ0xTSUQga2V5LCB0aGVuIG9wZW4gdGhlIEhLQ1JcXEFwcElkIGtleSBzcGVjaWZpZWQKICogdGhlcmUgYW5kIGNoZWNrIGZvciBhIExvY2FsU2VydmljZSB2YWx1ZS4KICoKICogTm90ZTogIExvY2FsIFNlcnZpY2VzIGFyZSBub3Qgc3VwcG9ydGVkIHVuZGVyIFdpbmRvd3MgOXgKICovCnN0YXRpYyBIUkVTVUxUIGNyZWF0ZV9sb2NhbF9zZXJ2aWNlKFJFRkNMU0lEIHJjbHNpZCkKewogICAgSFJFU1VMVCBocmVzOwogICAgV0NIQVIgYnVmW0NIQVJTX0lOX0dVSURdOwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHN6TG9jYWxTZXJ2aWNlW10gPSB7ICdMJywnbycsJ2MnLCdhJywnbCcsJ1MnLCdlJywncicsJ3YnLCdpJywnYycsJ2UnLDAgfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzelNlcnZpY2VQYXJhbXNbXSA9IHsnUycsJ2UnLCdyJywndicsJ2knLCdjJywnZScsJ1AnLCdhJywncicsJ2EnLCdtJywncycsMH07CiAgICBIS0VZIGhrZXk7CiAgICBMT05HIHI7CiAgICBEV09SRCB0eXBlLCBzejsKCiAgICBUUkFDRSgiQXR0ZW1wdGluZyB0byBzdGFydCBMb2NhbCBzZXJ2aWNlIGZvciAlc1xuIiwgZGVidWdzdHJfZ3VpZChyY2xzaWQpKTsKCiAgICBocmVzID0gQ09NX09wZW5LZXlGb3JBcHBJZEZyb21DTFNJRChyY2xzaWQsIEtFWV9SRUFELCAmaGtleSk7CiAgICBpZiAoRkFJTEVEKGhyZXMpKQogICAgICAgIHJldHVybiBocmVzOwoKICAgIC8qIHJlYWQgdGhlIExvY2FsU2VydmljZSBhbmQgU2VydmljZVBhcmFtZXRlcnMgdmFsdWVzIGZyb20gdGhlIEFwcElEIGtleSAqLwogICAgc3ogPSBzaXplb2YgYnVmOwogICAgciA9IFJlZ1F1ZXJ5VmFsdWVFeFcoaGtleSwgc3pMb2NhbFNlcnZpY2UsIE5VTEwsICZ0eXBlLCAoTFBCWVRFKWJ1ZiwgJnN6KTsKICAgIGlmIChyPT1FUlJPUl9TVUNDRVNTICYmIHR5cGU9PVJFR19TWikKICAgIHsKICAgICAgICBEV09SRCBudW1fYXJncyA9IDA7CiAgICAgICAgTFBXU1RSIGFyZ3NbMV0gPSB7IE5VTEwgfTsKCiAgICAgICAgLyoKICAgICAgICAgKiBGSVhNRTogSSdtIG5vdCByZWFsbHkgc3VyZSBob3cgdG8gZGVhbCB3aXRoIHRoZSBzZXJ2aWNlIHBhcmFtZXRlcnMuCiAgICAgICAgICogICAgICAgIEkgc3VzcGVjdCB0aGF0IHRoZSBzdHJpbmcgcmV0dXJuZWQgZnJvbSBSZWdRdWVyeVZhbHVlRXhXCiAgICAgICAgICogICAgICAgIHNob3VsZCBiZSBzcGxpdCBpbnRvIGEgbnVtYmVyIG9mIGFyZ3VtZW50cyBieSBzcGFjZXMuCiAgICAgICAgICogICAgICAgIEl0IHdvdWxkIG1ha2UgbW9yZSBzZW5zZSBpZiBTZXJ2aWNlUGFyYW1zIGNvbnRhaW5lZCBhCiAgICAgICAgICogICAgICAgIFJFR19NVUxUSV9TWiBoZXJlLCBidXQgaXQncyBhIFJFR19TWiBmb3IgdGhlIHNlcnZpY2VzCiAgICAgICAgICogICAgICAgIHRoYXQgSSdtIGludGVyZXN0ZWQgaW4gZm9yIHRoZSBtb21lbnQuCiAgICAgICAgICovCiAgICAgICAgciA9IFJlZ1F1ZXJ5VmFsdWVFeFcoaGtleSwgc3pTZXJ2aWNlUGFyYW1zLCBOVUxMLCAmdHlwZSwgTlVMTCwgJnN6KTsKICAgICAgICBpZiAociA9PSBFUlJPUl9TVUNDRVNTICYmIHR5cGUgPT0gUkVHX1NaICYmIHN6KQogICAgICAgIHsKICAgICAgICAgICAgYXJnc1swXSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLEhFQVBfWkVST19NRU1PUlksc3opOwogICAgICAgICAgICBudW1fYXJncysrOwogICAgICAgICAgICBSZWdRdWVyeVZhbHVlRXhXKGhrZXksIHN6U2VydmljZVBhcmFtcywgTlVMTCwgJnR5cGUsIChMUEJZVEUpYXJnc1swXSwgJnN6KTsKICAgICAgICB9CiAgICAgICAgciA9IHN0YXJ0X2xvY2FsX3NlcnZpY2UoYnVmLCBudW1fYXJncywgKExQQ1dTVFIgKilhcmdzKTsKICAgICAgICBpZiAociAhPSBFUlJPUl9TVUNDRVNTKQogICAgICAgICAgICBocmVzID0gUkVHREJfRV9DTEFTU05PVFJFRzsgLyogRklYTUU6IGNoZWNrIHJldHZhbCAqLwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCxhcmdzWzBdKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBXQVJOKCJObyBMb2NhbFNlcnZpY2UgdmFsdWVcbiIpOwogICAgICAgIGhyZXMgPSBSRUdEQl9FX0NMQVNTTk9UUkVHOyAvKiBGSVhNRTogY2hlY2sgcmV0dmFsICovCiAgICB9CiAgICBSZWdDbG9zZUtleShoa2V5KTsKCiAgICByZXR1cm4gaHJlczsKfQoKCnN0YXRpYyB2b2lkIGdldF9sb2NhbHNlcnZlcl9waXBlX25hbWUoV0NIQVIgKnBpcGVmbiwgUkVGQ0xTSUQgcmNsc2lkKQp7CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgd3N6UGlwZVJlZltdID0geydcXCcsJ1xcJywnLicsJ1xcJywncCcsJ2knLCdwJywnZScsJ1xcJywwfTsKICAgIHN0cmNweVcocGlwZWZuLCB3c3pQaXBlUmVmKTsKICAgIFN0cmluZ0Zyb21HVUlEMihyY2xzaWQsIHBpcGVmbiArIHNpemVvZih3c3pQaXBlUmVmKS9zaXplb2Yod3N6UGlwZVJlZlswXSkgLSAxLCBDSEFSU19JTl9HVUlEKTsKfQoKLyogRklYTUU6IHNob3VsZCBjYWxsIHRvIHJwY3NzIGluc3RlYWQgKi8KSFJFU1VMVCBSUENfR2V0TG9jYWxDbGFzc09iamVjdChSRUZDTFNJRCByY2xzaWQsIFJFRklJRCBpaWQsIExQVk9JRCAqcHB2KQp7CiAgICBIUkVTVUxUICAgICAgICBocmVzOwogICAgSEFORExFICAgICAgICAgaFBpcGU7CiAgICBXQ0hBUiAgICAgICAgICBwaXBlZm5bMTAwXTsKICAgIERXT1JEICAgICAgICAgIHJlcywgYnVmZmVybGVuOwogICAgY2hhciAgICAgICAgICAgbWFyc2hhbGJ1ZmZlclsyMDBdOwogICAgSVN0cmVhbSAgICAgICAqcFN0bTsKICAgIExBUkdFX0lOVEVHRVIgIHNlZWt0bzsKICAgIFVMQVJHRV9JTlRFR0VSIG5ld3BvczsKICAgIGludCAgICAgICAgICAgIHRyaWVzID0gMDsKCiAgICBzdGF0aWMgY29uc3QgaW50IE1BWFRSSUVTID0gMzA7IC8qIDMwIHNlY29uZHMgKi8KCiAgICBUUkFDRSgicmNsc2lkPSVzLCBpaWQ9JXNcbiIsIGRlYnVnc3RyX2d1aWQocmNsc2lkKSwgZGVidWdzdHJfZ3VpZChpaWQpKTsKCiAgICBnZXRfbG9jYWxzZXJ2ZXJfcGlwZV9uYW1lKHBpcGVmbiwgcmNsc2lkKTsKCiAgICB3aGlsZSAodHJpZXMrKyA8IE1BWFRSSUVTKSB7CiAgICAgICAgVFJBQ0UoIndhaXRpbmcgZm9yICVzXG4iLCBkZWJ1Z3N0cl93KHBpcGVmbikpOwoKICAgICAgICBXYWl0TmFtZWRQaXBlVyggcGlwZWZuLCBOTVBXQUlUX1dBSVRfRk9SRVZFUiApOwogICAgICAgIGhQaXBlID0gQ3JlYXRlRmlsZVcocGlwZWZuLCBHRU5FUklDX1JFQUQgfCBHRU5FUklDX1dSSVRFLCAwLCBOVUxMLCBPUEVOX0VYSVNUSU5HLCAwLCAwKTsKICAgICAgICBpZiAoaFBpcGUgPT0gSU5WQUxJRF9IQU5ETEVfVkFMVUUpIHsKICAgICAgICAgICAgRFdPUkQgaW5kZXg7CiAgICAgICAgICAgIERXT1JEIHN0YXJ0X3RpY2tzOwogICAgICAgICAgICBpZiAodHJpZXMgPT0gMSkgewogICAgICAgICAgICAgICAgaWYgKCAoaHJlcyA9IGNyZWF0ZV9sb2NhbF9zZXJ2aWNlKHJjbHNpZCkpICYmCiAgICAgICAgICAgICAgICAgICAgIChocmVzID0gY3JlYXRlX3NlcnZlcihyY2xzaWQpKSApCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGhyZXM7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBXQVJOKCJDb25uZWN0aW5nIHRvICVzLCBubyByZXNwb25zZSB5ZXQsIHJldHJ5aW5nOiBsZSBpcyAldVxuIiwgZGVidWdzdHJfdyhwaXBlZm4pLCBHZXRMYXN0RXJyb3IoKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyogd2FpdCBmb3Igb25lIHNlY29uZCwgZXZlbiBpZiBtZXNzYWdlcyBhcnJpdmUgKi8KICAgICAgICAgICAgc3RhcnRfdGlja3MgPSBHZXRUaWNrQ291bnQoKTsKICAgICAgICAgICAgZG8gewogICAgICAgICAgICAgICAgQ29XYWl0Rm9yTXVsdGlwbGVIYW5kbGVzKDAsIDEwMDAsIDAsIE5VTEwsICZpbmRleCk7CiAgICAgICAgICAgIH0gd2hpbGUgKEdldFRpY2tDb3VudCgpIC0gc3RhcnRfdGlja3MgPCAxMDAwKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIGJ1ZmZlcmxlbiA9IDA7CiAgICAgICAgaWYgKCFSZWFkRmlsZShoUGlwZSxtYXJzaGFsYnVmZmVyLHNpemVvZihtYXJzaGFsYnVmZmVyKSwmYnVmZmVybGVuLE5VTEwpKSB7CiAgICAgICAgICAgIEZJWE1FKCJGYWlsZWQgdG8gcmVhZCBtYXJzaGFsIGlkIGZyb20gY2xhc3NmYWN0b3J5IG9mICVzLlxuIixkZWJ1Z3N0cl9ndWlkKHJjbHNpZCkpOwogICAgICAgICAgICBTbGVlcCgxMDAwKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIFRSQUNFKCJyZWFkIG1hcnNoYWwgaWQgZnJvbSBwaXBlXG4iKTsKICAgICAgICBDbG9zZUhhbmRsZShoUGlwZSk7CiAgICAgICAgYnJlYWs7CiAgICB9CiAgICAKICAgIGlmICh0cmllcyA+PSBNQVhUUklFUykKICAgICAgICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKICAgIAogICAgaHJlcyA9IENyZWF0ZVN0cmVhbU9uSEdsb2JhbCgwLFRSVUUsJnBTdG0pOwogICAgaWYgKGhyZXMpIHJldHVybiBocmVzOwogICAgaHJlcyA9IElTdHJlYW1fV3JpdGUocFN0bSxtYXJzaGFsYnVmZmVyLGJ1ZmZlcmxlbiwmcmVzKTsKICAgIGlmIChocmVzKSBnb3RvIG91dDsKICAgIHNlZWt0by51Lkxvd1BhcnQgPSAwO3NlZWt0by51LkhpZ2hQYXJ0ID0gMDsKICAgIGhyZXMgPSBJU3RyZWFtX1NlZWsocFN0bSxzZWVrdG8sU1RSRUFNX1NFRUtfU0VULCZuZXdwb3MpOwogICAgCiAgICBUUkFDRSgidW5tYXJzaGFsbGluZyBjbGFzc2ZhY3RvcnlcbiIpOwogICAgaHJlcyA9IENvVW5tYXJzaGFsSW50ZXJmYWNlKHBTdG0sJklJRF9JQ2xhc3NGYWN0b3J5LHBwdik7Cm91dDoKICAgIElTdHJlYW1fUmVsZWFzZShwU3RtKTsKICAgIHJldHVybiBocmVzOwp9CgoKc3RydWN0IGxvY2FsX3NlcnZlcl9wYXJhbXMKewogICAgQ0xTSUQgY2xzaWQ7CiAgICBJU3RyZWFtICpzdHJlYW07CiAgICBIQU5ETEUgcmVhZHlfZXZlbnQ7CiAgICBIQU5ETEUgc3RvcF9ldmVudDsKICAgIEhBTkRMRSB0aHJlYWQ7CiAgICBCT09MIG11bHRpX3VzZTsKfTsKCi8qIEZJWE1FOiBzaG91bGQgY2FsbCB0byBycGNzcyBpbnN0ZWFkICovCnN0YXRpYyBEV09SRCBXSU5BUEkgbG9jYWxfc2VydmVyX3RocmVhZChMUFZPSUQgcGFyYW0pCnsKICAgIHN0cnVjdCBsb2NhbF9zZXJ2ZXJfcGFyYW1zICogbHNwID0gKHN0cnVjdCBsb2NhbF9zZXJ2ZXJfcGFyYW1zICopcGFyYW07CiAgICBIQU5ETEUJCWhQaXBlOwogICAgV0NIQVIgCQlwaXBlZm5bMTAwXTsKICAgIEhSRVNVTFQJCWhyZXM7CiAgICBJU3RyZWFtCQkqcFN0bSA9IGxzcC0+c3RyZWFtOwogICAgU1RBVFNURwkJc3RzdGc7CiAgICB1bnNpZ25lZCBjaGFyCSpidWZmZXI7CiAgICBpbnQgCQlidWZsZW47CiAgICBMQVJHRV9JTlRFR0VSCXNlZWt0bzsKICAgIFVMQVJHRV9JTlRFR0VSCW5ld3BvczsKICAgIFVMT05HCQlyZXM7CiAgICBCT09MIG11bHRpX3VzZSA9IGxzcC0+bXVsdGlfdXNlOwogICAgT1ZFUkxBUFBFRCBvdmw7CiAgICBIQU5ETEUgcGlwZV9ldmVudDsKCiAgICBUUkFDRSgiU3RhcnRpbmcgdGhyZWFkZXIgZm9yICVzLlxuIixkZWJ1Z3N0cl9ndWlkKCZsc3AtPmNsc2lkKSk7CgogICAgbWVtc2V0KCZvdmwsIDAsIHNpemVvZihvdmwpKTsKICAgIGdldF9sb2NhbHNlcnZlcl9waXBlX25hbWUocGlwZWZuLCAmbHNwLT5jbHNpZCk7CgogICAgaFBpcGUgPSBDcmVhdGVOYW1lZFBpcGVXKCBwaXBlZm4sIFBJUEVfQUNDRVNTX0RVUExFWCB8IEZJTEVfRkxBR19PVkVSTEFQUEVELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQSVBFX1RZUEVfQllURXxQSVBFX1dBSVQsIFBJUEVfVU5MSU1JVEVEX0lOU1RBTkNFUywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgNDA5NiwgNDA5NiwgNTAwIC8qIDAuNSBzZWNvbmQgdGltZW91dCAqLywgTlVMTCApOwoKICAgIFNldEV2ZW50KGxzcC0+cmVhZHlfZXZlbnQpOwoKICAgIGlmIChoUGlwZSA9PSBJTlZBTElEX0hBTkRMRV9WQUxVRSkKICAgIHsKICAgICAgICBGSVhNRSgicGlwZSBjcmVhdGlvbiBmYWlsZWQgZm9yICVzLCBsZSBpcyAldVxuIiwgZGVidWdzdHJfdyhwaXBlZm4pLCBHZXRMYXN0RXJyb3IoKSk7CiAgICAgICAgcmV0dXJuIDE7CiAgICB9CgogICAgb3ZsLmhFdmVudCA9IHBpcGVfZXZlbnQgPSBDcmVhdGVFdmVudFcoTlVMTCwgRkFMU0UsIEZBTFNFLCBOVUxMKTsKICAgIAogICAgd2hpbGUgKDEpIHsKICAgICAgICBpZiAoIUNvbm5lY3ROYW1lZFBpcGUoaFBpcGUsICZvdmwpKQogICAgICAgIHsKICAgICAgICAgICAgRFdPUkQgZXJyb3IgPSBHZXRMYXN0RXJyb3IoKTsKICAgICAgICAgICAgaWYgKGVycm9yID09IEVSUk9SX0lPX1BFTkRJTkcpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEhBTkRMRSBoYW5kbGVzWzJdID0geyBwaXBlX2V2ZW50LCBsc3AtPnN0b3BfZXZlbnQgfTsKICAgICAgICAgICAgICAgIERXT1JEIHJldDsKICAgICAgICAgICAgICAgIHJldCA9IFdhaXRGb3JNdWx0aXBsZU9iamVjdHMoMiwgaGFuZGxlcywgRkFMU0UsIElORklOSVRFKTsKICAgICAgICAgICAgICAgIGlmIChyZXQgIT0gV0FJVF9PQkpFQ1RfMCkKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICAvKiBjbGllbnQgYWxyZWFkeSBjb25uZWN0ZWQgaXNuJ3QgYW4gZXJyb3IgKi8KICAgICAgICAgICAgZWxzZSBpZiAoZXJyb3IgIT0gRVJST1JfUElQRV9DT05ORUNURUQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEVSUigiQ29ubmVjdE5hbWVkUGlwZSBmYWlsZWQgd2l0aCBlcnJvciAlZFxuIiwgR2V0TGFzdEVycm9yKCkpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIFRSQUNFKCJtYXJzaGFsbGluZyBJQ2xhc3NGYWN0b3J5IHRvIGNsaWVudFxuIik7CiAgICAgICAgCiAgICAgICAgaHJlcyA9IElTdHJlYW1fU3RhdChwU3RtLCZzdHN0ZywwKTsKICAgICAgICBpZiAoaHJlcykgcmV0dXJuIGhyZXM7CgogICAgICAgIHNlZWt0by51Lkxvd1BhcnQgPSAwOwogICAgICAgIHNlZWt0by51LkhpZ2hQYXJ0ID0gMDsKICAgICAgICBocmVzID0gSVN0cmVhbV9TZWVrKHBTdG0sc2Vla3RvLFNUUkVBTV9TRUVLX1NFVCwmbmV3cG9zKTsKICAgICAgICBpZiAoaHJlcykgewogICAgICAgICAgICBGSVhNRSgiSVN0cmVhbV9TZWVrIGZhaWxlZCwgJXhcbiIsaHJlcyk7CiAgICAgICAgICAgIENsb3NlSGFuZGxlKGhQaXBlKTsKICAgICAgICAgICAgQ2xvc2VIYW5kbGUocGlwZV9ldmVudCk7CiAgICAgICAgICAgIHJldHVybiBocmVzOwogICAgICAgIH0KCiAgICAgICAgYnVmbGVuID0gc3RzdGcuY2JTaXplLnUuTG93UGFydDsKICAgICAgICBidWZmZXIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwwLGJ1Zmxlbik7CiAgICAgICAgCiAgICAgICAgaHJlcyA9IElTdHJlYW1fUmVhZChwU3RtLGJ1ZmZlcixidWZsZW4sJnJlcyk7CiAgICAgICAgaWYgKGhyZXMpIHsKICAgICAgICAgICAgRklYTUUoIlN0cmVhbSBSZWFkIGZhaWxlZCwgJXhcbiIsaHJlcyk7CiAgICAgICAgICAgIENsb3NlSGFuZGxlKGhQaXBlKTsKICAgICAgICAgICAgQ2xvc2VIYW5kbGUocGlwZV9ldmVudCk7CiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCxidWZmZXIpOwogICAgICAgICAgICByZXR1cm4gaHJlczsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgV3JpdGVGaWxlKGhQaXBlLGJ1ZmZlcixidWZsZW4sJnJlcywmb3ZsKTsKICAgICAgICBHZXRPdmVybGFwcGVkUmVzdWx0KGhQaXBlLCAmb3ZsLCBOVUxMLCBUUlVFKTsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsYnVmZmVyKTsKCiAgICAgICAgRmx1c2hGaWxlQnVmZmVycyhoUGlwZSk7CiAgICAgICAgRGlzY29ubmVjdE5hbWVkUGlwZShoUGlwZSk7CgogICAgICAgIFRSQUNFKCJkb25lIG1hcnNoYWxsaW5nIElDbGFzc0ZhY3RvcnlcbiIpOwoKICAgICAgICBpZiAoIW11bHRpX3VzZSkKICAgICAgICB7CiAgICAgICAgICAgIFRSQUNFKCJzaW5nbGUgdXNlIG9iamVjdCwgc2h1dHRpbmcgZG93biBwaXBlICVzXG4iLCBkZWJ1Z3N0cl93KHBpcGVmbikpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CiAgICBDbG9zZUhhbmRsZShoUGlwZSk7CiAgICBDbG9zZUhhbmRsZShwaXBlX2V2ZW50KTsKICAgIHJldHVybiAwOwp9CgovKiBzdGFydHMgbGlzdGVuaW5nIGZvciBhIGxvY2FsIHNlcnZlciAqLwpIUkVTVUxUIFJQQ19TdGFydExvY2FsU2VydmVyKFJFRkNMU0lEIGNsc2lkLCBJU3RyZWFtICpzdHJlYW0sIEJPT0wgbXVsdGlfdXNlLCB2b2lkICoqcmVnaXN0cmF0aW9uKQp7CiAgICBEV09SRCB0aWQ7CiAgICBzdHJ1Y3QgbG9jYWxfc2VydmVyX3BhcmFtcyAqbHNwOwoKICAgIGxzcCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoKmxzcCkpOwogICAgaWYgKCFsc3ApCiAgICAgICAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CgogICAgbHNwLT5jbHNpZCA9ICpjbHNpZDsKICAgIGxzcC0+c3RyZWFtID0gc3RyZWFtOwogICAgSVN0cmVhbV9BZGRSZWYoc3RyZWFtKTsKICAgIGxzcC0+cmVhZHlfZXZlbnQgPSBDcmVhdGVFdmVudFcoTlVMTCwgRkFMU0UsIEZBTFNFLCBOVUxMKTsKICAgIGlmICghbHNwLT5yZWFkeV9ldmVudCkKICAgIHsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBsc3ApOwogICAgICAgIHJldHVybiBIUkVTVUxUX0ZST01fV0lOMzIoR2V0TGFzdEVycm9yKCkpOwogICAgfQogICAgbHNwLT5zdG9wX2V2ZW50ID0gQ3JlYXRlRXZlbnRXKE5VTEwsIEZBTFNFLCBGQUxTRSwgTlVMTCk7CiAgICBpZiAoIWxzcC0+c3RvcF9ldmVudCkKICAgIHsKICAgICAgICBDbG9zZUhhbmRsZShsc3AtPnJlYWR5X2V2ZW50KTsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBsc3ApOwogICAgICAgIHJldHVybiBIUkVTVUxUX0ZST01fV0lOMzIoR2V0TGFzdEVycm9yKCkpOwogICAgfQogICAgbHNwLT5tdWx0aV91c2UgPSBtdWx0aV91c2U7CgogICAgbHNwLT50aHJlYWQgPSBDcmVhdGVUaHJlYWQoTlVMTCwgMCwgbG9jYWxfc2VydmVyX3RocmVhZCwgbHNwLCAwLCAmdGlkKTsKICAgIGlmICghbHNwLT50aHJlYWQpCiAgICB7CiAgICAgICAgQ2xvc2VIYW5kbGUobHNwLT5yZWFkeV9ldmVudCk7CiAgICAgICAgQ2xvc2VIYW5kbGUobHNwLT5zdG9wX2V2ZW50KTsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBsc3ApOwogICAgICAgIHJldHVybiBIUkVTVUxUX0ZST01fV0lOMzIoR2V0TGFzdEVycm9yKCkpOwogICAgfQoKICAgIFdhaXRGb3JTaW5nbGVPYmplY3QobHNwLT5yZWFkeV9ldmVudCwgSU5GSU5JVEUpOwogICAgQ2xvc2VIYW5kbGUobHNwLT5yZWFkeV9ldmVudCk7CiAgICBsc3AtPnJlYWR5X2V2ZW50ID0gTlVMTDsKCiAgICAqcmVnaXN0cmF0aW9uID0gbHNwOwogICAgcmV0dXJuIFNfT0s7Cn0KCi8qIHN0b3BzIGxpc3RlbmluZyBmb3IgYSBsb2NhbCBzZXJ2ZXIgKi8Kdm9pZCBSUENfU3RvcExvY2FsU2VydmVyKHZvaWQgKnJlZ2lzdHJhdGlvbikKewogICAgc3RydWN0IGxvY2FsX3NlcnZlcl9wYXJhbXMgKmxzcCA9IHJlZ2lzdHJhdGlvbjsKCiAgICAvKiBzaWduYWwgbG9jYWxfc2VydmVyX3RocmVhZCB0byBzdG9wICovCiAgICBTZXRFdmVudChsc3AtPnN0b3BfZXZlbnQpOwogICAgLyogd2FpdCBmb3IgaXQgdG8gZXhpdCAqLwogICAgV2FpdEZvclNpbmdsZU9iamVjdChsc3AtPnRocmVhZCwgSU5GSU5JVEUpOwoKICAgIElTdHJlYW1fUmVsZWFzZShsc3AtPnN0cmVhbSk7CiAgICBDbG9zZUhhbmRsZShsc3AtPnN0b3BfZXZlbnQpOwogICAgQ2xvc2VIYW5kbGUobHNwLT50aHJlYWQpOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbHNwKTsKfQo=