LyoKICoJUlBDIE1hbmFnZXIKICoKICogQ29weXJpZ2h0IDIwMDEgIE92ZSBL5XZlbiwgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzCiAqIENvcHlyaWdodCAyMDAyICBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDIwMDUgIE1pa2UgSGVhcm4sIFJvYiBTaGVhcm1hbiBmb3IgQ29kZVdlYXZlcnMKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZS9wb3J0LmgiCgojaW5jbHVkZSA8c3RkYXJnLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KCiNkZWZpbmUgQ09CSk1BQ1JPUwojZGVmaW5lIE5PTkFNRUxFU1NVTklPTgojZGVmaW5lIE5PTkFNRUxFU1NTVFJVQ1QKCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbnN2Yy5oIgojaW5jbHVkZSAib2JqYmFzZS5oIgojaW5jbHVkZSAib2xlMi5oIgojaW5jbHVkZSAicnBjLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAid2lucmVnLmgiCiNpbmNsdWRlICJ3aW5lL3VuaWNvZGUuaCIKCiNpbmNsdWRlICJjb21wb2JqX3ByaXZhdGUuaCIKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChvbGUpOwoKc3RhdGljIHZvaWQgX19SUENfU1RVQiBkaXNwYXRjaF9ycGMoUlBDX01FU1NBR0UgKm1zZyk7CgovKiB3ZSBvbmx5IHVzZSBvbmUgZnVuY3Rpb24gdG8gZGlzcGF0Y2ggY2FsbHMgZm9yIGFsbCBtZXRob2RzIC0gd2UgdXNlIHRoZQogKiBSUENfSUZfT0xFIGZsYWcgdG8gdGVsbCB0aGUgUlBDIHJ1bnRpbWUgdGhhdCB0aGlzIGlzIHRoZSBjYXNlICovCnN0YXRpYyBSUENfRElTUEFUQ0hfRlVOQ1RJT04gcnBjX2Rpc3BhdGNoX3RhYmxlWzFdID0geyBkaXNwYXRjaF9ycGMgfTsgLyogKFJPKSAqLwpzdGF0aWMgUlBDX0RJU1BBVENIX1RBQkxFIHJwY19kaXNwYXRjaCA9IHsgMSwgcnBjX2Rpc3BhdGNoX3RhYmxlIH07IC8qIChSTykgKi8KCnN0YXRpYyBzdHJ1Y3QgbGlzdCByZWdpc3RlcmVkX2ludGVyZmFjZXMgPSBMSVNUX0lOSVQocmVnaXN0ZXJlZF9pbnRlcmZhY2VzKTsgLyogKENTIGNzUmVnSWYpICovCnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OIGNzUmVnSWY7CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OX0RFQlVHIGNzUmVnSWZfZGVidWcgPQp7CiAgICAwLCAwLCAmY3NSZWdJZiwKICAgIHsgJmNzUmVnSWZfZGVidWcuUHJvY2Vzc0xvY2tzTGlzdCwgJmNzUmVnSWZfZGVidWcuUHJvY2Vzc0xvY2tzTGlzdCB9LAogICAgICAwLCAwLCB7IChEV09SRF9QVFIpKF9fRklMRV9fICI6IGRjb20gcmVnaXN0ZXJlZCBzZXJ2ZXIgaW50ZXJmYWNlcyIpIH0KfTsKc3RhdGljIENSSVRJQ0FMX1NFQ1RJT04gY3NSZWdJZiA9IHsgJmNzUmVnSWZfZGVidWcsIC0xLCAwLCAwLCAwLCAwIH07CgpzdGF0aWMgc3RydWN0IGxpc3QgY2hhbm5lbF9ob29rcyA9IExJU1RfSU5JVChjaGFubmVsX2hvb2tzKTsgLyogKENTIGNzQ2hhbm5lbEhvb2spICovCnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OIGNzQ2hhbm5lbEhvb2s7CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OX0RFQlVHIGNzQ2hhbm5lbEhvb2tfZGVidWcgPQp7CiAgICAwLCAwLCAmY3NDaGFubmVsSG9vaywKICAgIHsgJmNzQ2hhbm5lbEhvb2tfZGVidWcuUHJvY2Vzc0xvY2tzTGlzdCwgJmNzQ2hhbm5lbEhvb2tfZGVidWcuUHJvY2Vzc0xvY2tzTGlzdCB9LAogICAgICAwLCAwLCB7IChEV09SRF9QVFIpKF9fRklMRV9fICI6IGNoYW5uZWwgaG9va3MiKSB9Cn07CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OIGNzQ2hhbm5lbEhvb2sgPSB7ICZjc0NoYW5uZWxIb29rX2RlYnVnLCAtMSwgMCwgMCwgMCwgMCB9OwoKc3RhdGljIFdDSEFSIHdzelJwY1RyYW5zcG9ydFtdID0geyduJywnYycsJ2EnLCdsJywncicsJ3AnLCdjJywwfTsKCgpzdHJ1Y3QgcmVnaXN0ZXJlZF9pZgp7CiAgICBzdHJ1Y3QgbGlzdCBlbnRyeTsKICAgIERXT1JEIHJlZnM7IC8qIHJlZiBjb3VudCAqLwogICAgUlBDX1NFUlZFUl9JTlRFUkZBQ0UgSWY7IC8qIGludGVyZmFjZSByZWdpc3RlcmVkIHdpdGggdGhlIFJQQyBydW50aW1lICovCn07CgovKiBnZXQgdGhlIHBpcGUgZW5kcG9pbnQgc3BlY2lmaWVkIG9mIHRoZSBzcGVjaWZpZWQgYXBhcnRtZW50ICovCnN0YXRpYyBpbmxpbmUgdm9pZCBnZXRfcnBjX2VuZHBvaW50KExQV1NUUiBlbmRwb2ludCwgY29uc3QgT1hJRCAqb3hpZCkKewogICAgLyogRklYTUU6IHNob3VsZCBnZXQgZW5kcG9pbnQgZnJvbSBycGNzcyAqLwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHdzekVuZHBvaW50Rm9ybWF0W10gPSB7J1xcJywncCcsJ2knLCdwJywnZScsJ1xcJywnTycsJ0wnLCdFJywnXycsJyUnLCcwJywnOCcsJ2wnLCd4JywnJScsJzAnLCc4JywnbCcsJ3gnLDB9OwogICAgd3NwcmludGZXKGVuZHBvaW50LCB3c3pFbmRwb2ludEZvcm1hdCwgKERXT1JEKSgqb3hpZCA+PiAzMiksKERXT1JEKSpveGlkKTsKfQoKdHlwZWRlZiBzdHJ1Y3QKewogICAgY29uc3QgSVJwY0NoYW5uZWxCdWZmZXJWdGJsICpscFZ0Ymw7CiAgICBMT05HICAgICAgICAgICAgICAgICAgcmVmczsKfSBScGNDaGFubmVsQnVmZmVyOwoKdHlwZWRlZiBzdHJ1Y3QKewogICAgUnBjQ2hhbm5lbEJ1ZmZlciAgICAgICBzdXBlcjsgLyogc3VwZXJjbGFzcyAqLwoKICAgIFJQQ19CSU5ESU5HX0hBTkRMRSAgICAgYmluZDsgLyogaGFuZGxlIHRvIHRoZSByZW1vdGUgc2VydmVyICovCiAgICBPWElEICAgICAgICAgICAgICAgICAgIG94aWQ7IC8qIGFwYXJ0bWVudCBpbiB3aGljaCB0aGUgY2hhbm5lbCBpcyB2YWxpZCAqLwogICAgRFdPUkQgICAgICAgICAgICAgICAgICBzZXJ2ZXJfcGlkOyAvKiBpZCBvZiBzZXJ2ZXIgcHJvY2VzcyAqLwogICAgRFdPUkQgICAgICAgICAgICAgICAgICBkZXN0X2NvbnRleHQ7IC8qIHJldHVybmVkIGZyb20gR2V0RGVzdEN0eCAqLwogICAgTFBWT0lEICAgICAgICAgICAgICAgICBkZXN0X2NvbnRleHRfZGF0YTsgLyogcmV0dXJuZWQgZnJvbSBHZXREZXN0Q3R4ICovCiAgICBIQU5ETEUgICAgICAgICAgICAgICAgIGV2ZW50OyAvKiBjYWNoZWQgZXZlbnQgaGFuZGxlICovCn0gQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlcjsKCnN0cnVjdCBkaXNwYXRjaF9wYXJhbXMKewogICAgUlBDT0xFTUVTU0FHRSAgICAgKm1zZzsgLyogbWVzc2FnZSAqLwogICAgSVJwY1N0dWJCdWZmZXIgICAgKnN0dWI7IC8qIHN0dWIgYnVmZmVyLCBpZiBhcHBsaWNhYmxlICovCiAgICBJUnBjQ2hhbm5lbEJ1ZmZlciAqY2hhbjsgLyogc2VydmVyIGNoYW5uZWwgYnVmZmVyLCBpZiBhcHBsaWNhYmxlICovCiAgICBJSUQgICAgICAgICAgICAgICAgaWlkOyAvKiBJRCBvZiBpbnRlcmZhY2UgYmVpbmcgY2FsbGVkICovCiAgICBJVW5rbm93biAgICAgICAgICAqaWZhY2U7IC8qIGludGVyZmFjZSBiZWluZyBjYWxsZWQgKi8KICAgIEhBTkRMRSAgICAgICAgICAgICBoYW5kbGU7IC8qIGhhbmRsZSB0aGF0IHdpbGwgYmVjb21lIHNpZ25hbGVkIHdoZW4gY2FsbCBmaW5pc2hlcyAqLwogICAgUlBDX1NUQVRVUyAgICAgICAgIHN0YXR1czsgLyogc3RhdHVzIChvdXQpICovCiAgICBIUkVTVUxUICAgICAgICAgICAgaHI7IC8qIGhyZXN1bHQgKG91dCkgKi8KfTsKCnN0cnVjdCBtZXNzYWdlX3N0YXRlCnsKICAgIFJQQ19CSU5ESU5HX0hBTkRMRSBiaW5kaW5nX2hhbmRsZTsKICAgIFVMT05HIHByZWZpeF9kYXRhX2xlbjsKICAgIFNDaGFubmVsSG9va0NhbGxJbmZvIGNoYW5uZWxfaG9va19pbmZvOwoKICAgIC8qIGNsaWVudCBvbmx5ICovCiAgICBzdHJ1Y3QgZGlzcGF0Y2hfcGFyYW1zIHBhcmFtczsKfTsKCnR5cGVkZWYgc3RydWN0CnsKICAgIFVMT05HIGNvbmZvcm1hbmNlOyAvKiBORFIgKi8KICAgIEdVSUQgaWQ7CiAgICBVTE9ORyBzaXplOwogICAgLyogW3NpemVfaXMoKHNpemUrNykmfjcpXSAqLyB1bnNpZ25lZCBjaGFyIGRhdGFbMV07Cn0gV0lSRV9PUlBDX0VYVEVOVDsKCnN0cnVjdCBjaGFubmVsX2hvb2tfZW50cnkKewogICAgc3RydWN0IGxpc3QgZW50cnk7CiAgICBHVUlEIGlkOwogICAgSUNoYW5uZWxIb29rICpob29rOwp9OwoKc3RydWN0IGNoYW5uZWxfaG9va19idWZmZXJfZGF0YQp7CiAgICBHVUlEIGlkOwogICAgVUxPTkcgZXh0ZW5zaW9uX3NpemU7Cn07CgoKc3RhdGljIEhSRVNVTFQgdW5tYXJzaGFsX09SUENUSEFUKFJQQ19NRVNTQUdFICptc2csIE9SUENUSEFUICpvcnBjdGhhdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9SUENfRVhURU5UX0FSUkFZICpvcnBjX2V4dF9hcnJheSwgV0lSRV9PUlBDX0VYVEVOVCAqKmZpcnN0X3dpcmVfb3JwY19leHRlbnQpOwoKLyogQ2hhbm5lbCBIb29rIEZ1bmN0aW9ucyAqLwoKc3RhdGljIFVMT05HIENoYW5uZWxIb29rc19DbGllbnRHZXRTaXplKFNDaGFubmVsSG9va0NhbGxJbmZvICppbmZvLAogICAgc3RydWN0IGNoYW5uZWxfaG9va19idWZmZXJfZGF0YSAqKmRhdGEsIHVuc2lnbmVkIGludCAqaG9va19jb3VudCwKICAgIFVMT05HICpleHRlbnNpb25fY291bnQpCnsKICAgIHN0cnVjdCBjaGFubmVsX2hvb2tfZW50cnkgKmVudHJ5OwogICAgVUxPTkcgdG90YWxfc2l6ZSA9IDA7CiAgICB1bnNpZ25lZCBpbnQgaG9va19pbmRleCA9IDA7CgogICAgKmhvb2tfY291bnQgPSAwOwogICAgKmV4dGVuc2lvbl9jb3VudCA9IDA7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmNzQ2hhbm5lbEhvb2spOwoKICAgIExJU1RfRk9SX0VBQ0hfRU5UUlkoZW50cnksICZjaGFubmVsX2hvb2tzLCBzdHJ1Y3QgY2hhbm5lbF9ob29rX2VudHJ5LCBlbnRyeSkKICAgICAgICAoKmhvb2tfY291bnQpKys7CgogICAgaWYgKCpob29rX2NvdW50KQogICAgICAgICpkYXRhID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsICpob29rX2NvdW50ICogc2l6ZW9mKHN0cnVjdCBjaGFubmVsX2hvb2tfYnVmZmVyX2RhdGEpKTsKICAgIGVsc2UKICAgICAgICAqZGF0YSA9IE5VTEw7CgogICAgTElTVF9GT1JfRUFDSF9FTlRSWShlbnRyeSwgJmNoYW5uZWxfaG9va3MsIHN0cnVjdCBjaGFubmVsX2hvb2tfZW50cnksIGVudHJ5KQogICAgewogICAgICAgIFVMT05HIGV4dGVuc2lvbl9zaXplID0gMDsKCiAgICAgICAgSUNoYW5uZWxIb29rX0NsaWVudEdldFNpemUoZW50cnktPmhvb2ssICZlbnRyeS0+aWQsICZpbmZvLT5paWQsICZleHRlbnNpb25fc2l6ZSk7CgogICAgICAgIFRSQUNFKCIlczogZXh0ZW5zaW9uX3NpemUgPSAldVxuIiwgZGVidWdzdHJfZ3VpZCgmZW50cnktPmlkKSwgZXh0ZW5zaW9uX3NpemUpOwoKICAgICAgICBleHRlbnNpb25fc2l6ZSA9IChleHRlbnNpb25fc2l6ZSs3KSZ+NzsKICAgICAgICAoKmRhdGEpW2hvb2tfaW5kZXhdLmlkID0gZW50cnktPmlkOwogICAgICAgICgqZGF0YSlbaG9va19pbmRleF0uZXh0ZW5zaW9uX3NpemUgPSBleHRlbnNpb25fc2l6ZTsKCiAgICAgICAgLyogYW4gZXh0ZW5zaW9uIGlzIG9ubHkgcHV0IG9udG8gdGhlIHdpcmUgaWYgaXQgaGFzIGRhdGEgdG8gd3JpdGUgKi8KICAgICAgICBpZiAoZXh0ZW5zaW9uX3NpemUpCiAgICAgICAgewogICAgICAgICAgICB0b3RhbF9zaXplICs9IEZJRUxEX09GRlNFVChXSVJFX09SUENfRVhURU5ULCBkYXRhW2V4dGVuc2lvbl9zaXplXSk7CiAgICAgICAgICAgICgqZXh0ZW5zaW9uX2NvdW50KSsrOwogICAgICAgIH0KCiAgICAgICAgaG9va19pbmRleCsrOwogICAgfQoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZjc0NoYW5uZWxIb29rKTsKCiAgICByZXR1cm4gdG90YWxfc2l6ZTsKfQoKc3RhdGljIHVuc2lnbmVkIGNoYXIgKiBDaGFubmVsSG9va3NfQ2xpZW50RmlsbEJ1ZmZlcihTQ2hhbm5lbEhvb2tDYWxsSW5mbyAqaW5mbywKICAgIHVuc2lnbmVkIGNoYXIgKmJ1ZmZlciwgc3RydWN0IGNoYW5uZWxfaG9va19idWZmZXJfZGF0YSAqZGF0YSwKICAgIHVuc2lnbmVkIGludCBob29rX2NvdW50KQp7CiAgICBzdHJ1Y3QgY2hhbm5lbF9ob29rX2VudHJ5ICplbnRyeTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmY3NDaGFubmVsSG9vayk7CgogICAgTElTVF9GT1JfRUFDSF9FTlRSWShlbnRyeSwgJmNoYW5uZWxfaG9va3MsIHN0cnVjdCBjaGFubmVsX2hvb2tfZW50cnksIGVudHJ5KQogICAgewogICAgICAgIHVuc2lnbmVkIGludCBpOwogICAgICAgIFVMT05HIGV4dGVuc2lvbl9zaXplID0gMDsKICAgICAgICBXSVJFX09SUENfRVhURU5UICp3aXJlX29ycGNfZXh0ZW50ID0gKFdJUkVfT1JQQ19FWFRFTlQgKilidWZmZXI7CgogICAgICAgIGZvciAoaSA9IDA7IGkgPCBob29rX2NvdW50OyBpKyspCiAgICAgICAgICAgIGlmIChJc0VxdWFsR1VJRCgmZW50cnktPmlkLCAmZGF0YVtpXS5pZCkpCiAgICAgICAgICAgICAgICBleHRlbnNpb25fc2l6ZSA9IGRhdGFbaV0uZXh0ZW5zaW9uX3NpemU7CgogICAgICAgIC8qIGFuIGV4dGVuc2lvbiBpcyBvbmx5IHB1dCBvbnRvIHRoZSB3aXJlIGlmIGl0IGhhcyBkYXRhIHRvIHdyaXRlICovCiAgICAgICAgaWYgKCFleHRlbnNpb25fc2l6ZSkKICAgICAgICAgICAgY29udGludWU7CgogICAgICAgIElDaGFubmVsSG9va19DbGllbnRGaWxsQnVmZmVyKGVudHJ5LT5ob29rLCAmZW50cnktPmlkLCAmaW5mby0+aWlkLAogICAgICAgICAgICAmZXh0ZW5zaW9uX3NpemUsIGJ1ZmZlciArIEZJRUxEX09GRlNFVChXSVJFX09SUENfRVhURU5ULCBkYXRhWzBdKSk7CgogICAgICAgIFRSQUNFKCIlczogZXh0ZW5zaW9uX3NpemUgPSAldVxuIiwgZGVidWdzdHJfZ3VpZCgmZW50cnktPmlkKSwgZXh0ZW5zaW9uX3NpemUpOwoKICAgICAgICAvKiBGSVhNRTogc2V0IHVudXNlZCBwb3J0aW9uIG9mIHdpcmVfb3JwY19leHRlbnQtPmRhdGEgdG8gMD8gKi8KCiAgICAgICAgd2lyZV9vcnBjX2V4dGVudC0+Y29uZm9ybWFuY2UgPSAoZXh0ZW5zaW9uX3NpemUrNykmfjc7CiAgICAgICAgd2lyZV9vcnBjX2V4dGVudC0+c2l6ZSA9IGV4dGVuc2lvbl9zaXplOwogICAgICAgIG1lbWNweSgmd2lyZV9vcnBjX2V4dGVudC0+aWQsICZlbnRyeS0+aWQsIHNpemVvZih3aXJlX29ycGNfZXh0ZW50LT5pZCkpOwogICAgICAgIGJ1ZmZlciArPSBGSUVMRF9PRkZTRVQoV0lSRV9PUlBDX0VYVEVOVCwgZGF0YVt3aXJlX29ycGNfZXh0ZW50LT5jb25mb3JtYW5jZV0pOwogICAgfQoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZjc0NoYW5uZWxIb29rKTsKCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBkYXRhKTsKCiAgICByZXR1cm4gYnVmZmVyOwp9CgpzdGF0aWMgdm9pZCBDaGFubmVsSG9va3NfU2VydmVyTm90aWZ5KFNDaGFubmVsSG9va0NhbGxJbmZvICppbmZvLAogICAgRFdPUkQgbERhdGFSZXAsIFdJUkVfT1JQQ19FWFRFTlQgKmZpcnN0X3dpcmVfb3JwY19leHRlbnQsCiAgICBVTE9ORyBleHRlbnNpb25fY291bnQpCnsKICAgIHN0cnVjdCBjaGFubmVsX2hvb2tfZW50cnkgKmVudHJ5OwogICAgVUxPTkcgaTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmY3NDaGFubmVsSG9vayk7CgogICAgTElTVF9GT1JfRUFDSF9FTlRSWShlbnRyeSwgJmNoYW5uZWxfaG9va3MsIHN0cnVjdCBjaGFubmVsX2hvb2tfZW50cnksIGVudHJ5KQogICAgewogICAgICAgIFdJUkVfT1JQQ19FWFRFTlQgKndpcmVfb3JwY19leHRlbnQ7CiAgICAgICAgZm9yIChpID0gMCwgd2lyZV9vcnBjX2V4dGVudCA9IGZpcnN0X3dpcmVfb3JwY19leHRlbnQ7CiAgICAgICAgICAgICBpIDwgZXh0ZW5zaW9uX2NvdW50OwogICAgICAgICAgICAgaSsrLCB3aXJlX29ycGNfZXh0ZW50ID0gKFdJUkVfT1JQQ19FWFRFTlQgKikmd2lyZV9vcnBjX2V4dGVudC0+ZGF0YVt3aXJlX29ycGNfZXh0ZW50LT5jb25mb3JtYW5jZV0pCiAgICAgICAgewogICAgICAgICAgICBpZiAoSXNFcXVhbEdVSUQoJmVudHJ5LT5pZCwgJndpcmVfb3JwY19leHRlbnQtPmlkKSkKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBpZiAoaSA9PSBleHRlbnNpb25fY291bnQpIHdpcmVfb3JwY19leHRlbnQgPSBOVUxMOwoKICAgICAgICBJQ2hhbm5lbEhvb2tfU2VydmVyTm90aWZ5KGVudHJ5LT5ob29rLCAmZW50cnktPmlkLCAmaW5mby0+aWlkLAogICAgICAgICAgICB3aXJlX29ycGNfZXh0ZW50ID8gd2lyZV9vcnBjX2V4dGVudC0+c2l6ZSA6IDAsCiAgICAgICAgICAgIHdpcmVfb3JwY19leHRlbnQgPyB3aXJlX29ycGNfZXh0ZW50LT5kYXRhIDogTlVMTCwKICAgICAgICAgICAgbERhdGFSZXApOwogICAgfQoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZjc0NoYW5uZWxIb29rKTsKfQoKc3RhdGljIFVMT05HIENoYW5uZWxIb29rc19TZXJ2ZXJHZXRTaXplKFNDaGFubmVsSG9va0NhbGxJbmZvICppbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IGNoYW5uZWxfaG9va19idWZmZXJfZGF0YSAqKmRhdGEsIHVuc2lnbmVkIGludCAqaG9va19jb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVMT05HICpleHRlbnNpb25fY291bnQpCnsKICAgIHN0cnVjdCBjaGFubmVsX2hvb2tfZW50cnkgKmVudHJ5OwogICAgVUxPTkcgdG90YWxfc2l6ZSA9IDA7CiAgICB1bnNpZ25lZCBpbnQgaG9va19pbmRleCA9IDA7CgogICAgKmhvb2tfY291bnQgPSAwOwogICAgKmV4dGVuc2lvbl9jb3VudCA9IDA7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmNzQ2hhbm5lbEhvb2spOwoKICAgIExJU1RfRk9SX0VBQ0hfRU5UUlkoZW50cnksICZjaGFubmVsX2hvb2tzLCBzdHJ1Y3QgY2hhbm5lbF9ob29rX2VudHJ5LCBlbnRyeSkKICAgICAgICAoKmhvb2tfY291bnQpKys7CgogICAgaWYgKCpob29rX2NvdW50KQogICAgICAgICpkYXRhID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsICpob29rX2NvdW50ICogc2l6ZW9mKHN0cnVjdCBjaGFubmVsX2hvb2tfYnVmZmVyX2RhdGEpKTsKICAgIGVsc2UKICAgICAgICAqZGF0YSA9IE5VTEw7CgogICAgTElTVF9GT1JfRUFDSF9FTlRSWShlbnRyeSwgJmNoYW5uZWxfaG9va3MsIHN0cnVjdCBjaGFubmVsX2hvb2tfZW50cnksIGVudHJ5KQogICAgewogICAgICAgIFVMT05HIGV4dGVuc2lvbl9zaXplID0gMDsKCiAgICAgICAgSUNoYW5uZWxIb29rX1NlcnZlckdldFNpemUoZW50cnktPmhvb2ssICZlbnRyeS0+aWQsICZpbmZvLT5paWQsIFNfT0ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmV4dGVuc2lvbl9zaXplKTsKCiAgICAgICAgVFJBQ0UoIiVzOiBleHRlbnNpb25fc2l6ZSA9ICV1XG4iLCBkZWJ1Z3N0cl9ndWlkKCZlbnRyeS0+aWQpLCBleHRlbnNpb25fc2l6ZSk7CgogICAgICAgIGV4dGVuc2lvbl9zaXplID0gKGV4dGVuc2lvbl9zaXplKzcpJn43OwogICAgICAgICgqZGF0YSlbaG9va19pbmRleF0uaWQgPSBlbnRyeS0+aWQ7CiAgICAgICAgKCpkYXRhKVtob29rX2luZGV4XS5leHRlbnNpb25fc2l6ZSA9IGV4dGVuc2lvbl9zaXplOwoKICAgICAgICAvKiBhbiBleHRlbnNpb24gaXMgb25seSBwdXQgb250byB0aGUgd2lyZSBpZiBpdCBoYXMgZGF0YSB0byB3cml0ZSAqLwogICAgICAgIGlmIChleHRlbnNpb25fc2l6ZSkKICAgICAgICB7CiAgICAgICAgICAgIHRvdGFsX3NpemUgKz0gRklFTERfT0ZGU0VUKFdJUkVfT1JQQ19FWFRFTlQsIGRhdGFbZXh0ZW5zaW9uX3NpemVdKTsKICAgICAgICAgICAgKCpleHRlbnNpb25fY291bnQpKys7CiAgICAgICAgfQoKICAgICAgICBob29rX2luZGV4Kys7CiAgICB9CgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmNzQ2hhbm5lbEhvb2spOwoKICAgIHJldHVybiB0b3RhbF9zaXplOwp9CgpzdGF0aWMgdW5zaWduZWQgY2hhciAqIENoYW5uZWxIb29rc19TZXJ2ZXJGaWxsQnVmZmVyKFNDaGFubmVsSG9va0NhbGxJbmZvICppbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgKmJ1ZmZlciwgc3RydWN0IGNoYW5uZWxfaG9va19idWZmZXJfZGF0YSAqZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgaG9va19jb3VudCkKewogICAgc3RydWN0IGNoYW5uZWxfaG9va19lbnRyeSAqZW50cnk7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmNzQ2hhbm5lbEhvb2spOwoKICAgIExJU1RfRk9SX0VBQ0hfRU5UUlkoZW50cnksICZjaGFubmVsX2hvb2tzLCBzdHJ1Y3QgY2hhbm5lbF9ob29rX2VudHJ5LCBlbnRyeSkKICAgIHsKICAgICAgICB1bnNpZ25lZCBpbnQgaTsKICAgICAgICBVTE9ORyBleHRlbnNpb25fc2l6ZSA9IDA7CiAgICAgICAgV0lSRV9PUlBDX0VYVEVOVCAqd2lyZV9vcnBjX2V4dGVudCA9IChXSVJFX09SUENfRVhURU5UICopYnVmZmVyOwoKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgaG9va19jb3VudDsgaSsrKQogICAgICAgICAgICBpZiAoSXNFcXVhbEdVSUQoJmVudHJ5LT5pZCwgJmRhdGFbaV0uaWQpKQogICAgICAgICAgICAgICAgZXh0ZW5zaW9uX3NpemUgPSBkYXRhW2ldLmV4dGVuc2lvbl9zaXplOwoKICAgICAgICAvKiBhbiBleHRlbnNpb24gaXMgb25seSBwdXQgb250byB0aGUgd2lyZSBpZiBpdCBoYXMgZGF0YSB0byB3cml0ZSAqLwogICAgICAgIGlmICghZXh0ZW5zaW9uX3NpemUpCiAgICAgICAgICAgIGNvbnRpbnVlOwoKICAgICAgICBJQ2hhbm5lbEhvb2tfU2VydmVyRmlsbEJ1ZmZlcihlbnRyeS0+aG9vaywgJmVudHJ5LT5pZCwgJmluZm8tPmlpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmZXh0ZW5zaW9uX3NpemUsIGJ1ZmZlciArIEZJRUxEX09GRlNFVChXSVJFX09SUENfRVhURU5ULCBkYXRhWzBdKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTX09LKTsKCiAgICAgICAgVFJBQ0UoIiVzOiBleHRlbnNpb25fc2l6ZSA9ICV1XG4iLCBkZWJ1Z3N0cl9ndWlkKCZlbnRyeS0+aWQpLCBleHRlbnNpb25fc2l6ZSk7CgogICAgICAgIC8qIEZJWE1FOiBzZXQgdW51c2VkIHBvcnRpb24gb2Ygd2lyZV9vcnBjX2V4dGVudC0+ZGF0YSB0byAwPyAqLwoKICAgICAgICB3aXJlX29ycGNfZXh0ZW50LT5jb25mb3JtYW5jZSA9IChleHRlbnNpb25fc2l6ZSs3KSZ+NzsKICAgICAgICB3aXJlX29ycGNfZXh0ZW50LT5zaXplID0gZXh0ZW5zaW9uX3NpemU7CiAgICAgICAgbWVtY3B5KCZ3aXJlX29ycGNfZXh0ZW50LT5pZCwgJmVudHJ5LT5pZCwgc2l6ZW9mKHdpcmVfb3JwY19leHRlbnQtPmlkKSk7CiAgICAgICAgYnVmZmVyICs9IEZJRUxEX09GRlNFVChXSVJFX09SUENfRVhURU5ULCBkYXRhW3dpcmVfb3JwY19leHRlbnQtPmNvbmZvcm1hbmNlXSk7CiAgICB9CgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmNzQ2hhbm5lbEhvb2spOwoKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGRhdGEpOwoKICAgIHJldHVybiBidWZmZXI7Cn0KCnN0YXRpYyB2b2lkIENoYW5uZWxIb29rc19DbGllbnROb3RpZnkoU0NoYW5uZWxIb29rQ2FsbEluZm8gKmluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgbERhdGFSZXAsIFdJUkVfT1JQQ19FWFRFTlQgKmZpcnN0X3dpcmVfb3JwY19leHRlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUxPTkcgZXh0ZW5zaW9uX2NvdW50LCBIUkVTVUxUIGhyRmF1bHQpCnsKICAgIHN0cnVjdCBjaGFubmVsX2hvb2tfZW50cnkgKmVudHJ5OwogICAgVUxPTkcgaTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmY3NDaGFubmVsSG9vayk7CgogICAgTElTVF9GT1JfRUFDSF9FTlRSWShlbnRyeSwgJmNoYW5uZWxfaG9va3MsIHN0cnVjdCBjaGFubmVsX2hvb2tfZW50cnksIGVudHJ5KQogICAgewogICAgICAgIFdJUkVfT1JQQ19FWFRFTlQgKndpcmVfb3JwY19leHRlbnQ7CiAgICAgICAgZm9yIChpID0gMCwgd2lyZV9vcnBjX2V4dGVudCA9IGZpcnN0X3dpcmVfb3JwY19leHRlbnQ7CiAgICAgICAgICAgICBpIDwgZXh0ZW5zaW9uX2NvdW50OwogICAgICAgICAgICAgaSsrLCB3aXJlX29ycGNfZXh0ZW50ID0gKFdJUkVfT1JQQ19FWFRFTlQgKikmd2lyZV9vcnBjX2V4dGVudC0+ZGF0YVt3aXJlX29ycGNfZXh0ZW50LT5jb25mb3JtYW5jZV0pCiAgICAgICAgewogICAgICAgICAgICBpZiAoSXNFcXVhbEdVSUQoJmVudHJ5LT5pZCwgJndpcmVfb3JwY19leHRlbnQtPmlkKSkKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBpZiAoaSA9PSBleHRlbnNpb25fY291bnQpIHdpcmVfb3JwY19leHRlbnQgPSBOVUxMOwoKICAgICAgICBJQ2hhbm5lbEhvb2tfQ2xpZW50Tm90aWZ5KGVudHJ5LT5ob29rLCAmZW50cnktPmlkLCAmaW5mby0+aWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lyZV9vcnBjX2V4dGVudCA/IHdpcmVfb3JwY19leHRlbnQtPnNpemUgOiAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lyZV9vcnBjX2V4dGVudCA/IHdpcmVfb3JwY19leHRlbnQtPmRhdGEgOiBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbERhdGFSZXAsIGhyRmF1bHQpOwogICAgfQoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZjc0NoYW5uZWxIb29rKTsKfQoKSFJFU1VMVCBSUENfUmVnaXN0ZXJDaGFubmVsSG9vayhSRUZHVUlEIHJndWlkLCBJQ2hhbm5lbEhvb2sgKmhvb2spCnsKICAgIHN0cnVjdCBjaGFubmVsX2hvb2tfZW50cnkgKmVudHJ5OwoKICAgIFRSQUNFKCIoJXMsICVwKVxuIiwgZGVidWdzdHJfZ3VpZChyZ3VpZCksIGhvb2spOwoKICAgIGVudHJ5ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZigqZW50cnkpKTsKICAgIGlmICghZW50cnkpCiAgICAgICAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CgogICAgbWVtY3B5KCZlbnRyeS0+aWQsIHJndWlkLCBzaXplb2YoZW50cnktPmlkKSk7CiAgICBlbnRyeS0+aG9vayA9IGhvb2s7CiAgICBJQ2hhbm5lbEhvb2tfQWRkUmVmKGhvb2spOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZjc0NoYW5uZWxIb29rKTsKICAgIGxpc3RfYWRkX3RhaWwoJmNoYW5uZWxfaG9va3MsICZlbnRyeS0+ZW50cnkpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmNzQ2hhbm5lbEhvb2spOwoKICAgIHJldHVybiBTX09LOwp9Cgp2b2lkIFJQQ19VbnJlZ2lzdGVyQWxsQ2hhbm5lbEhvb2tzKHZvaWQpCnsKICAgIHN0cnVjdCBjaGFubmVsX2hvb2tfZW50cnkgKmN1cnNvcjsKICAgIHN0cnVjdCBjaGFubmVsX2hvb2tfZW50cnkgKmN1cnNvcjI7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmNzQ2hhbm5lbEhvb2spOwogICAgTElTVF9GT1JfRUFDSF9FTlRSWV9TQUZFKGN1cnNvciwgY3Vyc29yMiwgJmNoYW5uZWxfaG9va3MsIHN0cnVjdCBjaGFubmVsX2hvb2tfZW50cnksIGVudHJ5KQogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGN1cnNvcik7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmY3NDaGFubmVsSG9vayk7Cn0KCi8qIFJQQyBDaGFubmVsIEJ1ZmZlciBGdW5jdGlvbnMgKi8KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBScGNDaGFubmVsQnVmZmVyX1F1ZXJ5SW50ZXJmYWNlKExQUlBDQ0hBTk5FTEJVRkZFUiBpZmFjZSwgUkVGSUlEIHJpaWQsIExQVk9JRCAqcHB2KQp7CiAgICAqcHB2ID0gTlVMTDsKICAgIGlmIChJc0VxdWFsSUlEKHJpaWQsJklJRF9JUnBjQ2hhbm5lbEJ1ZmZlcikgfHwgSXNFcXVhbElJRChyaWlkLCZJSURfSVVua25vd24pKQogICAgewogICAgICAgICpwcHYgPSAoTFBWT0lEKWlmYWNlOwogICAgICAgIElVbmtub3duX0FkZFJlZihpZmFjZSk7CiAgICAgICAgcmV0dXJuIFNfT0s7CiAgICB9CiAgICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBScGNDaGFubmVsQnVmZmVyX0FkZFJlZihMUFJQQ0NIQU5ORUxCVUZGRVIgaWZhY2UpCnsKICAgIFJwY0NoYW5uZWxCdWZmZXIgKlRoaXMgPSAoUnBjQ2hhbm5lbEJ1ZmZlciAqKWlmYWNlOwogICAgcmV0dXJuIEludGVybG9ja2VkSW5jcmVtZW50KCZUaGlzLT5yZWZzKTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBTZXJ2ZXJScGNDaGFubmVsQnVmZmVyX1JlbGVhc2UoTFBSUENDSEFOTkVMQlVGRkVSIGlmYWNlKQp7CiAgICBScGNDaGFubmVsQnVmZmVyICpUaGlzID0gKFJwY0NoYW5uZWxCdWZmZXIgKilpZmFjZTsKICAgIFVMT05HIHJlZjsKCiAgICByZWYgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+cmVmcyk7CiAgICBpZiAocmVmKQogICAgICAgIHJldHVybiByZWY7CgogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcyk7CiAgICByZXR1cm4gMDsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBDbGllbnRScGNDaGFubmVsQnVmZmVyX1JlbGVhc2UoTFBSUENDSEFOTkVMQlVGRkVSIGlmYWNlKQp7CiAgICBDbGllbnRScGNDaGFubmVsQnVmZmVyICpUaGlzID0gKENsaWVudFJwY0NoYW5uZWxCdWZmZXIgKilpZmFjZTsKICAgIFVMT05HIHJlZjsKCiAgICByZWYgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+c3VwZXIucmVmcyk7CiAgICBpZiAocmVmKQogICAgICAgIHJldHVybiByZWY7CgogICAgaWYgKFRoaXMtPmV2ZW50KSBDbG9zZUhhbmRsZShUaGlzLT5ldmVudCk7CiAgICBScGNCaW5kaW5nRnJlZSgmVGhpcy0+YmluZCk7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzKTsKICAgIHJldHVybiAwOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgU2VydmVyUnBjQ2hhbm5lbEJ1ZmZlcl9HZXRCdWZmZXIoTFBSUENDSEFOTkVMQlVGRkVSIGlmYWNlLCBSUENPTEVNRVNTQUdFKiBvbGVtc2csIFJFRklJRCByaWlkKQp7CiAgICBScGNDaGFubmVsQnVmZmVyICpUaGlzID0gKFJwY0NoYW5uZWxCdWZmZXIgKilpZmFjZTsKICAgIFJQQ19NRVNTQUdFICptc2cgPSAoUlBDX01FU1NBR0UgKilvbGVtc2c7CiAgICBSUENfU1RBVFVTIHN0YXR1czsKICAgIE9SUENUSEFUICpvcnBjdGhhdDsKICAgIHN0cnVjdCBtZXNzYWdlX3N0YXRlICptZXNzYWdlX3N0YXRlOwogICAgVUxPTkcgZXh0ZW5zaW9uc19zaXplOwogICAgc3RydWN0IGNoYW5uZWxfaG9va19idWZmZXJfZGF0YSAqY2hhbm5lbF9ob29rX2RhdGE7CiAgICB1bnNpZ25lZCBpbnQgY2hhbm5lbF9ob29rX2NvdW50OwogICAgVUxPTkcgZXh0ZW5zaW9uX2NvdW50OwoKICAgIFRSQUNFKCIoJXApLT4oJXAsJXMpXG4iLCBUaGlzLCBvbGVtc2csIGRlYnVnc3RyX2d1aWQocmlpZCkpOwoKICAgIG1lc3NhZ2Vfc3RhdGUgPSAoc3RydWN0IG1lc3NhZ2Vfc3RhdGUgKiltc2ctPkhhbmRsZTsKICAgIC8qIHJlc3RvcmUgdGhlIGJpbmRpbmcgaGFuZGxlIGFuZCB0aGUgcmVhbCBzdGFydCBvZiBkYXRhICovCiAgICBtc2ctPkhhbmRsZSA9IG1lc3NhZ2Vfc3RhdGUtPmJpbmRpbmdfaGFuZGxlOwogICAgbXNnLT5CdWZmZXIgPSAoY2hhciAqKW1zZy0+QnVmZmVyIC0gbWVzc2FnZV9zdGF0ZS0+cHJlZml4X2RhdGFfbGVuOwoKICAgIGV4dGVuc2lvbnNfc2l6ZSA9IENoYW5uZWxIb29rc19TZXJ2ZXJHZXRTaXplKCZtZXNzYWdlX3N0YXRlLT5jaGFubmVsX2hvb2tfaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZjaGFubmVsX2hvb2tfZGF0YSwgJmNoYW5uZWxfaG9va19jb3VudCwgJmV4dGVuc2lvbl9jb3VudCk7CgogICAgbXNnLT5CdWZmZXJMZW5ndGggKz0gRklFTERfT0ZGU0VUKE9SUENUSEFULCBleHRlbnNpb25zKSArIDQ7CiAgICBpZiAoZXh0ZW5zaW9uc19zaXplKQogICAgewogICAgICAgIG1zZy0+QnVmZmVyTGVuZ3RoICs9IEZJRUxEX09GRlNFVChPUlBDX0VYVEVOVF9BUlJBWSwgZXh0ZW50KSArIDIqc2l6ZW9mKERXT1JEKSArIGV4dGVuc2lvbnNfc2l6ZTsKICAgICAgICBpZiAoZXh0ZW5zaW9uX2NvdW50ICYgMSkKICAgICAgICAgICAgbXNnLT5CdWZmZXJMZW5ndGggKz0gRklFTERfT0ZGU0VUKFdJUkVfT1JQQ19FWFRFTlQsIGRhdGFbMF0pOwogICAgfQoKICAgIHN0YXR1cyA9IElfUnBjR2V0QnVmZmVyKG1zZyk7CgogICAgb3JwY3RoYXQgPSAoT1JQQ1RIQVQgKiltc2ctPkJ1ZmZlcjsKICAgIG1zZy0+QnVmZmVyID0gKGNoYXIgKiltc2ctPkJ1ZmZlciArIEZJRUxEX09GRlNFVChPUlBDVEhBVCwgZXh0ZW5zaW9ucyk7CgogICAgb3JwY3RoYXQtPmZsYWdzID0gT1JQQ0ZfTlVMTCAvKiBGSVhNRT8gKi87CgogICAgLyogTkRSIHJlcHJlc2VudGF0aW9uIG9mIG9ycGN0aGF0LT5leHRlbnNpb25zICovCiAgICAqKERXT1JEICopbXNnLT5CdWZmZXIgPSBleHRlbnNpb25zX3NpemUgPyAxIDogMDsKICAgIG1zZy0+QnVmZmVyID0gKGNoYXIgKiltc2ctPkJ1ZmZlciArIHNpemVvZihEV09SRCk7CgogICAgaWYgKGV4dGVuc2lvbnNfc2l6ZSkKICAgIHsKICAgICAgICBPUlBDX0VYVEVOVF9BUlJBWSAqb3JwY19leHRlbnRfYXJyYXkgPSBtc2ctPkJ1ZmZlcjsKICAgICAgICBvcnBjX2V4dGVudF9hcnJheS0+c2l6ZSA9IGV4dGVuc2lvbl9jb3VudDsKICAgICAgICBvcnBjX2V4dGVudF9hcnJheS0+cmVzZXJ2ZWQgPSAwOwogICAgICAgIG1zZy0+QnVmZmVyID0gKGNoYXIgKiltc2ctPkJ1ZmZlciArIEZJRUxEX09GRlNFVChPUlBDX0VYVEVOVF9BUlJBWSwgZXh0ZW50KTsKICAgICAgICAvKiBORFIgcmVwcmVzZW50YXRpb24gb2Ygb3JwY19leHRlbnRfYXJyYXktPmV4dGVudCAqLwogICAgICAgICooRFdPUkQgKiltc2ctPkJ1ZmZlciA9IDE7CiAgICAgICAgbXNnLT5CdWZmZXIgPSAoY2hhciAqKW1zZy0+QnVmZmVyICsgc2l6ZW9mKERXT1JEKTsKICAgICAgICAvKiBORFIgcmVwcmVzZW50YXRpb24gb2YgW3NpemVfaXNdIGF0dHJpYnV0ZSBvZiBvcnBjX2V4dGVudF9hcnJheS0+ZXh0ZW50ICovCiAgICAgICAgKihEV09SRCAqKW1zZy0+QnVmZmVyID0gKGV4dGVuc2lvbl9jb3VudCArIDEpICYgfjE7CiAgICAgICAgbXNnLT5CdWZmZXIgPSAoY2hhciAqKW1zZy0+QnVmZmVyICsgc2l6ZW9mKERXT1JEKTsKCiAgICAgICAgbXNnLT5CdWZmZXIgPSBDaGFubmVsSG9va3NfU2VydmVyRmlsbEJ1ZmZlcigmbWVzc2FnZV9zdGF0ZS0+Y2hhbm5lbF9ob29rX2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtc2ctPkJ1ZmZlciwgY2hhbm5lbF9ob29rX2RhdGEsIGNoYW5uZWxfaG9va19jb3VudCk7CgogICAgICAgIC8qIHdlIG11c3QgYWRkIGEgZHVtbXkgZXh0ZW5zaW9uIGlmIHRoZXJlIGlzIGFuIG9kZCBleHRlbnNpb24KICAgICAgICAgKiBjb3VudCB0byBtZWV0IHRoZSBjb250cmFjdCBzcGVjaWZpZWQgYnkgdGhlIHNpemVfaXMgYXR0cmlidXRlICovCiAgICAgICAgaWYgKGV4dGVuc2lvbl9jb3VudCAmIDEpCiAgICAgICAgewogICAgICAgICAgICBXSVJFX09SUENfRVhURU5UICp3aXJlX29ycGNfZXh0ZW50ID0gbXNnLT5CdWZmZXI7CiAgICAgICAgICAgIHdpcmVfb3JwY19leHRlbnQtPmNvbmZvcm1hbmNlID0gMDsKICAgICAgICAgICAgbWVtY3B5KCZ3aXJlX29ycGNfZXh0ZW50LT5pZCwgJkdVSURfTlVMTCwgc2l6ZW9mKHdpcmVfb3JwY19leHRlbnQtPmlkKSk7CiAgICAgICAgICAgIHdpcmVfb3JwY19leHRlbnQtPnNpemUgPSAwOwogICAgICAgICAgICBtc2ctPkJ1ZmZlciA9IChjaGFyICopbXNnLT5CdWZmZXIgKyBGSUVMRF9PRkZTRVQoV0lSRV9PUlBDX0VYVEVOVCwgZGF0YVswXSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qIHN0b3JlIHRoZSBwcmVmaXhlZCBkYXRhIGxlbmd0aCBzbyB0aGF0IHdlIGNhbiByZXN0b3JlIHRoZSByZWFsIGJ1ZmZlcgogICAgICogbGF0ZXIgKi8KICAgIG1lc3NhZ2Vfc3RhdGUtPnByZWZpeF9kYXRhX2xlbiA9IChjaGFyICopbXNnLT5CdWZmZXIgLSAoY2hhciAqKW9ycGN0aGF0OwogICAgbXNnLT5CdWZmZXJMZW5ndGggLT0gbWVzc2FnZV9zdGF0ZS0+cHJlZml4X2RhdGFfbGVuOwogICAgLyogc2F2ZSBhd2F5IHRoZSBtZXNzYWdlIHN0YXRlIGFnYWluICovCiAgICBtc2ctPkhhbmRsZSA9IG1lc3NhZ2Vfc3RhdGU7CgogICAgVFJBQ0UoIi0tICVsZFxuIiwgc3RhdHVzKTsKCiAgICByZXR1cm4gSFJFU1VMVF9GUk9NX1dJTjMyKHN0YXR1cyk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBDbGllbnRScGNDaGFubmVsQnVmZmVyX0dldEJ1ZmZlcihMUFJQQ0NIQU5ORUxCVUZGRVIgaWZhY2UsIFJQQ09MRU1FU1NBR0UqIG9sZW1zZywgUkVGSUlEIHJpaWQpCnsKICAgIENsaWVudFJwY0NoYW5uZWxCdWZmZXIgKlRoaXMgPSAoQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlciAqKWlmYWNlOwogICAgUlBDX01FU1NBR0UgKm1zZyA9IChSUENfTUVTU0FHRSAqKW9sZW1zZzsKICAgIFJQQ19DTElFTlRfSU5URVJGQUNFICpjaWY7CiAgICBSUENfU1RBVFVTIHN0YXR1czsKICAgIE9SUENUSElTICpvcnBjdGhpczsKICAgIHN0cnVjdCBtZXNzYWdlX3N0YXRlICptZXNzYWdlX3N0YXRlOwogICAgVUxPTkcgZXh0ZW5zaW9uc19zaXplOwogICAgc3RydWN0IGNoYW5uZWxfaG9va19idWZmZXJfZGF0YSAqY2hhbm5lbF9ob29rX2RhdGE7CiAgICB1bnNpZ25lZCBpbnQgY2hhbm5lbF9ob29rX2NvdW50OwogICAgVUxPTkcgZXh0ZW5zaW9uX2NvdW50OwoKICAgIFRSQUNFKCIoJXApLT4oJXAsJXMpXG4iLCBUaGlzLCBvbGVtc2csIGRlYnVnc3RyX2d1aWQocmlpZCkpOwoKICAgIGNpZiA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoUlBDX0NMSUVOVF9JTlRFUkZBQ0UpKTsKICAgIGlmICghY2lmKQogICAgICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwoKICAgIG1lc3NhZ2Vfc3RhdGUgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKCptZXNzYWdlX3N0YXRlKSk7CiAgICBpZiAoIW1lc3NhZ2Vfc3RhdGUpCiAgICB7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgY2lmKTsKICAgICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKICAgIH0KCiAgICBjaWYtPkxlbmd0aCA9IHNpemVvZihSUENfQ0xJRU5UX0lOVEVSRkFDRSk7CiAgICAvKiBSUEMgaW50ZXJmYWNlIElEID0gQ09NIGludGVyZmFjZSBJRCAqLwogICAgY2lmLT5JbnRlcmZhY2VJZC5TeW50YXhHVUlEID0gKnJpaWQ7CiAgICAvKiBDT00gb2JqZWN0cyBhbHdheXMgaGF2ZSBhIHZlcnNpb24gb2YgMC4wICovCiAgICBjaWYtPkludGVyZmFjZUlkLlN5bnRheFZlcnNpb24uTWFqb3JWZXJzaW9uID0gMDsKICAgIGNpZi0+SW50ZXJmYWNlSWQuU3ludGF4VmVyc2lvbi5NaW5vclZlcnNpb24gPSAwOwogICAgbXNnLT5IYW5kbGUgPSBUaGlzLT5iaW5kOwogICAgbXNnLT5ScGNJbnRlcmZhY2VJbmZvcm1hdGlvbiA9IGNpZjsKCiAgICBtZXNzYWdlX3N0YXRlLT5jaGFubmVsX2hvb2tfaW5mby5paWQgPSAqcmlpZDsKICAgIG1lc3NhZ2Vfc3RhdGUtPmNoYW5uZWxfaG9va19pbmZvLmNiU2l6ZSA9IHNpemVvZihtZXNzYWdlX3N0YXRlLT5jaGFubmVsX2hvb2tfaW5mbyk7CiAgICBtZXNzYWdlX3N0YXRlLT5jaGFubmVsX2hvb2tfaW5mby51Q2F1c2FsaXR5ID0gQ09NX0N1cnJlbnRDYXVzYWxpdHlJZCgpOwogICAgbWVzc2FnZV9zdGF0ZS0+Y2hhbm5lbF9ob29rX2luZm8uZHdTZXJ2ZXJQaWQgPSBUaGlzLT5zZXJ2ZXJfcGlkOwogICAgbWVzc2FnZV9zdGF0ZS0+Y2hhbm5lbF9ob29rX2luZm8uaU1ldGhvZCA9IG1zZy0+UHJvY051bTsKICAgIG1lc3NhZ2Vfc3RhdGUtPmNoYW5uZWxfaG9va19pbmZvLnBPYmplY3QgPSBOVUxMOyAvKiBvbmx5IHByZXNlbnQgb24gc2VydmVyLXNpZGUgKi8KICAgIG1lbXNldCgmbWVzc2FnZV9zdGF0ZS0+cGFyYW1zLCAwLCBzaXplb2YobWVzc2FnZV9zdGF0ZS0+cGFyYW1zKSk7CgogICAgZXh0ZW5zaW9uc19zaXplID0gQ2hhbm5lbEhvb2tzX0NsaWVudEdldFNpemUoJm1lc3NhZ2Vfc3RhdGUtPmNoYW5uZWxfaG9va19pbmZvLAogICAgICAgICZjaGFubmVsX2hvb2tfZGF0YSwgJmNoYW5uZWxfaG9va19jb3VudCwgJmV4dGVuc2lvbl9jb3VudCk7CgogICAgbXNnLT5CdWZmZXJMZW5ndGggKz0gRklFTERfT0ZGU0VUKE9SUENUSElTLCBleHRlbnNpb25zKSArIDQ7CiAgICBpZiAoZXh0ZW5zaW9uc19zaXplKQogICAgewogICAgICAgIG1zZy0+QnVmZmVyTGVuZ3RoICs9IEZJRUxEX09GRlNFVChPUlBDX0VYVEVOVF9BUlJBWSwgZXh0ZW50KSArIDIqc2l6ZW9mKERXT1JEKSArIGV4dGVuc2lvbnNfc2l6ZTsKICAgICAgICBpZiAoZXh0ZW5zaW9uX2NvdW50ICYgMSkKICAgICAgICAgICAgbXNnLT5CdWZmZXJMZW5ndGggKz0gRklFTERfT0ZGU0VUKFdJUkVfT1JQQ19FWFRFTlQsIGRhdGFbMF0pOwogICAgfQoKICAgIHN0YXR1cyA9IElfUnBjR2V0QnVmZmVyKG1zZyk7CgogICAgbWVzc2FnZV9zdGF0ZS0+cHJlZml4X2RhdGFfbGVuID0gMDsKICAgIG1lc3NhZ2Vfc3RhdGUtPmJpbmRpbmdfaGFuZGxlID0gVGhpcy0+YmluZDsKICAgIG1zZy0+SGFuZGxlID0gbWVzc2FnZV9zdGF0ZTsKCiAgICBpZiAoc3RhdHVzID09IFJQQ19TX09LKQogICAgewogICAgICAgIG9ycGN0aGlzID0gKE9SUENUSElTICopbXNnLT5CdWZmZXI7CiAgICAgICAgbXNnLT5CdWZmZXIgPSAoY2hhciAqKW1zZy0+QnVmZmVyICsgRklFTERfT0ZGU0VUKE9SUENUSElTLCBleHRlbnNpb25zKTsKCiAgICAgICAgb3JwY3RoaXMtPnZlcnNpb24uTWFqb3JWZXJzaW9uID0gQ09NX01BSk9SX1ZFUlNJT047CiAgICAgICAgb3JwY3RoaXMtPnZlcnNpb24uTWlub3JWZXJzaW9uID0gQ09NX01JTk9SX1ZFUlNJT047CiAgICAgICAgb3JwY3RoaXMtPmZsYWdzID0gbWVzc2FnZV9zdGF0ZS0+Y2hhbm5lbF9ob29rX2luZm8uZHdTZXJ2ZXJQaWQgPyBPUlBDRl9MT0NBTCA6IE9SUENGX05VTEw7CiAgICAgICAgb3JwY3RoaXMtPnJlc2VydmVkMSA9IDA7CiAgICAgICAgb3JwY3RoaXMtPmNpZCA9IG1lc3NhZ2Vfc3RhdGUtPmNoYW5uZWxfaG9va19pbmZvLnVDYXVzYWxpdHk7CgogICAgICAgIC8qIE5EUiByZXByZXNlbnRhdGlvbiBvZiBvcnBjdGhpcy0+ZXh0ZW5zaW9ucyAqLwogICAgICAgICooRFdPUkQgKiltc2ctPkJ1ZmZlciA9IGV4dGVuc2lvbnNfc2l6ZSA/IDEgOiAwOwogICAgICAgIG1zZy0+QnVmZmVyID0gKGNoYXIgKiltc2ctPkJ1ZmZlciArIHNpemVvZihEV09SRCk7CgogICAgICAgIGlmIChleHRlbnNpb25zX3NpemUpCiAgICAgICAgewogICAgICAgICAgICBPUlBDX0VYVEVOVF9BUlJBWSAqb3JwY19leHRlbnRfYXJyYXkgPSBtc2ctPkJ1ZmZlcjsKICAgICAgICAgICAgb3JwY19leHRlbnRfYXJyYXktPnNpemUgPSBleHRlbnNpb25fY291bnQ7CiAgICAgICAgICAgIG9ycGNfZXh0ZW50X2FycmF5LT5yZXNlcnZlZCA9IDA7CiAgICAgICAgICAgIG1zZy0+QnVmZmVyID0gKGNoYXIgKiltc2ctPkJ1ZmZlciArIEZJRUxEX09GRlNFVChPUlBDX0VYVEVOVF9BUlJBWSwgZXh0ZW50KTsKICAgICAgICAgICAgLyogTkRSIHJlcHJlc2VudGF0aW9uIG9mIG9ycGNfZXh0ZW50X2FycmF5LT5leHRlbnQgKi8KICAgICAgICAgICAgKihEV09SRCAqKW1zZy0+QnVmZmVyID0gMTsKICAgICAgICAgICAgbXNnLT5CdWZmZXIgPSAoY2hhciAqKW1zZy0+QnVmZmVyICsgc2l6ZW9mKERXT1JEKTsKICAgICAgICAgICAgLyogTkRSIHJlcHJlc2VudGF0aW9uIG9mIFtzaXplX2lzXSBhdHRyaWJ1dGUgb2Ygb3JwY19leHRlbnRfYXJyYXktPmV4dGVudCAqLwogICAgICAgICAgICAqKERXT1JEICopbXNnLT5CdWZmZXIgPSAoZXh0ZW5zaW9uX2NvdW50ICsgMSkgJiB+MTsKICAgICAgICAgICAgbXNnLT5CdWZmZXIgPSAoY2hhciAqKW1zZy0+QnVmZmVyICsgc2l6ZW9mKERXT1JEKTsKCiAgICAgICAgICAgIG1zZy0+QnVmZmVyID0gQ2hhbm5lbEhvb2tzX0NsaWVudEZpbGxCdWZmZXIoJm1lc3NhZ2Vfc3RhdGUtPmNoYW5uZWxfaG9va19pbmZvLAogICAgICAgICAgICAgICAgbXNnLT5CdWZmZXIsIGNoYW5uZWxfaG9va19kYXRhLCBjaGFubmVsX2hvb2tfY291bnQpOwoKICAgICAgICAgICAgLyogd2UgbXVzdCBhZGQgYSBkdW1teSBleHRlbnNpb24gaWYgdGhlcmUgaXMgYW4gb2RkIGV4dGVuc2lvbgogICAgICAgICAgICAgKiBjb3VudCB0byBtZWV0IHRoZSBjb250cmFjdCBzcGVjaWZpZWQgYnkgdGhlIHNpemVfaXMgYXR0cmlidXRlICovCiAgICAgICAgICAgIGlmIChleHRlbnNpb25fY291bnQgJiAxKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBXSVJFX09SUENfRVhURU5UICp3aXJlX29ycGNfZXh0ZW50ID0gbXNnLT5CdWZmZXI7CiAgICAgICAgICAgICAgICB3aXJlX29ycGNfZXh0ZW50LT5jb25mb3JtYW5jZSA9IDA7CiAgICAgICAgICAgICAgICBtZW1jcHkoJndpcmVfb3JwY19leHRlbnQtPmlkLCAmR1VJRF9OVUxMLCBzaXplb2Yod2lyZV9vcnBjX2V4dGVudC0+aWQpKTsKICAgICAgICAgICAgICAgIHdpcmVfb3JwY19leHRlbnQtPnNpemUgPSAwOwogICAgICAgICAgICAgICAgbXNnLT5CdWZmZXIgPSAoY2hhciAqKW1zZy0+QnVmZmVyICsgRklFTERfT0ZGU0VUKFdJUkVfT1JQQ19FWFRFTlQsIGRhdGFbMF0pOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKiBzdG9yZSB0aGUgcHJlZml4ZWQgZGF0YSBsZW5ndGggc28gdGhhdCB3ZSBjYW4gcmVzdG9yZSB0aGUgcmVhbCBidWZmZXIKICAgICAgICAgKiBwb2ludGVyIGluIENsaWVudFJwY0NoYW5uZWxCdWZmZXJfU2VuZFJlY2VpdmUuICovCiAgICAgICAgbWVzc2FnZV9zdGF0ZS0+cHJlZml4X2RhdGFfbGVuID0gKGNoYXIgKiltc2ctPkJ1ZmZlciAtIChjaGFyICopb3JwY3RoaXM7CiAgICAgICAgbXNnLT5CdWZmZXJMZW5ndGggLT0gbWVzc2FnZV9zdGF0ZS0+cHJlZml4X2RhdGFfbGVuOwogICAgfQoKICAgIFRSQUNFKCItLSAlbGRcbiIsIHN0YXR1cyk7CgogICAgcmV0dXJuIEhSRVNVTFRfRlJPTV9XSU4zMihzdGF0dXMpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgU2VydmVyUnBjQ2hhbm5lbEJ1ZmZlcl9TZW5kUmVjZWl2ZShMUFJQQ0NIQU5ORUxCVUZGRVIgaWZhY2UsIFJQQ09MRU1FU1NBR0UgKm9sZW1zZywgVUxPTkcgKnBzdGF0dXMpCnsKICAgIEZJWE1FKCJzdHViXG4iKTsKICAgIHJldHVybiBFX05PVElNUEw7Cn0KCnN0YXRpYyBIQU5ETEUgQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlcl9HZXRFdmVudEhhbmRsZShDbGllbnRScGNDaGFubmVsQnVmZmVyICpUaGlzKQp7CiAgICBIQU5ETEUgZXZlbnQgPSBJbnRlcmxvY2tlZEV4Y2hhbmdlUG9pbnRlcigmVGhpcy0+ZXZlbnQsIE5VTEwpOwoKICAgIC8qIE5vdGU6IG11c3QgYmUgYXV0by1yZXNldCBldmVudCBzbyB3ZSBjYW4gcmV1c2UgaXQgd2l0aG91dCBhIGNhbGwKICAgICAqIHRvIFJlc2V0RXZlbnQgKi8KICAgIGlmICghZXZlbnQpIGV2ZW50ID0gQ3JlYXRlRXZlbnRXKE5VTEwsIEZBTFNFLCBGQUxTRSwgTlVMTCk7CgogICAgcmV0dXJuIGV2ZW50Owp9CgpzdGF0aWMgdm9pZCBDbGllbnRScGNDaGFubmVsQnVmZmVyX1JlbGVhc2VFdmVudEhhbmRsZShDbGllbnRScGNDaGFubmVsQnVmZmVyICpUaGlzLCBIQU5ETEUgZXZlbnQpCnsKICAgIGlmIChJbnRlcmxvY2tlZENvbXBhcmVFeGNoYW5nZVBvaW50ZXIoJlRoaXMtPmV2ZW50LCBldmVudCwgTlVMTCkpCiAgICAgICAgLyogYWxyZWFkeSBhIGhhbmRsZSBjYWNoZWQgaW4gVGhpcyAqLwogICAgICAgIENsb3NlSGFuZGxlKGV2ZW50KTsKfQoKLyogdGhpcyB0aHJlYWQgcnVucyBhbiBvdXRnb2luZyBSUEMgKi8Kc3RhdGljIERXT1JEIFdJTkFQSSBycGNfc2VuZHJlY2VpdmVfdGhyZWFkKExQVk9JRCBwYXJhbSkKewogICAgc3RydWN0IGRpc3BhdGNoX3BhcmFtcyAqZGF0YSA9IChzdHJ1Y3QgZGlzcGF0Y2hfcGFyYW1zICopIHBhcmFtOwoKICAgIC8qIE5vdGU6IElfUnBjU2VuZFJlY2VpdmUgZG9lc24ndCByYWlzZSBleGNlcHRpb25zIGxpa2UgdGhlIGhpZ2hlci1sZXZlbAogICAgICogUlBDIGZ1bmN0aW9ucyBkbyAqLwogICAgZGF0YS0+c3RhdHVzID0gSV9ScGNTZW5kUmVjZWl2ZSgoUlBDX01FU1NBR0UgKilkYXRhLT5tc2cpOwoKICAgIFRSQUNFKCJjb21wbGV0ZWQgd2l0aCBzdGF0dXMgMHglbHhcbiIsIGRhdGEtPnN0YXR1cyk7CgogICAgU2V0RXZlbnQoZGF0YS0+aGFuZGxlKTsKCiAgICByZXR1cm4gMDsKfQoKc3RhdGljIGlubGluZSBIUkVTVUxUIENsaWVudFJwY0NoYW5uZWxCdWZmZXJfSXNDb3JyZWN0QXBhcnRtZW50KENsaWVudFJwY0NoYW5uZWxCdWZmZXIgKlRoaXMsIEFQQVJUTUVOVCAqYXB0KQp7CiAgICBPWElEIG94aWQ7CiAgICBpZiAoIWFwdCkKICAgICAgICByZXR1cm4gU19GQUxTRTsKICAgIGlmIChhcGFydG1lbnRfZ2V0b3hpZChhcHQsICZveGlkKSAhPSBTX09LKQogICAgICAgIHJldHVybiBTX0ZBTFNFOwogICAgaWYgKFRoaXMtPm94aWQgIT0gb3hpZCkKICAgICAgICByZXR1cm4gU19GQUxTRTsKICAgIHJldHVybiBTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlcl9TZW5kUmVjZWl2ZShMUFJQQ0NIQU5ORUxCVUZGRVIgaWZhY2UsIFJQQ09MRU1FU1NBR0UgKm9sZW1zZywgVUxPTkcgKnBzdGF0dXMpCnsKICAgIENsaWVudFJwY0NoYW5uZWxCdWZmZXIgKlRoaXMgPSAoQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlciAqKWlmYWNlOwogICAgSFJFU1VMVCBocjsKICAgIFJQQ19NRVNTQUdFICptc2cgPSAoUlBDX01FU1NBR0UgKilvbGVtc2c7CiAgICBSUENfU1RBVFVTIHN0YXR1czsKICAgIERXT1JEIGluZGV4OwogICAgQVBBUlRNRU5UICphcHQgPSBOVUxMOwogICAgSVBJRCBpcGlkOwogICAgc3RydWN0IG1lc3NhZ2Vfc3RhdGUgKm1lc3NhZ2Vfc3RhdGU7CiAgICBPUlBDVEhBVCBvcnBjdGhhdDsKICAgIE9SUENfRVhURU5UX0FSUkFZIG9ycGNfZXh0X2FycmF5OwogICAgV0lSRV9PUlBDX0VYVEVOVCAqZmlyc3Rfd2lyZV9vcnBjX2V4dGVudCA9IE5VTEw7CiAgICBIUkVTVUxUIGhyRmF1bHQgPSBTX09LOwoKICAgIFRSQUNFKCIoJXApIGlNZXRob2Q9JWRcbiIsIG9sZW1zZywgb2xlbXNnLT5pTWV0aG9kKTsKCiAgICBociA9IENsaWVudFJwY0NoYW5uZWxCdWZmZXJfSXNDb3JyZWN0QXBhcnRtZW50KFRoaXMsIENPTV9DdXJyZW50QXB0KCkpOwogICAgaWYgKGhyICE9IFNfT0spCiAgICB7CiAgICAgICAgRVJSKCJjYWxsZWQgZnJvbSB3cm9uZyBhcGFydG1lbnQsIHNob3VsZCBoYXZlIGJlZW4gMHglc1xuIiwKICAgICAgICAgICAgd2luZV9kYmdzdHJfbG9uZ2xvbmcoVGhpcy0+b3hpZCkpOwogICAgICAgIHJldHVybiBSUENfRV9XUk9OR19USFJFQUQ7CiAgICB9CiAgICAvKiB0aGlzIHNpdHVhdGlvbiBzaG91bGQgYmUgaW1wb3NzaWJsZSBpbiBtdWx0aS10aHJlYWRlZCBhcGFydG1lbnRzLAogICAgICogYmVjYXVzZSB0aGUgY2FsbGluZyB0aHJlYWQgaXNuJ3QgcmUtZW50cmFibGUuCiAgICAgKiBOb3RlOiBkb2luZyBhIENPTSBjYWxsIGR1cmluZyB0aGUgcHJvY2Vzc2luZyBvZiBhIHNlbnQgbWVzc2FnZSBpcwogICAgICogb25seSBkaXNhbGxvd2VkIGlmIGEgY2xpZW50IGNhbGwgaXMgYWxyZWFkeSBiZWluZyB3YWl0ZWQgZm9yCiAgICAgKiBjb21wbGV0aW9uICovCiAgICBpZiAoIUNPTV9DdXJyZW50QXB0KCktPm11bHRpX3RocmVhZGVkICYmCiAgICAgICAgQ09NX0N1cnJlbnRJbmZvKCktPnBlbmRpbmdfY2FsbF9jb3VudF9jbGllbnQgJiYKICAgICAgICBJblNlbmRNZXNzYWdlKCkpCiAgICB7CiAgICAgICAgRVJSKCJjYW4ndCBtYWtlIGFuIG91dGdvaW5nIENPTSBjYWxsIGluIHJlc3BvbnNlIHRvIGEgc2VudCBtZXNzYWdlXG4iKTsKICAgICAgICByZXR1cm4gUlBDX0VfQ0FOVENBTExPVVRfSU5JTlBVVFNZTkNDQUxMOwogICAgfQoKICAgIG1lc3NhZ2Vfc3RhdGUgPSAoc3RydWN0IG1lc3NhZ2Vfc3RhdGUgKiltc2ctPkhhbmRsZTsKICAgIC8qIHJlc3RvcmUgdGhlIGJpbmRpbmcgaGFuZGxlIGFuZCB0aGUgcmVhbCBzdGFydCBvZiBkYXRhICovCiAgICBtc2ctPkhhbmRsZSA9IG1lc3NhZ2Vfc3RhdGUtPmJpbmRpbmdfaGFuZGxlOwogICAgbXNnLT5CdWZmZXIgPSAoY2hhciAqKW1zZy0+QnVmZmVyIC0gbWVzc2FnZV9zdGF0ZS0+cHJlZml4X2RhdGFfbGVuOwogICAgbXNnLT5CdWZmZXJMZW5ndGggKz0gbWVzc2FnZV9zdGF0ZS0+cHJlZml4X2RhdGFfbGVuOwoKICAgIG1lc3NhZ2Vfc3RhdGUtPnBhcmFtcy5tc2cgPSBvbGVtc2c7CiAgICBtZXNzYWdlX3N0YXRlLT5wYXJhbXMuc3RhdHVzID0gUlBDX1NfT0s7CiAgICBtZXNzYWdlX3N0YXRlLT5wYXJhbXMuaHIgPSBTX09LOwoKICAgIC8qIE5vdGU6IHRoaXMgaXMgYW4gb3B0aW1pemF0aW9uIGluIHRoZSBNaWNyb3NvZnQgT0xFIHJ1bnRpbWUgdGhhdCB3ZSBuZWVkCiAgICAgKiB0byBjb3B5LCBhcyBzaG93biBieSB0aGUgdGVzdF9ub19jb3VuaW5pdGlhbGl6ZV9jbGllbnQgdGVzdC4gd2l0aG91dAogICAgICogc2hvcnQtY2lyY3VpdGluZyB0aGUgUlBDIHJ1bnRpbWUgaW4gdGhlIGNhc2UgYmVsb3csIHRoZSB0ZXN0IHdpbGwKICAgICAqIGRlYWRsb2NrIG9uIHRoZSBsb2FkZXIgbG9jayBkdWUgdG8gdGhlIFJQQyBydW50aW1lIG5lZWRpbmcgdG8gY3JlYXRlCiAgICAgKiBhIHRocmVhZCB0byBwcm9jZXNzIHRoZSBSUEMgd2hlbiB0aGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBpbmRpcmVjdGx5CiAgICAgKiBmcm9tIERsbE1haW4gKi8KCiAgICBScGNCaW5kaW5nSW5xT2JqZWN0KG1lc3NhZ2Vfc3RhdGUtPmJpbmRpbmdfaGFuZGxlLCAmaXBpZCk7CiAgICBociA9IGlwaWRfZ2V0X2Rpc3BhdGNoX3BhcmFtcygmaXBpZCwgJmFwdCwgJm1lc3NhZ2Vfc3RhdGUtPnBhcmFtcy5zdHViLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJm1lc3NhZ2Vfc3RhdGUtPnBhcmFtcy5jaGFuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJm1lc3NhZ2Vfc3RhdGUtPnBhcmFtcy5paWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbWVzc2FnZV9zdGF0ZS0+cGFyYW1zLmlmYWNlKTsKICAgIG1lc3NhZ2Vfc3RhdGUtPnBhcmFtcy5oYW5kbGUgPSBDbGllbnRScGNDaGFubmVsQnVmZmVyX0dldEV2ZW50SGFuZGxlKFRoaXMpOwogICAgaWYgKChociA9PSBTX09LKSAmJiAhYXB0LT5tdWx0aV90aHJlYWRlZCkKICAgIHsKICAgICAgICBUUkFDRSgiQ2FsbGluZyBhcGFydG1lbnQgdGhyZWFkIDB4JTA4eC4uLlxuIiwgYXB0LT50aWQpOwoKICAgICAgICBpZiAoIVBvc3RNZXNzYWdlVyhhcGFydG1lbnRfZ2V0d2luZG93KGFwdCksIERNX0VYRUNVVEVSUEMsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgKExQQVJBTSkmbWVzc2FnZV9zdGF0ZS0+cGFyYW1zKSkKICAgICAgICB7CiAgICAgICAgICAgIEVSUigiUG9zdE1lc3NhZ2UgZmFpbGVkIHdpdGggZXJyb3IgJXVcbiIsIEdldExhc3RFcnJvcigpKTsKCiAgICAgICAgICAgIElScGNTdHViQnVmZmVyX1JlbGVhc2UobWVzc2FnZV9zdGF0ZS0+cGFyYW1zLnN0dWIpOwogICAgICAgICAgICBtZXNzYWdlX3N0YXRlLT5wYXJhbXMuc3R1YiA9IE5VTEw7CiAgICAgICAgICAgIElScGNDaGFubmVsQnVmZmVyX1JlbGVhc2UobWVzc2FnZV9zdGF0ZS0+cGFyYW1zLmNoYW4pOwogICAgICAgICAgICBtZXNzYWdlX3N0YXRlLT5wYXJhbXMuY2hhbiA9IE5VTEw7CiAgICAgICAgICAgIC8qIE5vdGU6IG1lc3NhZ2Vfc3RhdGUtPnBhcmFtcy5pZmFjZSBkb2Vzbid0IGhhdmUgYSByZWZlcmVuY2UgYW5kCiAgICAgICAgICAgICAqIHNvIGRvZXNuJ3QgbmVlZCB0byBiZSByZWxlYXNlZCAqLwoKICAgICAgICAgICAgaHIgPSBIUkVTVUxUX0ZST01fV0lOMzIoR2V0TGFzdEVycm9yKCkpOwogICAgICAgIH0KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBpZiAoaHIgPT0gU19PSykKICAgICAgICB7CiAgICAgICAgICAgIC8qIG90aGVyd2lzZSwgd2UgZ28gdmlhIFJQQyBydW50aW1lIHNvIHRoZSBzdHViIGFuZCBjaGFubmVsIGFyZW4ndAogICAgICAgICAgICAgKiBuZWVkZWQgaGVyZSAqLwogICAgICAgICAgICBJUnBjU3R1YkJ1ZmZlcl9SZWxlYXNlKG1lc3NhZ2Vfc3RhdGUtPnBhcmFtcy5zdHViKTsKICAgICAgICAgICAgbWVzc2FnZV9zdGF0ZS0+cGFyYW1zLnN0dWIgPSBOVUxMOwogICAgICAgICAgICBJUnBjQ2hhbm5lbEJ1ZmZlcl9SZWxlYXNlKG1lc3NhZ2Vfc3RhdGUtPnBhcmFtcy5jaGFuKTsKICAgICAgICAgICAgbWVzc2FnZV9zdGF0ZS0+cGFyYW1zLmNoYW4gPSBOVUxMOwogICAgICAgIH0KCiAgICAgICAgLyogd2UgdXNlIGEgc2VwYXJhdGUgdGhyZWFkIGhlcmUgYmVjYXVzZSB3ZSBuZWVkIHRvIGJlIGFibGUgdG8KICAgICAgICAgKiBwdW1wIHRoZSBtZXNzYWdlIGxvb3AgaW4gdGhlIGFwcGxpY2F0aW9uIHRocmVhZDogaWYgd2UgZG8gbm90LAogICAgICAgICAqIGFueSB3aW5kb3dzIGNyZWF0ZWQgYnkgdGhpcyB0aHJlYWQgd2lsbCBoYW5nIGFuZCBSUENzIHRoYXQgdHJ5CiAgICAgICAgICogYW5kIHJlLWVudGVyIHRoaXMgU1RBIGZyb20gYW4gaW5jb21pbmcgc2VydmVyIHRocmVhZCB3aWxsCiAgICAgICAgICogZGVhZGxvY2suIEluc3RhbGxTaGllbGQgaXMgYW4gZXhhbXBsZSBvZiB0aGF0LgogICAgICAgICAqLwogICAgICAgIGlmICghUXVldWVVc2VyV29ya0l0ZW0ocnBjX3NlbmRyZWNlaXZlX3RocmVhZCwgJm1lc3NhZ2Vfc3RhdGUtPnBhcmFtcywgV1RfRVhFQ1VURURFRkFVTFQpKQogICAgICAgIHsKICAgICAgICAgICAgRVJSKCJRdWV1ZVVzZXJXb3JrSXRlbSBmYWlsZWQgd2l0aCBlcnJvciAldVxuIiwgR2V0TGFzdEVycm9yKCkpOwogICAgICAgICAgICBociA9IEVfVU5FWFBFQ1RFRDsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgICAgICBociA9IFNfT0s7CiAgICB9CiAgICBpZiAoYXB0KSBhcGFydG1lbnRfcmVsZWFzZShhcHQpOwoKICAgIGlmIChociA9PSBTX09LKQogICAgewogICAgICAgIGlmIChXYWl0Rm9yU2luZ2xlT2JqZWN0KG1lc3NhZ2Vfc3RhdGUtPnBhcmFtcy5oYW5kbGUsIDApKQogICAgICAgIHsKICAgICAgICAgICAgQ09NX0N1cnJlbnRJbmZvKCktPnBlbmRpbmdfY2FsbF9jb3VudF9jbGllbnQrKzsKICAgICAgICAgICAgaHIgPSBDb1dhaXRGb3JNdWx0aXBsZUhhbmRsZXMoMCwgSU5GSU5JVEUsIDEsICZtZXNzYWdlX3N0YXRlLT5wYXJhbXMuaGFuZGxlLCAmaW5kZXgpOwogICAgICAgICAgICBDT01fQ3VycmVudEluZm8oKS0+cGVuZGluZ19jYWxsX2NvdW50X2NsaWVudC0tOwogICAgICAgIH0KICAgIH0KICAgIENsaWVudFJwY0NoYW5uZWxCdWZmZXJfUmVsZWFzZUV2ZW50SGFuZGxlKFRoaXMsIG1lc3NhZ2Vfc3RhdGUtPnBhcmFtcy5oYW5kbGUpOwoKICAgIC8qIGZvciBXTSBzaG9ydGN1dCwgZmF1bHRzIGFyZSByZXR1cm5lZCBpbiBwYXJhbXMtPmhyICovCiAgICBpZiAoaHIgPT0gU19PSykKICAgICAgICBockZhdWx0ID0gbWVzc2FnZV9zdGF0ZS0+cGFyYW1zLmhyOwoKICAgIHN0YXR1cyA9IG1lc3NhZ2Vfc3RhdGUtPnBhcmFtcy5zdGF0dXM7CgogICAgb3JwY3RoYXQuZmxhZ3MgPSBPUlBDRl9OVUxMOwogICAgb3JwY3RoYXQuZXh0ZW5zaW9ucyA9IE5VTEw7CgogICAgLyogZm9yIG5vcm1hbCBSUEMgY2FsbHMsIGZhdWx0cyBhcmUgcmV0dXJuZWQgaW4gZmlyc3QgNCBieXRlcyBvZiB0aGUKICAgICAqIGJ1ZmZlciAqLwogICAgVFJBQ0UoIlJQQyBjYWxsIHN0YXR1czogMHglbHhcbiIsIHN0YXR1cyk7CiAgICBpZiAoc3RhdHVzID09IFJQQ19TX0NBTExfRkFJTEVEKQogICAgICAgIGhyRmF1bHQgPSAqKEhSRVNVTFQgKilvbGVtc2ctPkJ1ZmZlcjsKICAgIGVsc2UgaWYgKHN0YXR1cyAhPSBSUENfU19PSykKICAgICAgICBociA9IEhSRVNVTFRfRlJPTV9XSU4zMihzdGF0dXMpOwoKICAgIFRSQUNFKCJockZhdWx0ID0gMHglMDh4XG4iLCBockZhdWx0KTsKCiAgICAvKiBGSVhNRTogdGhpcyBjb25kaXRpb24gc2hvdWxkIGJlCiAgICAgKiAiaHIgPT0gU19PSyAmJiAoIWhyRmF1bHQgfHwgbXNnLT5CdWZmZXJMZW5ndGggPiBGSUVMRF9PRkZTRVQoT1JQQ1RIQVQsIGV4dGVuc2lvbnMpICsgNCkiCiAgICAgKiBidXQgd2UgZG9uJ3QgY3VycmVudGx5IHJlc2V0IHRoZSBtZXNzYWdlIGxlbmd0aCBmb3IgUG9zdE1lc3NhZ2UKICAgICAqIGRpc3BhdGNoZWQgY2FsbHMgKi8KICAgIGlmIChociA9PSBTX09LICYmIGhyRmF1bHQgPT0gU19PSykKICAgIHsKICAgICAgICBIUkVTVUxUIGhyMjsKICAgICAgICBjaGFyICpvcmlnaW5hbF9idWZmZXIgPSBtc2ctPkJ1ZmZlcjsKCiAgICAgICAgLyogaGFuZGxlIE9SUENUSEFUIGFuZCBjbGllbnQgZXh0ZW5zaW9ucyAqLwoKICAgICAgICBocjIgPSB1bm1hcnNoYWxfT1JQQ1RIQVQobXNnLCAmb3JwY3RoYXQsICZvcnBjX2V4dF9hcnJheSwgJmZpcnN0X3dpcmVfb3JwY19leHRlbnQpOwogICAgICAgIGlmIChGQUlMRUQoaHIyKSkKICAgICAgICAgICAgaHIgPSBocjI7CgogICAgICAgIG1lc3NhZ2Vfc3RhdGUtPnByZWZpeF9kYXRhX2xlbiA9IChjaGFyICopbXNnLT5CdWZmZXIgLSBvcmlnaW5hbF9idWZmZXI7CiAgICAgICAgbXNnLT5CdWZmZXJMZW5ndGggLT0gbWVzc2FnZV9zdGF0ZS0+cHJlZml4X2RhdGFfbGVuOwogICAgfQogICAgZWxzZQogICAgICAgIG1lc3NhZ2Vfc3RhdGUtPnByZWZpeF9kYXRhX2xlbiA9IDA7CgogICAgaWYgKGhyID09IFNfT0spCiAgICB7CiAgICAgICAgQ2hhbm5lbEhvb2tzX0NsaWVudE5vdGlmeSgmbWVzc2FnZV9zdGF0ZS0+Y2hhbm5lbF9ob29rX2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtc2ctPkRhdGFSZXByZXNlbnRhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpcnN0X3dpcmVfb3JwY19leHRlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcnBjdGhhdC5leHRlbnNpb25zICYmIGZpcnN0X3dpcmVfb3JwY19leHRlbnQgPyBvcnBjdGhhdC5leHRlbnNpb25zLT5zaXplIDogMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhyRmF1bHQpOwogICAgfQoKICAgIC8qIHNhdmUgYXdheSB0aGUgbWVzc2FnZSBzdGF0ZSBhZ2FpbiAqLwogICAgbXNnLT5IYW5kbGUgPSBtZXNzYWdlX3N0YXRlOwoKICAgIGlmIChwc3RhdHVzKSAqcHN0YXR1cyA9IHN0YXR1czsKCiAgICBpZiAoaHIgPT0gU19PSykKICAgICAgICBociA9IGhyRmF1bHQ7CgogICAgVFJBQ0UoIi0tIDB4JTA4eFxuIiwgaHIpOwoKICAgIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFNlcnZlclJwY0NoYW5uZWxCdWZmZXJfRnJlZUJ1ZmZlcihMUFJQQ0NIQU5ORUxCVUZGRVIgaWZhY2UsIFJQQ09MRU1FU1NBR0UqIG9sZW1zZykKewogICAgUlBDX01FU1NBR0UgKm1zZyA9IChSUENfTUVTU0FHRSAqKW9sZW1zZzsKICAgIFJQQ19TVEFUVVMgc3RhdHVzOwogICAgc3RydWN0IG1lc3NhZ2Vfc3RhdGUgKm1lc3NhZ2Vfc3RhdGU7CgogICAgVFJBQ0UoIiglcClcbiIsIG1zZyk7CgogICAgbWVzc2FnZV9zdGF0ZSA9IChzdHJ1Y3QgbWVzc2FnZV9zdGF0ZSAqKW1zZy0+SGFuZGxlOwogICAgLyogcmVzdG9yZSB0aGUgYmluZGluZyBoYW5kbGUgYW5kIHRoZSByZWFsIHN0YXJ0IG9mIGRhdGEgKi8KICAgIG1zZy0+SGFuZGxlID0gbWVzc2FnZV9zdGF0ZS0+YmluZGluZ19oYW5kbGU7CiAgICBtc2ctPkJ1ZmZlciA9IChjaGFyICopbXNnLT5CdWZmZXIgLSBtZXNzYWdlX3N0YXRlLT5wcmVmaXhfZGF0YV9sZW47CiAgICBtc2ctPkJ1ZmZlckxlbmd0aCArPSBtZXNzYWdlX3N0YXRlLT5wcmVmaXhfZGF0YV9sZW47CiAgICBtZXNzYWdlX3N0YXRlLT5wcmVmaXhfZGF0YV9sZW4gPSAwOwoKICAgIHN0YXR1cyA9IElfUnBjRnJlZUJ1ZmZlcihtc2cpOwoKICAgIG1zZy0+SGFuZGxlID0gbWVzc2FnZV9zdGF0ZTsKCiAgICBUUkFDRSgiLS0gJWxkXG4iLCBzdGF0dXMpOwoKICAgIHJldHVybiBIUkVTVUxUX0ZST01fV0lOMzIoc3RhdHVzKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIENsaWVudFJwY0NoYW5uZWxCdWZmZXJfRnJlZUJ1ZmZlcihMUFJQQ0NIQU5ORUxCVUZGRVIgaWZhY2UsIFJQQ09MRU1FU1NBR0UqIG9sZW1zZykKewogICAgUlBDX01FU1NBR0UgKm1zZyA9IChSUENfTUVTU0FHRSAqKW9sZW1zZzsKICAgIFJQQ19TVEFUVVMgc3RhdHVzOwogICAgc3RydWN0IG1lc3NhZ2Vfc3RhdGUgKm1lc3NhZ2Vfc3RhdGU7CgogICAgVFJBQ0UoIiglcClcbiIsIG1zZyk7CgogICAgbWVzc2FnZV9zdGF0ZSA9IChzdHJ1Y3QgbWVzc2FnZV9zdGF0ZSAqKW1zZy0+SGFuZGxlOwogICAgLyogcmVzdG9yZSB0aGUgYmluZGluZyBoYW5kbGUgYW5kIHRoZSByZWFsIHN0YXJ0IG9mIGRhdGEgKi8KICAgIG1zZy0+SGFuZGxlID0gbWVzc2FnZV9zdGF0ZS0+YmluZGluZ19oYW5kbGU7CiAgICBtc2ctPkJ1ZmZlciA9IChjaGFyICopbXNnLT5CdWZmZXIgLSBtZXNzYWdlX3N0YXRlLT5wcmVmaXhfZGF0YV9sZW47CiAgICBtc2ctPkJ1ZmZlckxlbmd0aCArPSBtZXNzYWdlX3N0YXRlLT5wcmVmaXhfZGF0YV9sZW47CgogICAgc3RhdHVzID0gSV9ScGNGcmVlQnVmZmVyKG1zZyk7CgogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbXNnLT5ScGNJbnRlcmZhY2VJbmZvcm1hdGlvbik7CiAgICBtc2ctPlJwY0ludGVyZmFjZUluZm9ybWF0aW9uID0gTlVMTDsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG1lc3NhZ2Vfc3RhdGUpOwoKICAgIFRSQUNFKCItLSAlbGRcbiIsIHN0YXR1cyk7CgogICAgcmV0dXJuIEhSRVNVTFRfRlJPTV9XSU4zMihzdGF0dXMpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlcl9HZXREZXN0Q3R4KExQUlBDQ0hBTk5FTEJVRkZFUiBpZmFjZSwgRFdPUkQqIHBkd0Rlc3RDb250ZXh0LCB2b2lkKiogcHB2RGVzdENvbnRleHQpCnsKICAgIENsaWVudFJwY0NoYW5uZWxCdWZmZXIgKlRoaXMgPSAoQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlciAqKWlmYWNlOwoKICAgIFRSQUNFKCIoJXAsJXApXG4iLCBwZHdEZXN0Q29udGV4dCwgcHB2RGVzdENvbnRleHQpOwoKICAgICpwZHdEZXN0Q29udGV4dCA9IFRoaXMtPmRlc3RfY29udGV4dDsKICAgICpwcHZEZXN0Q29udGV4dCA9IFRoaXMtPmRlc3RfY29udGV4dF9kYXRhOwoKICAgIHJldHVybiBTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgU2VydmVyUnBjQ2hhbm5lbEJ1ZmZlcl9HZXREZXN0Q3R4KExQUlBDQ0hBTk5FTEJVRkZFUiBpZmFjZSwgRFdPUkQqIHBkd0Rlc3RDb250ZXh0LCB2b2lkKiogcHB2RGVzdENvbnRleHQpCnsKICAgIEZJWE1FKCIoJXAsJXApLCBzdHViIVxuIiwgcGR3RGVzdENvbnRleHQsIHBwdkRlc3RDb250ZXh0KTsKICAgIHJldHVybiBFX0ZBSUw7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBScGNDaGFubmVsQnVmZmVyX0lzQ29ubmVjdGVkKExQUlBDQ0hBTk5FTEJVRkZFUiBpZmFjZSkKewogICAgVFJBQ0UoIigpXG4iKTsKICAgIC8qIG5hdGl2ZSBkb2VzIG5vdGhpbmcgdG9vICovCiAgICByZXR1cm4gU19PSzsKfQoKc3RhdGljIGNvbnN0IElScGNDaGFubmVsQnVmZmVyVnRibCBDbGllbnRScGNDaGFubmVsQnVmZmVyVnRibCA9CnsKICAgIFJwY0NoYW5uZWxCdWZmZXJfUXVlcnlJbnRlcmZhY2UsCiAgICBScGNDaGFubmVsQnVmZmVyX0FkZFJlZiwKICAgIENsaWVudFJwY0NoYW5uZWxCdWZmZXJfUmVsZWFzZSwKICAgIENsaWVudFJwY0NoYW5uZWxCdWZmZXJfR2V0QnVmZmVyLAogICAgQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlcl9TZW5kUmVjZWl2ZSwKICAgIENsaWVudFJwY0NoYW5uZWxCdWZmZXJfRnJlZUJ1ZmZlciwKICAgIENsaWVudFJwY0NoYW5uZWxCdWZmZXJfR2V0RGVzdEN0eCwKICAgIFJwY0NoYW5uZWxCdWZmZXJfSXNDb25uZWN0ZWQKfTsKCnN0YXRpYyBjb25zdCBJUnBjQ2hhbm5lbEJ1ZmZlclZ0YmwgU2VydmVyUnBjQ2hhbm5lbEJ1ZmZlclZ0YmwgPQp7CiAgICBScGNDaGFubmVsQnVmZmVyX1F1ZXJ5SW50ZXJmYWNlLAogICAgUnBjQ2hhbm5lbEJ1ZmZlcl9BZGRSZWYsCiAgICBTZXJ2ZXJScGNDaGFubmVsQnVmZmVyX1JlbGVhc2UsCiAgICBTZXJ2ZXJScGNDaGFubmVsQnVmZmVyX0dldEJ1ZmZlciwKICAgIFNlcnZlclJwY0NoYW5uZWxCdWZmZXJfU2VuZFJlY2VpdmUsCiAgICBTZXJ2ZXJScGNDaGFubmVsQnVmZmVyX0ZyZWVCdWZmZXIsCiAgICBTZXJ2ZXJScGNDaGFubmVsQnVmZmVyX0dldERlc3RDdHgsCiAgICBScGNDaGFubmVsQnVmZmVyX0lzQ29ubmVjdGVkCn07CgovKiByZXR1cm5zIGEgY2hhbm5lbCBidWZmZXIgZm9yIHByb3hpZXMgKi8KSFJFU1VMVCBSUENfQ3JlYXRlQ2xpZW50Q2hhbm5lbChjb25zdCBPWElEICpveGlkLCBjb25zdCBJUElEICppcGlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE9YSURfSU5GTyAqb3hpZF9pbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGRlc3RfY29udGV4dCwgdm9pZCAqZGVzdF9jb250ZXh0X2RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVJwY0NoYW5uZWxCdWZmZXIgKipjaGFuKQp7CiAgICBDbGllbnRScGNDaGFubmVsQnVmZmVyICpUaGlzOwogICAgV0NIQVIgICAgICAgICAgICAgICAgICAgZW5kcG9pbnRbMjAwXTsKICAgIFJQQ19CSU5ESU5HX0hBTkRMRSAgICAgIGJpbmQ7CiAgICBSUENfU1RBVFVTICAgICAgICAgICAgICBzdGF0dXM7CiAgICBMUFdTVFIgICAgICAgICAgICAgICAgICBzdHJpbmdfYmluZGluZzsKCiAgICAvKiBGSVhNRTogZ2V0IHRoZSBlbmRwb2ludCBmcm9tIG94aWRfaW5mby0+cHNhIGluc3RlYWQgKi8KICAgIGdldF9ycGNfZW5kcG9pbnQoZW5kcG9pbnQsIG94aWQpOwoKICAgIFRSQUNFKCJwcm94eSBwaXBlOiBjb25uZWN0aW5nIHRvIGVuZHBvaW50OiAlc1xuIiwgZGVidWdzdHJfdyhlbmRwb2ludCkpOwoKICAgIHN0YXR1cyA9IFJwY1N0cmluZ0JpbmRpbmdDb21wb3NlVygKICAgICAgICBOVUxMLAogICAgICAgIHdzelJwY1RyYW5zcG9ydCwKICAgICAgICBOVUxMLAogICAgICAgIGVuZHBvaW50LAogICAgICAgIE5VTEwsCiAgICAgICAgJnN0cmluZ19iaW5kaW5nKTsKICAgICAgICAKICAgIGlmIChzdGF0dXMgPT0gUlBDX1NfT0spCiAgICB7CiAgICAgICAgc3RhdHVzID0gUnBjQmluZGluZ0Zyb21TdHJpbmdCaW5kaW5nVyhzdHJpbmdfYmluZGluZywgJmJpbmQpOwoKICAgICAgICBpZiAoc3RhdHVzID09IFJQQ19TX09LKQogICAgICAgIHsKICAgICAgICAgICAgSVBJRCBpcGlkMiA9ICppcGlkOyAvKiB3aHkgY2FuJ3QgUnBjQmluZGluZ1NldE9iamVjdCB0YWtlIGEgY29uc3Q/ICovCiAgICAgICAgICAgIHN0YXR1cyA9IFJwY0JpbmRpbmdTZXRPYmplY3QoYmluZCwgJmlwaWQyKTsKICAgICAgICAgICAgaWYgKHN0YXR1cyAhPSBSUENfU19PSykKICAgICAgICAgICAgICAgIFJwY0JpbmRpbmdGcmVlKCZiaW5kKTsKICAgICAgICB9CgogICAgICAgIFJwY1N0cmluZ0ZyZWVXKCZzdHJpbmdfYmluZGluZyk7CiAgICB9CgogICAgaWYgKHN0YXR1cyAhPSBSUENfU19PSykKICAgIHsKICAgICAgICBFUlIoIkNvdWxkbid0IGdldCBiaW5kaW5nIGZvciBlbmRwb2ludCAlcywgc3RhdHVzID0gJWxkXG4iLCBkZWJ1Z3N0cl93KGVuZHBvaW50KSwgc3RhdHVzKTsKICAgICAgICByZXR1cm4gSFJFU1VMVF9GUk9NX1dJTjMyKHN0YXR1cyk7CiAgICB9CgogICAgVGhpcyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoKlRoaXMpKTsKICAgIGlmICghVGhpcykKICAgIHsKICAgICAgICBScGNCaW5kaW5nRnJlZSgmYmluZCk7CiAgICAgICAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CiAgICB9CgogICAgVGhpcy0+c3VwZXIubHBWdGJsID0gJkNsaWVudFJwY0NoYW5uZWxCdWZmZXJWdGJsOwogICAgVGhpcy0+c3VwZXIucmVmcyA9IDE7CiAgICBUaGlzLT5iaW5kID0gYmluZDsKICAgIGFwYXJ0bWVudF9nZXRveGlkKENPTV9DdXJyZW50QXB0KCksICZUaGlzLT5veGlkKTsKICAgIFRoaXMtPnNlcnZlcl9waWQgPSBveGlkX2luZm8tPmR3UGlkOwogICAgVGhpcy0+ZGVzdF9jb250ZXh0ID0gZGVzdF9jb250ZXh0OwogICAgVGhpcy0+ZGVzdF9jb250ZXh0X2RhdGEgPSBkZXN0X2NvbnRleHRfZGF0YTsKICAgIFRoaXMtPmV2ZW50ID0gTlVMTDsKCiAgICAqY2hhbiA9IChJUnBjQ2hhbm5lbEJ1ZmZlciopVGhpczsKCiAgICByZXR1cm4gU19PSzsKfQoKSFJFU1VMVCBSUENfQ3JlYXRlU2VydmVyQ2hhbm5lbChJUnBjQ2hhbm5lbEJ1ZmZlciAqKmNoYW4pCnsKICAgIFJwY0NoYW5uZWxCdWZmZXIgKlRoaXMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKCpUaGlzKSk7CiAgICBpZiAoIVRoaXMpCiAgICAgICAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CgogICAgVGhpcy0+bHBWdGJsID0gJlNlcnZlclJwY0NoYW5uZWxCdWZmZXJWdGJsOwogICAgVGhpcy0+cmVmcyA9IDE7CiAgICAKICAgICpjaGFuID0gKElScGNDaGFubmVsQnVmZmVyKilUaGlzOwoKICAgIHJldHVybiBTX09LOwp9CgovKiB1bm1hcnNoYWxzIE9SUENfRVhURU5UX0FSUkFZIGFjY29yZGluZyB0byBORFIgcnVsZXMsIGJ1dCBkb2Vzbid0IGFsbG9jYXRlCiAqIGFueSBtZW1vcnkgKi8Kc3RhdGljIEhSRVNVTFQgdW5tYXJzaGFsX09SUENfRVhURU5UX0FSUkFZKFJQQ19NRVNTQUdFICptc2csIGNvbnN0IGNoYXIgKmVuZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9SUENfRVhURU5UX0FSUkFZICpleHRlbnNpb25zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lSRV9PUlBDX0VYVEVOVCAqKmZpcnN0X3dpcmVfb3JwY19leHRlbnQpCnsKICAgIERXT1JEIHBvaW50ZXJfaWQ7CiAgICBEV09SRCBpOwoKICAgIG1lbWNweShleHRlbnNpb25zLCBtc2ctPkJ1ZmZlciwgRklFTERfT0ZGU0VUKE9SUENfRVhURU5UX0FSUkFZLCBleHRlbnQpKTsKICAgIG1zZy0+QnVmZmVyID0gKGNoYXIgKiltc2ctPkJ1ZmZlciArIEZJRUxEX09GRlNFVChPUlBDX0VYVEVOVF9BUlJBWSwgZXh0ZW50KTsKCiAgICBpZiAoKGNvbnN0IGNoYXIgKiltc2ctPkJ1ZmZlciArIDIgKiBzaXplb2YoRFdPUkQpID4gZW5kKQogICAgICAgIHJldHVybiBSUENfRV9JTlZBTElEX0hFQURFUjsKCiAgICBwb2ludGVyX2lkID0gKihEV09SRCAqKW1zZy0+QnVmZmVyOwogICAgbXNnLT5CdWZmZXIgPSAoY2hhciAqKW1zZy0+QnVmZmVyICsgc2l6ZW9mKERXT1JEKTsKICAgIGV4dGVuc2lvbnMtPmV4dGVudCA9IE5VTEw7CgogICAgaWYgKHBvaW50ZXJfaWQpCiAgICB7CiAgICAgICAgV0lSRV9PUlBDX0VYVEVOVCAqd2lyZV9vcnBjX2V4dGVudDsKCiAgICAgICAgLyogY29uZm9ybWFuY2UgKi8KICAgICAgICBpZiAoKihEV09SRCAqKW1zZy0+QnVmZmVyICE9ICgoZXh0ZW5zaW9ucy0+c2l6ZSsxKSZ+MSkpCiAgICAgICAgICAgIHJldHVybiBSUENfU19JTlZBTElEX0JPVU5EOwoKICAgICAgICBtc2ctPkJ1ZmZlciA9IChjaGFyICopbXNnLT5CdWZmZXIgKyBzaXplb2YoRFdPUkQpOwoKICAgICAgICAvKiBhcmJyaXRhcnkgbGltaXQgZm9yIHNlY3VyaXR5IChkb24ndCBrbm93IHdoYXQgbmF0aXZlIGRvZXMpICovCiAgICAgICAgaWYgKGV4dGVuc2lvbnMtPnNpemUgPiAyNTYpCiAgICAgICAgewogICAgICAgICAgICBFUlIoInRvbyBtYW55IGV4dGVuc2lvbnM6ICVsZFxuIiwgZXh0ZW5zaW9ucy0+c2l6ZSk7CiAgICAgICAgICAgIHJldHVybiBSUENfU19JTlZBTElEX0JPVU5EOwogICAgICAgIH0KCiAgICAgICAgKmZpcnN0X3dpcmVfb3JwY19leHRlbnQgPSB3aXJlX29ycGNfZXh0ZW50ID0gKFdJUkVfT1JQQ19FWFRFTlQgKiltc2ctPkJ1ZmZlcjsKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgKChleHRlbnNpb25zLT5zaXplKzEpJn4xKTsgaSsrKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKChjb25zdCBjaGFyICopJndpcmVfb3JwY19leHRlbnQtPmRhdGFbMF0gPiBlbmQpCiAgICAgICAgICAgICAgICByZXR1cm4gUlBDX1NfSU5WQUxJRF9CT1VORDsKICAgICAgICAgICAgaWYgKHdpcmVfb3JwY19leHRlbnQtPmNvbmZvcm1hbmNlICE9ICgod2lyZV9vcnBjX2V4dGVudC0+c2l6ZSs3KSZ+NykpCiAgICAgICAgICAgICAgICByZXR1cm4gUlBDX1NfSU5WQUxJRF9CT1VORDsKICAgICAgICAgICAgaWYgKChjb25zdCBjaGFyICopJndpcmVfb3JwY19leHRlbnQtPmRhdGFbd2lyZV9vcnBjX2V4dGVudC0+Y29uZm9ybWFuY2VdID4gZW5kKQogICAgICAgICAgICAgICAgcmV0dXJuIFJQQ19TX0lOVkFMSURfQk9VTkQ7CiAgICAgICAgICAgIFRSQUNFKCJzaXplICV1LCBndWlkICVzXG4iLCB3aXJlX29ycGNfZXh0ZW50LT5zaXplLCBkZWJ1Z3N0cl9ndWlkKCZ3aXJlX29ycGNfZXh0ZW50LT5pZCkpOwogICAgICAgICAgICB3aXJlX29ycGNfZXh0ZW50ID0gKFdJUkVfT1JQQ19FWFRFTlQgKikmd2lyZV9vcnBjX2V4dGVudC0+ZGF0YVt3aXJlX29ycGNfZXh0ZW50LT5jb25mb3JtYW5jZV07CiAgICAgICAgfQogICAgICAgIG1zZy0+QnVmZmVyID0gd2lyZV9vcnBjX2V4dGVudDsKICAgIH0KCiAgICByZXR1cm4gU19PSzsKfQoKLyogdW5tYXJzaGFscyBPUlBDVEhJUyBhY2NvcmRpbmcgdG8gTkRSIHJ1bGVzLCBidXQgZG9lc24ndCBhbGxvY2F0ZSBhbnkgbWVtb3J5ICovCnN0YXRpYyBIUkVTVUxUIHVubWFyc2hhbF9PUlBDVEhJUyhSUENfTUVTU0FHRSAqbXNnLCBPUlBDVEhJUyAqb3JwY3RoaXMsCiAgICBPUlBDX0VYVEVOVF9BUlJBWSAqb3JwY19leHRfYXJyYXksIFdJUkVfT1JQQ19FWFRFTlQgKipmaXJzdF93aXJlX29ycGNfZXh0ZW50KQp7CiAgICBjb25zdCBjaGFyICplbmQgPSAoY2hhciAqKW1zZy0+QnVmZmVyICsgbXNnLT5CdWZmZXJMZW5ndGg7CgogICAgKmZpcnN0X3dpcmVfb3JwY19leHRlbnQgPSBOVUxMOwoKICAgIGlmIChtc2ctPkJ1ZmZlckxlbmd0aCA8IEZJRUxEX09GRlNFVChPUlBDVEhJUywgZXh0ZW5zaW9ucykgKyA0KQogICAgewogICAgICAgIEVSUigiaW52YWxpZCBidWZmZXIgbGVuZ3RoXG4iKTsKICAgICAgICByZXR1cm4gUlBDX0VfSU5WQUxJRF9IRUFERVI7CiAgICB9CgogICAgbWVtY3B5KG9ycGN0aGlzLCBtc2ctPkJ1ZmZlciwgRklFTERfT0ZGU0VUKE9SUENUSElTLCBleHRlbnNpb25zKSk7CiAgICBtc2ctPkJ1ZmZlciA9IChjaGFyICopbXNnLT5CdWZmZXIgKyBGSUVMRF9PRkZTRVQoT1JQQ1RISVMsIGV4dGVuc2lvbnMpOwoKICAgIGlmICgoY29uc3QgY2hhciAqKW1zZy0+QnVmZmVyICsgc2l6ZW9mKERXT1JEKSA+IGVuZCkKICAgICAgICByZXR1cm4gUlBDX0VfSU5WQUxJRF9IRUFERVI7CgogICAgaWYgKCooRFdPUkQgKiltc2ctPkJ1ZmZlcikKICAgICAgICBvcnBjdGhpcy0+ZXh0ZW5zaW9ucyA9IG9ycGNfZXh0X2FycmF5OwogICAgZWxzZQogICAgICAgIG9ycGN0aGlzLT5leHRlbnNpb25zID0gTlVMTDsKCiAgICBtc2ctPkJ1ZmZlciA9IChjaGFyICopbXNnLT5CdWZmZXIgKyBzaXplb2YoRFdPUkQpOwoKICAgIGlmIChvcnBjdGhpcy0+ZXh0ZW5zaW9ucykKICAgIHsKICAgICAgICBIUkVTVUxUIGhyID0gdW5tYXJzaGFsX09SUENfRVhURU5UX0FSUkFZKG1zZywgZW5kLCBvcnBjX2V4dF9hcnJheSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpcnN0X3dpcmVfb3JwY19leHRlbnQpOwogICAgICAgIGlmIChGQUlMRUQoaHIpKQogICAgICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgaWYgKChvcnBjdGhpcy0+dmVyc2lvbi5NYWpvclZlcnNpb24gIT0gQ09NX01BSk9SX1ZFUlNJT04pIHx8CiAgICAgICAgKG9ycGN0aGlzLT52ZXJzaW9uLk1pbm9yVmVyc2lvbiA+IENPTV9NSU5PUl9WRVJTSU9OKSkKICAgIHsKICAgICAgICBFUlIoIkNPTSB2ZXJzaW9uIHslZCwgJWR9IG5vdCBzdXBwb3J0ZWRcbiIsCiAgICAgICAgICAgIG9ycGN0aGlzLT52ZXJzaW9uLk1ham9yVmVyc2lvbiwgb3JwY3RoaXMtPnZlcnNpb24uTWlub3JWZXJzaW9uKTsKICAgICAgICByZXR1cm4gUlBDX0VfVkVSU0lPTl9NSVNNQVRDSDsKICAgIH0KCiAgICBpZiAob3JwY3RoaXMtPmZsYWdzICYgfihPUlBDRl9MT0NBTHxPUlBDRl9SRVNFUlZFRDF8T1JQQ0ZfUkVTRVJWRUQyfE9SUENGX1JFU0VSVkVEM3xPUlBDRl9SRVNFUlZFRDQpKQogICAgewogICAgICAgIEVSUigiaW52YWxpZCBmbGFncyAweCVseFxuIiwgb3JwY3RoaXMtPmZsYWdzICYgfihPUlBDRl9MT0NBTHxPUlBDRl9SRVNFUlZFRDF8T1JQQ0ZfUkVTRVJWRUQyfE9SUENGX1JFU0VSVkVEM3xPUlBDRl9SRVNFUlZFRDQpKTsKICAgICAgICByZXR1cm4gUlBDX0VfSU5WQUxJRF9IRUFERVI7CiAgICB9CgogICAgcmV0dXJuIFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIHVubWFyc2hhbF9PUlBDVEhBVChSUENfTUVTU0FHRSAqbXNnLCBPUlBDVEhBVCAqb3JwY3RoYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPUlBDX0VYVEVOVF9BUlJBWSAqb3JwY19leHRfYXJyYXksIFdJUkVfT1JQQ19FWFRFTlQgKipmaXJzdF93aXJlX29ycGNfZXh0ZW50KQp7CiAgICBjb25zdCBjaGFyICplbmQgPSAoY2hhciAqKW1zZy0+QnVmZmVyICsgbXNnLT5CdWZmZXJMZW5ndGg7CgogICAgKmZpcnN0X3dpcmVfb3JwY19leHRlbnQgPSBOVUxMOwoKICAgIGlmIChtc2ctPkJ1ZmZlckxlbmd0aCA8IEZJRUxEX09GRlNFVChPUlBDVEhBVCwgZXh0ZW5zaW9ucykgKyA0KQogICAgewogICAgICAgIEVSUigiaW52YWxpZCBidWZmZXIgbGVuZ3RoXG4iKTsKICAgICAgICByZXR1cm4gUlBDX0VfSU5WQUxJRF9IRUFERVI7CiAgICB9CgogICAgbWVtY3B5KG9ycGN0aGF0LCBtc2ctPkJ1ZmZlciwgRklFTERfT0ZGU0VUKE9SUENUSEFULCBleHRlbnNpb25zKSk7CiAgICBtc2ctPkJ1ZmZlciA9IChjaGFyICopbXNnLT5CdWZmZXIgKyBGSUVMRF9PRkZTRVQoT1JQQ1RIQVQsIGV4dGVuc2lvbnMpOwoKICAgIGlmICgoY29uc3QgY2hhciAqKW1zZy0+QnVmZmVyICsgc2l6ZW9mKERXT1JEKSA+IGVuZCkKICAgICAgICByZXR1cm4gUlBDX0VfSU5WQUxJRF9IRUFERVI7CgogICAgaWYgKCooRFdPUkQgKiltc2ctPkJ1ZmZlcikKICAgICAgICBvcnBjdGhhdC0+ZXh0ZW5zaW9ucyA9IG9ycGNfZXh0X2FycmF5OwogICAgZWxzZQogICAgICAgIG9ycGN0aGF0LT5leHRlbnNpb25zID0gTlVMTDsKCiAgICBtc2ctPkJ1ZmZlciA9IChjaGFyICopbXNnLT5CdWZmZXIgKyBzaXplb2YoRFdPUkQpOwoKICAgIGlmIChvcnBjdGhhdC0+ZXh0ZW5zaW9ucykKICAgIHsKICAgICAgICBIUkVTVUxUIGhyID0gdW5tYXJzaGFsX09SUENfRVhURU5UX0FSUkFZKG1zZywgZW5kLCBvcnBjX2V4dF9hcnJheSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpcnN0X3dpcmVfb3JwY19leHRlbnQpOwogICAgICAgIGlmIChGQUlMRUQoaHIpKQogICAgICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgaWYgKG9ycGN0aGF0LT5mbGFncyAmIH4oT1JQQ0ZfTE9DQUx8T1JQQ0ZfUkVTRVJWRUQxfE9SUENGX1JFU0VSVkVEMnxPUlBDRl9SRVNFUlZFRDN8T1JQQ0ZfUkVTRVJWRUQ0KSkKICAgIHsKICAgICAgICBFUlIoImludmFsaWQgZmxhZ3MgMHglbHhcbiIsIG9ycGN0aGF0LT5mbGFncyAmIH4oT1JQQ0ZfTE9DQUx8T1JQQ0ZfUkVTRVJWRUQxfE9SUENGX1JFU0VSVkVEMnxPUlBDRl9SRVNFUlZFRDN8T1JQQ0ZfUkVTRVJWRUQ0KSk7CiAgICAgICAgcmV0dXJuIFJQQ19FX0lOVkFMSURfSEVBREVSOwogICAgfQoKICAgIHJldHVybiBTX09LOwp9Cgp2b2lkIFJQQ19FeGVjdXRlQ2FsbChzdHJ1Y3QgZGlzcGF0Y2hfcGFyYW1zICpwYXJhbXMpCnsKICAgIHN0cnVjdCBtZXNzYWdlX3N0YXRlICptZXNzYWdlX3N0YXRlID0gTlVMTDsKICAgIFJQQ19NRVNTQUdFICptc2cgPSAoUlBDX01FU1NBR0UgKilwYXJhbXMtPm1zZzsKICAgIGNoYXIgKm9yaWdpbmFsX2J1ZmZlciA9IG1zZy0+QnVmZmVyOwogICAgT1JQQ1RISVMgb3JwY3RoaXM7CiAgICBPUlBDX0VYVEVOVF9BUlJBWSBvcnBjX2V4dF9hcnJheTsKICAgIFdJUkVfT1JQQ19FWFRFTlQgKmZpcnN0X3dpcmVfb3JwY19leHRlbnQ7CiAgICBHVUlEIG9sZF9jYXVzYWxpdHlfaWQ7CgogICAgLyogaGFuZGxlIE9SUENUSElTIGFuZCBzZXJ2ZXIgZXh0ZW5zaW9ucyAqLwoKICAgIHBhcmFtcy0+aHIgPSB1bm1hcnNoYWxfT1JQQ1RISVMobXNnLCAmb3JwY3RoaXMsICZvcnBjX2V4dF9hcnJheSwgJmZpcnN0X3dpcmVfb3JwY19leHRlbnQpOwogICAgaWYgKHBhcmFtcy0+aHIgIT0gU19PSykKICAgIHsKICAgICAgICBtc2ctPkJ1ZmZlciA9IG9yaWdpbmFsX2J1ZmZlcjsKICAgICAgICBnb3RvIGV4aXQ7CiAgICB9CgogICAgbWVzc2FnZV9zdGF0ZSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoKm1lc3NhZ2Vfc3RhdGUpKTsKICAgIGlmICghbWVzc2FnZV9zdGF0ZSkKICAgIHsKICAgICAgICBwYXJhbXMtPmhyID0gRV9PVVRPRk1FTU9SWTsKICAgICAgICBtc2ctPkJ1ZmZlciA9IG9yaWdpbmFsX2J1ZmZlcjsKICAgICAgICBnb3RvIGV4aXQ7CiAgICB9CgogICAgbWVzc2FnZV9zdGF0ZS0+cHJlZml4X2RhdGFfbGVuID0gKGNoYXIgKiltc2ctPkJ1ZmZlciAtIG9yaWdpbmFsX2J1ZmZlcjsKICAgIG1lc3NhZ2Vfc3RhdGUtPmJpbmRpbmdfaGFuZGxlID0gbXNnLT5IYW5kbGU7CgogICAgbWVzc2FnZV9zdGF0ZS0+Y2hhbm5lbF9ob29rX2luZm8uaWlkID0gcGFyYW1zLT5paWQ7CiAgICBtZXNzYWdlX3N0YXRlLT5jaGFubmVsX2hvb2tfaW5mby5jYlNpemUgPSBzaXplb2YobWVzc2FnZV9zdGF0ZS0+Y2hhbm5lbF9ob29rX2luZm8pOwogICAgbWVzc2FnZV9zdGF0ZS0+Y2hhbm5lbF9ob29rX2luZm8udUNhdXNhbGl0eSA9IG9ycGN0aGlzLmNpZDsKICAgIG1lc3NhZ2Vfc3RhdGUtPmNoYW5uZWxfaG9va19pbmZvLmR3U2VydmVyUGlkID0gR2V0Q3VycmVudFByb2Nlc3NJZCgpOwogICAgbWVzc2FnZV9zdGF0ZS0+Y2hhbm5lbF9ob29rX2luZm8uaU1ldGhvZCA9IG1zZy0+UHJvY051bTsKICAgIG1lc3NhZ2Vfc3RhdGUtPmNoYW5uZWxfaG9va19pbmZvLnBPYmplY3QgPSBwYXJhbXMtPmlmYWNlOwoKICAgIGlmIChvcnBjdGhpcy5leHRlbnNpb25zICYmIGZpcnN0X3dpcmVfb3JwY19leHRlbnQgJiYKICAgICAgICBvcnBjdGhpcy5leHRlbnNpb25zLT5zaXplKQogICAgICAgIENoYW5uZWxIb29rc19TZXJ2ZXJOb3RpZnkoJm1lc3NhZ2Vfc3RhdGUtPmNoYW5uZWxfaG9va19pbmZvLCBtc2ctPkRhdGFSZXByZXNlbnRhdGlvbiwgZmlyc3Rfd2lyZV9vcnBjX2V4dGVudCwgb3JwY3RoaXMuZXh0ZW5zaW9ucy0+c2l6ZSk7CgogICAgbXNnLT5IYW5kbGUgPSBtZXNzYWdlX3N0YXRlOwogICAgbXNnLT5CdWZmZXJMZW5ndGggLT0gbWVzc2FnZV9zdGF0ZS0+cHJlZml4X2RhdGFfbGVuOwoKICAgIC8qIGNhbGwgbWVzc2FnZSBmaWx0ZXIgKi8KCiAgICBpZiAoQ09NX0N1cnJlbnRBcHQoKS0+ZmlsdGVyKQogICAgewogICAgICAgIERXT1JEIGhhbmRsZWNhbGw7CiAgICAgICAgSU5URVJGQUNFSU5GTyBpbnRlcmZhY2VfaW5mbzsKICAgICAgICBDQUxMVFlQRSBjYWxsdHlwZTsKCiAgICAgICAgaW50ZXJmYWNlX2luZm8ucFVuayA9IHBhcmFtcy0+aWZhY2U7CiAgICAgICAgaW50ZXJmYWNlX2luZm8uaWlkID0gcGFyYW1zLT5paWQ7CiAgICAgICAgaW50ZXJmYWNlX2luZm8ud01ldGhvZCA9IG1zZy0+UHJvY051bTsKCiAgICAgICAgaWYgKElzRXF1YWxHVUlEKCZvcnBjdGhpcy5jaWQsICZDT01fQ3VycmVudEluZm8oKS0+Y2F1c2FsaXR5X2lkKSkKICAgICAgICAgICAgY2FsbHR5cGUgPSBDQUxMVFlQRV9ORVNURUQ7CiAgICAgICAgZWxzZSBpZiAoQ09NX0N1cnJlbnRJbmZvKCktPnBlbmRpbmdfY2FsbF9jb3VudF9zZXJ2ZXIgPT0gMCkKICAgICAgICAgICAgY2FsbHR5cGUgPSBDQUxMVFlQRV9UT1BMRVZFTDsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGNhbGx0eXBlID0gQ0FMTFRZUEVfVE9QTEVWRUxfQ0FMTFBFTkRJTkc7CgogICAgICAgIGhhbmRsZWNhbGwgPSBJTWVzc2FnZUZpbHRlcl9IYW5kbGVJbkNvbWluZ0NhbGwoQ09NX0N1cnJlbnRBcHQoKS0+ZmlsdGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbHR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoSFRBU0spR2V0Q3VycmVudFByb2Nlc3NJZCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCAvKiBGSVhNRSAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZpbnRlcmZhY2VfaW5mbyk7CiAgICAgICAgVFJBQ0UoIklNZXNzYWdlRmlsdGVyX0hhbmRsZUluQ29taW5nQ2FsbCByZXR1cm5lZCAlZFxuIiwgaGFuZGxlY2FsbCk7CiAgICAgICAgc3dpdGNoIChoYW5kbGVjYWxsKQogICAgICAgIHsKICAgICAgICBjYXNlIFNFUlZFUkNBTExfUkVKRUNURUQ6CiAgICAgICAgICAgIHBhcmFtcy0+aHIgPSBSUENfRV9DQUxMX1JFSkVDVEVEOwogICAgICAgICAgICBnb3RvIGV4aXRfcmVzZXRfc3RhdGU7CiAgICAgICAgY2FzZSBTRVJWRVJDQUxMX1JFVFJZTEFURVI6CiNpZiAwIC8qIEZJWE1FOiBoYW5kbGUgcmV0cmllcyBvbiB0aGUgY2xpZW50IHNpZGUgYmVmb3JlIGVuYWJsaW5nIHRoaXMgY29kZSAqLwogICAgICAgICAgICBwYXJhbXMtPmhyID0gUlBDX0VfUkVUUlk7CiAgICAgICAgICAgIGdvdG8gZXhpdF9yZXNldF9zdGF0ZTsKI2Vsc2UKICAgICAgICAgICAgRklYTUUoInJldHJ5IGNhbGwgbGF0ZXIgbm90IGltcGxlbWVudGVkXG4iKTsKICAgICAgICAgICAgYnJlYWs7CiNlbmRpZgogICAgICAgIGNhc2UgU0VSVkVSQ0FMTF9JU0hBTkRMRUQ6CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQoKICAgIC8qIGludm9rZSB0aGUgbWV0aG9kICovCgogICAgLyogc2F2ZSB0aGUgb2xkIGNhdXNhbGl0eSBJRCAtIG5vdGU6IGFueSBjYWxscyBleGVjdXRlZCB3aGlsZSBwcm9jZXNzaW5nCiAgICAgKiBtZXNzYWdlcyByZWNlaXZlZCBkdXJpbmcgdGhlIFNlbmRSZWNlaXZlIHdpbGwgYXBwZWFyIHRvIG9yaWdpbmF0ZSBmcm9tCiAgICAgKiB0aGlzIGNhbGwgLSB0aGlzIHNob3VsZCBiZSBjaGVja2VkIHdpdGggd2hhdCBXaW5kb3dzIGRvZXMgKi8KICAgIG9sZF9jYXVzYWxpdHlfaWQgPSBDT01fQ3VycmVudEluZm8oKS0+Y2F1c2FsaXR5X2lkOwogICAgQ09NX0N1cnJlbnRJbmZvKCktPmNhdXNhbGl0eV9pZCA9IG9ycGN0aGlzLmNpZDsKICAgIENPTV9DdXJyZW50SW5mbygpLT5wZW5kaW5nX2NhbGxfY291bnRfc2VydmVyKys7CiAgICBwYXJhbXMtPmhyID0gSVJwY1N0dWJCdWZmZXJfSW52b2tlKHBhcmFtcy0+c3R1YiwgcGFyYW1zLT5tc2csIHBhcmFtcy0+Y2hhbik7CiAgICBDT01fQ3VycmVudEluZm8oKS0+cGVuZGluZ19jYWxsX2NvdW50X3NlcnZlci0tOwogICAgQ09NX0N1cnJlbnRJbmZvKCktPmNhdXNhbGl0eV9pZCA9IG9sZF9jYXVzYWxpdHlfaWQ7CgpleGl0X3Jlc2V0X3N0YXRlOgogICAgbWVzc2FnZV9zdGF0ZSA9IChzdHJ1Y3QgbWVzc2FnZV9zdGF0ZSAqKW1zZy0+SGFuZGxlOwogICAgbXNnLT5IYW5kbGUgPSBtZXNzYWdlX3N0YXRlLT5iaW5kaW5nX2hhbmRsZTsKICAgIG1zZy0+QnVmZmVyID0gKGNoYXIgKiltc2ctPkJ1ZmZlciAtIG1lc3NhZ2Vfc3RhdGUtPnByZWZpeF9kYXRhX2xlbjsKICAgIG1zZy0+QnVmZmVyTGVuZ3RoICs9IG1lc3NhZ2Vfc3RhdGUtPnByZWZpeF9kYXRhX2xlbjsKCmV4aXQ6CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBtZXNzYWdlX3N0YXRlKTsKICAgIElScGNTdHViQnVmZmVyX1JlbGVhc2UocGFyYW1zLT5zdHViKTsKICAgIElScGNDaGFubmVsQnVmZmVyX1JlbGVhc2UocGFyYW1zLT5jaGFuKTsKICAgIGlmIChwYXJhbXMtPmhhbmRsZSkgU2V0RXZlbnQocGFyYW1zLT5oYW5kbGUpOwp9CgpzdGF0aWMgdm9pZCBfX1JQQ19TVFVCIGRpc3BhdGNoX3JwYyhSUENfTUVTU0FHRSAqbXNnKQp7CiAgICBzdHJ1Y3QgZGlzcGF0Y2hfcGFyYW1zICpwYXJhbXM7CiAgICBBUEFSVE1FTlQgKmFwdDsKICAgIElQSUQgaXBpZDsKICAgIEhSRVNVTFQgaHI7CgogICAgUnBjQmluZGluZ0lucU9iamVjdChtc2ctPkhhbmRsZSwgJmlwaWQpOwoKICAgIFRSQUNFKCJpcGlkID0gJXMsIGlNZXRob2QgPSAlZFxuIiwgZGVidWdzdHJfZ3VpZCgmaXBpZCksIG1zZy0+UHJvY051bSk7CgogICAgcGFyYW1zID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZigqcGFyYW1zKSk7CiAgICBpZiAoIXBhcmFtcykKICAgIHsKICAgICAgICBScGNSYWlzZUV4Y2VwdGlvbihFX09VVE9GTUVNT1JZKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgaHIgPSBpcGlkX2dldF9kaXNwYXRjaF9wYXJhbXMoJmlwaWQsICZhcHQsICZwYXJhbXMtPnN0dWIsICZwYXJhbXMtPmNoYW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcGFyYW1zLT5paWQsICZwYXJhbXMtPmlmYWNlKTsKICAgIGlmIChociAhPSBTX09LKQogICAgewogICAgICAgIEVSUigibm8gYXBhcnRtZW50IGZvdW5kIGZvciBpcGlkICVzXG4iLCBkZWJ1Z3N0cl9ndWlkKCZpcGlkKSk7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcGFyYW1zKTsKICAgICAgICBScGNSYWlzZUV4Y2VwdGlvbihocik7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIHBhcmFtcy0+bXNnID0gKFJQQ09MRU1FU1NBR0UgKiltc2c7CiAgICBwYXJhbXMtPnN0YXR1cyA9IFJQQ19TX09LOwogICAgcGFyYW1zLT5ociA9IFNfT0s7CiAgICBwYXJhbXMtPmhhbmRsZSA9IE5VTEw7CgogICAgLyogTm90ZTogdGhpcyBpcyB0aGUgaW1wb3J0YW50IGRpZmZlcmVuY2UgYmV0d2VlbiBTVEFzIGFuZCBNVEFzIC0gd2UKICAgICAqIGFsd2F5cyBleGVjdXRlIFJQQ3MgdG8gU1RBcyBpbiB0aGUgdGhyZWFkIHRoYXQgb3JpZ2luYWxseSBjcmVhdGVkIHRoZQogICAgICogYXBhcnRtZW50IChpLmUuIHRoZSBvbmUgdGhhdCBwdW1wcyBtZXNzYWdlcyB0byB0aGUgd2luZG93KSAqLwogICAgaWYgKCFhcHQtPm11bHRpX3RocmVhZGVkKQogICAgewogICAgICAgIHBhcmFtcy0+aGFuZGxlID0gQ3JlYXRlRXZlbnRXKE5VTEwsIEZBTFNFLCBGQUxTRSwgTlVMTCk7CgogICAgICAgIFRSQUNFKCJDYWxsaW5nIGFwYXJ0bWVudCB0aHJlYWQgMHglMDh4Li4uXG4iLCBhcHQtPnRpZCk7CgogICAgICAgIGlmIChQb3N0TWVzc2FnZVcoYXBhcnRtZW50X2dldHdpbmRvdyhhcHQpLCBETV9FWEVDVVRFUlBDLCAwLCAoTFBBUkFNKXBhcmFtcykpCiAgICAgICAgICAgIFdhaXRGb3JTaW5nbGVPYmplY3QocGFyYW1zLT5oYW5kbGUsIElORklOSVRFKTsKICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBFUlIoIlBvc3RNZXNzYWdlIGZhaWxlZCB3aXRoIGVycm9yICV1XG4iLCBHZXRMYXN0RXJyb3IoKSk7CiAgICAgICAgICAgIElScGNDaGFubmVsQnVmZmVyX1JlbGVhc2UocGFyYW1zLT5jaGFuKTsKICAgICAgICAgICAgSVJwY1N0dWJCdWZmZXJfUmVsZWFzZShwYXJhbXMtPnN0dWIpOwogICAgICAgIH0KICAgICAgICBDbG9zZUhhbmRsZShwYXJhbXMtPmhhbmRsZSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgQk9PTCBqb2luZWQgPSBGQUxTRTsKICAgICAgICBpZiAoIUNPTV9DdXJyZW50SW5mbygpLT5hcHQpCiAgICAgICAgewogICAgICAgICAgICBhcGFydG1lbnRfam9pbm10YSgpOwogICAgICAgICAgICBqb2luZWQgPSBUUlVFOwogICAgICAgIH0KICAgICAgICBSUENfRXhlY3V0ZUNhbGwocGFyYW1zKTsKICAgICAgICBpZiAoam9pbmVkKQogICAgICAgIHsKICAgICAgICAgICAgYXBhcnRtZW50X3JlbGVhc2UoQ09NX0N1cnJlbnRJbmZvKCktPmFwdCk7CiAgICAgICAgICAgIENPTV9DdXJyZW50SW5mbygpLT5hcHQgPSBOVUxMOwogICAgICAgIH0KICAgIH0KCiAgICBociA9IHBhcmFtcy0+aHI7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwYXJhbXMpOwoKICAgIGFwYXJ0bWVudF9yZWxlYXNlKGFwdCk7CgogICAgLyogaWYgSVJwY1N0dWJCdWZmZXJfSW52b2tlIGZhaWxzLCB3ZSBzaG91bGQgcmFpc2UgYW4gZXhjZXB0aW9uIHRvIHRlbGwKICAgICAqIHRoZSBSUEMgcnVudGltZSB0aGF0IHRoZSBjYWxsIGZhaWxlZCAqLwogICAgaWYgKGhyKSBScGNSYWlzZUV4Y2VwdGlvbihocik7Cn0KCi8qIHN0dWIgcmVnaXN0cmF0aW9uICovCkhSRVNVTFQgUlBDX1JlZ2lzdGVySW50ZXJmYWNlKFJFRklJRCByaWlkKQp7CiAgICBzdHJ1Y3QgcmVnaXN0ZXJlZF9pZiAqcmlmOwogICAgQk9PTCBmb3VuZCA9IEZBTFNFOwogICAgSFJFU1VMVCBociA9IFNfT0s7CiAgICAKICAgIFRSQUNFKCIoJXMpXG4iLCBkZWJ1Z3N0cl9ndWlkKHJpaWQpKTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmY3NSZWdJZik7CiAgICBMSVNUX0ZPUl9FQUNIX0VOVFJZKHJpZiwgJnJlZ2lzdGVyZWRfaW50ZXJmYWNlcywgc3RydWN0IHJlZ2lzdGVyZWRfaWYsIGVudHJ5KQogICAgewogICAgICAgIGlmIChJc0VxdWFsR1VJRCgmcmlmLT5JZi5JbnRlcmZhY2VJZC5TeW50YXhHVUlELCByaWlkKSkKICAgICAgICB7CiAgICAgICAgICAgIHJpZi0+cmVmcysrOwogICAgICAgICAgICBmb3VuZCA9IFRSVUU7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KICAgIGlmICghZm91bmQpCiAgICB7CiAgICAgICAgVFJBQ0UoIkNyZWF0aW5nIG5ldyBpbnRlcmZhY2VcbiIpOwoKICAgICAgICByaWYgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKCpyaWYpKTsKICAgICAgICBpZiAocmlmKQogICAgICAgIHsKICAgICAgICAgICAgUlBDX1NUQVRVUyBzdGF0dXM7CgogICAgICAgICAgICByaWYtPnJlZnMgPSAxOwogICAgICAgICAgICByaWYtPklmLkxlbmd0aCA9IHNpemVvZihSUENfU0VSVkVSX0lOVEVSRkFDRSk7CiAgICAgICAgICAgIC8qIFJQQyBpbnRlcmZhY2UgSUQgPSBDT00gaW50ZXJmYWNlIElEICovCiAgICAgICAgICAgIHJpZi0+SWYuSW50ZXJmYWNlSWQuU3ludGF4R1VJRCA9ICpyaWlkOwogICAgICAgICAgICByaWYtPklmLkRpc3BhdGNoVGFibGUgPSAmcnBjX2Rpc3BhdGNoOwogICAgICAgICAgICAvKiBhbGwgb3RoZXIgZmllbGRzIGFyZSAwLCBpbmNsdWRpbmcgdGhlIHZlcnNpb24gYXNDT00gb2JqZWN0cwogICAgICAgICAgICAgKiBhbHdheXMgaGF2ZSBhIHZlcnNpb24gb2YgMC4wICovCiAgICAgICAgICAgIHN0YXR1cyA9IFJwY1NlcnZlclJlZ2lzdGVySWZFeCgKICAgICAgICAgICAgICAgIChSUENfSUZfSEFORExFKSZyaWYtPklmLAogICAgICAgICAgICAgICAgTlVMTCwgTlVMTCwKICAgICAgICAgICAgICAgIFJQQ19JRl9PTEUgfCBSUENfSUZfQVVUT0xJU1RFTiwKICAgICAgICAgICAgICAgIFJQQ19DX0xJU1RFTl9NQVhfQ0FMTFNfREVGQVVMVCwKICAgICAgICAgICAgICAgIE5VTEwpOwogICAgICAgICAgICBpZiAoc3RhdHVzID09IFJQQ19TX09LKQogICAgICAgICAgICAgICAgbGlzdF9hZGRfdGFpbCgmcmVnaXN0ZXJlZF9pbnRlcmZhY2VzLCAmcmlmLT5lbnRyeSk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgRVJSKCJScGNTZXJ2ZXJSZWdpc3RlcklmRXggZmFpbGVkIHdpdGggZXJyb3IgJWxkXG4iLCBzdGF0dXMpOwogICAgICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcmlmKTsKICAgICAgICAgICAgICAgIGhyID0gSFJFU1VMVF9GUk9NX1dJTjMyKHN0YXR1cyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgICAgICBociA9IEVfT1VUT0ZNRU1PUlk7CiAgICB9CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmY3NSZWdJZik7CiAgICByZXR1cm4gaHI7Cn0KCi8qIHN0dWIgdW5yZWdpc3RyYXRpb24gKi8Kdm9pZCBSUENfVW5yZWdpc3RlckludGVyZmFjZShSRUZJSUQgcmlpZCkKewogICAgc3RydWN0IHJlZ2lzdGVyZWRfaWYgKnJpZjsKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZjc1JlZ0lmKTsKICAgIExJU1RfRk9SX0VBQ0hfRU5UUlkocmlmLCAmcmVnaXN0ZXJlZF9pbnRlcmZhY2VzLCBzdHJ1Y3QgcmVnaXN0ZXJlZF9pZiwgZW50cnkpCiAgICB7CiAgICAgICAgaWYgKElzRXF1YWxHVUlEKCZyaWYtPklmLkludGVyZmFjZUlkLlN5bnRheEdVSUQsIHJpaWQpKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCEtLXJpZi0+cmVmcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgUnBjU2VydmVyVW5yZWdpc3RlcklmKChSUENfSUZfSEFORExFKSZyaWYtPklmLCBOVUxMLCBUUlVFKTsKICAgICAgICAgICAgICAgIGxpc3RfcmVtb3ZlKCZyaWYtPmVudHJ5KTsKICAgICAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHJpZik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmNzUmVnSWYpOwp9CgovKiBnZXQgdGhlIGluZm8gZm9yIGFuIE9YSUQsIGluY2x1ZGluZyB0aGUgSVBJRCBmb3IgdGhlIHJlbSB1bmtub3duIGludGVyZmFjZQogKiBhbmQgdGhlIHN0cmluZyBiaW5kaW5nICovCkhSRVNVTFQgUlBDX1Jlc29sdmVPeGlkKE9YSUQgb3hpZCwgT1hJRF9JTkZPICpveGlkX2luZm8pCnsKICAgIFRSQUNFKCIlc1xuIiwgd2luZV9kYmdzdHJfbG9uZ2xvbmcob3hpZCkpOwoKICAgIG94aWRfaW5mby0+ZHdUaWQgPSAwOwogICAgb3hpZF9pbmZvLT5kd1BpZCA9IDA7CiAgICBveGlkX2luZm8tPmR3QXV0aG5IaW50ID0gUlBDX0NfQVVUSE5fTEVWRUxfTk9ORTsKICAgIC8qIEZJWE1FOiB0aGlzIGlzIGEgaGFjayBhcm91bmQgbm90IGhhdmluZyBhbiBPWElEIHJlc29sdmVyIHlldCAtCiAgICAgKiB0aGlzIGZ1bmN0aW9uIHNob3VsZCBjb250YWN0IHRoZSBtYWNoaW5lJ3MgT1hJRCByZXNvbHZlciBhbmQgdGhlbiBpdAogICAgICogc2hvdWxkIGdpdmUgdXMgdGhlIElQSUQgb2YgdGhlIElSZW1Vbmtub3duIGludGVyZmFjZSAqLwogICAgb3hpZF9pbmZvLT5pcGlkUmVtVW5rbm93bi5EYXRhMSA9IDB4ZmZmZmZmZmY7CiAgICBveGlkX2luZm8tPmlwaWRSZW1Vbmtub3duLkRhdGEyID0gMHhmZmZmOwogICAgb3hpZF9pbmZvLT5pcGlkUmVtVW5rbm93bi5EYXRhMyA9IDB4ZmZmZjsKICAgIG1lbWNweSgmb3hpZF9pbmZvLT5pcGlkUmVtVW5rbm93bi5EYXRhNCwgJm94aWQsIHNpemVvZihPWElEKSk7CiAgICBveGlkX2luZm8tPnBzYSA9IE5VTEwgLyogRklYTUUgKi87CgogICAgcmV0dXJuIFNfT0s7Cn0KCi8qIG1ha2UgdGhlIGFwYXJ0bWVudCByZWFjaGFibGUgYnkgb3RoZXIgdGhyZWFkcyBhbmQgcHJvY2Vzc2VzIGFuZCBjcmVhdGUgdGhlCiAqIElSZW1Vbmtub3duIG9iamVjdCAqLwp2b2lkIFJQQ19TdGFydFJlbW90aW5nKHN0cnVjdCBhcGFydG1lbnQgKmFwdCkKewogICAgaWYgKCFJbnRlcmxvY2tlZEV4Y2hhbmdlKCZhcHQtPnJlbW90aW5nX3N0YXJ0ZWQsIFRSVUUpKQogICAgewogICAgICAgIFdDSEFSIGVuZHBvaW50WzIwMF07CiAgICAgICAgUlBDX1NUQVRVUyBzdGF0dXM7CgogICAgICAgIGdldF9ycGNfZW5kcG9pbnQoZW5kcG9pbnQsICZhcHQtPm94aWQpOwogICAgCiAgICAgICAgc3RhdHVzID0gUnBjU2VydmVyVXNlUHJvdHNlcUVwVygKICAgICAgICAgICAgd3N6UnBjVHJhbnNwb3J0LAogICAgICAgICAgICBSUENfQ19QUk9UU0VRX01BWF9SRVFTX0RFRkFVTFQsCiAgICAgICAgICAgIGVuZHBvaW50LAogICAgICAgICAgICBOVUxMKTsKICAgICAgICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKQogICAgICAgICAgICBFUlIoIkNvdWxkbid0IHJlZ2lzdGVyIGVuZHBvaW50ICVzXG4iLCBkZWJ1Z3N0cl93KGVuZHBvaW50KSk7CgogICAgICAgIC8qIEZJWE1FOiBtb3ZlIHJlbW90ZSB1bmtub3duIGV4cG9ydGluZyBpbnRvIHRoaXMgZnVuY3Rpb24gKi8KICAgIH0KICAgIHN0YXJ0X2FwYXJ0bWVudF9yZW1vdGVfdW5rbm93bigpOwp9CgoKc3RhdGljIEhSRVNVTFQgY3JlYXRlX3NlcnZlcihSRUZDTFNJRCByY2xzaWQpCnsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiAgd3N6TG9jYWxTZXJ2ZXIzMltdID0geyAnTCcsJ28nLCdjJywnYScsJ2wnLCdTJywnZScsJ3InLCd2JywnZScsJ3InLCczJywnMicsMCB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSICBlbWJlZGRpbmdbXSA9IHsgJyAnLCAnLScsJ0UnLCdtJywnYicsJ2UnLCdkJywnZCcsJ2knLCduJywnZycsMCB9OwogICAgSEtFWSAgICAgICAgICAgICAgICBrZXk7CiAgICBIUkVTVUxUICAgICAgICAgICAgIGhyZXM7CiAgICBXQ0hBUiAgICAgICAgICAgICAgIGNvbW1hbmRbTUFYX1BBVEgrc2l6ZW9mKGVtYmVkZGluZykvc2l6ZW9mKFdDSEFSKV07CiAgICBEV09SRCAgICAgICAgICAgICAgIHNpemUgPSAoTUFYX1BBVEgrMSkgKiBzaXplb2YoV0NIQVIpOwogICAgU1RBUlRVUElORk9XICAgICAgICBzaW5mbzsKICAgIFBST0NFU1NfSU5GT1JNQVRJT04gcGluZm87CgogICAgaHJlcyA9IENPTV9PcGVuS2V5Rm9yQ0xTSUQocmNsc2lkLCB3c3pMb2NhbFNlcnZlcjMyLCBLRVlfUkVBRCwgJmtleSk7CiAgICBpZiAoRkFJTEVEKGhyZXMpKSB7CiAgICAgICAgRVJSKCJjbGFzcyAlcyBub3QgcmVnaXN0ZXJlZFxuIiwgZGVidWdzdHJfZ3VpZChyY2xzaWQpKTsKICAgICAgICByZXR1cm4gaHJlczsKICAgIH0KCiAgICBocmVzID0gUmVnUXVlcnlWYWx1ZUV4VyhrZXksIE5VTEwsIE5VTEwsIE5VTEwsIChMUEJZVEUpY29tbWFuZCwgJnNpemUpOwogICAgUmVnQ2xvc2VLZXkoa2V5KTsKICAgIGlmIChocmVzKSB7CiAgICAgICAgV0FSTigiTm8gZGVmYXVsdCB2YWx1ZSBmb3IgTG9jYWxTZXJ2ZXIzMiBrZXlcbiIpOwogICAgICAgIHJldHVybiBSRUdEQl9FX0NMQVNTTk9UUkVHOyAvKiBGSVhNRTogY2hlY2sgcmV0dmFsICovCiAgICB9CgogICAgbWVtc2V0KCZzaW5mbywwLHNpemVvZihzaW5mbykpOwogICAgc2luZm8uY2IgPSBzaXplb2Yoc2luZm8pOwoKICAgIC8qIEVYRSBzZXJ2ZXJzIGFyZSBzdGFydGVkIHdpdGggdGhlIC1FbWJlZGRpbmcgc3dpdGNoLiAqLwoKICAgIHN0cmNhdFcoY29tbWFuZCwgZW1iZWRkaW5nKTsKCiAgICBUUkFDRSgiYWN0aXZhdGluZyBsb2NhbCBzZXJ2ZXIgJXMgZm9yICVzXG4iLCBkZWJ1Z3N0cl93KGNvbW1hbmQpLCBkZWJ1Z3N0cl9ndWlkKHJjbHNpZCkpOwoKICAgIC8qIEZJWE1FOiBXaW4yMDAzIHN1cHBvcnRzIGEgU2VydmVyRXhlY3V0YWJsZSB2YWx1ZSB0aGF0IGlzIHBhc3NlZCBpbnRvCiAgICAgKiBDcmVhdGVQcm9jZXNzICovCiAgICBpZiAoIUNyZWF0ZVByb2Nlc3NXKE5VTEwsIGNvbW1hbmQsIE5VTEwsIE5VTEwsIEZBTFNFLCAwLCBOVUxMLCBOVUxMLCAmc2luZm8sICZwaW5mbykpIHsKICAgICAgICBXQVJOKCJmYWlsZWQgdG8gcnVuIGxvY2FsIHNlcnZlciAlc1xuIiwgZGVidWdzdHJfdyhjb21tYW5kKSk7CiAgICAgICAgcmV0dXJuIEhSRVNVTFRfRlJPTV9XSU4zMihHZXRMYXN0RXJyb3IoKSk7CiAgICB9CiAgICBDbG9zZUhhbmRsZShwaW5mby5oUHJvY2Vzcyk7CiAgICBDbG9zZUhhbmRsZShwaW5mby5oVGhyZWFkKTsKCiAgICByZXR1cm4gU19PSzsKfQoKLyoKICogc3RhcnRfbG9jYWxfc2VydmljZSgpICAtIHN0YXJ0IGEgc2VydmljZSBnaXZlbiBpdHMgbmFtZSBhbmQgcGFyYW1ldGVycwogKi8Kc3RhdGljIERXT1JEIHN0YXJ0X2xvY2FsX3NlcnZpY2UoTFBDV1NUUiBuYW1lLCBEV09SRCBudW0sIExQQ1dTVFIgKnBhcmFtcykKewogICAgU0NfSEFORExFIGhhbmRsZSwgaHN2YzsKICAgIERXT1JEICAgICByID0gRVJST1JfRlVOQ1RJT05fRkFJTEVEOwoKICAgIFRSQUNFKCJTdGFydGluZyBzZXJ2aWNlICVzICVkIHBhcmFtc1xuIiwgZGVidWdzdHJfdyhuYW1lKSwgbnVtKTsKCiAgICBoYW5kbGUgPSBPcGVuU0NNYW5hZ2VyVyhOVUxMLCBOVUxMLCBTQ19NQU5BR0VSX0NPTk5FQ1QpOwogICAgaWYgKCFoYW5kbGUpCiAgICAgICAgcmV0dXJuIHI7CiAgICBoc3ZjID0gT3BlblNlcnZpY2VXKGhhbmRsZSwgbmFtZSwgU0VSVklDRV9TVEFSVCk7CiAgICBpZiAoaHN2YykKICAgIHsKICAgICAgICBpZihTdGFydFNlcnZpY2VXKGhzdmMsIG51bSwgcGFyYW1zKSkKICAgICAgICAgICAgciA9IEVSUk9SX1NVQ0NFU1M7CiAgICAgICAgZWxzZQogICAgICAgICAgICByID0gR2V0TGFzdEVycm9yKCk7CiAgICAgICAgaWYgKHIgPT0gRVJST1JfU0VSVklDRV9BTFJFQURZX1JVTk5JTkcpCiAgICAgICAgICAgIHIgPSBFUlJPUl9TVUNDRVNTOwogICAgICAgIENsb3NlU2VydmljZUhhbmRsZShoc3ZjKTsKICAgIH0KICAgIGVsc2UKICAgICAgICByID0gR2V0TGFzdEVycm9yKCk7CiAgICBDbG9zZVNlcnZpY2VIYW5kbGUoaGFuZGxlKTsKCiAgICBUUkFDRSgiU3RhcnRTZXJ2aWNlIHJldHVybmVkIGVycm9yICV1ICglcylcbiIsIHIsIChyID09IEVSUk9SX1NVQ0NFU1MpID8gIm9rIjoiZmFpbGVkIik7CgogICAgcmV0dXJuIHI7Cn0KCi8qCiAqIGNyZWF0ZV9sb2NhbF9zZXJ2aWNlKCkgIC0gc3RhcnQgYSBDT00gc2VydmVyIGluIGEgc2VydmljZQogKgogKiAgIFRvIHN0YXJ0IGEgTG9jYWwgU2VydmljZSwgd2UgcmVhZCB0aGUgQXBwSUQgdmFsdWUgdW5kZXIKICogdGhlIGNsYXNzJ3MgQ0xTSUQga2V5LCB0aGVuIG9wZW4gdGhlIEhLQ1JcXEFwcElkIGtleSBzcGVjaWZpZWQKICogdGhlcmUgYW5kIGNoZWNrIGZvciBhIExvY2FsU2VydmljZSB2YWx1ZS4KICoKICogTm90ZTogIExvY2FsIFNlcnZpY2VzIGFyZSBub3Qgc3VwcG9ydGVkIHVuZGVyIFdpbmRvd3MgOXgKICovCnN0YXRpYyBIUkVTVUxUIGNyZWF0ZV9sb2NhbF9zZXJ2aWNlKFJFRkNMU0lEIHJjbHNpZCkKewogICAgSFJFU1VMVCBocmVzOwogICAgV0NIQVIgYnVmW0NIQVJTX0lOX0dVSURdOwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHN6TG9jYWxTZXJ2aWNlW10gPSB7ICdMJywnbycsJ2MnLCdhJywnbCcsJ1MnLCdlJywncicsJ3YnLCdpJywnYycsJ2UnLDAgfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzelNlcnZpY2VQYXJhbXNbXSA9IHsnUycsJ2UnLCdyJywndicsJ2knLCdjJywnZScsJ1AnLCdhJywncicsJ2EnLCdtJywncycsMH07CiAgICBIS0VZIGhrZXk7CiAgICBMT05HIHI7CiAgICBEV09SRCB0eXBlLCBzejsKCiAgICBUUkFDRSgiQXR0ZW1wdGluZyB0byBzdGFydCBMb2NhbCBzZXJ2aWNlIGZvciAlc1xuIiwgZGVidWdzdHJfZ3VpZChyY2xzaWQpKTsKCiAgICBocmVzID0gQ09NX09wZW5LZXlGb3JBcHBJZEZyb21DTFNJRChyY2xzaWQsIEtFWV9SRUFELCAmaGtleSk7CiAgICBpZiAoRkFJTEVEKGhyZXMpKQogICAgICAgIHJldHVybiBocmVzOwoKICAgIC8qIHJlYWQgdGhlIExvY2FsU2VydmljZSBhbmQgU2VydmljZVBhcmFtZXRlcnMgdmFsdWVzIGZyb20gdGhlIEFwcElEIGtleSAqLwogICAgc3ogPSBzaXplb2YgYnVmOwogICAgciA9IFJlZ1F1ZXJ5VmFsdWVFeFcoaGtleSwgc3pMb2NhbFNlcnZpY2UsIE5VTEwsICZ0eXBlLCAoTFBCWVRFKWJ1ZiwgJnN6KTsKICAgIGlmIChyPT1FUlJPUl9TVUNDRVNTICYmIHR5cGU9PVJFR19TWikKICAgIHsKICAgICAgICBEV09SRCBudW1fYXJncyA9IDA7CiAgICAgICAgTFBXU1RSIGFyZ3NbMV0gPSB7IE5VTEwgfTsKCiAgICAgICAgLyoKICAgICAgICAgKiBGSVhNRTogSSdtIG5vdCByZWFsbHkgc3VyZSBob3cgdG8gZGVhbCB3aXRoIHRoZSBzZXJ2aWNlIHBhcmFtZXRlcnMuCiAgICAgICAgICogICAgICAgIEkgc3VzcGVjdCB0aGF0IHRoZSBzdHJpbmcgcmV0dXJuZWQgZnJvbSBSZWdRdWVyeVZhbHVlRXhXCiAgICAgICAgICogICAgICAgIHNob3VsZCBiZSBzcGxpdCBpbnRvIGEgbnVtYmVyIG9mIGFyZ3VtZW50cyBieSBzcGFjZXMuCiAgICAgICAgICogICAgICAgIEl0IHdvdWxkIG1ha2UgbW9yZSBzZW5zZSBpZiBTZXJ2aWNlUGFyYW1zIGNvbnRhaW5lZCBhCiAgICAgICAgICogICAgICAgIFJFR19NVUxUSV9TWiBoZXJlLCBidXQgaXQncyBhIFJFR19TWiBmb3IgdGhlIHNlcnZpY2VzCiAgICAgICAgICogICAgICAgIHRoYXQgSSdtIGludGVyZXN0ZWQgaW4gZm9yIHRoZSBtb21lbnQuCiAgICAgICAgICovCiAgICAgICAgciA9IFJlZ1F1ZXJ5VmFsdWVFeFcoaGtleSwgc3pTZXJ2aWNlUGFyYW1zLCBOVUxMLCAmdHlwZSwgTlVMTCwgJnN6KTsKICAgICAgICBpZiAociA9PSBFUlJPUl9TVUNDRVNTICYmIHR5cGUgPT0gUkVHX1NaICYmIHN6KQogICAgICAgIHsKICAgICAgICAgICAgYXJnc1swXSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLEhFQVBfWkVST19NRU1PUlksc3opOwogICAgICAgICAgICBudW1fYXJncysrOwogICAgICAgICAgICBSZWdRdWVyeVZhbHVlRXhXKGhrZXksIHN6U2VydmljZVBhcmFtcywgTlVMTCwgJnR5cGUsIChMUEJZVEUpYXJnc1swXSwgJnN6KTsKICAgICAgICB9CiAgICAgICAgciA9IHN0YXJ0X2xvY2FsX3NlcnZpY2UoYnVmLCBudW1fYXJncywgKExQQ1dTVFIgKilhcmdzKTsKICAgICAgICBpZiAociAhPSBFUlJPUl9TVUNDRVNTKQogICAgICAgICAgICBocmVzID0gUkVHREJfRV9DTEFTU05PVFJFRzsgLyogRklYTUU6IGNoZWNrIHJldHZhbCAqLwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCxhcmdzWzBdKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBXQVJOKCJObyBMb2NhbFNlcnZpY2UgdmFsdWVcbiIpOwogICAgICAgIGhyZXMgPSBSRUdEQl9FX0NMQVNTTk9UUkVHOyAvKiBGSVhNRTogY2hlY2sgcmV0dmFsICovCiAgICB9CiAgICBSZWdDbG9zZUtleShoa2V5KTsKCiAgICByZXR1cm4gaHJlczsKfQoKCnN0YXRpYyB2b2lkIGdldF9sb2NhbHNlcnZlcl9waXBlX25hbWUoV0NIQVIgKnBpcGVmbiwgUkVGQ0xTSUQgcmNsc2lkKQp7CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgd3N6UGlwZVJlZltdID0geydcXCcsJ1xcJywnLicsJ1xcJywncCcsJ2knLCdwJywnZScsJ1xcJywwfTsKICAgIHN0cmNweVcocGlwZWZuLCB3c3pQaXBlUmVmKTsKICAgIFN0cmluZ0Zyb21HVUlEMihyY2xzaWQsIHBpcGVmbiArIHNpemVvZih3c3pQaXBlUmVmKS9zaXplb2Yod3N6UGlwZVJlZlswXSkgLSAxLCBDSEFSU19JTl9HVUlEKTsKfQoKLyogRklYTUU6IHNob3VsZCBjYWxsIHRvIHJwY3NzIGluc3RlYWQgKi8KSFJFU1VMVCBSUENfR2V0TG9jYWxDbGFzc09iamVjdChSRUZDTFNJRCByY2xzaWQsIFJFRklJRCBpaWQsIExQVk9JRCAqcHB2KQp7CiAgICBIUkVTVUxUICAgICAgICBocmVzOwogICAgSEFORExFICAgICAgICAgaFBpcGU7CiAgICBXQ0hBUiAgICAgICAgICBwaXBlZm5bMTAwXTsKICAgIERXT1JEICAgICAgICAgIHJlcywgYnVmZmVybGVuOwogICAgY2hhciAgICAgICAgICAgbWFyc2hhbGJ1ZmZlclsyMDBdOwogICAgSVN0cmVhbSAgICAgICAqcFN0bTsKICAgIExBUkdFX0lOVEVHRVIgIHNlZWt0bzsKICAgIFVMQVJHRV9JTlRFR0VSIG5ld3BvczsKICAgIGludCAgICAgICAgICAgIHRyaWVzID0gMDsKCiAgICBzdGF0aWMgY29uc3QgaW50IE1BWFRSSUVTID0gMzA7IC8qIDMwIHNlY29uZHMgKi8KCiAgICBUUkFDRSgicmNsc2lkPSVzLCBpaWQ9JXNcbiIsIGRlYnVnc3RyX2d1aWQocmNsc2lkKSwgZGVidWdzdHJfZ3VpZChpaWQpKTsKCiAgICBnZXRfbG9jYWxzZXJ2ZXJfcGlwZV9uYW1lKHBpcGVmbiwgcmNsc2lkKTsKCiAgICB3aGlsZSAodHJpZXMrKyA8IE1BWFRSSUVTKSB7CiAgICAgICAgVFJBQ0UoIndhaXRpbmcgZm9yICVzXG4iLCBkZWJ1Z3N0cl93KHBpcGVmbikpOwoKICAgICAgICBXYWl0TmFtZWRQaXBlVyggcGlwZWZuLCBOTVBXQUlUX1dBSVRfRk9SRVZFUiApOwogICAgICAgIGhQaXBlID0gQ3JlYXRlRmlsZVcocGlwZWZuLCBHRU5FUklDX1JFQUQgfCBHRU5FUklDX1dSSVRFLCAwLCBOVUxMLCBPUEVOX0VYSVNUSU5HLCAwLCAwKTsKICAgICAgICBpZiAoaFBpcGUgPT0gSU5WQUxJRF9IQU5ETEVfVkFMVUUpIHsKICAgICAgICAgICAgRFdPUkQgaW5kZXg7CiAgICAgICAgICAgIGlmICh0cmllcyA9PSAxKSB7CiAgICAgICAgICAgICAgICBpZiAoIChocmVzID0gY3JlYXRlX2xvY2FsX3NlcnZpY2UocmNsc2lkKSkgJiYKICAgICAgICAgICAgICAgICAgICAgKGhyZXMgPSBjcmVhdGVfc2VydmVyKHJjbHNpZCkpICkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gaHJlczsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIFdBUk4oIkNvbm5lY3RpbmcgdG8gJXMsIG5vIHJlc3BvbnNlIHlldCwgcmV0cnlpbmc6IGxlIGlzICV1XG4iLCBkZWJ1Z3N0cl93KHBpcGVmbiksIEdldExhc3RFcnJvcigpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBDb1dhaXRGb3JNdWx0aXBsZUhhbmRsZXMoMCwgMTAwMCwgMCwgTlVMTCwgJmluZGV4KTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIGJ1ZmZlcmxlbiA9IDA7CiAgICAgICAgaWYgKCFSZWFkRmlsZShoUGlwZSxtYXJzaGFsYnVmZmVyLHNpemVvZihtYXJzaGFsYnVmZmVyKSwmYnVmZmVybGVuLE5VTEwpKSB7CiAgICAgICAgICAgIEZJWE1FKCJGYWlsZWQgdG8gcmVhZCBtYXJzaGFsIGlkIGZyb20gY2xhc3NmYWN0b3J5IG9mICVzLlxuIixkZWJ1Z3N0cl9ndWlkKHJjbHNpZCkpOwogICAgICAgICAgICBTbGVlcCgxMDAwKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIFRSQUNFKCJyZWFkIG1hcnNoYWwgaWQgZnJvbSBwaXBlXG4iKTsKICAgICAgICBDbG9zZUhhbmRsZShoUGlwZSk7CiAgICAgICAgYnJlYWs7CiAgICB9CiAgICAKICAgIGlmICh0cmllcyA+PSBNQVhUUklFUykKICAgICAgICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKICAgIAogICAgaHJlcyA9IENyZWF0ZVN0cmVhbU9uSEdsb2JhbCgwLFRSVUUsJnBTdG0pOwogICAgaWYgKGhyZXMpIHJldHVybiBocmVzOwogICAgaHJlcyA9IElTdHJlYW1fV3JpdGUocFN0bSxtYXJzaGFsYnVmZmVyLGJ1ZmZlcmxlbiwmcmVzKTsKICAgIGlmIChocmVzKSBnb3RvIG91dDsKICAgIHNlZWt0by51Lkxvd1BhcnQgPSAwO3NlZWt0by51LkhpZ2hQYXJ0ID0gMDsKICAgIGhyZXMgPSBJU3RyZWFtX1NlZWsocFN0bSxzZWVrdG8sU0VFS19TRVQsJm5ld3Bvcyk7CiAgICAKICAgIFRSQUNFKCJ1bm1hcnNoYWxsaW5nIGNsYXNzZmFjdG9yeVxuIik7CiAgICBocmVzID0gQ29Vbm1hcnNoYWxJbnRlcmZhY2UocFN0bSwmSUlEX0lDbGFzc0ZhY3RvcnkscHB2KTsKb3V0OgogICAgSVN0cmVhbV9SZWxlYXNlKHBTdG0pOwogICAgcmV0dXJuIGhyZXM7Cn0KCgpzdHJ1Y3QgbG9jYWxfc2VydmVyX3BhcmFtcwp7CiAgICBDTFNJRCBjbHNpZDsKICAgIElTdHJlYW0gKnN0cmVhbTsKICAgIEhBTkRMRSByZWFkeV9ldmVudDsKICAgIEhBTkRMRSBzdG9wX2V2ZW50OwogICAgSEFORExFIHRocmVhZDsKICAgIEJPT0wgbXVsdGlfdXNlOwp9OwoKLyogRklYTUU6IHNob3VsZCBjYWxsIHRvIHJwY3NzIGluc3RlYWQgKi8Kc3RhdGljIERXT1JEIFdJTkFQSSBsb2NhbF9zZXJ2ZXJfdGhyZWFkKExQVk9JRCBwYXJhbSkKewogICAgc3RydWN0IGxvY2FsX3NlcnZlcl9wYXJhbXMgKiBsc3AgPSAoc3RydWN0IGxvY2FsX3NlcnZlcl9wYXJhbXMgKilwYXJhbTsKICAgIEhBTkRMRQkJaFBpcGU7CiAgICBXQ0hBUiAJCXBpcGVmblsxMDBdOwogICAgSFJFU1VMVAkJaHJlczsKICAgIElTdHJlYW0JCSpwU3RtID0gbHNwLT5zdHJlYW07CiAgICBTVEFUU1RHCQlzdHN0ZzsKICAgIHVuc2lnbmVkIGNoYXIJKmJ1ZmZlcjsKICAgIGludCAJCWJ1ZmxlbjsKICAgIExBUkdFX0lOVEVHRVIJc2Vla3RvOwogICAgVUxBUkdFX0lOVEVHRVIJbmV3cG9zOwogICAgVUxPTkcJCXJlczsKICAgIEJPT0wgbXVsdGlfdXNlID0gbHNwLT5tdWx0aV91c2U7CiAgICBPVkVSTEFQUEVEIG92bDsKICAgIEhBTkRMRSBwaXBlX2V2ZW50OwoKICAgIFRSQUNFKCJTdGFydGluZyB0aHJlYWRlciBmb3IgJXMuXG4iLGRlYnVnc3RyX2d1aWQoJmxzcC0+Y2xzaWQpKTsKCiAgICBtZW1zZXQoJm92bCwgMCwgc2l6ZW9mKG92bCkpOwogICAgZ2V0X2xvY2Fsc2VydmVyX3BpcGVfbmFtZShwaXBlZm4sICZsc3AtPmNsc2lkKTsKCiAgICBoUGlwZSA9IENyZWF0ZU5hbWVkUGlwZVcoIHBpcGVmbiwgUElQRV9BQ0NFU1NfRFVQTEVYIHwgRklMRV9GTEFHX09WRVJMQVBQRUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBJUEVfVFlQRV9CWVRFfFBJUEVfV0FJVCwgUElQRV9VTkxJTUlURURfSU5TVEFOQ0VTLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICA0MDk2LCA0MDk2LCA1MDAgLyogMC41IHNlY29uZCB0aW1lb3V0ICovLCBOVUxMICk7CgogICAgU2V0RXZlbnQobHNwLT5yZWFkeV9ldmVudCk7CgogICAgaWYgKGhQaXBlID09IElOVkFMSURfSEFORExFX1ZBTFVFKQogICAgewogICAgICAgIEZJWE1FKCJwaXBlIGNyZWF0aW9uIGZhaWxlZCBmb3IgJXMsIGxlIGlzICV1XG4iLCBkZWJ1Z3N0cl93KHBpcGVmbiksIEdldExhc3RFcnJvcigpKTsKICAgICAgICByZXR1cm4gMTsKICAgIH0KCiAgICBvdmwuaEV2ZW50ID0gcGlwZV9ldmVudCA9IENyZWF0ZUV2ZW50VyhOVUxMLCBGQUxTRSwgRkFMU0UsIE5VTEwpOwogICAgCiAgICB3aGlsZSAoMSkgewogICAgICAgIGlmICghQ29ubmVjdE5hbWVkUGlwZShoUGlwZSwgJm92bCkpCiAgICAgICAgewogICAgICAgICAgICBEV09SRCBlcnJvciA9IEdldExhc3RFcnJvcigpOwogICAgICAgICAgICBpZiAoZXJyb3IgPT0gRVJST1JfSU9fUEVORElORykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgSEFORExFIGhhbmRsZXNbMl0gPSB7IHBpcGVfZXZlbnQsIGxzcC0+c3RvcF9ldmVudCB9OwogICAgICAgICAgICAgICAgRFdPUkQgcmV0OwogICAgICAgICAgICAgICAgcmV0ID0gV2FpdEZvck11bHRpcGxlT2JqZWN0cygyLCBoYW5kbGVzLCBGQUxTRSwgSU5GSU5JVEUpOwogICAgICAgICAgICAgICAgaWYgKHJldCAhPSBXQUlUX09CSkVDVF8wKQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qIGNsaWVudCBhbHJlYWR5IGNvbm5lY3RlZCBpc24ndCBhbiBlcnJvciAqLwogICAgICAgICAgICBlbHNlIGlmIChlcnJvciAhPSBFUlJPUl9QSVBFX0NPTk5FQ1RFRCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgRVJSKCJDb25uZWN0TmFtZWRQaXBlIGZhaWxlZCB3aXRoIGVycm9yICVkXG4iLCBHZXRMYXN0RXJyb3IoKSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgVFJBQ0UoIm1hcnNoYWxsaW5nIElDbGFzc0ZhY3RvcnkgdG8gY2xpZW50XG4iKTsKICAgICAgICAKICAgICAgICBocmVzID0gSVN0cmVhbV9TdGF0KHBTdG0sJnN0c3RnLDApOwogICAgICAgIGlmIChocmVzKSByZXR1cm4gaHJlczsKCiAgICAgICAgc2Vla3RvLnUuTG93UGFydCA9IDA7CiAgICAgICAgc2Vla3RvLnUuSGlnaFBhcnQgPSAwOwogICAgICAgIGhyZXMgPSBJU3RyZWFtX1NlZWsocFN0bSxzZWVrdG8sU0VFS19TRVQsJm5ld3Bvcyk7CiAgICAgICAgaWYgKGhyZXMpIHsKICAgICAgICAgICAgRklYTUUoIklTdHJlYW1fU2VlayBmYWlsZWQsICV4XG4iLGhyZXMpOwogICAgICAgICAgICBDbG9zZUhhbmRsZShoUGlwZSk7CiAgICAgICAgICAgIENsb3NlSGFuZGxlKHBpcGVfZXZlbnQpOwogICAgICAgICAgICByZXR1cm4gaHJlczsKICAgICAgICB9CgogICAgICAgIGJ1ZmxlbiA9IHN0c3RnLmNiU2l6ZS51Lkxvd1BhcnQ7CiAgICAgICAgYnVmZmVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksMCxidWZsZW4pOwogICAgICAgIAogICAgICAgIGhyZXMgPSBJU3RyZWFtX1JlYWQocFN0bSxidWZmZXIsYnVmbGVuLCZyZXMpOwogICAgICAgIGlmIChocmVzKSB7CiAgICAgICAgICAgIEZJWE1FKCJTdHJlYW0gUmVhZCBmYWlsZWQsICV4XG4iLGhyZXMpOwogICAgICAgICAgICBDbG9zZUhhbmRsZShoUGlwZSk7CiAgICAgICAgICAgIENsb3NlSGFuZGxlKHBpcGVfZXZlbnQpOwogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsYnVmZmVyKTsKICAgICAgICAgICAgcmV0dXJuIGhyZXM7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIFdyaXRlRmlsZShoUGlwZSxidWZmZXIsYnVmbGVuLCZyZXMsJm92bCk7CiAgICAgICAgR2V0T3ZlcmxhcHBlZFJlc3VsdChoUGlwZSwgJm92bCwgTlVMTCwgVFJVRSk7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLGJ1ZmZlcik7CgogICAgICAgIEZsdXNoRmlsZUJ1ZmZlcnMoaFBpcGUpOwogICAgICAgIERpc2Nvbm5lY3ROYW1lZFBpcGUoaFBpcGUpOwoKICAgICAgICBUUkFDRSgiZG9uZSBtYXJzaGFsbGluZyBJQ2xhc3NGYWN0b3J5XG4iKTsKCiAgICAgICAgaWYgKCFtdWx0aV91c2UpCiAgICAgICAgewogICAgICAgICAgICBUUkFDRSgic2luZ2xlIHVzZSBvYmplY3QsIHNodXR0aW5nIGRvd24gcGlwZSAlc1xuIiwgZGVidWdzdHJfdyhwaXBlZm4pKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQogICAgQ2xvc2VIYW5kbGUoaFBpcGUpOwogICAgQ2xvc2VIYW5kbGUocGlwZV9ldmVudCk7CiAgICByZXR1cm4gMDsKfQoKLyogc3RhcnRzIGxpc3RlbmluZyBmb3IgYSBsb2NhbCBzZXJ2ZXIgKi8KSFJFU1VMVCBSUENfU3RhcnRMb2NhbFNlcnZlcihSRUZDTFNJRCBjbHNpZCwgSVN0cmVhbSAqc3RyZWFtLCBCT09MIG11bHRpX3VzZSwgdm9pZCAqKnJlZ2lzdHJhdGlvbikKewogICAgRFdPUkQgdGlkOwogICAgc3RydWN0IGxvY2FsX3NlcnZlcl9wYXJhbXMgKmxzcDsKCiAgICBsc3AgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKCpsc3ApKTsKICAgIGlmICghbHNwKQogICAgICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwoKICAgIGxzcC0+Y2xzaWQgPSAqY2xzaWQ7CiAgICBsc3AtPnN0cmVhbSA9IHN0cmVhbTsKICAgIElTdHJlYW1fQWRkUmVmKHN0cmVhbSk7CiAgICBsc3AtPnJlYWR5X2V2ZW50ID0gQ3JlYXRlRXZlbnRXKE5VTEwsIEZBTFNFLCBGQUxTRSwgTlVMTCk7CiAgICBpZiAoIWxzcC0+cmVhZHlfZXZlbnQpCiAgICB7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbHNwKTsKICAgICAgICByZXR1cm4gSFJFU1VMVF9GUk9NX1dJTjMyKEdldExhc3RFcnJvcigpKTsKICAgIH0KICAgIGxzcC0+c3RvcF9ldmVudCA9IENyZWF0ZUV2ZW50VyhOVUxMLCBGQUxTRSwgRkFMU0UsIE5VTEwpOwogICAgaWYgKCFsc3AtPnN0b3BfZXZlbnQpCiAgICB7CiAgICAgICAgQ2xvc2VIYW5kbGUobHNwLT5yZWFkeV9ldmVudCk7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbHNwKTsKICAgICAgICByZXR1cm4gSFJFU1VMVF9GUk9NX1dJTjMyKEdldExhc3RFcnJvcigpKTsKICAgIH0KICAgIGxzcC0+bXVsdGlfdXNlID0gbXVsdGlfdXNlOwoKICAgIGxzcC0+dGhyZWFkID0gQ3JlYXRlVGhyZWFkKE5VTEwsIDAsIGxvY2FsX3NlcnZlcl90aHJlYWQsIGxzcCwgMCwgJnRpZCk7CiAgICBpZiAoIWxzcC0+dGhyZWFkKQogICAgewogICAgICAgIENsb3NlSGFuZGxlKGxzcC0+cmVhZHlfZXZlbnQpOwogICAgICAgIENsb3NlSGFuZGxlKGxzcC0+c3RvcF9ldmVudCk7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbHNwKTsKICAgICAgICByZXR1cm4gSFJFU1VMVF9GUk9NX1dJTjMyKEdldExhc3RFcnJvcigpKTsKICAgIH0KCiAgICBXYWl0Rm9yU2luZ2xlT2JqZWN0KGxzcC0+cmVhZHlfZXZlbnQsIElORklOSVRFKTsKICAgIENsb3NlSGFuZGxlKGxzcC0+cmVhZHlfZXZlbnQpOwogICAgbHNwLT5yZWFkeV9ldmVudCA9IE5VTEw7CgogICAgKnJlZ2lzdHJhdGlvbiA9IGxzcDsKICAgIHJldHVybiBTX09LOwp9CgovKiBzdG9wcyBsaXN0ZW5pbmcgZm9yIGEgbG9jYWwgc2VydmVyICovCnZvaWQgUlBDX1N0b3BMb2NhbFNlcnZlcih2b2lkICpyZWdpc3RyYXRpb24pCnsKICAgIHN0cnVjdCBsb2NhbF9zZXJ2ZXJfcGFyYW1zICpsc3AgPSByZWdpc3RyYXRpb247CgogICAgLyogc2lnbmFsIGxvY2FsX3NlcnZlcl90aHJlYWQgdG8gc3RvcCAqLwogICAgU2V0RXZlbnQobHNwLT5zdG9wX2V2ZW50KTsKICAgIC8qIHdhaXQgZm9yIGl0IHRvIGV4aXQgKi8KICAgIFdhaXRGb3JTaW5nbGVPYmplY3QobHNwLT50aHJlYWQsIElORklOSVRFKTsKCiAgICBJU3RyZWFtX1JlbGVhc2UobHNwLT5zdHJlYW0pOwogICAgQ2xvc2VIYW5kbGUobHNwLT5zdG9wX2V2ZW50KTsKICAgIENsb3NlSGFuZGxlKGxzcC0+dGhyZWFkKTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGxzcCk7Cn0K