LyoKICogQ29weXJpZ2h0IChjKSAyMDExIFJvZ2VyIFBhdSBNb25u6SA8cm9nZXIucGF1QGVudGVsLnVwYy5lZHU+CiAqIENvcHlyaWdodCAoYykgMjAxMSBTdGVmYW5vIFNhYmF0aW5pCiAqIENvcHlyaWdodCAoYykgMjAxMyBQYXVsIEIgTWFob2wKICoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgRkZtcGVnLgogKgogKiBGRm1wZWcgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBGRm1wZWcgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggRkZtcGVnOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0cmVldCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSBVU0EKICovCgovKioKICogQGZpbGUKICogQ2FjdWxhdGUgdGhlIFBTTlIgYmV0d2VlbiB0d28gaW5wdXQgdmlkZW9zLgogKi8KCiNpbmNsdWRlICJsaWJhdnV0aWwvb3B0LmgiCiNpbmNsdWRlICJsaWJhdnV0aWwvcGl4ZGVzYy5oIgojaW5jbHVkZSAiYXZmaWx0ZXIuaCIKI2luY2x1ZGUgImR1YWxpbnB1dC5oIgojaW5jbHVkZSAiZHJhd3V0aWxzLmgiCiNpbmNsdWRlICJmb3JtYXRzLmgiCiNpbmNsdWRlICJpbnRlcm5hbC5oIgojaW5jbHVkZSAidmlkZW8uaCIKCnR5cGVkZWYgc3RydWN0IFBTTlJDb250ZXh0IHsKICAgIGNvbnN0IEFWQ2xhc3MgKmNsYXNzOwogICAgRkZEdWFsSW5wdXRDb250ZXh0IGRpbnB1dDsKICAgIGRvdWJsZSBtc2UsIG1pbl9tc2UsIG1heF9tc2U7CiAgICB1aW50NjRfdCBuYl9mcmFtZXM7CiAgICBGSUxFICpzdGF0c19maWxlOwogICAgY2hhciAqc3RhdHNfZmlsZV9zdHI7CiAgICBpbnQgbWF4WzRdLCBhdmVyYWdlX21heDsKICAgIGludCBpc19yZ2I7CiAgICB1aW50OF90IHJnYmFfbWFwWzRdOwogICAgY2hhciBjb21wc1s0XTsKICAgIGludCBuYl9jb21wb25lbnRzOwogICAgaW50IHBsYW5ld2lkdGhbNF07CiAgICBpbnQgcGxhbmVoZWlnaHRbNF07CgogICAgdm9pZCAoKmNvbXB1dGVfbXNlKShzdHJ1Y3QgUFNOUkNvbnRleHQgKnMsCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVpbnQ4X3QgKm1bNF0sIGNvbnN0IGludCBtbFs0XSwKICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdWludDhfdCAqcls0XSwgY29uc3QgaW50IHJsWzRdLAogICAgICAgICAgICAgICAgICAgICAgICBpbnQgdywgaW50IGgsIGRvdWJsZSBtc2VbNF0pOwp9IFBTTlJDb250ZXh0OwoKI2RlZmluZSBPRkZTRVQoeCkgb2Zmc2V0b2YoUFNOUkNvbnRleHQsIHgpCiNkZWZpbmUgRkxBR1MgQVZfT1BUX0ZMQUdfRklMVEVSSU5HX1BBUkFNfEFWX09QVF9GTEFHX1ZJREVPX1BBUkFNCgpzdGF0aWMgY29uc3QgQVZPcHRpb24gcHNucl9vcHRpb25zW10gPSB7CiAgICB7InN0YXRzX2ZpbGUiLCAiU2V0IGZpbGUgd2hlcmUgdG8gc3RvcmUgcGVyLWZyYW1lIGRpZmZlcmVuY2UgaW5mb3JtYXRpb24iLCBPRkZTRVQoc3RhdHNfZmlsZV9zdHIpLCBBVl9PUFRfVFlQRV9TVFJJTkcsIHsuc3RyPU5VTEx9LCAwLCAwLCBGTEFHUyB9LAogICAgeyJmIiwgICAgICAgICAgIlNldCBmaWxlIHdoZXJlIHRvIHN0b3JlIHBlci1mcmFtZSBkaWZmZXJlbmNlIGluZm9ybWF0aW9uIiwgT0ZGU0VUKHN0YXRzX2ZpbGVfc3RyKSwgQVZfT1BUX1RZUEVfU1RSSU5HLCB7LnN0cj1OVUxMfSwgMCwgMCwgRkxBR1MgfSwKICAgIHsgTlVMTCB9Cn07CgpBVkZJTFRFUl9ERUZJTkVfQ0xBU1MocHNucik7CgpzdGF0aWMgaW5saW5lIHVuc2lnbmVkIHBvdzIodW5zaWduZWQgYmFzZSkKewogICAgcmV0dXJuIGJhc2UqYmFzZTsKfQoKc3RhdGljIGlubGluZSBkb3VibGUgZ2V0X3BzbnIoZG91YmxlIG1zZSwgdWludDY0X3QgbmJfZnJhbWVzLCBpbnQgbWF4KQp7CiAgICByZXR1cm4gMTAuMCAqIGxvZyhwb3cyKG1heCkgLyAobXNlIC8gbmJfZnJhbWVzKSkgLyBsb2coMTAuMCk7Cn0KCnN0YXRpYyBpbmxpbmUKdm9pZCBjb21wdXRlX2ltYWdlc19tc2UoUFNOUkNvbnRleHQgKnMsCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVpbnQ4X3QgKm1haW5fZGF0YVs0XSwgY29uc3QgaW50IG1haW5fbGluZXNpemVzWzRdLAogICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1aW50OF90ICpyZWZfZGF0YVs0XSwgY29uc3QgaW50IHJlZl9saW5lc2l6ZXNbNF0sCiAgICAgICAgICAgICAgICAgICAgICAgIGludCB3LCBpbnQgaCwgZG91YmxlIG1zZVs0XSkKewogICAgaW50IGksIGMsIGo7CgogICAgZm9yIChjID0gMDsgYyA8IHMtPm5iX2NvbXBvbmVudHM7IGMrKykgewogICAgICAgIGNvbnN0IGludCBvdXR3ID0gcy0+cGxhbmV3aWR0aFtjXTsKICAgICAgICBjb25zdCBpbnQgb3V0aCA9IHMtPnBsYW5laGVpZ2h0W2NdOwogICAgICAgIGNvbnN0IHVpbnQ4X3QgKm1haW5fbGluZSA9IG1haW5fZGF0YVtjXTsKICAgICAgICBjb25zdCB1aW50OF90ICpyZWZfbGluZSA9IHJlZl9kYXRhW2NdOwogICAgICAgIGNvbnN0IGludCByZWZfbGluZXNpemUgPSByZWZfbGluZXNpemVzW2NdOwogICAgICAgIGNvbnN0IGludCBtYWluX2xpbmVzaXplID0gbWFpbl9saW5lc2l6ZXNbY107CiAgICAgICAgdWludDY0X3QgbSA9IDA7CgogICAgICAgIGZvciAoaSA9IDA7IGkgPCBvdXRoOyBpKyspIHsKICAgICAgICAgICAgaW50IG0yID0gMDsKICAgICAgICAgICAgZm9yIChqID0gMDsgaiA8IG91dHc7IGorKykKICAgICAgICAgICAgICAgIG0yICs9IHBvdzIobWFpbl9saW5lW2pdIC0gcmVmX2xpbmVbal0pOwogICAgICAgICAgICBtICs9IG0yOwogICAgICAgICAgICByZWZfbGluZSArPSByZWZfbGluZXNpemU7CiAgICAgICAgICAgIG1haW5fbGluZSArPSBtYWluX2xpbmVzaXplOwogICAgICAgIH0KICAgICAgICBtc2VbY10gPSBtIC8gKGRvdWJsZSkob3V0dyAqIG91dGgpOwogICAgfQp9CgpzdGF0aWMgaW5saW5lCnZvaWQgY29tcHV0ZV9pbWFnZXNfbXNlXzE2Yml0KFBTTlJDb250ZXh0ICpzLAogICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1aW50OF90ICptYWluX2RhdGFbNF0sIGNvbnN0IGludCBtYWluX2xpbmVzaXplc1s0XSwKICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdWludDhfdCAqcmVmX2RhdGFbNF0sIGNvbnN0IGludCByZWZfbGluZXNpemVzWzRdLAogICAgICAgICAgICAgICAgICAgICAgICBpbnQgdywgaW50IGgsIGRvdWJsZSBtc2VbNF0pCnsKICAgIGludCBpLCBjLCBqOwoKICAgIGZvciAoYyA9IDA7IGMgPCBzLT5uYl9jb21wb25lbnRzOyBjKyspIHsKICAgICAgICBjb25zdCBpbnQgb3V0dyA9IHMtPnBsYW5ld2lkdGhbY107CiAgICAgICAgY29uc3QgaW50IG91dGggPSBzLT5wbGFuZWhlaWdodFtjXTsKICAgICAgICBjb25zdCB1aW50MTZfdCAqbWFpbl9saW5lID0gKHVpbnQxNl90ICopbWFpbl9kYXRhW2NdOwogICAgICAgIGNvbnN0IHVpbnQxNl90ICpyZWZfbGluZSA9ICh1aW50MTZfdCAqKXJlZl9kYXRhW2NdOwogICAgICAgIGNvbnN0IGludCByZWZfbGluZXNpemUgPSByZWZfbGluZXNpemVzW2NdIC8gMjsKICAgICAgICBjb25zdCBpbnQgbWFpbl9saW5lc2l6ZSA9IG1haW5fbGluZXNpemVzW2NdIC8gMjsKICAgICAgICB1aW50NjRfdCBtID0gMDsKCiAgICAgICAgZm9yIChpID0gMDsgaSA8IG91dGg7IGkrKykgewogICAgICAgICAgICBmb3IgKGogPSAwOyBqIDwgb3V0dzsgaisrKQogICAgICAgICAgICAgICAgbSArPSBwb3cyKG1haW5fbGluZVtqXSAtIHJlZl9saW5lW2pdKTsKICAgICAgICAgICAgcmVmX2xpbmUgKz0gcmVmX2xpbmVzaXplOwogICAgICAgICAgICBtYWluX2xpbmUgKz0gbWFpbl9saW5lc2l6ZTsKICAgICAgICB9CiAgICAgICAgbXNlW2NdID0gbSAvIChkb3VibGUpKG91dHcgKiBvdXRoKTsKICAgIH0KfQoKc3RhdGljIHZvaWQgc2V0X21ldGEoQVZEaWN0aW9uYXJ5ICoqbWV0YWRhdGEsIGNvbnN0IGNoYXIgKmtleSwgY2hhciBjb21wLCBmbG9hdCBkKQp7CiAgICBjaGFyIHZhbHVlWzEyOF07CiAgICBzbnByaW50Zih2YWx1ZSwgc2l6ZW9mKHZhbHVlKSwgIiUwLjJmIiwgZCk7CiAgICBpZiAoY29tcCkgewogICAgICAgIGNoYXIga2V5MlsxMjhdOwogICAgICAgIHNucHJpbnRmKGtleTIsIHNpemVvZihrZXkyKSwgIiVzJWMiLCBrZXksIGNvbXApOwogICAgICAgIGF2X2RpY3Rfc2V0KG1ldGFkYXRhLCBrZXkyLCB2YWx1ZSwgMCk7CiAgICB9IGVsc2UgewogICAgICAgIGF2X2RpY3Rfc2V0KG1ldGFkYXRhLCBrZXksIHZhbHVlLCAwKTsKICAgIH0KfQoKc3RhdGljIEFWRnJhbWUgKmRvX3BzbnIoQVZGaWx0ZXJDb250ZXh0ICpjdHgsIEFWRnJhbWUgKm1haW4sCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEFWRnJhbWUgKnJlZikKewogICAgUFNOUkNvbnRleHQgKnMgPSBjdHgtPnByaXY7CiAgICBkb3VibGUgY29tcF9tc2VbNF0sIG1zZSA9IDA7CiAgICBpbnQgaiwgYzsKICAgIEFWRGljdGlvbmFyeSAqKm1ldGFkYXRhID0gYXZwcml2X2ZyYW1lX2dldF9tZXRhZGF0YXAobWFpbik7CgogICAgcy0+Y29tcHV0ZV9tc2UocywgKGNvbnN0IHVpbnQ4X3QgKiopbWFpbi0+ZGF0YSwgbWFpbi0+bGluZXNpemUsCiAgICAgICAgICAgICAgICAgICAgICAoY29uc3QgdWludDhfdCAqKilyZWYtPmRhdGEsIHJlZi0+bGluZXNpemUsCiAgICAgICAgICAgICAgICAgICAgICAgbWFpbi0+d2lkdGgsIG1haW4tPmhlaWdodCwgY29tcF9tc2UpOwoKICAgIGZvciAoaiA9IDA7IGogPCBzLT5uYl9jb21wb25lbnRzOyBqKyspCiAgICAgICAgbXNlICs9IGNvbXBfbXNlW2pdOwogICAgbXNlIC89IHMtPm5iX2NvbXBvbmVudHM7CgogICAgcy0+bWluX21zZSA9IEZGTUlOKHMtPm1pbl9tc2UsIG1zZSk7CiAgICBzLT5tYXhfbXNlID0gRkZNQVgocy0+bWF4X21zZSwgbXNlKTsKCiAgICBzLT5tc2UgKz0gbXNlOwogICAgcy0+bmJfZnJhbWVzKys7CgogICAgZm9yIChqID0gMDsgaiA8IHMtPm5iX2NvbXBvbmVudHM7IGorKykgewogICAgICAgIGMgPSBzLT5pc19yZ2IgPyBzLT5yZ2JhX21hcFtqXSA6IGo7CiAgICAgICAgc2V0X21ldGEobWV0YWRhdGEsICJsYXZmaS5wc25yLm1zZS4iLCBzLT5jb21wc1tqXSwgY29tcF9tc2VbY10pOwogICAgICAgIHNldF9tZXRhKG1ldGFkYXRhLCAibGF2ZmkucHNuci5tc2VfYXZnIiwgMCwgbXNlKTsKICAgICAgICBzZXRfbWV0YShtZXRhZGF0YSwgImxhdmZpLnBzbnIucHNuci4iLCBzLT5jb21wc1tqXSwgZ2V0X3BzbnIoY29tcF9tc2VbY10sIDEsIHMtPm1heFtjXSkpOwogICAgICAgIHNldF9tZXRhKG1ldGFkYXRhLCAibGF2ZmkucHNuci5wc25yX2F2ZyIsIDAsIGdldF9wc25yKG1zZSwgMSwgcy0+YXZlcmFnZV9tYXgpKTsKICAgIH0KCiAgICBpZiAocy0+c3RhdHNfZmlsZSkgewogICAgICAgIGZwcmludGYocy0+c3RhdHNfZmlsZSwgIm46JSJQUklkNjQiIG1zZV9hdmc6JTAuMmYgIiwgcy0+bmJfZnJhbWVzLCBtc2UpOwogICAgICAgIGZvciAoaiA9IDA7IGogPCBzLT5uYl9jb21wb25lbnRzOyBqKyspIHsKICAgICAgICAgICAgYyA9IHMtPmlzX3JnYiA/IHMtPnJnYmFfbWFwW2pdIDogajsKICAgICAgICAgICAgZnByaW50ZihzLT5zdGF0c19maWxlLCAibXNlXyVjOiUwLjJmICIsIHMtPmNvbXBzW2pdLCBjb21wX21zZVtjXSk7CiAgICAgICAgfQogICAgICAgIGZvciAoaiA9IDA7IGogPCBzLT5uYl9jb21wb25lbnRzOyBqKyspIHsKICAgICAgICAgICAgYyA9IHMtPmlzX3JnYiA/IHMtPnJnYmFfbWFwW2pdIDogajsKICAgICAgICAgICAgZnByaW50ZihzLT5zdGF0c19maWxlLCAicHNucl8lYzolMC4yZiAiLCBzLT5jb21wc1tqXSwKICAgICAgICAgICAgICAgICAgICBnZXRfcHNucihjb21wX21zZVtjXSwgMSwgcy0+bWF4W2NdKSk7CiAgICAgICAgfQogICAgICAgIGZwcmludGYocy0+c3RhdHNfZmlsZSwgIlxuIik7CiAgICB9CgogICAgcmV0dXJuIG1haW47Cn0KCnN0YXRpYyBhdl9jb2xkIGludCBpbml0KEFWRmlsdGVyQ29udGV4dCAqY3R4KQp7CiAgICBQU05SQ29udGV4dCAqcyA9IGN0eC0+cHJpdjsKCiAgICBzLT5taW5fbXNlID0gK0lORklOSVRZOwogICAgcy0+bWF4X21zZSA9IC1JTkZJTklUWTsKCiAgICBpZiAocy0+c3RhdHNfZmlsZV9zdHIpIHsKICAgICAgICBzLT5zdGF0c19maWxlID0gZm9wZW4ocy0+c3RhdHNfZmlsZV9zdHIsICJ3Iik7CiAgICAgICAgaWYgKCFzLT5zdGF0c19maWxlKSB7CiAgICAgICAgICAgIGludCBlcnIgPSBBVkVSUk9SKGVycm5vKTsKICAgICAgICAgICAgY2hhciBidWZbMTI4XTsKICAgICAgICAgICAgYXZfc3RyZXJyb3IoZXJyLCBidWYsIHNpemVvZihidWYpKTsKICAgICAgICAgICAgYXZfbG9nKGN0eCwgQVZfTE9HX0VSUk9SLCAiQ291bGQgbm90IG9wZW4gc3RhdHMgZmlsZSAlczogJXNcbiIsCiAgICAgICAgICAgICAgICAgICBzLT5zdGF0c19maWxlX3N0ciwgYnVmKTsKICAgICAgICAgICAgcmV0dXJuIGVycjsKICAgICAgICB9CiAgICB9CgogICAgcy0+ZGlucHV0LnByb2Nlc3MgPSBkb19wc25yOwogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgcXVlcnlfZm9ybWF0cyhBVkZpbHRlckNvbnRleHQgKmN0eCkKewogICAgc3RhdGljIGNvbnN0IGVudW0gUGl4ZWxGb3JtYXQgcGl4X2ZtdHNbXSA9IHsKICAgICAgICBBVl9QSVhfRk1UX0dSQVk4LCBBVl9QSVhfRk1UX0dSQVkxNiwKI2RlZmluZSBQRl9OT0FMUEhBKHN1ZikgQVZfUElYX0ZNVF9ZVVY0MjAjI3N1ZiwgIEFWX1BJWF9GTVRfWVVWNDIyIyNzdWYsICBBVl9QSVhfRk1UX1lVVjQ0NCMjc3VmCiNkZWZpbmUgUEZfQUxQSEEoc3VmKSAgIEFWX1BJWF9GTVRfWVVWQTQyMCMjc3VmLCBBVl9QSVhfRk1UX1lVVkE0MjIjI3N1ZiwgQVZfUElYX0ZNVF9ZVVZBNDQ0IyNzdWYKI2RlZmluZSBQRihzdWYpICAgICAgICAgUEZfTk9BTFBIQShzdWYpLCBQRl9BTFBIQShzdWYpCiAgICAgICAgUEYoUCksIFBGKFA5KSwgUEYoUDEwKSwgUEZfTk9BTFBIQShQMTIpLCBQRl9OT0FMUEhBKFAxNCksIFBGKFAxNiksCiAgICAgICAgQVZfUElYX0ZNVF9ZVVY0NDBQLCBBVl9QSVhfRk1UX1lVVjQxMVAsIEFWX1BJWF9GTVRfWVVWNDEwUCwKICAgICAgICBBVl9QSVhfRk1UX1lVVko0MTFQLCBBVl9QSVhfRk1UX1lVVko0MjBQLCBBVl9QSVhfRk1UX1lVVko0MjJQLAogICAgICAgIEFWX1BJWF9GTVRfWVVWSjQ0MFAsIEFWX1BJWF9GTVRfWVVWSjQ0NFAsCiAgICAgICAgQVZfUElYX0ZNVF9HQlJQLCBBVl9QSVhfRk1UX0dCUlA5LCBBVl9QSVhfRk1UX0dCUlAxMCwKICAgICAgICBBVl9QSVhfRk1UX0dCUlAxMiwgQVZfUElYX0ZNVF9HQlJQMTQsIEFWX1BJWF9GTVRfR0JSUDE2LAogICAgICAgIEFWX1BJWF9GTVRfR0JSQVAsIEFWX1BJWF9GTVRfR0JSQVAxNiwKICAgICAgICBBVl9QSVhfRk1UX05PTkUKICAgIH07CgogICAgZmZfc2V0X2NvbW1vbl9mb3JtYXRzKGN0eCwgZmZfbWFrZV9mb3JtYXRfbGlzdChwaXhfZm10cykpOwogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgY29uZmlnX2lucHV0X3JlZihBVkZpbHRlckxpbmsgKmlubGluaykKewogICAgY29uc3QgQVZQaXhGbXREZXNjcmlwdG9yICpkZXNjID0gYXZfcGl4X2ZtdF9kZXNjX2dldChpbmxpbmstPmZvcm1hdCk7CiAgICBBVkZpbHRlckNvbnRleHQgKmN0eCAgPSBpbmxpbmstPmRzdDsKICAgIFBTTlJDb250ZXh0ICpzID0gY3R4LT5wcml2OwogICAgaW50IGo7CgogICAgcy0+bmJfY29tcG9uZW50cyA9IGRlc2MtPm5iX2NvbXBvbmVudHM7CiAgICBpZiAoY3R4LT5pbnB1dHNbMF0tPncgIT0gY3R4LT5pbnB1dHNbMV0tPncgfHwKICAgICAgICBjdHgtPmlucHV0c1swXS0+aCAhPSBjdHgtPmlucHV0c1sxXS0+aCkgewogICAgICAgIGF2X2xvZyhjdHgsIEFWX0xPR19FUlJPUiwgIldpZHRoIGFuZCBoZWlnaHQgb2YgaW5wdXQgdmlkZW9zIG11c3QgYmUgc2FtZS5cbiIpOwogICAgICAgIHJldHVybiBBVkVSUk9SKEVJTlZBTCk7CiAgICB9CiAgICBpZiAoY3R4LT5pbnB1dHNbMF0tPmZvcm1hdCAhPSBjdHgtPmlucHV0c1sxXS0+Zm9ybWF0KSB7CiAgICAgICAgYXZfbG9nKGN0eCwgQVZfTE9HX0VSUk9SLCAiSW5wdXRzIG11c3QgYmUgb2Ygc2FtZSBwaXhlbCBmb3JtYXQuXG4iKTsKICAgICAgICByZXR1cm4gQVZFUlJPUihFSU5WQUwpOwogICAgfQoKICAgIHN3aXRjaCAoaW5saW5rLT5mb3JtYXQpIHsKICAgIGNhc2UgQVZfUElYX0ZNVF9HUkFZODoKICAgIGNhc2UgQVZfUElYX0ZNVF9HUkFZMTY6CiAgICBjYXNlIEFWX1BJWF9GTVRfR0JSUDoKICAgIGNhc2UgQVZfUElYX0ZNVF9HQlJQOToKICAgIGNhc2UgQVZfUElYX0ZNVF9HQlJQMTA6CiAgICBjYXNlIEFWX1BJWF9GTVRfR0JSUDEyOgogICAgY2FzZSBBVl9QSVhfRk1UX0dCUlAxNDoKICAgIGNhc2UgQVZfUElYX0ZNVF9HQlJQMTY6CiAgICBjYXNlIEFWX1BJWF9GTVRfR0JSQVA6CiAgICBjYXNlIEFWX1BJWF9GTVRfR0JSQVAxNjoKICAgIGNhc2UgQVZfUElYX0ZNVF9ZVVZKNDExUDoKICAgIGNhc2UgQVZfUElYX0ZNVF9ZVVZKNDIwUDoKICAgIGNhc2UgQVZfUElYX0ZNVF9ZVVZKNDIyUDoKICAgIGNhc2UgQVZfUElYX0ZNVF9ZVVZKNDQwUDoKICAgIGNhc2UgQVZfUElYX0ZNVF9ZVVZKNDQ0UDoKICAgICAgICBzLT5tYXhbMF0gPSAoMSA8PCAoZGVzYy0+Y29tcFswXS5kZXB0aF9taW51czEgKyAxKSkgLSAxOwogICAgICAgIHMtPm1heFsxXSA9ICgxIDw8IChkZXNjLT5jb21wWzFdLmRlcHRoX21pbnVzMSArIDEpKSAtIDE7CiAgICAgICAgcy0+bWF4WzJdID0gKDEgPDwgKGRlc2MtPmNvbXBbMl0uZGVwdGhfbWludXMxICsgMSkpIC0gMTsKICAgICAgICBzLT5tYXhbM10gPSAoMSA8PCAoZGVzYy0+Y29tcFszXS5kZXB0aF9taW51czEgKyAxKSkgLSAxOwogICAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgICBzLT5tYXhbMF0gPSAyMzUgKiAoMSA8PCAoZGVzYy0+Y29tcFswXS5kZXB0aF9taW51czEgLSA3KSk7CiAgICAgICAgcy0+bWF4WzFdID0gMjQwICogKDEgPDwgKGRlc2MtPmNvbXBbMV0uZGVwdGhfbWludXMxIC0gNykpOwogICAgICAgIHMtPm1heFsyXSA9IDI0MCAqICgxIDw8IChkZXNjLT5jb21wWzJdLmRlcHRoX21pbnVzMSAtIDcpKTsKICAgICAgICBzLT5tYXhbM10gPSAoMSA8PCAoZGVzYy0+Y29tcFszXS5kZXB0aF9taW51czEgKyAxKSkgLSAxOwogICAgfQoKICAgIHMtPmlzX3JnYiA9IGZmX2ZpbGxfcmdiYV9tYXAocy0+cmdiYV9tYXAsIGlubGluay0+Zm9ybWF0KSA+PSAwOwogICAgcy0+Y29tcHNbMF0gPSBzLT5pc19yZ2IgPyAncicgOiAneScgOwogICAgcy0+Y29tcHNbMV0gPSBzLT5pc19yZ2IgPyAnZycgOiAndScgOwogICAgcy0+Y29tcHNbMl0gPSBzLT5pc19yZ2IgPyAnYicgOiAndicgOwogICAgcy0+Y29tcHNbM10gPSAnYSc7CgogICAgZm9yIChqID0gMDsgaiA8IHMtPm5iX2NvbXBvbmVudHM7IGorKykKICAgICAgICBzLT5hdmVyYWdlX21heCArPSBzLT5tYXhbal07CiAgICBzLT5hdmVyYWdlX21heCAvPSBzLT5uYl9jb21wb25lbnRzOwoKICAgIHMtPnBsYW5laGVpZ2h0WzFdID0gcy0+cGxhbmVoZWlnaHRbMl0gPSBGRl9DRUlMX1JTSElGVChpbmxpbmstPmgsIGRlc2MtPmxvZzJfY2hyb21hX2gpOwogICAgcy0+cGxhbmVoZWlnaHRbMF0gPSBzLT5wbGFuZWhlaWdodFszXSA9IGlubGluay0+aDsKICAgIHMtPnBsYW5ld2lkdGhbMV0gID0gcy0+cGxhbmV3aWR0aFsyXSAgPSBGRl9DRUlMX1JTSElGVChpbmxpbmstPncsIGRlc2MtPmxvZzJfY2hyb21hX3cpOwogICAgcy0+cGxhbmV3aWR0aFswXSAgPSBzLT5wbGFuZXdpZHRoWzNdICA9IGlubGluay0+dzsKCiAgICBzLT5jb21wdXRlX21zZSA9IGRlc2MtPmNvbXBbMF0uZGVwdGhfbWludXMxID4gNyA/IGNvbXB1dGVfaW1hZ2VzX21zZV8xNmJpdCA6IGNvbXB1dGVfaW1hZ2VzX21zZTsKCiAgICByZXR1cm4gMDsKfQoKc3RhdGljIGludCBjb25maWdfb3V0cHV0KEFWRmlsdGVyTGluayAqb3V0bGluaykKewogICAgQVZGaWx0ZXJDb250ZXh0ICpjdHggPSBvdXRsaW5rLT5zcmM7CiAgICBQU05SQ29udGV4dCAqcyA9IGN0eC0+cHJpdjsKICAgIEFWRmlsdGVyTGluayAqbWFpbmxpbmsgPSBjdHgtPmlucHV0c1swXTsKICAgIGludCByZXQ7CgogICAgb3V0bGluay0+dyA9IG1haW5saW5rLT53OwogICAgb3V0bGluay0+aCA9IG1haW5saW5rLT5oOwogICAgb3V0bGluay0+dGltZV9iYXNlID0gbWFpbmxpbmstPnRpbWVfYmFzZTsKICAgIG91dGxpbmstPnNhbXBsZV9hc3BlY3RfcmF0aW8gPSBtYWlubGluay0+c2FtcGxlX2FzcGVjdF9yYXRpbzsKICAgIG91dGxpbmstPmZyYW1lX3JhdGUgPSBtYWlubGluay0+ZnJhbWVfcmF0ZTsKICAgIGlmICgocmV0ID0gZmZfZHVhbGlucHV0X2luaXQoY3R4LCAmcy0+ZGlucHV0KSkgPCAwKQogICAgICAgIHJldHVybiByZXQ7CgogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgZmlsdGVyX2ZyYW1lKEFWRmlsdGVyTGluayAqaW5saW5rLCBBVkZyYW1lICppbnBpY3JlZikKewogICAgUFNOUkNvbnRleHQgKnMgPSBpbmxpbmstPmRzdC0+cHJpdjsKICAgIHJldHVybiBmZl9kdWFsaW5wdXRfZmlsdGVyX2ZyYW1lKCZzLT5kaW5wdXQsIGlubGluaywgaW5waWNyZWYpOwp9CgpzdGF0aWMgaW50IHJlcXVlc3RfZnJhbWUoQVZGaWx0ZXJMaW5rICpvdXRsaW5rKQp7CiAgICBQU05SQ29udGV4dCAqcyA9IG91dGxpbmstPnNyYy0+cHJpdjsKICAgIHJldHVybiBmZl9kdWFsaW5wdXRfcmVxdWVzdF9mcmFtZSgmcy0+ZGlucHV0LCBvdXRsaW5rKTsKfQoKc3RhdGljIGF2X2NvbGQgdm9pZCB1bmluaXQoQVZGaWx0ZXJDb250ZXh0ICpjdHgpCnsKICAgIFBTTlJDb250ZXh0ICpzID0gY3R4LT5wcml2OwoKICAgIGlmIChzLT5uYl9mcmFtZXMgPiAwKSB7CiAgICAgICAgYXZfbG9nKGN0eCwgQVZfTE9HX0lORk8sICJQU05SIGF2ZXJhZ2U6JTAuMmYgbWluOiUwLjJmIG1heDolMC4yZlxuIiwKICAgICAgICAgICAgICAgZ2V0X3BzbnIocy0+bXNlLCBzLT5uYl9mcmFtZXMsIHMtPmF2ZXJhZ2VfbWF4KSwKICAgICAgICAgICAgICAgZ2V0X3BzbnIocy0+bWF4X21zZSwgMSwgcy0+YXZlcmFnZV9tYXgpLAogICAgICAgICAgICAgICBnZXRfcHNucihzLT5taW5fbXNlLCAxLCBzLT5hdmVyYWdlX21heCkpOwogICAgfQoKICAgIGZmX2R1YWxpbnB1dF91bmluaXQoJnMtPmRpbnB1dCk7CgogICAgaWYgKHMtPnN0YXRzX2ZpbGUpCiAgICAgICAgZmNsb3NlKHMtPnN0YXRzX2ZpbGUpOwp9CgpzdGF0aWMgY29uc3QgQVZGaWx0ZXJQYWQgcHNucl9pbnB1dHNbXSA9IHsKICAgIHsKICAgICAgICAubmFtZSAgICAgICAgID0gIm1haW4iLAogICAgICAgIC50eXBlICAgICAgICAgPSBBVk1FRElBX1RZUEVfVklERU8sCiAgICAgICAgLmZpbHRlcl9mcmFtZSA9IGZpbHRlcl9mcmFtZSwKICAgIH0sewogICAgICAgIC5uYW1lICAgICAgICAgPSAicmVmZXJlbmNlIiwKICAgICAgICAudHlwZSAgICAgICAgID0gQVZNRURJQV9UWVBFX1ZJREVPLAogICAgICAgIC5maWx0ZXJfZnJhbWUgPSBmaWx0ZXJfZnJhbWUsCiAgICAgICAgLmNvbmZpZ19wcm9wcyA9IGNvbmZpZ19pbnB1dF9yZWYsCiAgICB9LAogICAgeyBOVUxMIH0KfTsKCnN0YXRpYyBjb25zdCBBVkZpbHRlclBhZCBwc25yX291dHB1dHNbXSA9IHsKICAgIHsKICAgICAgICAubmFtZSAgICAgICAgICA9ICJkZWZhdWx0IiwKICAgICAgICAudHlwZSAgICAgICAgICA9IEFWTUVESUFfVFlQRV9WSURFTywKICAgICAgICAuY29uZmlnX3Byb3BzICA9IGNvbmZpZ19vdXRwdXQsCiAgICAgICAgLnJlcXVlc3RfZnJhbWUgPSByZXF1ZXN0X2ZyYW1lLAogICAgfSwKICAgIHsgTlVMTCB9Cn07CgpBVkZpbHRlciBmZl92Zl9wc25yID0gewogICAgLm5hbWUgICAgICAgICAgPSAicHNuciIsCiAgICAuZGVzY3JpcHRpb24gICA9IE5VTExfSUZfQ09ORklHX1NNQUxMKCJDYWxjdWxhdGUgdGhlIFBTTlIgYmV0d2VlbiB0d28gdmlkZW8gc3RyZWFtcy4iKSwKICAgIC5pbml0ICAgICAgICAgID0gaW5pdCwKICAgIC51bmluaXQgICAgICAgID0gdW5pbml0LAogICAgLnF1ZXJ5X2Zvcm1hdHMgPSBxdWVyeV9mb3JtYXRzLAogICAgLnByaXZfc2l6ZSAgICAgPSBzaXplb2YoUFNOUkNvbnRleHQpLAogICAgLnByaXZfY2xhc3MgICAgPSAmcHNucl9jbGFzcywKICAgIC5pbnB1dHMgICAgICAgID0gcHNucl9pbnB1dHMsCiAgICAub3V0cHV0cyAgICAgICA9IHBzbnJfb3V0cHV0cywKfTsK