LyogIAkJCURpcmVjdFNvdW5kCiAqCiAqIENvcHlyaWdodCAxOTk4IE1hcmN1cyBNZWlzc25lcgogKiBDb3B5cmlnaHQgMTk5OCBSb2IgUmlnZ3MKICogQ29weXJpZ2h0IDIwMDAtMjAwMiBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMsIEluYy4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAgMDIxMTEtMTMwNyAgVVNBCiAqLwoKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CiNpbmNsdWRlIDxtYXRoLmg+CS8qIEluc29tbmlhIC0gcG93KCkgZnVuY3Rpb24gKi8KCiNkZWZpbmUgTk9OQU1FTEVTU1NUUlVDVAojZGVmaW5lIE5PTkFNRUxFU1NVTklPTgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJtbXN5c3RlbS5oIgojaW5jbHVkZSAid2lucmVnLmgiCiNpbmNsdWRlICJ3aW50ZXJubC5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgojaW5jbHVkZSAiZHNvdW5kLmgiCiNpbmNsdWRlICJkc2RyaXZlci5oIgojaW5jbHVkZSAiZHNvdW5kX3ByaXZhdGUuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGRzb3VuZCk7Cgp2b2lkIERTT1VORF9SZWNhbGNWb2xQYW4oUERTVk9MVU1FUEFOIHZvbHBhbikKewoJZG91YmxlIHRlbXA7CglUUkFDRSgiKCVwKVxuIix2b2xwYW4pOwoKCVRSQUNFKCJWb2w9JWxkIFBhbj0lbGRcbiIsIHZvbHBhbi0+bFZvbHVtZSwgdm9scGFuLT5sUGFuKTsKCS8qIHRoZSBBbXBGYWN0b3JzIGFyZSBleHByZXNzZWQgaW4gMTYuMTYgZml4ZWQgcG9pbnQgKi8KCXZvbHBhbi0+ZHdWb2xBbXBGYWN0b3IgPSAoVUxPTkcpIChwb3coMi4wLCB2b2xwYW4tPmxWb2x1bWUgLyA2MDAuMCkgKiAweGZmZmYpOwoJLyogRklYTUU6IGR3UGFue0xlZnR8UmlnaHR9QW1wRmFjdG9yICovCgoJLyogRklYTUU6IHVzZSBjYWxjdWxhdGVkIHZvbCBhbmQgcGFuIGFtcGZhY3RvcnMgKi8KCXRlbXAgPSAoZG91YmxlKSAodm9scGFuLT5sVm9sdW1lIC0gKHZvbHBhbi0+bFBhbiA+IDAgPyB2b2xwYW4tPmxQYW4gOiAwKSk7Cgl2b2xwYW4tPmR3VG90YWxMZWZ0QW1wRmFjdG9yID0gKFVMT05HKSAocG93KDIuMCwgdGVtcCAvIDYwMC4wKSAqIDB4ZmZmZik7Cgl0ZW1wID0gKGRvdWJsZSkgKHZvbHBhbi0+bFZvbHVtZSArICh2b2xwYW4tPmxQYW4gPCAwID8gdm9scGFuLT5sUGFuIDogMCkpOwoJdm9scGFuLT5kd1RvdGFsUmlnaHRBbXBGYWN0b3IgPSAoVUxPTkcpIChwb3coMi4wLCB0ZW1wIC8gNjAwLjApICogMHhmZmZmKTsKCglUUkFDRSgibGVmdCA9ICVseCwgcmlnaHQgPSAlbHhcbiIsIHZvbHBhbi0+ZHdUb3RhbExlZnRBbXBGYWN0b3IsIHZvbHBhbi0+ZHdUb3RhbFJpZ2h0QW1wRmFjdG9yKTsKfQoKdm9pZCBEU09VTkRfQW1wRmFjdG9yVG9Wb2xQYW4oUERTVk9MVU1FUEFOIHZvbHBhbikKewogICAgZG91YmxlIGxlZnQscmlnaHQ7CiAgICBUUkFDRSgiKCVwKVxuIix2b2xwYW4pOwoKICAgIFRSQUNFKCJsZWZ0PSVseCwgcmlnaHQ9JWx4XG4iLHZvbHBhbi0+ZHdUb3RhbExlZnRBbXBGYWN0b3Isdm9scGFuLT5kd1RvdGFsUmlnaHRBbXBGYWN0b3IpOwogICAgaWYgKHZvbHBhbi0+ZHdUb3RhbExlZnRBbXBGYWN0b3I9PTApCiAgICAgICAgbGVmdD0tMTAwMDA7CiAgICBlbHNlCiAgICAgICAgbGVmdD02MDAgKiBsb2coKChkb3VibGUpdm9scGFuLT5kd1RvdGFsTGVmdEFtcEZhY3RvcikgLyAweGZmZmYpIC8gbG9nKDIpOwogICAgaWYgKHZvbHBhbi0+ZHdUb3RhbFJpZ2h0QW1wRmFjdG9yPT0wKQogICAgICAgIHJpZ2h0PS0xMDAwMDsKICAgIGVsc2UKICAgICAgICByaWdodD02MDAgKiBsb2coKChkb3VibGUpdm9scGFuLT5kd1RvdGFsUmlnaHRBbXBGYWN0b3IpIC8gMHhmZmZmKSAvIGxvZygyKTsKICAgIGlmIChsZWZ0PHJpZ2h0KQogICAgewogICAgICAgIHZvbHBhbi0+bFZvbHVtZT1yaWdodDsKICAgICAgICB2b2xwYW4tPmR3Vm9sQW1wRmFjdG9yPXZvbHBhbi0+ZHdUb3RhbFJpZ2h0QW1wRmFjdG9yOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHZvbHBhbi0+bFZvbHVtZT1sZWZ0OwogICAgICAgIHZvbHBhbi0+ZHdWb2xBbXBGYWN0b3I9dm9scGFuLT5kd1RvdGFsTGVmdEFtcEZhY3RvcjsKICAgIH0KICAgIGlmICh2b2xwYW4tPmxWb2x1bWUgPCAtMTAwMDApCiAgICAgICAgdm9scGFuLT5sVm9sdW1lPS0xMDAwMDsKICAgIHZvbHBhbi0+bFBhbj1yaWdodC1sZWZ0OwogICAgaWYgKHZvbHBhbi0+bFBhbiA8IC0xMDAwMCkKICAgICAgICB2b2xwYW4tPmxQYW49LTEwMDAwOwoKICAgIFRSQUNFKCJWb2w9JWxkIFBhbj0lbGRcbiIsIHZvbHBhbi0+bFZvbHVtZSwgdm9scGFuLT5sUGFuKTsKfQoKdm9pZCBEU09VTkRfUmVjYWxjRm9ybWF0KElEaXJlY3RTb3VuZEJ1ZmZlckltcGwgKmRzYikKewoJVFJBQ0UoIiglcClcbiIsZHNiKTsKCgkvKiBjYWxjdWxhdGUgdGhlIDEwbXMgd3JpdGUgbGVhZCAqLwoJZHNiLT53cml0ZWxlYWQgPSAoZHNiLT5mcmVxIC8gMTAwKSAqIGRzYi0+cHdmeC0+bkJsb2NrQWxpZ247Cn0KCnZvaWQgRFNPVU5EX0NoZWNrRXZlbnQoSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiLCBpbnQgbGVuKQp7CglpbnQJCQlpOwoJRFdPUkQJCQlvZmZzZXQ7CglMUERTQlBPU0lUSU9OTk9USUZZCWV2ZW50OwoJVFJBQ0UoIiglcCwlZClcbiIsZHNiLGxlbik7CgoJaWYgKGRzYi0+bnJvZm5vdGlmaWVzID09IDApCgkJcmV0dXJuOwoKCVRSQUNFKCIoJXApIGJ1ZmxlbiA9ICVsZCwgcGxheXBvcyA9ICVsZCwgbGVuID0gJWRcbiIsCgkJZHNiLCBkc2ItPmJ1ZmxlbiwgZHNiLT5wbGF5cG9zLCBsZW4pOwoJZm9yIChpID0gMDsgaSA8IGRzYi0+bnJvZm5vdGlmaWVzIDsgaSsrKSB7CgkJZXZlbnQgPSBkc2ItPm5vdGlmaWVzICsgaTsKCQlvZmZzZXQgPSBldmVudC0+ZHdPZmZzZXQ7CgkJVFJBQ0UoImNoZWNraW5nICVkLCBwb3NpdGlvbiAlbGQsIGV2ZW50ID0gJXBcbiIsCgkJCWksIG9mZnNldCwgZXZlbnQtPmhFdmVudE5vdGlmeSk7CgkJLyogRFNCUE5fT0ZGU0VUU1RPUCBoYXMgdG8gYmUgdGhlIGxhc3QgZWxlbWVudC4gU28gdGhpcyBpcyAqLwoJCS8qIE9LLiBbSW5zaWRlIERpcmVjdFgsIHAyNzRdICovCgkJLyogICovCgkJLyogVGhpcyBhbHNvIG1lYW5zIHdlIGNhbid0IHNvcnQgdGhlIGVudHJpZXMgYnkgb2Zmc2V0LCAqLwoJCS8qIGJlY2F1c2UgRFNCUE5fT0ZGU0VUU1RPUCA9PSAtMSAqLwoJCWlmIChvZmZzZXQgPT0gRFNCUE5fT0ZGU0VUU1RPUCkgewoJCQlpZiAoZHNiLT5zdGF0ZSA9PSBTVEFURV9TVE9QUEVEKSB7CgkJCQlTZXRFdmVudChldmVudC0+aEV2ZW50Tm90aWZ5KTsKCQkJCVRSQUNFKCJzaWduYWxsZWQgZXZlbnQgJXAgKCVkKVxuIiwgZXZlbnQtPmhFdmVudE5vdGlmeSwgaSk7CgkJCQlyZXR1cm47CgkJCX0gZWxzZQoJCQkJcmV0dXJuOwoJCX0KCQlpZiAoKGRzYi0+cGxheXBvcyArIGxlbikgPj0gZHNiLT5idWZsZW4pIHsKCQkJaWYgKChvZmZzZXQgPCAoKGRzYi0+cGxheXBvcyArIGxlbikgJSBkc2ItPmJ1ZmxlbikpIHx8CgkJCSAgICAob2Zmc2V0ID49IGRzYi0+cGxheXBvcykpIHsKCQkJCVRSQUNFKCJzaWduYWxsZWQgZXZlbnQgJXAgKCVkKVxuIiwgZXZlbnQtPmhFdmVudE5vdGlmeSwgaSk7CgkJCQlTZXRFdmVudChldmVudC0+aEV2ZW50Tm90aWZ5KTsKCQkJfQoJCX0gZWxzZSB7CgkJCWlmICgob2Zmc2V0ID49IGRzYi0+cGxheXBvcykgJiYgKG9mZnNldCA8IChkc2ItPnBsYXlwb3MgKyBsZW4pKSkgewoJCQkJVFJBQ0UoInNpZ25hbGxlZCBldmVudCAlcCAoJWQpXG4iLCBldmVudC0+aEV2ZW50Tm90aWZ5LCBpKTsKCQkJCVNldEV2ZW50KGV2ZW50LT5oRXZlbnROb3RpZnkpOwoJCQl9CgkJfQoJfQp9CgovKiBXQVYgZm9ybWF0IGluZm8gY2FuIGJlIGZvdW5kIGF0OgogKgogKiAgICBodHRwOi8vd3d3LmN3aS5ubC9mdHAvYXVkaW8vQXVkaW9Gb3JtYXRzLnBhcnQyCiAqICAgIGZ0cDovL2Z0cC5jd2kubmwvcHViL2F1ZGlvL1JJRkYtZm9ybWF0CiAqCiAqIEltcG9ydCBwb2ludHMgdG8gcmVtZW1iZXI6CiAqICAgIDgtYml0IFdBViBpcyB1bnNpZ25lZAogKiAgICAxNi1iaXQgV0FWIGlzIHNpZ25lZAogKi8KIC8qIFVzZSB0aGUgc2FtZSBmb3JtdWxhcyBhcyBwY21jb252ZXJ0ZXIuYyAqLwpzdGF0aWMgaW5saW5lIElOVDE2IGN2dFU4dG9TMTYoQllURSBiKQp7CiAgICByZXR1cm4gKHNob3J0KSgoYisoYiA8PCA4KSktMzI3NjgpOwp9CgpzdGF0aWMgaW5saW5lIEJZVEUgY3Z0UzE2dG9VOChJTlQxNiBzKQp7CiAgICByZXR1cm4gKHMgPj4gOCkgXiAodW5zaWduZWQgY2hhcikweDgwOwp9CgpzdGF0aWMgaW5saW5lIHZvaWQgY3BfZmllbGRzKGNvbnN0IElEaXJlY3RTb3VuZEJ1ZmZlckltcGwgKmRzYiwgQllURSAqaWJ1ZiwgQllURSAqb2J1ZiApCnsKICAgICAgICBJTlQgZmwsZnI7CgogICAgICAgIGlmIChkc2ItPnB3ZngtPndCaXRzUGVyU2FtcGxlID09IDgpICB7CiAgICAgICAgICAgICAgICBpZiAoZHNiLT5kc291bmQtPnB3ZngtPndCaXRzUGVyU2FtcGxlID09IDggJiYKICAgICAgICAgICAgICAgICAgICBkc2ItPmRzb3VuZC0+cHdmeC0+bkNoYW5uZWxzID09IGRzYi0+cHdmeC0+bkNoYW5uZWxzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIGF2b2lkIG5lZWRsZXNzIDgtPjE2LT44IGNvbnZlcnNpb24gKi8KICAgICAgICAgICAgICAgICAgICAgICAgKm9idWY9KmlidWY7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkc2ItPnB3ZngtPm5DaGFubmVscz09MikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKG9idWYrMSk9KihpYnVmKzEpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBmbCA9IGN2dFU4dG9TMTYoKmlidWYpOwogICAgICAgICAgICAgICAgZnIgPSAoZHNiLT5wd2Z4LT5uQ2hhbm5lbHM9PTIgPyBjdnRVOHRvUzE2KCooaWJ1ZiArIDEpKSA6IGZsKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZmwgPSAqKChJTlQxNiAqKWlidWYpOwogICAgICAgICAgICAgICAgZnIgPSAoZHNiLT5wd2Z4LT5uQ2hhbm5lbHM9PTIgPyAqKCgoSU5UMTYgKilpYnVmKSArIDEpICA6IGZsKTsKICAgICAgICB9CgogICAgICAgIGlmIChkc2ItPmRzb3VuZC0+cHdmeC0+bkNoYW5uZWxzID09IDIpIHsKICAgICAgICAgICAgICAgIGlmIChkc2ItPmRzb3VuZC0+cHdmeC0+d0JpdHNQZXJTYW1wbGUgPT0gOCkgewogICAgICAgICAgICAgICAgICAgICAgICAqb2J1ZiA9IGN2dFMxNnRvVTgoZmwpOwogICAgICAgICAgICAgICAgICAgICAgICAqKG9idWYgKyAxKSA9IGN2dFMxNnRvVTgoZnIpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoZHNiLT5kc291bmQtPnB3ZngtPndCaXRzUGVyU2FtcGxlID09IDE2KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICooKElOVDE2ICopb2J1ZikgPSBmbDsKICAgICAgICAgICAgICAgICAgICAgICAgKigoKElOVDE2ICopb2J1ZikgKyAxKSA9IGZyOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChkc2ItPmRzb3VuZC0+cHdmeC0+bkNoYW5uZWxzID09IDEpIHsKICAgICAgICAgICAgICAgIGZsID0gKGZsICsgZnIpID4+IDE7CiAgICAgICAgICAgICAgICBpZiAoZHNiLT5kc291bmQtPnB3ZngtPndCaXRzUGVyU2FtcGxlID09IDgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgKm9idWYgPSBjdnRTMTZ0b1U4KGZsKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGRzYi0+ZHNvdW5kLT5wd2Z4LT53Qml0c1BlclNhbXBsZSA9PSAxNikgewogICAgICAgICAgICAgICAgICAgICAgICAqKChJTlQxNiAqKW9idWYpID0gZmw7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICB9Cn0KCi8qIE5vdyB3aXRoIFBlcmZlY3RQaXRjaCAodG0pIHRlY2hub2xvZ3kgKi8Kc3RhdGljIElOVCBEU09VTkRfTWl4ZXJOb3JtKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwgKmRzYiwgQllURSAqYnVmLCBJTlQgbGVuKQp7CglJTlQJaSwgc2l6ZSwgaXBvcywgaWxlbjsKCUJZVEUJKmlicCwgKm9icDsKCUlOVAlpQWR2YW5jZSA9IGRzYi0+cHdmeC0+bkJsb2NrQWxpZ247CglJTlQJb0FkdmFuY2UgPSBkc2ItPmRzb3VuZC0+cHdmeC0+bkJsb2NrQWxpZ247CgoJaWJwID0gZHNiLT5idWZmZXItPm1lbW9yeSArIGRzYi0+YnVmX21peHBvczsKCW9icCA9IGJ1ZjsKCglUUkFDRSgiKCVwLCAlcCwgJXApLCBidWZfbWl4cG9zPSVsZFxuIiwgZHNiLCBpYnAsIG9icCwgZHNiLT5idWZfbWl4cG9zKTsKCS8qIENoZWNrIGZvciB0aGUgYmVzdCBjYXNlICovCglpZiAoKGRzYi0+ZnJlcSA9PSBkc2ItPmRzb3VuZC0+cHdmeC0+blNhbXBsZXNQZXJTZWMpICYmCgkgICAgKGRzYi0+cHdmeC0+d0JpdHNQZXJTYW1wbGUgPT0gZHNiLT5kc291bmQtPnB3ZngtPndCaXRzUGVyU2FtcGxlKSAmJgoJICAgIChkc2ItPnB3ZngtPm5DaGFubmVscyA9PSBkc2ItPmRzb3VuZC0+cHdmeC0+bkNoYW5uZWxzKSkgewoJICAgICAgICBJTlQgYnl0ZXNsZWZ0ID0gZHNiLT5idWZsZW4gLSBkc2ItPmJ1Zl9taXhwb3M7CgkJVFJBQ0UoIiglcCkgQmVzdCBjYXNlXG4iLCBkc2IpOwoJICAgIAlpZiAobGVuIDw9IGJ5dGVzbGVmdCApCgkJCUNvcHlNZW1vcnkob2JwLCBpYnAsIGxlbik7CgkJZWxzZSB7IC8qIHdyYXAgKi8KCQkJQ29weU1lbW9yeShvYnAsIGlicCwgYnl0ZXNsZWZ0KTsKCQkJQ29weU1lbW9yeShvYnAgKyBieXRlc2xlZnQsIGRzYi0+YnVmZmVyLT5tZW1vcnksIGxlbiAtIGJ5dGVzbGVmdCk7CgkJfQoJCXJldHVybiBsZW47Cgl9CgoJLyogQ2hlY2sgZm9yIHNhbWUgc2FtcGxlIHJhdGUgKi8KCWlmIChkc2ItPmZyZXEgPT0gZHNiLT5kc291bmQtPnB3ZngtPm5TYW1wbGVzUGVyU2VjKSB7CgkJVFJBQ0UoIiglcCkgU2FtZSBzYW1wbGUgcmF0ZSAlbGQgPSBwcmltYXJ5ICVsZFxuIiwgZHNiLAoJCQlkc2ItPmZyZXEsIGRzYi0+ZHNvdW5kLT5wd2Z4LT5uU2FtcGxlc1BlclNlYyk7CgkJaWxlbiA9IDA7CgkJZm9yIChpID0gMDsgaSA8IGxlbjsgaSArPSBvQWR2YW5jZSkgewoJCQljcF9maWVsZHMoZHNiLCBpYnAsIG9icCApOwoJCQlpYnAgKz0gaUFkdmFuY2U7CgkJCWlsZW4gKz0gaUFkdmFuY2U7CgkJCW9icCArPSBvQWR2YW5jZTsKCQkJaWYgKGlicCA+PSAoQllURSAqKShkc2ItPmJ1ZmZlci0+bWVtb3J5ICsgZHNiLT5idWZsZW4pKQoJCQkJaWJwID0gZHNiLT5idWZmZXItPm1lbW9yeTsJLyogd3JhcCAqLwoJCX0KCQlyZXR1cm4gKGlsZW4pOwoJfQoKCS8qIE1peCBpbiBkaWZmZXJlbnQgc2FtcGxlIHJhdGVzICovCgkvKiAqLwoJLyogTmV3IFBlcmZlY3RQaXRjaCh0bSkgVGVjaG5vbG9neSAoYykgMTk5OCBSb2IgUmlnZ3MgKi8KCS8qIFBhdGVudCBQZW5kaW5nIDotXSAqLwoKCS8qIFBhdGVudCBlbmhhbmNlbWVudHMgKGMpIDIwMDAgT3ZlIEvldmVuLAoJICogVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzIEluYy4gKi8KCgkvKiBGSVhNRSgiKCVwKSBBZGp1c3RpbmcgZnJlcXVlbmN5OiAlbGQgLT4gJWxkIChuZWVkIG9wdGltaXphdGlvbilcbiIsCgkgICBkc2IsIGRzYi0+ZnJlcSwgZHNiLT5kc291bmQtPnB3ZngtPm5TYW1wbGVzUGVyU2VjKTsgKi8KCglzaXplID0gbGVuIC8gb0FkdmFuY2U7CglpbGVuID0gMDsKCWlwb3MgPSBkc2ItPmJ1Zl9taXhwb3M7Cglmb3IgKGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CiAgICAgICAgICAgICAgICBjcF9maWVsZHMoZHNiLCAoZHNiLT5idWZmZXItPm1lbW9yeSArIGlwb3MpLCBvYnApOwoJCW9icCArPSBvQWR2YW5jZTsKCQlkc2ItPmZyZXFBY2MgKz0gZHNiLT5mcmVxQWRqdXN0OwoJCWlmIChkc2ItPmZyZXFBY2MgPj0gKDE8PERTT1VORF9GUkVRU0hJRlQpKSB7CgkJCVVMT05HIGFkdiA9IChkc2ItPmZyZXFBY2M+PkRTT1VORF9GUkVRU0hJRlQpICogaUFkdmFuY2U7CgkJCWRzYi0+ZnJlcUFjYyAmPSAoMTw8RFNPVU5EX0ZSRVFTSElGVCktMTsKCQkJaXBvcyArPSBhZHY7IGlsZW4gKz0gYWR2OwoJCQlpcG9zICU9IGRzYi0+YnVmbGVuOwoJCX0KCX0KCXJldHVybiBpbGVuOwp9CgpzdGF0aWMgdm9pZCBEU09VTkRfTWl4ZXJWb2woSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiLCBCWVRFICpidWYsIElOVCBsZW4pCnsKCUlOVAlpOwoJQllURQkqYnBjID0gYnVmOwoJSU5UMTYJKmJwcyA9IChJTlQxNiAqKSBidWY7CgoJVFJBQ0UoIiglcCwlcCwlZClcbiIsZHNiLGJ1ZixsZW4pOwoJVFJBQ0UoImxlZnQgPSAlbHgsIHJpZ2h0ID0gJWx4XG4iLCBkc2ItPmN2b2xwYW4uZHdUb3RhbExlZnRBbXBGYWN0b3IsIAoJCWRzYi0+Y3ZvbHBhbi5kd1RvdGFsUmlnaHRBbXBGYWN0b3IpOwoKCWlmICgoIShkc2ItPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfQ1RSTFBBTikgfHwgKGRzYi0+Y3ZvbHBhbi5sUGFuID09IDApKSAmJgoJICAgICghKGRzYi0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19DVFJMVk9MVU1FKSB8fCAoZHNiLT5jdm9scGFuLmxWb2x1bWUgPT0gMCkpICYmCgkgICAgIShkc2ItPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfQ1RSTDNEKSkKCQlyZXR1cm47CQkvKiBOb3RoaW5nIHRvIGRvICovCgoJLyogSWYgd2UgZW5kIHVwIHdpdGggc29tZSBib3pvIGNvZGVyIHVzaW5nIHBhbm5pbmcgb3IgM0Qgc291bmQgKi8KCS8qIHdpdGggYSBtb25vIHByaW1hcnkgYnVmZmVyLCBpdCBjb3VsZCBzb3VuZCB2ZXJ5IHdlaXJkIHVzaW5nICovCgkvKiB0aGlzIG1ldGhvZC4gT2ggd2VsbCwgdG91Z2ggcGF0b290aWVzLiAqLwoKCXN3aXRjaCAoZHNiLT5kc291bmQtPnB3ZngtPndCaXRzUGVyU2FtcGxlKSB7CgljYXNlIDg6CgkJLyogOC1iaXQgV0FWIGlzIHVuc2lnbmVkLCBidXQgd2UgbmVlZCB0byBvcGVyYXRlICovCgkJLyogb24gc2lnbmVkIGRhdGEgZm9yIHRoaXMgdG8gd29yayBwcm9wZXJseSAqLwoJCXN3aXRjaCAoZHNiLT5kc291bmQtPnB3ZngtPm5DaGFubmVscykgewoJCWNhc2UgMToKCQkJZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB7CgkJCQlJTlQgdmFsID0gKmJwYyAtIDEyODsKCQkJCXZhbCA9ICh2YWwgKiBkc2ItPmN2b2xwYW4uZHdUb3RhbExlZnRBbXBGYWN0b3IpID4+IDE2OwoJCQkJKmJwYyA9IHZhbCArIDEyODsKCQkJCWJwYysrOwoJCQl9CgkJCWJyZWFrOwoJCWNhc2UgMjoKCQkJZm9yIChpID0gMDsgaSA8IGxlbjsgaSs9MikgewoJCQkJSU5UIHZhbCA9ICpicGMgLSAxMjg7CgkJCQl2YWwgPSAodmFsICogZHNiLT5jdm9scGFuLmR3VG90YWxMZWZ0QW1wRmFjdG9yKSA+PiAxNjsKCQkJCSpicGMrKyA9IHZhbCArIDEyODsKCQkJCXZhbCA9ICpicGMgLSAxMjg7CgkJCQl2YWwgPSAodmFsICogZHNiLT5jdm9scGFuLmR3VG90YWxSaWdodEFtcEZhY3RvcikgPj4gMTY7CgkJCQkqYnBjID0gdmFsICsgMTI4OwoJCQkJYnBjKys7CgkJCX0KCQkJYnJlYWs7CgkJZGVmYXVsdDoKCQkJRklYTUUoImRvZXNuJ3Qgc3VwcG9ydCAlZCBjaGFubmVsc1xuIiwgZHNiLT5kc291bmQtPnB3ZngtPm5DaGFubmVscyk7CgkJCWJyZWFrOwoJCX0KCQlicmVhazsKCWNhc2UgMTY6CgkJLyogMTYtYml0IFdBViBpcyBzaWduZWQgLS0gbXVjaCBiZXR0ZXIgKi8KCQlzd2l0Y2ggKGRzYi0+ZHNvdW5kLT5wd2Z4LT5uQ2hhbm5lbHMpIHsKCQljYXNlIDE6CgkJCWZvciAoaSA9IDA7IGkgPCBsZW47IGkgKz0gMikgewoJCQkJKmJwcyA9ICgqYnBzICogZHNiLT5jdm9scGFuLmR3VG90YWxMZWZ0QW1wRmFjdG9yKSA+PiAxNjsKCQkJCWJwcysrOwoJCQl9CgkJCWJyZWFrOwoJCWNhc2UgMjoKCQkJZm9yIChpID0gMDsgaSA8IGxlbjsgaSArPSA0KSB7CgkJCQkqYnBzID0gKCpicHMgKiBkc2ItPmN2b2xwYW4uZHdUb3RhbExlZnRBbXBGYWN0b3IpID4+IDE2OwoJCQkJYnBzKys7CgkJCQkqYnBzID0gKCpicHMgKiBkc2ItPmN2b2xwYW4uZHdUb3RhbFJpZ2h0QW1wRmFjdG9yKSA+PiAxNjsKCQkJCWJwcysrOwoJCQl9CgkJCWJyZWFrOwoJCWRlZmF1bHQ6CgkJCUZJWE1FKCJkb2Vzbid0IHN1cHBvcnQgJWQgY2hhbm5lbHNcbiIsIGRzYi0+ZHNvdW5kLT5wd2Z4LT5uQ2hhbm5lbHMpOwoJCQlicmVhazsKCQl9CgkJYnJlYWs7CglkZWZhdWx0OgoJCUZJWE1FKCJkb2Vzbid0IHN1cHBvcnQgJWQgYml0IHNhbXBsZXNcbiIsIGRzYi0+ZHNvdW5kLT5wd2Z4LT53Qml0c1BlclNhbXBsZSk7CgkJYnJlYWs7Cgl9Cn0KCnN0YXRpYyBMUEJZVEUgRFNPVU5EX3RtcGJ1ZmZlcihJRGlyZWN0U291bmRJbXBsICpkc291bmQsIERXT1JEIGxlbikKewogICAgVFJBQ0UoIiglcCwlbGQpXG4iLGRzb3VuZCxsZW4pOwoKICAgIGlmIChsZW4gPiBkc291bmQtPnRtcF9idWZmZXJfbGVuKSB7CiAgICAgICAgaWYgKGRzb3VuZC0+dG1wX2J1ZmZlcikKICAgICAgICAgICAgZHNvdW5kLT50bXBfYnVmZmVyID0gSGVhcFJlQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZHNvdW5kLT50bXBfYnVmZmVyLCBsZW4pOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZHNvdW5kLT50bXBfYnVmZmVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGxlbik7CgogICAgICAgIGRzb3VuZC0+dG1wX2J1ZmZlcl9sZW4gPSBsZW47CiAgICB9CgogICAgcmV0dXJuIGRzb3VuZC0+dG1wX2J1ZmZlcjsKfQoKc3RhdGljIERXT1JEIERTT1VORF9NaXhJbkJ1ZmZlcihJRGlyZWN0U291bmRCdWZmZXJJbXBsICpkc2IsIERXT1JEIHdyaXRlcG9zLCBEV09SRCBmcmFnbGVuKQp7CglJTlQJaSwgbGVuLCBpbGVuLCBmaWVsZCwgdG9kbzsKCUJZVEUJKmJ1ZiwgKmlidWY7CgoJVFJBQ0UoIiglcCwlbGQsJWxkKVxuIixkc2Isd3JpdGVwb3MsZnJhZ2xlbik7CgoJbGVuID0gZnJhZ2xlbjsKCWlmICghKGRzYi0+cGxheWZsYWdzICYgRFNCUExBWV9MT09QSU5HKSkgewoJCUlOVCB0ZW1wID0gTXVsRGl2KGRzYi0+ZHNvdW5kLT5wd2Z4LT5uQXZnQnl0ZXNQZXJTZWMsIGRzYi0+YnVmbGVuLAoJCQlkc2ItPm5BdmdCeXRlc1BlclNlYykgLQoJCQlNdWxEaXYoZHNiLT5kc291bmQtPnB3ZngtPm5BdmdCeXRlc1BlclNlYywgZHNiLT5idWZfbWl4cG9zLAoJCQlkc2ItPm5BdmdCeXRlc1BlclNlYyk7CgkJbGVuID0gbWluKGxlbiwgdGVtcCk7Cgl9CgoJaWYgKGxlbiAlIGRzYi0+ZHNvdW5kLT5wd2Z4LT5uQmxvY2tBbGlnbikgewoJCUlOVCBuQmxvY2tBbGlnbiA9IGRzYi0+ZHNvdW5kLT5wd2Z4LT5uQmxvY2tBbGlnbjsKCQlsZW4gPSAobGVuIC8gbkJsb2NrQWxpZ24pICogbkJsb2NrQWxpZ247CS8qIGRhdGEgYWxpZ25tZW50ICovCgkJRVJSKCJsZW5ndGggbm90IGEgbXVsdGlwbGUgb2YgYmxvY2sgc2l6ZSwgbGVuID0gJWQsIGJsb2NrIHNpemUgPSAlZFxuIiwgbGVuLCBuQmxvY2tBbGlnbik7Cgl9CgoJaWYgKGxlbiA9PSAwKSB7CgkJLyogVGhpcyBzaG91bGQgb25seSBoYXBwZW4gaWYgd2UgYXJlbid0IGxvb3BpbmcgYW5kIHRlbXAgPCBuQmxvY2tBbGlnbiAqLwoJCXJldHVybiAwOwoJfQoKCWlmICgoYnVmID0gaWJ1ZiA9IERTT1VORF90bXBidWZmZXIoZHNiLT5kc291bmQsIGxlbikpID09IE5VTEwpCgkJcmV0dXJuIDA7CgoJVFJBQ0UoIk1peEluQnVmZmVyICglcCkgbGVuID0gJWQsIGRlc3QgPSAlbGRcbiIsIGRzYiwgbGVuLCB3cml0ZXBvcyk7CgoJaWxlbiA9IERTT1VORF9NaXhlck5vcm0oZHNiLCBpYnVmLCBsZW4pOwoJaWYgKChkc2ItPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfQ1RSTFBBTikgfHwKCSAgICAoZHNiLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX0NUUkxWT0xVTUUpIHx8CgkgICAgKGRzYi0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19DVFJMM0QpKQoJCURTT1VORF9NaXhlclZvbChkc2IsIGlidWYsIGxlbik7CgoJaWYgKGRzYi0+ZHNvdW5kLT5wd2Z4LT53Qml0c1BlclNhbXBsZSA9PSA4KSB7CgkJQllURQkqb2J1ZiA9IGRzYi0+ZHNvdW5kLT5idWZmZXIgKyB3cml0ZXBvczsKCgkJaWYgKCh3cml0ZXBvcyArIGxlbikgPD0gZHNiLT5kc291bmQtPmJ1ZmxlbikKCQkJdG9kbyA9IGxlbjsKCQllbHNlCgkJCXRvZG8gPSBkc2ItPmRzb3VuZC0+YnVmbGVuIC0gd3JpdGVwb3M7CgoJCWZvciAoaSA9IDA7IGkgPCB0b2RvOyBpKyspIHsKCQkJLyogOC1iaXQgV0FWIGlzIHVuc2lnbmVkICovCgkJCWZpZWxkID0gKCppYnVmKysgLSAxMjgpOwoJCQlmaWVsZCArPSAoKm9idWYgLSAxMjgpOwoJCQlpZiAoZmllbGQgPiAxMjcpIGZpZWxkID0gMTI3OwoJCQllbHNlIGlmIChmaWVsZCA8IC0xMjgpIGZpZWxkID0gLTEyODsKCQkJKm9idWYrKyA9IGZpZWxkICsgMTI4OwoJCX0KIAoJCWlmICh0b2RvIDwgbGVuKSB7CgkJCXRvZG8gPSBsZW4gLSB0b2RvOwoJCQlvYnVmID0gZHNiLT5kc291bmQtPmJ1ZmZlcjsKCgkJCWZvciAoaSA9IDA7IGkgPCB0b2RvOyBpKyspIHsKCQkJCS8qIDgtYml0IFdBViBpcyB1bnNpZ25lZCAqLwoJCQkJZmllbGQgPSAoKmlidWYrKyAtIDEyOCk7CgkJCQlmaWVsZCArPSAoKm9idWYgLSAxMjgpOwoJCQkJaWYgKGZpZWxkID4gMTI3KSBmaWVsZCA9IDEyNzsKCQkJCWVsc2UgaWYgKGZpZWxkIDwgLTEyOCkgZmllbGQgPSAtMTI4OwoJCQkJKm9idWYrKyA9IGZpZWxkICsgMTI4OwoJCQl9CgkJfQogICAgICAgIH0gZWxzZSB7CgkJSU5UMTYJKmlidWZzLCAqb2J1ZnM7CgoJCWlidWZzID0gKElOVDE2ICopIGlidWY7CgkJb2J1ZnMgPSAoSU5UMTYgKikoZHNiLT5kc291bmQtPmJ1ZmZlciArIHdyaXRlcG9zKTsKCgkJaWYgKCh3cml0ZXBvcyArIGxlbikgPD0gZHNiLT5kc291bmQtPmJ1ZmxlbikKCQkJdG9kbyA9IGxlbiAvIDI7CgkJZWxzZQoJCQl0b2RvID0gKGRzYi0+ZHNvdW5kLT5idWZsZW4gLSB3cml0ZXBvcykgLyAyOwoKCQlmb3IgKGkgPSAwOyBpIDwgdG9kbzsgaSsrKSB7CgkJCS8qIDE2LWJpdCBXQVYgaXMgc2lnbmVkICovCgkJCWZpZWxkID0gKmlidWZzKys7CgkJCWZpZWxkICs9ICpvYnVmczsKCQkJaWYgKGZpZWxkID4gMzI3NjcpIGZpZWxkID0gMzI3Njc7CgkJCWVsc2UgaWYgKGZpZWxkIDwgLTMyNzY4KSBmaWVsZCA9IC0zMjc2ODsKCQkJKm9idWZzKysgPSBmaWVsZDsKCQl9CgoJCWlmICh0b2RvIDwgKGxlbiAvIDIpKSB7CgkJCXRvZG8gPSAobGVuIC8gMikgLSB0b2RvOwoJCQlvYnVmcyA9IChJTlQxNiAqKWRzYi0+ZHNvdW5kLT5idWZmZXI7CgoJCQlmb3IgKGkgPSAwOyBpIDwgdG9kbzsgaSsrKSB7CgkJCQkvKiAxNi1iaXQgV0FWIGlzIHNpZ25lZCAqLwoJCQkJZmllbGQgPSAqaWJ1ZnMrKzsKCQkJCWZpZWxkICs9ICpvYnVmczsKCQkJCWlmIChmaWVsZCA+IDMyNzY3KSBmaWVsZCA9IDMyNzY3OwoJCQkJZWxzZSBpZiAoZmllbGQgPCAtMzI3NjgpIGZpZWxkID0gLTMyNzY4OwoJCQkJKm9idWZzKysgPSBmaWVsZDsKCQkJfQoJCX0KICAgICAgICB9CgoJaWYgKGRzYi0+bGVhZGluICYmIChkc2ItPnN0YXJ0cG9zID4gZHNiLT5idWZfbWl4cG9zKSAmJiAoZHNiLT5zdGFydHBvcyA8PSBkc2ItPmJ1Zl9taXhwb3MgKyBpbGVuKSkgewoJCS8qIEhBQ0suLi4gbGVhZGluIHNob3VsZCBiZSByZXNldCB3aGVuIHRoZSBQTEFZIHBvc2l0aW9uIHJlYWNoZXMgdGhlIHN0YXJ0cG9zLAoJCSAqIG5vdCB0aGUgTUlYIHBvc2l0aW9uLi4uIGJ1dCBpZiB0aGUgc291bmQgYnVmZmVyIGlzIGJpZ2dlciB0aGFuIG91ciBwcmVidWZmZXJpbmcKCQkgKiAod2hpY2ggbXVzdCBiZSB0aGUgY2FzZSBmb3IgdGhlIHN0cmVhbWluZyBidWZmZXJzIHRoYXQgbmVlZCB0aGlzIGhhY2sgYW55d2F5KQoJCSAqIHBsdXMgRFNfSEVMX01BUkdJTiBvciBlcXVpdmFsZW50LCB0aGVuIHRoaXMgb3VnaHQgdG8gd29yayBhbnl3YXkuICovCgkJZHNiLT5sZWFkaW4gPSBGQUxTRTsKCX0KCglkc2ItPmJ1Zl9taXhwb3MgKz0gaWxlbjsKCglpZiAoZHNiLT5idWZfbWl4cG9zID49IGRzYi0+YnVmbGVuKSB7CgkJaWYgKGRzYi0+cGxheWZsYWdzICYgRFNCUExBWV9MT09QSU5HKSB7CgkJCS8qIHdyYXAgKi8KCQkJZHNiLT5idWZfbWl4cG9zICU9IGRzYi0+YnVmbGVuOwoJCQlpZiAoZHNiLT5sZWFkaW4gJiYgKGRzYi0+c3RhcnRwb3MgPD0gZHNiLT5idWZfbWl4cG9zKSkKCQkJCWRzYi0+bGVhZGluID0gRkFMU0U7IC8qIEhBQ0s6IHNlZSBhYm92ZSAqLwoJCX0KCX0KCglyZXR1cm4gbGVuOwp9CgpzdGF0aWMgdm9pZCBEU09VTkRfUGhhc2VDYW5jZWwoSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiLCBEV09SRCB3cml0ZXBvcywgRFdPUkQgbGVuKQp7CglJTlQgICAgIGlsZW4sIGZpZWxkOwoJVUlOVCAgICBpLCB0b2RvOwoJQllURQkqYnVmLCAqaWJ1ZjsKCglUUkFDRSgiKCVwLCVsZCwlbGQpXG4iLGRzYix3cml0ZXBvcyxsZW4pOwoKCWlmIChsZW4gJSBkc2ItPmRzb3VuZC0+cHdmeC0+bkJsb2NrQWxpZ24pIHsKCQlJTlQgbkJsb2NrQWxpZ24gPSBkc2ItPmRzb3VuZC0+cHdmeC0+bkJsb2NrQWxpZ247CgkJbGVuID0gKGxlbiAvIG5CbG9ja0FsaWduKSAqIG5CbG9ja0FsaWduOwkvKiBkYXRhIGFsaWdubWVudCAqLwoJCUVSUigibGVuZ3RoIG5vdCBhIG11bHRpcGxlIG9mIGJsb2NrIHNpemUsIGxlbiA9ICVsZCwgYmxvY2sgc2l6ZSA9ICVkXG4iLCBsZW4sIG5CbG9ja0FsaWduKTsKCX0KCglpZiAoKGJ1ZiA9IGlidWYgPSBEU09VTkRfdG1wYnVmZmVyKGRzYi0+ZHNvdW5kLCBsZW4pKSA9PSBOVUxMKQoJCXJldHVybjsKCglUUkFDRSgiUGhhc2VDYW5jZWwgKCVwKSBsZW4gPSAlbGQsIGRlc3QgPSAlbGRcbiIsIGRzYiwgbGVuLCB3cml0ZXBvcyk7CgoJaWxlbiA9IERTT1VORF9NaXhlck5vcm0oZHNiLCBpYnVmLCBsZW4pOwoJaWYgKChkc2ItPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfQ1RSTFBBTikgfHwKCSAgICAoZHNiLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX0NUUkxWT0xVTUUpIHx8CgkgICAgKGRzYi0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19DVFJMM0QpKQoJCURTT1VORF9NaXhlclZvbChkc2IsIGlidWYsIGxlbik7CgoJLyogc3VidHJhY3QgaW5zdGVhZCBvZiBhZGQsIHRvIHBoYXNlIG91dCBwcmVtaXhlZCBkYXRhICovCglpZiAoZHNiLT5kc291bmQtPnB3ZngtPndCaXRzUGVyU2FtcGxlID09IDgpIHsKCQlCWVRFCSpvYnVmID0gZHNiLT5kc291bmQtPmJ1ZmZlciArIHdyaXRlcG9zOwoKCQlpZiAoKHdyaXRlcG9zICsgbGVuKSA8PSBkc2ItPmRzb3VuZC0+YnVmbGVuKQoJCQl0b2RvID0gbGVuOwoJCWVsc2UKCQkJdG9kbyA9IGRzYi0+ZHNvdW5kLT5idWZsZW4gLSB3cml0ZXBvczsKCgkJZm9yIChpID0gMDsgaSA8IHRvZG87IGkrKykgewoJCQkvKiA4LWJpdCBXQVYgaXMgdW5zaWduZWQgKi8KCQkJZmllbGQgPSAoKmlidWYrKyAtIDEyOCk7CgkJCWZpZWxkIC09ICgqb2J1ZiAtIDEyOCk7CgkJCWlmIChmaWVsZCA+IDEyNykgZmllbGQgPSAxMjc7CgkJCWVsc2UgaWYgKGZpZWxkIDwgLTEyOCkgZmllbGQgPSAtMTI4OwoJCQkqb2J1ZisrID0gZmllbGQgKyAxMjg7CgkJfQogCgkJaWYgKHRvZG8gPCBsZW4pIHsKCQkJdG9kbyA9IGxlbiAtIHRvZG87CgkJCW9idWYgPSBkc2ItPmRzb3VuZC0+YnVmZmVyOwoKCQkJZm9yIChpID0gMDsgaSA8IHRvZG87IGkrKykgewoJCQkJLyogOC1iaXQgV0FWIGlzIHVuc2lnbmVkICovCgkJCQlmaWVsZCA9ICgqaWJ1ZisrIC0gMTI4KTsKCQkJCWZpZWxkIC09ICgqb2J1ZiAtIDEyOCk7CgkJCQlpZiAoZmllbGQgPiAxMjcpIGZpZWxkID0gMTI3OwoJCQkJZWxzZSBpZiAoZmllbGQgPCAtMTI4KSBmaWVsZCA9IC0xMjg7CgkJCQkqb2J1ZisrID0gZmllbGQgKyAxMjg7CgkJCX0KCQl9CiAgICAgICAgfSBlbHNlIHsKCQlJTlQxNgkqaWJ1ZnMsICpvYnVmczsKCgkJaWJ1ZnMgPSAoSU5UMTYgKikgaWJ1ZjsKCQlvYnVmcyA9IChJTlQxNiAqKShkc2ItPmRzb3VuZC0+YnVmZmVyICsgd3JpdGVwb3MpOwoKCQlpZiAoKHdyaXRlcG9zICsgbGVuKSA8PSBkc2ItPmRzb3VuZC0+YnVmbGVuKQoJCQl0b2RvID0gbGVuIC8gMjsKCQllbHNlCgkJCXRvZG8gPSAoZHNiLT5kc291bmQtPmJ1ZmxlbiAtIHdyaXRlcG9zKSAvIDI7CgoJCWZvciAoaSA9IDA7IGkgPCB0b2RvOyBpKyspIHsKCQkJLyogMTYtYml0IFdBViBpcyBzaWduZWQgKi8KCQkJZmllbGQgPSAqaWJ1ZnMrKzsKCQkJZmllbGQgLT0gKm9idWZzOwoJCQlpZiAoZmllbGQgPiAzMjc2NykgZmllbGQgPSAzMjc2NzsKCQkJZWxzZSBpZiAoZmllbGQgPCAtMzI3NjgpIGZpZWxkID0gLTMyNzY4OwoJCQkqb2J1ZnMrKyA9IGZpZWxkOwoJCX0KCgkJaWYgKHRvZG8gPCAobGVuIC8gMikpIHsKCQkJdG9kbyA9IChsZW4gLyAyKSAtIHRvZG87CgkJCW9idWZzID0gKElOVDE2ICopZHNiLT5kc291bmQtPmJ1ZmZlcjsKCgkJCWZvciAoaSA9IDA7IGkgPCB0b2RvOyBpKyspIHsKCQkJCS8qIDE2LWJpdCBXQVYgaXMgc2lnbmVkICovCgkJCQlmaWVsZCA9ICppYnVmcysrOwoJCQkJZmllbGQgLT0gKm9idWZzOwoJCQkJaWYgKGZpZWxkID4gMzI3NjcpIGZpZWxkID0gMzI3Njc7CgkJCQllbHNlIGlmIChmaWVsZCA8IC0zMjc2OCkgZmllbGQgPSAtMzI3Njg7CgkJCQkqb2J1ZnMrKyA9IGZpZWxkOwoJCQl9CgkJfQogICAgICAgIH0KfQoKc3RhdGljIHZvaWQgRFNPVU5EX01peENhbmNlbChJRGlyZWN0U291bmRCdWZmZXJJbXBsICpkc2IsIERXT1JEIHdyaXRlcG9zLCBCT09MIGNhbmNlbCkKewoJRFdPUkQgICBzaXplLCBmbGVuLCBsZW4sIG5wb3MsIG5sZW47CglJTlQJaUFkdmFuY2UgPSBkc2ItPnB3ZngtPm5CbG9ja0FsaWduOwoJSU5UCW9BZHZhbmNlID0gZHNiLT5kc291bmQtPnB3ZngtPm5CbG9ja0FsaWduOwoJLyogZGV0ZXJtaW5lIGFtb3VudCBvZiBwcmVtaXhlZCBkYXRhIHRvIGNhbmNlbCAqLwoJRFdPUkQgcHJpbWFyeV9kb25lID0KCQkoKGRzYi0+cHJpbWFyeV9taXhwb3MgPCB3cml0ZXBvcykgPyBkc2ItPmRzb3VuZC0+YnVmbGVuIDogMCkgKwoJCWRzYi0+cHJpbWFyeV9taXhwb3MgLSB3cml0ZXBvczsKCglUUkFDRSgiKCVwLCAlbGQpLCBidWZfbWl4cG9zPSVsZFxuIiwgZHNiLCB3cml0ZXBvcywgZHNiLT5idWZfbWl4cG9zKTsKCgkvKiBiYWNrdHJhY2sgdGhlIG1peCBwb3NpdGlvbiAqLwoJc2l6ZSA9IHByaW1hcnlfZG9uZSAvIG9BZHZhbmNlOwoJZmxlbiA9IHNpemUgKiBkc2ItPmZyZXFBZGp1c3Q7CglsZW4gPSAoZmxlbiA+PiBEU09VTkRfRlJFUVNISUZUKSAqIGlBZHZhbmNlOwoJZmxlbiAmPSAoMTw8RFNPVU5EX0ZSRVFTSElGVCktMTsKCXdoaWxlIChkc2ItPmZyZXFBY2MgPCBmbGVuKSB7CgkJbGVuICs9IGlBZHZhbmNlOwoJCWRzYi0+ZnJlcUFjYyArPSAxPDxEU09VTkRfRlJFUVNISUZUOwoJfQoJbGVuICU9IGRzYi0+YnVmbGVuOwoJbnBvcyA9ICgoZHNiLT5idWZfbWl4cG9zIDwgbGVuKSA/IGRzYi0+YnVmbGVuIDogMCkgKwoJCWRzYi0+YnVmX21peHBvcyAtIGxlbjsKCWlmIChkc2ItPmxlYWRpbiAmJiAoZHNiLT5zdGFydHBvcyA+IG5wb3MpICYmIChkc2ItPnN0YXJ0cG9zIDw9IG5wb3MgKyBsZW4pKSB7CgkJLyogc3RvcCBiYWNrdHJhY2tpbmcgYXQgc3RhcnRwb3MgKi8KCQlucG9zID0gZHNiLT5zdGFydHBvczsKCQlsZW4gPSAoKGRzYi0+YnVmX21peHBvcyA8IG5wb3MpID8gZHNiLT5idWZsZW4gOiAwKSArCgkJCWRzYi0+YnVmX21peHBvcyAtIG5wb3M7CgkJZmxlbiA9IGRzYi0+ZnJlcUFjYzsKCQlubGVuID0gbGVuIC8gZHNiLT5wd2Z4LT5uQmxvY2tBbGlnbjsKCQlubGVuID0gKChubGVuIDw8IERTT1VORF9GUkVRU0hJRlQpICsgZmxlbikgLyBkc2ItPmZyZXFBZGp1c3Q7CgkJbmxlbiAqPSBkc2ItPmRzb3VuZC0+cHdmeC0+bkJsb2NrQWxpZ247CgkJd3JpdGVwb3MgPQoJCQkoKGRzYi0+cHJpbWFyeV9taXhwb3MgPCBubGVuKSA/IGRzYi0+ZHNvdW5kLT5idWZsZW4gOiAwKSArCgkJCWRzYi0+cHJpbWFyeV9taXhwb3MgLSBubGVuOwoJfQoKCWRzYi0+ZnJlcUFjYyAtPSBmbGVuOwoJZHNiLT5idWZfbWl4cG9zID0gbnBvczsKCWRzYi0+cHJpbWFyeV9taXhwb3MgPSB3cml0ZXBvczsKCglUUkFDRSgibmV3IGJ1Zl9taXhwb3M9JWxkLCBwcmltYXJ5X21peHBvcz0lbGQgKGxlbj0lbGQpXG4iLAoJICAgICAgZHNiLT5idWZfbWl4cG9zLCBkc2ItPnByaW1hcnlfbWl4cG9zLCBsZW4pOwoKCWlmIChjYW5jZWwpIERTT1VORF9QaGFzZUNhbmNlbChkc2IsIHdyaXRlcG9zLCBsZW4pOwp9Cgp2b2lkIERTT1VORF9NaXhDYW5jZWxBdChJRGlyZWN0U291bmRCdWZmZXJJbXBsICpkc2IsIERXT1JEIGJ1Zl93cml0ZXBvcykKewojaWYgMAoJRFdPUkQgICBpLCBzaXplLCBmbGVuLCBsZW4sIG5wb3MsIG5sZW47CglJTlQJaUFkdmFuY2UgPSBkc2ItPnB3ZngtPm5CbG9ja0FsaWduOwoJSU5UCW9BZHZhbmNlID0gZHNiLT5kc291bmQtPnB3ZngtPm5CbG9ja0FsaWduOwoJLyogZGV0ZXJtaW5lIGFtb3VudCBvZiBwcmVtaXhlZCBkYXRhIHRvIGNhbmNlbCAqLwoJRFdPUkQgYnVmX2RvbmUgPQoJCSgoZHNiLT5idWZfbWl4cG9zIDwgYnVmX3dyaXRlcG9zKSA/IGRzYi0+YnVmbGVuIDogMCkgKwoJCWRzYi0+YnVmX21peHBvcyAtIGJ1Zl93cml0ZXBvczsKI2VuZGlmCgoJV0FSTigiKCVwLCAlbGQpLCBidWZfbWl4cG9zPSVsZFxuIiwgZHNiLCBidWZfd3JpdGVwb3MsIGRzYi0+YnVmX21peHBvcyk7CgkvKiBzaW5jZSB0aGlzIGlzIG5vdCBpbXBsZW1lbnRlZCB5ZXQsIGp1c3QgY2FuY2VsICpBTEwqIHByZWJ1ZmZlcmluZyBmb3Igbm93CgkgKiAod2hpY2ggaXMgZmFzdGVyIGFueXdheSB3aGVuIHRoZXJlJ3Mgb25seSBhIHNpbmdsZSBzZWNvbmRhcnkgYnVmZmVyKSAqLwoJZHNiLT5kc291bmQtPm5lZWRfcmVtaXggPSBUUlVFOwp9Cgp2b2lkIERTT1VORF9Gb3JjZVJlbWl4KElEaXJlY3RTb3VuZEJ1ZmZlckltcGwgKmRzYikKewoJVFJBQ0UoIiglcClcbiIsZHNiKTsKCUVudGVyQ3JpdGljYWxTZWN0aW9uKCZkc2ItPmxvY2spOwoJaWYgKGRzYi0+c3RhdGUgPT0gU1RBVEVfUExBWUlORykgewojaWYgMCAvKiB0aGlzIG1heSBub3QgYmUgcXVpdGUgcmVsaWFibGUgeWV0ICovCgkJZHNiLT5uZWVkX3JlbWl4ID0gVFJVRTsKI2Vsc2UKCQlkc2ItPmRzb3VuZC0+bmVlZF9yZW1peCA9IFRSVUU7CiNlbmRpZgoJfQoJTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRzYi0+bG9jayk7Cn0KCnN0YXRpYyBEV09SRCBEU09VTkRfTWl4T25lKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwgKmRzYiwgRFdPUkQgcGxheXBvcywgRFdPUkQgd3JpdGVwb3MsIERXT1JEIG1peGxlbikKewoJRFdPUkQgbGVuLCBzbGVuOwoJLyogZGV0ZXJtaW5lIHRoaXMgYnVmZmVyJ3Mgd3JpdGUgcG9zaXRpb24gKi8KCURXT1JEIGJ1Zl93cml0ZXBvcyA9IERTT1VORF9DYWxjUGxheVBvc2l0aW9uKGRzYiwgZHNiLT5zdGF0ZSAmIGRzYi0+ZHNvdW5kLT5zdGF0ZSwgd3JpdGVwb3MsCgkJCQkJCSAgICAgd3JpdGVwb3MsIGRzYi0+cHJpbWFyeV9taXhwb3MsIGRzYi0+YnVmX21peHBvcyk7CgkvKiBkZXRlcm1pbmUgaG93IG11Y2ggYWxyZWFkeS1taXhlZCBkYXRhIGV4aXN0cyAqLwoJRFdPUkQgYnVmX2RvbmUgPQoJCSgoZHNiLT5idWZfbWl4cG9zIDwgYnVmX3dyaXRlcG9zKSA/IGRzYi0+YnVmbGVuIDogMCkgKwoJCWRzYi0+YnVmX21peHBvcyAtIGJ1Zl93cml0ZXBvczsKCURXT1JEIHByaW1hcnlfZG9uZSA9CgkJKChkc2ItPnByaW1hcnlfbWl4cG9zIDwgd3JpdGVwb3MpID8gZHNiLT5kc291bmQtPmJ1ZmxlbiA6IDApICsKCQlkc2ItPnByaW1hcnlfbWl4cG9zIC0gd3JpdGVwb3M7CglEV09SRCBhZHZfZG9uZSA9CgkJKChkc2ItPmRzb3VuZC0+bWl4cG9zIDwgd3JpdGVwb3MpID8gZHNiLT5kc291bmQtPmJ1ZmxlbiA6IDApICsKCQlkc2ItPmRzb3VuZC0+bWl4cG9zIC0gd3JpdGVwb3M7CglEV09SRCBwbGF5ZWQgPQoJCSgoYnVmX3dyaXRlcG9zIDwgZHNiLT5wbGF5cG9zKSA/IGRzYi0+YnVmbGVuIDogMCkgKwoJCWJ1Zl93cml0ZXBvcyAtIGRzYi0+cGxheXBvczsKCURXT1JEIGJ1Zl9sZWZ0ID0gZHNiLT5idWZsZW4gLSBidWZfd3JpdGVwb3M7CglpbnQgc3RpbGxfYmVoaW5kOwoKCVRSQUNFKCIoJXAsJWxkLCVsZCwlbGQpXG4iLGRzYixwbGF5cG9zLHdyaXRlcG9zLG1peGxlbik7CglUUkFDRSgiYnVmX3dyaXRlcG9zPSVsZCwgcHJpbWFyeV93cml0ZXBvcz0lbGRcbiIsIGJ1Zl93cml0ZXBvcywgd3JpdGVwb3MpOwoJVFJBQ0UoImJ1Zl9kb25lPSVsZCwgcHJpbWFyeV9kb25lPSVsZFxuIiwgYnVmX2RvbmUsIHByaW1hcnlfZG9uZSk7CglUUkFDRSgiYnVmX21peHBvcz0lbGQsIHByaW1hcnlfbWl4cG9zPSVsZCwgbWl4bGVuPSVsZFxuIiwgZHNiLT5idWZfbWl4cG9zLCBkc2ItPnByaW1hcnlfbWl4cG9zLAoJICAgICAgbWl4bGVuKTsKCVRSQUNFKCJsb29waW5nPSVsZCwgc3RhcnRwb3M9JWxkLCBsZWFkaW49JWxkXG4iLCBkc2ItPnBsYXlmbGFncywgZHNiLT5zdGFydHBvcywgZHNiLT5sZWFkaW4pOwoKCS8qIGNoZWNrIGZvciBub3RpZmljYXRpb24gcG9zaXRpb25zICovCglpZiAoZHNiLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX0NUUkxQT1NJVElPTk5PVElGWSAmJgoJICAgIGRzYi0+c3RhdGUgIT0gU1RBVEVfU1RBUlRJTkcpIHsKCQlEU09VTkRfQ2hlY2tFdmVudChkc2IsIHBsYXllZCk7Cgl9CgoJLyogc2F2ZSB3cml0ZSBwb3NpdGlvbiBmb3Igbm9uLUdFVENVUlJFTlRQT1NJVElPTjIuLi4gKi8KCWRzYi0+cGxheXBvcyA9IGJ1Zl93cml0ZXBvczsKCgkvKiBjaGVjayB3aGV0aGVyIENhbGNQbGF5UG9zaXRpb24gZGV0ZWN0ZWQgYSBtaXhpbmcgdW5kZXJydW4gKi8KCWlmICgoYnVmX2RvbmUgPT0gMCkgJiYgKGRzYi0+cHJpbWFyeV9taXhwb3MgIT0gd3JpdGVwb3MpKSB7CgkJLyogaXQgZGlkLCBidXQgZGlkIHdlIGhhdmUgbW9yZSB0byBwbGF5PyAqLwoJCWlmICgoZHNiLT5wbGF5ZmxhZ3MgJiBEU0JQTEFZX0xPT1BJTkcpIHx8CgkJICAgIChkc2ItPmJ1Zl9taXhwb3MgPCBkc2ItPmJ1ZmxlbikpIHsKCQkJLyogeWVzLCBoYXZlIHRvIHJlY292ZXIgKi8KCQkJRVJSKCJ1bmRlcnJ1biBvbiBzb3VuZCBidWZmZXIgJXBcbiIsIGRzYik7CgkJCVRSQUNFKCJyZWNvdmVyaW5nIGZyb20gdW5kZXJydW46IHByaW1hcnlfbWl4cG9zPSVsZFxuIiwgd3JpdGVwb3MpOwoJCX0KCQlkc2ItPnByaW1hcnlfbWl4cG9zID0gd3JpdGVwb3M7CgkJcHJpbWFyeV9kb25lID0gMDsKCX0KCS8qIGRldGVybWluZSBob3cgZmFyIGFoZWFkIHdlIHNob3VsZCBtaXggKi8KCWlmICgoKGRzYi0+cGxheWZsYWdzICYgRFNCUExBWV9MT09QSU5HKSB8fAoJICAgICAoZHNiLT5sZWFkaW4gJiYgKGRzYi0+cHJvYmFibHlfdmFsaWRfdG8gIT0gMCkpKSAmJgoJICAgICEoZHNiLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX1NUQVRJQykpIHsKCQkvKiBpZiB0aGlzIGlzIGEgc3RyZWFtaW5nIGJ1ZmZlciwgaXQgdHlwaWNhbGx5IG1lYW5zIHRoYXQKCQkgKiB3ZSBzaG91bGQgZGVmZXIgbWl4aW5nIHBhc3QgcHJvYmFibHlfdmFsaWRfdG8gYXMgbG9uZwoJCSAqIGFzIHdlIGNhbiwgdG8gYXZvaWQgdW5uZWNlc3NhcnkgcmVtaXhpbmcgKi8KCQkvKiB0aGUgaGVhdnktbG9va2luZyBjYWxjdWxhdGlvbnMgc2hvdWxkbid0IGJlIHRoYXQgYmFkLAoJCSAqIGFzIGFueSBnYW1lIGlzbid0IGxpa2VseSB0byBiZSBoYXZlIG1vcmUgdGhhbiAxIG9yIDIKCQkgKiBzdHJlYW1pbmcgYnVmZmVycyBpbiB1c2UgYXQgYW55IHRpbWUgYW55d2F5Li4uICovCgkJRFdPUkQgcHJvYmFibHlfdmFsaWRfbGVmdCA9CgkJCShkc2ItPnByb2JhYmx5X3ZhbGlkX3RvID09IChEV09SRCktMSkgPyBkc2ItPmJ1ZmxlbiA6CgkJCSgoZHNiLT5wcm9iYWJseV92YWxpZF90byA8IGJ1Zl93cml0ZXBvcykgPyBkc2ItPmJ1ZmxlbiA6IDApICsKCQkJZHNiLT5wcm9iYWJseV92YWxpZF90byAtIGJ1Zl93cml0ZXBvczsKCQkvKiBjaGVjayBmb3IgbGVhZGluIGNvbmRpdGlvbiAqLwoJCWlmICgocHJvYmFibHlfdmFsaWRfbGVmdCA9PSAwKSAmJgoJCSAgICAoZHNiLT5wcm9iYWJseV92YWxpZF90byA9PSBkc2ItPnN0YXJ0cG9zKSAmJgoJCSAgICBkc2ItPmxlYWRpbikKCQkJcHJvYmFibHlfdmFsaWRfbGVmdCA9IGRzYi0+YnVmbGVuOwoJCVRSQUNFKCJzdHJlYW1pbmcgYnVmZmVyIHByb2JhYmx5X3ZhbGlkX3RvPSVsZCwgcHJvYmFibHlfdmFsaWRfbGVmdD0lbGRcbiIsCgkJICAgICAgZHNiLT5wcm9iYWJseV92YWxpZF90bywgcHJvYmFibHlfdmFsaWRfbGVmdCk7CgkJLyogY2hlY2sgd2hldGhlciB0aGUgYXBwJ3MgdGltZSBpcyBhbHJlYWR5IHVwICovCgkJaWYgKHByb2JhYmx5X3ZhbGlkX2xlZnQgPCBkc2ItPndyaXRlbGVhZCkgewoJCQlXQVJOKCJwcm9iYWJseV92YWxpZF90byBub3cgd2l0aGluIHdyaXRlbGVhZCwgcG9zc2libGUgc3RyZWFtaW5nIHVuZGVycnVuXG4iKTsKCQkJLyogb25jZSB3ZSBwYXNzIHRoZSBwb2ludCBvZiBubyByZXR1cm4sCgkJCSAqIG5vIHJlYXNvbiB0byBob2xkIGJhY2sgYW55bW9yZSAqLwoJCQlkc2ItPnByb2JhYmx5X3ZhbGlkX3RvID0gKERXT1JEKS0xOwoJCQkvKiB3ZSBqdXN0IGhhdmUgdG8gZ28gYWhlYWQgYW5kIG1peCB3aGF0IHdlIGhhdmUsCgkJCSAqIHRoZXJlJ3Mgbm8gdGVsbGluZyB3aGF0IHRoZSBhcHAgaXMgdGhpbmtpbmcgYW55d2F5ICovCgkJfSBlbHNlIHsKCQkJLyogYWRqdXN0IGZvciBvdXIgZnJlcXVlbmN5IGFuZCBvdXIgc2FtcGxlIHNpemUgKi8KCQkJcHJvYmFibHlfdmFsaWRfbGVmdCA9IE11bERpdihwcm9iYWJseV92YWxpZF9sZWZ0LAoJCQkJCQkgICAgIDEgPDwgRFNPVU5EX0ZSRVFTSElGVCwKCQkJCQkJICAgICBkc2ItPnB3ZngtPm5CbG9ja0FsaWduICogZHNiLT5mcmVxQWRqdXN0KSAqCgkJCQkgICAgICAgICAgICAgIGRzYi0+ZHNvdW5kLT5wd2Z4LT5uQmxvY2tBbGlnbjsKCQkJLyogY2hlY2sgd2hldGhlciB0byBjbGlwIG1peF9sZW4gKi8KCQkJaWYgKHByb2JhYmx5X3ZhbGlkX2xlZnQgPCBtaXhsZW4pIHsKCQkJCVRSQUNFKCJjbGlwcGluZyB0byBwcm9iYWJseV92YWxpZF9sZWZ0PSVsZFxuIiwgcHJvYmFibHlfdmFsaWRfbGVmdCk7CgkJCQltaXhsZW4gPSBwcm9iYWJseV92YWxpZF9sZWZ0OwoJCQl9CgkJfQoJfQoJLyogY3V0IG1peGxlbiB3aXRoIHdoYXQncyBhbHJlYWR5IGJlZW4gbWl4ZWQgKi8KCWlmIChtaXhsZW4gPCBwcmltYXJ5X2RvbmUpIHsKCQkvKiBodWg/IGFuZCBzdGlsbCBDYWxjUGxheVBvc2l0aW9uIGRpZG4ndAoJCSAqIGRldGVjdCBhbiB1bmRlcnJ1bj8gKi8KCQlGSVhNRSgicHJvYmxlbSB3aXRoIHVuZGVycnVuIGRldGVjdGlvbiAobWl4bGVuPSVsZCA8IHByaW1hcnlfZG9uZT0lbGQpXG4iLCBtaXhsZW4sIHByaW1hcnlfZG9uZSk7CgkJcmV0dXJuIDA7Cgl9CglsZW4gPSBtaXhsZW4gLSBwcmltYXJ5X2RvbmU7CglUUkFDRSgicmVtYWluaW5nIG1peGxlbj0lbGRcbiIsIGxlbik7CgoJaWYgKGxlbiA8IGRzYi0+ZHNvdW5kLT5mcmFnbGVuKSB7CgkJLyogc21hbGxlciB0aGFuIGEgZnJhZ21lbnQsIHdhaXQgdW50aWwgaXQgZ2V0cyBsYXJnZXIKCQkgKiBiZWZvcmUgd2UgdGFrZSB0aGUgbWl4aW5nIG92ZXJoZWFkICovCgkJVFJBQ0UoIm1peGxlbiBub3Qgd29ydGggaXQsIGRlZmVycmluZyBtaXhpbmdcbiIpOwoJCXN0aWxsX2JlaGluZCA9IDE7CgkJZ290byBwb3N0X21peDsKCX0KCgkvKiBvaywgd2Uga25vdyBob3cgbXVjaCB0byBtaXgsIGxldCdzIGdvICovCglzdGlsbF9iZWhpbmQgPSAoYWR2X2RvbmUgPiBwcmltYXJ5X2RvbmUpOwoJd2hpbGUgKGxlbikgewoJCXNsZW4gPSBkc2ItPmRzb3VuZC0+YnVmbGVuIC0gZHNiLT5wcmltYXJ5X21peHBvczsKCQlpZiAoc2xlbiA+IGxlbikgc2xlbiA9IGxlbjsKCQlzbGVuID0gRFNPVU5EX01peEluQnVmZmVyKGRzYiwgZHNiLT5wcmltYXJ5X21peHBvcywgc2xlbik7CgoJCWlmICgoZHNiLT5wcmltYXJ5X21peHBvcyA8IGRzYi0+ZHNvdW5kLT5taXhwb3MpICYmCgkJICAgIChkc2ItPnByaW1hcnlfbWl4cG9zICsgc2xlbiA+PSBkc2ItPmRzb3VuZC0+bWl4cG9zKSkKCQkJc3RpbGxfYmVoaW5kID0gRkFMU0U7CgoJCWRzYi0+cHJpbWFyeV9taXhwb3MgKz0gc2xlbjsgbGVuIC09IHNsZW47CgkJZHNiLT5wcmltYXJ5X21peHBvcyAlPSBkc2ItPmRzb3VuZC0+YnVmbGVuOwoKCQlpZiAoKGRzYi0+c3RhdGUgPT0gU1RBVEVfU1RPUFBFRCkgfHwgIXNsZW4pIGJyZWFrOwoJfQoJVFJBQ0UoIm5ldyBwcmltYXJ5X21peHBvcz0lbGQsIHByaW1hcnlfYWR2YmFzZT0lbGRcbiIsIGRzYi0+cHJpbWFyeV9taXhwb3MsIGRzYi0+ZHNvdW5kLT5taXhwb3MpOwoJVFJBQ0UoIm1peGVkIGRhdGEgbGVuPSVsZCwgc3RpbGxfYmVoaW5kPSVkXG4iLCBtaXhsZW4tbGVuLCBzdGlsbF9iZWhpbmQpOwoKcG9zdF9taXg6CgkvKiBjaGVjayBpZiBidWZmZXIgc2hvdWxkIGJlIGNvbnNpZGVyZWQgY29tcGxldGUgKi8KCWlmIChidWZfbGVmdCA8IGRzYi0+d3JpdGVsZWFkICYmCgkgICAgIShkc2ItPnBsYXlmbGFncyAmIERTQlBMQVlfTE9PUElORykpIHsKCQlkc2ItPnN0YXRlID0gU1RBVEVfU1RPUFBFRDsKCQlkc2ItPnBsYXlwb3MgPSAwOwoJCWRzYi0+bGFzdF9wbGF5cG9zID0gMDsKCQlkc2ItPmJ1Zl9taXhwb3MgPSAwOwoJCWRzYi0+bGVhZGluID0gRkFMU0U7CgkJRFNPVU5EX0NoZWNrRXZlbnQoZHNiLCBidWZfbGVmdCk7Cgl9CgoJLyogcmV0dXJuIGhvdyBmYXIgd2UgdGhpbmsgdGhlIHByaW1hcnkgYnVmZmVyIGNhbgoJICogYWR2YW5jZSBpdHMgdW5kZXJydW4gZGV0ZWN0b3IuLi4qLwoJaWYgKHN0aWxsX2JlaGluZCkgcmV0dXJuIDA7CglpZiAoKG1peGxlbiAtIGxlbikgPCBwcmltYXJ5X2RvbmUpIHJldHVybiAwOwoJc2xlbiA9ICgoZHNiLT5wcmltYXJ5X21peHBvcyA8IGRzYi0+ZHNvdW5kLT5taXhwb3MpID8KCQlkc2ItPmRzb3VuZC0+YnVmbGVuIDogMCkgKyBkc2ItPnByaW1hcnlfbWl4cG9zIC0KCQlkc2ItPmRzb3VuZC0+bWl4cG9zOwoJaWYgKHNsZW4gPiBtaXhsZW4pIHsKCQkvKiB0aGUgcHJpbWFyeV9kb25lIGFuZCBzdGlsbF9iZWhpbmQgY2hlY2tzIGFib3ZlIHNob3VsZCBoYXZlIHdvcmtlZCAqLwoJCUZJWE1FKCJwcm9ibGVtIHdpdGggYWR2YW5jZW1lbnQgY2FsY3VsYXRpb24gKGFkdmxlbj0lbGQgPiBtaXhsZW49JWxkKVxuIiwgc2xlbiwgbWl4bGVuKTsKCQlzbGVuID0gMDsKCX0KCXJldHVybiBzbGVuOwp9CgpzdGF0aWMgRFdPUkQgRFNPVU5EX01peFRvUHJpbWFyeShJRGlyZWN0U291bmRJbXBsICpkc291bmQsIERXT1JEIHBsYXlwb3MsIERXT1JEIHdyaXRlcG9zLCBEV09SRCBtaXhsZW4sIEJPT0wgcmVjb3ZlcikKewoJSU5UCQkJaSwgbGVuLCBtYXhsZW4gPSAwOwoJSURpcmVjdFNvdW5kQnVmZmVySW1wbAkqZHNiOwoKCVRSQUNFKCIoJWxkLCVsZCwlbGQsJWQpXG4iLCBwbGF5cG9zLCB3cml0ZXBvcywgbWl4bGVuLCByZWNvdmVyKTsKCWZvciAoaSA9IDA7IGkgPCBkc291bmQtPm5yb2ZidWZmZXJzOyBpKyspIHsKCQlkc2IgPSBkc291bmQtPmJ1ZmZlcnNbaV07CgoJCWlmIChkc2ItPmJ1ZmxlbiAmJiBkc2ItPnN0YXRlICYmICFkc2ItPmh3YnVmKSB7CgkJCVRSQUNFKCJDaGVja2luZyAlcCwgbWl4bGVuPSVsZFxuIiwgZHNiLCBtaXhsZW4pOwoJCQlFbnRlckNyaXRpY2FsU2VjdGlvbigmKGRzYi0+bG9jaykpOwoJCQlpZiAoZHNiLT5zdGF0ZSA9PSBTVEFURV9TVE9QUElORykgewoJCQkJRFNPVU5EX01peENhbmNlbChkc2IsIHdyaXRlcG9zLCBUUlVFKTsKCQkJCWRzYi0+c3RhdGUgPSBTVEFURV9TVE9QUEVEOwoJCQkJRFNPVU5EX0NoZWNrRXZlbnQoZHNiLCAwKTsKCQkJfSBlbHNlIHsKCQkJCWlmICgoZHNiLT5zdGF0ZSA9PSBTVEFURV9TVEFSVElORykgfHwgcmVjb3ZlcikgewoJCQkJCWRzYi0+cHJpbWFyeV9taXhwb3MgPSB3cml0ZXBvczsKCQkJCQlkc2ItPmN2b2xwYW4gPSBkc2ItPnZvbHBhbjsKCQkJCQlkc2ItPm5lZWRfcmVtaXggPSBGQUxTRTsKCQkJCX0KCQkJCWVsc2UgaWYgKGRzYi0+bmVlZF9yZW1peCkgewoJCQkJCURTT1VORF9NaXhDYW5jZWwoZHNiLCB3cml0ZXBvcywgVFJVRSk7CgkJCQkJZHNiLT5jdm9scGFuID0gZHNiLT52b2xwYW47CgkJCQkJZHNiLT5uZWVkX3JlbWl4ID0gRkFMU0U7CgkJCQl9CgkJCQlsZW4gPSBEU09VTkRfTWl4T25lKGRzYiwgcGxheXBvcywgd3JpdGVwb3MsIG1peGxlbik7CgkJCQlpZiAoZHNiLT5zdGF0ZSA9PSBTVEFURV9TVEFSVElORykKCQkJCQlkc2ItPnN0YXRlID0gU1RBVEVfUExBWUlORzsKCQkJCW1heGxlbiA9IChsZW4gPiBtYXhsZW4pID8gbGVuIDogbWF4bGVuOwoJCQl9CgkJCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCYoZHNiLT5sb2NrKSk7CgkJfQoJfQoKCXJldHVybiBtYXhsZW47Cn0KCnN0YXRpYyB2b2lkIERTT1VORF9NaXhSZXNldChJRGlyZWN0U291bmRJbXBsICpkc291bmQsIERXT1JEIHdyaXRlcG9zKQp7CglJTlQJCQlpOwoJSURpcmVjdFNvdW5kQnVmZmVySW1wbAkqZHNiOwoJaW50IG5maWxsZXI7CgoJVFJBQ0UoIiglbGQpXG4iLCB3cml0ZXBvcyk7CgoJLyogdGhlIHNvdW5kIG9mIHNpbGVuY2UgKi8KCW5maWxsZXIgPSBkc291bmQtPnB3ZngtPndCaXRzUGVyU2FtcGxlID09IDggPyAxMjggOiAwOwoKCS8qIHJlc2V0IGFsbCBidWZmZXIgbWl4IHBvc2l0aW9ucyAqLwoJZm9yIChpID0gMDsgaSA8IGRzb3VuZC0+bnJvZmJ1ZmZlcnM7IGkrKykgewoJCWRzYiA9IGRzb3VuZC0+YnVmZmVyc1tpXTsKCgkJaWYgKGRzYi0+YnVmbGVuICYmIGRzYi0+c3RhdGUgJiYgIWRzYi0+aHdidWYpIHsKCQkJVFJBQ0UoIlJlc2V0dGluZyAlcFxuIiwgZHNiKTsKCQkJRW50ZXJDcml0aWNhbFNlY3Rpb24oJihkc2ItPmxvY2spKTsKCQkJaWYgKGRzYi0+c3RhdGUgPT0gU1RBVEVfU1RPUFBJTkcpIHsKCQkJCWRzYi0+c3RhdGUgPSBTVEFURV9TVE9QUEVEOwoJCQl9CgkJCWVsc2UgaWYgKGRzYi0+c3RhdGUgPT0gU1RBVEVfU1RBUlRJTkcpIHsKCQkJCS8qIG5vdGhpbmcgKi8KCQkJfSBlbHNlIHsKCQkJCURTT1VORF9NaXhDYW5jZWwoZHNiLCB3cml0ZXBvcywgRkFMU0UpOwoJCQkJZHNiLT5jdm9scGFuID0gZHNiLT52b2xwYW47CgkJCQlkc2ItPm5lZWRfcmVtaXggPSBGQUxTRTsKCQkJfQoJCQlMZWF2ZUNyaXRpY2FsU2VjdGlvbigmKGRzYi0+bG9jaykpOwoJCX0KCX0KCgkvKiB3aXBlIG91dCBwcmVtaXhlZCBkYXRhICovCglpZiAoZHNvdW5kLT5taXhwb3MgPCB3cml0ZXBvcykgewoJCUZpbGxNZW1vcnkoZHNvdW5kLT5idWZmZXIgKyB3cml0ZXBvcywgZHNvdW5kLT5idWZsZW4gLSB3cml0ZXBvcywgbmZpbGxlcik7CgkJRmlsbE1lbW9yeShkc291bmQtPmJ1ZmZlciwgZHNvdW5kLT5taXhwb3MsIG5maWxsZXIpOwoJfSBlbHNlIHsKCQlGaWxsTWVtb3J5KGRzb3VuZC0+YnVmZmVyICsgd3JpdGVwb3MsIGRzb3VuZC0+bWl4cG9zIC0gd3JpdGVwb3MsIG5maWxsZXIpOwoJfQoKCS8qIHJlc2V0IHByaW1hcnkgbWl4IHBvc2l0aW9uICovCglkc291bmQtPm1peHBvcyA9IHdyaXRlcG9zOwp9CgpzdGF0aWMgdm9pZCBEU09VTkRfQ2hlY2tSZXNldChJRGlyZWN0U291bmRJbXBsICpkc291bmQsIERXT1JEIHdyaXRlcG9zKQp7CglUUkFDRSgiKCVwLCVsZClcbiIsZHNvdW5kLHdyaXRlcG9zKTsKCWlmIChkc291bmQtPm5lZWRfcmVtaXgpIHsKCQlEU09VTkRfTWl4UmVzZXQoZHNvdW5kLCB3cml0ZXBvcyk7CgkJZHNvdW5kLT5uZWVkX3JlbWl4ID0gRkFMU0U7CgkJLyogbWF4aW1pemUgSGFsZi1MaWZlIHBlcmZvcm1hbmNlICovCgkJZHNvdW5kLT5wcmVidWYgPSBkc19zbmRfcXVldWVfbWluOwoJCWRzb3VuZC0+cHJlY291bnQgPSAwOwoJfSBlbHNlIHsKCQlkc291bmQtPnByZWNvdW50Kys7CgkJaWYgKGRzb3VuZC0+cHJlY291bnQgPj0gNCkgewoJCQlpZiAoZHNvdW5kLT5wcmVidWYgPCBkc19zbmRfcXVldWVfbWF4KQoJCQkJZHNvdW5kLT5wcmVidWYrKzsKCQkJZHNvdW5kLT5wcmVjb3VudCA9IDA7CgkJfQoJfQoJVFJBQ0UoInByZW1peCBhZGp1c3Q6ICVkXG4iLCBkc291bmQtPnByZWJ1Zik7Cn0KCnZvaWQgRFNPVU5EX1dhdmVRdWV1ZShJRGlyZWN0U291bmRJbXBsICpkc291bmQsIERXT1JEIG1peHEpCnsKCVRSQUNFKCIoJXAsJWxkKVxuIixkc291bmQsbWl4cSk7CglpZiAobWl4cSArIGRzb3VuZC0+cHdxdWV1ZSA+IGRzX2hlbF9xdWV1ZSkgbWl4cSA9IGRzX2hlbF9xdWV1ZSAtIGRzb3VuZC0+cHdxdWV1ZTsKCVRSQUNFKCJxdWV1ZWluZyAlbGQgYnVmZmVycywgc3RhcnRpbmcgYXQgJWRcbiIsIG1peHEsIGRzb3VuZC0+cHd3cml0ZSk7Cglmb3IgKDsgbWl4cTsgbWl4cS0tKSB7CgkJd2F2ZU91dFdyaXRlKGRzb3VuZC0+aHdvLCBkc291bmQtPnB3YXZlW2Rzb3VuZC0+cHd3cml0ZV0sIHNpemVvZihXQVZFSERSKSk7CgkJZHNvdW5kLT5wd3dyaXRlKys7CgkJaWYgKGRzb3VuZC0+cHd3cml0ZSA+PSBEU19IRUxfRlJBR1MpIGRzb3VuZC0+cHd3cml0ZSA9IDA7CgkJZHNvdW5kLT5wd3F1ZXVlKys7Cgl9Cn0KCi8qICNkZWZpbmUgU1lOQ19DQUxMQkFDSyAqLwoKdm9pZCBEU09VTkRfUGVyZm9ybU1peChJRGlyZWN0U291bmRJbXBsICpkc291bmQpCnsKCWludCBuZmlsbGVyOwoJQk9PTCBmb3JjZWQ7CglIUkVTVUxUIGhyZXM7CgoJVFJBQ0UoIiglcClcbiIsIGRzb3VuZCk7CgoJLyogdGhlIHNvdW5kIG9mIHNpbGVuY2UgKi8KCW5maWxsZXIgPSBkc291bmQtPnB3ZngtPndCaXRzUGVyU2FtcGxlID09IDggPyAxMjggOiAwOwoKCS8qIHdoZXRoZXIgdGhlIHByaW1hcnkgaXMgZm9yY2VkIHRvIHBsYXkgZXZlbiB3aXRob3V0IHNlY29uZGFyeSBidWZmZXJzICovCglmb3JjZWQgPSAoKGRzb3VuZC0+c3RhdGUgPT0gU1RBVEVfUExBWUlORykgfHwgKGRzb3VuZC0+c3RhdGUgPT0gU1RBVEVfU1RBUlRJTkcpKTsKCglpZiAoZHNvdW5kLT5wcmlvbGV2ZWwgIT0gRFNTQ0xfV1JJVEVQUklNQVJZKSB7CgkJQk9PTCBwYXVzZWQgPSAoKGRzb3VuZC0+c3RhdGUgPT0gU1RBVEVfU1RPUFBFRCkgfHwgKGRzb3VuZC0+c3RhdGUgPT0gU1RBVEVfU1RBUlRJTkcpKTsKCQkvKiBGSVhNRTogZG9jdW1lbnQgdmFyaWFibGVzICovCiAJCURXT1JEIHBsYXlwb3MsIHdyaXRlcG9zLCBpbnEsIG1heHEsIGZyYWc7CiAJCWlmIChkc291bmQtPmh3YnVmKSB7CgkJCWhyZXMgPSBJRHNEcml2ZXJCdWZmZXJfR2V0UG9zaXRpb24oZHNvdW5kLT5od2J1ZiwgJnBsYXlwb3MsICZ3cml0ZXBvcyk7CgkJCWlmIChocmVzKSB7CgkJCSAgICBXQVJOKCJJRHNEcml2ZXJCdWZmZXJfR2V0UG9zaXRpb24gZmFpbGVkXG4iKTsKCQkJICAgIHJldHVybjsKCQkJfQoJCQkvKiBXZWxsLCB3ZSAqY291bGQqIGRvIEp1c3QtSW4tVGltZSBtaXhpbmcgdXNpbmcgdGhlIHdyaXRlcG9zLAoJCQkgKiBidXQgdGhhdCdzIGEgbGl0dGxlIGJpdCBhbWJpdGlvdXMgYW5kIHVubmVjZXNzYXJ5Li4uICovCgkJCS8qIHJhdGhlciBhZGQgb3VyIHNhZmV0eSBtYXJnaW4gdG8gdGhlIHdyaXRlcG9zLCBpZiB3ZSdyZSBwbGF5aW5nICovCgkJCWlmICghcGF1c2VkKSB7CgkJCQl3cml0ZXBvcyArPSBkc291bmQtPndyaXRlbGVhZDsKCQkJCXdyaXRlcG9zICU9IGRzb3VuZC0+YnVmbGVuOwoJCQl9IGVsc2Ugd3JpdGVwb3MgPSBwbGF5cG9zOwoJCX0gZWxzZSB7CiAJCQlwbGF5cG9zID0gZHNvdW5kLT5wd3BsYXkgKiBkc291bmQtPmZyYWdsZW47CiAJCQl3cml0ZXBvcyA9IHBsYXlwb3M7CiAJCQlpZiAoIXBhdXNlZCkgewoJIAkJCXdyaXRlcG9zICs9IGRzX2hlbF9tYXJnaW4gKiBkc291bmQtPmZyYWdsZW47CiAJCQkJd3JpdGVwb3MgJT0gZHNvdW5kLT5idWZsZW47CgkgCQl9CgkJfQoJCVRSQUNFKCJwcmltYXJ5IHBsYXlwb3M9JWxkLCB3cml0ZXBvcz0lbGQsIGNscnBvcz0lbGQsIG1peHBvcz0lbGQsIGJ1Zmxlbj0lbGRcbiIsCgkJICAgICAgcGxheXBvcyx3cml0ZXBvcyxkc291bmQtPnBsYXlwb3MsZHNvdW5kLT5taXhwb3MsZHNvdW5kLT5idWZsZW4pOwoJCWFzc2VydChkc291bmQtPnBsYXlwb3MgPCBkc291bmQtPmJ1Zmxlbik7CgkJLyogd2lwZSBvdXQganVzdC1wbGF5ZWQgc291bmQgZGF0YSAqLwoJCWlmIChwbGF5cG9zIDwgZHNvdW5kLT5wbGF5cG9zKSB7CgkJCUZpbGxNZW1vcnkoZHNvdW5kLT5idWZmZXIgKyBkc291bmQtPnBsYXlwb3MsIGRzb3VuZC0+YnVmbGVuIC0gZHNvdW5kLT5wbGF5cG9zLCBuZmlsbGVyKTsKCQkJRmlsbE1lbW9yeShkc291bmQtPmJ1ZmZlciwgcGxheXBvcywgbmZpbGxlcik7CgkJfSBlbHNlIHsKCQkJRmlsbE1lbW9yeShkc291bmQtPmJ1ZmZlciArIGRzb3VuZC0+cGxheXBvcywgcGxheXBvcyAtIGRzb3VuZC0+cGxheXBvcywgbmZpbGxlcik7CgkJfQoJCWRzb3VuZC0+cGxheXBvcyA9IHBsYXlwb3M7CgoJCUVudGVyQ3JpdGljYWxTZWN0aW9uKCYoZHNvdW5kLT5taXhsb2NrKSk7CgoJCS8qIHJlc2V0IG1peGluZyBpZiBuZWNlc3NhcnkgKi8KCQlEU09VTkRfQ2hlY2tSZXNldChkc291bmQsIHdyaXRlcG9zKTsKCgkJLyogY2hlY2sgaG93IG11Y2ggcHJlYnVmZmVyaW5nIGlzIGxlZnQgKi8KCQlpbnEgPSBkc291bmQtPm1peHBvczsKCQlpZiAoaW5xIDwgd3JpdGVwb3MpCgkJCWlucSArPSBkc291bmQtPmJ1ZmxlbjsKCQlpbnEgLT0gd3JpdGVwb3M7CgoJCS8qIGZpbmQgdGhlIG1heGltdW0gd2UgY2FuIHByZWJ1ZmZlciAqLwoJCWlmICghcGF1c2VkKSB7CgkJCW1heHEgPSBwbGF5cG9zOwoJCQlpZiAobWF4cSA8IHdyaXRlcG9zKQoJCQkJbWF4cSArPSBkc291bmQtPmJ1ZmxlbjsKCQkJbWF4cSAtPSB3cml0ZXBvczsKCQl9IGVsc2UgbWF4cSA9IGRzb3VuZC0+YnVmbGVuOwoKCQkvKiBjbGlwIG1heHEgdG8gZHNvdW5kLT5wcmVidWYgKi8KCQlmcmFnID0gZHNvdW5kLT5wcmVidWYgKiBkc291bmQtPmZyYWdsZW47CgkJaWYgKG1heHEgPiBmcmFnKSBtYXhxID0gZnJhZzsKCgkJLyogY2hlY2sgZm9yIGNvbnNpc3RlbmN5ICovCgkJaWYgKGlucSA+IG1heHEpIHsKCQkJLyogdGhlIHBsYXliYWNrIHBvc2l0aW9uIG11c3QgaGF2ZSBwYXNzZWQgb3VyIGxhc3QKCQkJICogbWl4ZWQgcG9zaXRpb24sIGkuZS4gaXQncyBhbiB1bmRlcnJ1biwgb3Igd2UgaGF2ZQoJCQkgKiBub3RoaW5nIG1vcmUgdG8gcGxheSAqLwoJCQlUUkFDRSgicmVhY2hlZCBlbmQgb2YgbWl4ZWQgZGF0YSAoaW5xPSVsZCwgbWF4cT0lbGQpXG4iLCBpbnEsIG1heHEpOwoJCQlpbnEgPSAwOwoJCQkvKiBzdG9wIHRoZSBwbGF5YmFjayBub3csIHRvIGFsbG93IGJ1ZmZlcnMgdG8gcmVmaWxsICovCgkJCWlmIChkc291bmQtPnN0YXRlID09IFNUQVRFX1BMQVlJTkcpIHsKCQkJCWRzb3VuZC0+c3RhdGUgPSBTVEFURV9TVEFSVElORzsKCQkJfQoJCQllbHNlIGlmIChkc291bmQtPnN0YXRlID09IFNUQVRFX1NUT1BQSU5HKSB7CgkJCQlkc291bmQtPnN0YXRlID0gU1RBVEVfU1RPUFBFRDsKCQkJfQoJCQllbHNlIHsKCQkJCS8qIGhvdyBjYW4gd2UgaGF2ZSBhbiB1bmRlcnJ1biBpZiB3ZSBhcmVuJ3QgcGxheWluZz8gKi8KCQkJCVdBUk4oInVuZXhwZWN0ZWQgcHJpbWFyeSBzdGF0ZSAoJWxkKVxuIiwgZHNvdW5kLT5zdGF0ZSk7CgkJCX0KI2lmZGVmIFNZTkNfQ0FMTEJBQ0sKCQkJLyogRFNPVU5EX2NhbGxiYWNrIG1heSBuZWVkIHRoaXMgbG9jayAqLwoJCQlMZWF2ZUNyaXRpY2FsU2VjdGlvbigmKGRzb3VuZC0+bWl4bG9jaykpOwojZW5kaWYKCQkJaWYgKERTT1VORF9QcmltYXJ5U3RvcChkc291bmQpICE9IERTX09LKQoJCQkJV0FSTigiRFNPVU5EX1ByaW1hcnlTdG9wIGZhaWxlZFxuIik7CiNpZmRlZiBTWU5DX0NBTExCQUNLCgkJCUVudGVyQ3JpdGljYWxTZWN0aW9uKCYoZHNvdW5kLT5taXhsb2NrKSk7CiNlbmRpZgoJCQlpZiAoZHNvdW5kLT5od2J1ZikgewoJCQkJLyogdGhlIFN0b3AgaXMgc3VwcG9zZWQgdG8gcmVzZXQgcGxheSBwb3NpdGlvbiB0byBiZWdpbm5pbmcgb2YgYnVmZmVyICovCgkJCQkvKiB1bmZvcnR1bmF0ZWx5LCBPU1MgaXMgbm90IGFibGUgdG8gZG8gc28sIHNvIGdldCBjdXJyZW50IHBvaW50ZXIgKi8KCQkJCWhyZXMgPSBJRHNEcml2ZXJCdWZmZXJfR2V0UG9zaXRpb24oZHNvdW5kLT5od2J1ZiwgJnBsYXlwb3MsIE5VTEwpOwoJCQkJaWYgKGhyZXMpIHsKCQkJCQlMZWF2ZUNyaXRpY2FsU2VjdGlvbigmKGRzb3VuZC0+bWl4bG9jaykpOwoJCQkJCVdBUk4oIklEc0RyaXZlckJ1ZmZlcl9HZXRQb3NpdGlvbiBmYWlsZWRcbiIpOwoJCQkJCXJldHVybjsKCQkJCX0KCQkJfSBlbHNlIHsKCSAJCQlwbGF5cG9zID0gZHNvdW5kLT5wd3BsYXkgKiBkc291bmQtPmZyYWdsZW47CgkJCX0KCQkJd3JpdGVwb3MgPSBwbGF5cG9zOwoJCQlkc291bmQtPnBsYXlwb3MgPSBwbGF5cG9zOwoJCQlkc291bmQtPm1peHBvcyA9IHdyaXRlcG9zOwoJCQlpbnEgPSAwOwoJCQltYXhxID0gZHNvdW5kLT5idWZsZW47CgkJCWlmIChtYXhxID4gZnJhZykgbWF4cSA9IGZyYWc7CgkJCUZpbGxNZW1vcnkoZHNvdW5kLT5idWZmZXIsIGRzb3VuZC0+YnVmbGVuLCBuZmlsbGVyKTsKCQkJcGF1c2VkID0gVFJVRTsKCQl9CgoJCS8qIGRvIHRoZSBtaXhpbmcgKi8KCQlmcmFnID0gRFNPVU5EX01peFRvUHJpbWFyeShkc291bmQsIHBsYXlwb3MsIHdyaXRlcG9zLCBtYXhxLCBwYXVzZWQpOwoJCWlmIChmb3JjZWQpIGZyYWcgPSBtYXhxIC0gaW5xOwoJCWRzb3VuZC0+bWl4cG9zICs9IGZyYWc7CgkJZHNvdW5kLT5taXhwb3MgJT0gZHNvdW5kLT5idWZsZW47CgoJCWlmIChmcmFnKSB7CgkJCS8qIGJ1ZmZlcnMgaGF2ZSBiZWVuIGZpbGxlZCwgcmVzdGFydCBwbGF5YmFjayAqLwoJCQlpZiAoZHNvdW5kLT5zdGF0ZSA9PSBTVEFURV9TVEFSVElORykgewoJCQkJZHNvdW5kLT5zdGF0ZSA9IFNUQVRFX1BMQVlJTkc7CgkJCX0KCQkJZWxzZSBpZiAoZHNvdW5kLT5zdGF0ZSA9PSBTVEFURV9TVE9QUEVEKSB7CgkJCQkvKiB0aGUgZHNvdW5kIGlzIHN1cHBvc2VkIHRvIHBsYXkgaWYgdGhlcmUncyBzb21ldGhpbmcgdG8gcGxheQoJCQkJICogZXZlbiBpZiBpdCBpcyByZXBvcnRlZCBhcyBzdG9wcGVkLCBzbyBkb24ndCBsZXQgdGhpcyBjb25mdXNlIHlvdSAqLwoJCQkJZHNvdW5kLT5zdGF0ZSA9IFNUQVRFX1NUT1BQSU5HOwoJCQl9CgkJCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCYoZHNvdW5kLT5taXhsb2NrKSk7CgkJCWlmIChwYXVzZWQpIHsKCQkJCWlmIChEU09VTkRfUHJpbWFyeVBsYXkoZHNvdW5kKSAhPSBEU19PSykKCQkJCQlXQVJOKCJEU09VTkRfUHJpbWFyeVBsYXkgZmFpbGVkXG4iKTsKCQkJCWVsc2UKCQkJCQlUUkFDRSgic3RhcnRpbmcgcGxheWJhY2tcbiIpOwoJCQl9CgkJfQoJCWVsc2UKCQkJTGVhdmVDcml0aWNhbFNlY3Rpb24oJihkc291bmQtPm1peGxvY2spKTsKCX0gZWxzZSB7CgkJLyogaW4gdGhlIERTU0NMX1dSSVRFUFJJTUFSWSBtb2RlLCB0aGUgYXBwIGlzIHRvdGFsbHkgaW4gY2hhcmdlLi4uICovCgkJaWYgKGRzb3VuZC0+c3RhdGUgPT0gU1RBVEVfU1RBUlRJTkcpIHsKCQkJaWYgKERTT1VORF9QcmltYXJ5UGxheShkc291bmQpICE9IERTX09LKQoJCQkJV0FSTigiRFNPVU5EX1ByaW1hcnlQbGF5IGZhaWxlZFxuIik7CgkJCWVsc2UKCQkJCWRzb3VuZC0+c3RhdGUgPSBTVEFURV9QTEFZSU5HOwoJCX0KCQllbHNlIGlmIChkc291bmQtPnN0YXRlID09IFNUQVRFX1NUT1BQSU5HKSB7CgkJCWlmIChEU09VTkRfUHJpbWFyeVN0b3AoZHNvdW5kKSAhPSBEU19PSykKCQkJCVdBUk4oIkRTT1VORF9QcmltYXJ5U3RvcCBmYWlsZWRcbiIpOwoJCQllbHNlCgkJCQlkc291bmQtPnN0YXRlID0gU1RBVEVfU1RPUFBFRDsKCQl9Cgl9Cn0KCnZvaWQgQ0FMTEJBQ0sgRFNPVU5EX3RpbWVyKFVJTlQgdGltZXJJRCwgVUlOVCBtc2csIERXT1JEIGR3VXNlciwgRFdPUkQgZHcxLCBEV09SRCBkdzIpCnsKICAgICAgICBJRGlyZWN0U291bmRJbXBsKiBUaGlzID0gKElEaXJlY3RTb3VuZEltcGwqKWR3VXNlcjsKCURXT1JEIHN0YXJ0X3RpbWUgPSAgR2V0VGlja0NvdW50KCk7CiAgICAgICAgRFdPUkQgZW5kX3RpbWU7CglUUkFDRSgiKCVkLCVkLDB4JWx4LDB4JWx4LDB4JWx4KVxuIix0aW1lcklELG1zZyxkd1VzZXIsZHcxLGR3Mik7CiAgICAgICAgVFJBQ0UoImVudGVyaW5nIGF0ICVsZFxuIiwgc3RhcnRfdGltZSk7CgoJaWYgKERTT1VORF9yZW5kZXJlciAhPSBUaGlzKSB7CgkJRVJSKCJkc291bmQgZGllZCB3aXRob3V0IGtpbGxpbmcgdXM/XG4iKTsKCQl0aW1lS2lsbEV2ZW50KHRpbWVySUQpOwoJCXRpbWVFbmRQZXJpb2QoRFNfVElNRV9SRVMpOwoJCXJldHVybjsKCX0KCglSdGxBY3F1aXJlUmVzb3VyY2VTaGFyZWQoJihUaGlzLT5idWZmZXJfbGlzdF9sb2NrKSwgVFJVRSk7CgoJaWYgKFRoaXMtPnJlZikKCQlEU09VTkRfUGVyZm9ybU1peChUaGlzKTsKCglSdGxSZWxlYXNlUmVzb3VyY2UoJihUaGlzLT5idWZmZXJfbGlzdF9sb2NrKSk7CgoJZW5kX3RpbWUgPSBHZXRUaWNrQ291bnQoKTsKCVRSQUNFKCJjb21wbGV0ZWQgcHJvY2Vzc2luZyBhdCAlbGQsIGR1cmF0aW9uID0gJWxkXG4iLCBlbmRfdGltZSwgZW5kX3RpbWUgLSBzdGFydF90aW1lKTsKfQoKdm9pZCBDQUxMQkFDSyBEU09VTkRfY2FsbGJhY2soSFdBVkVPVVQgaHdvLCBVSU5UIG1zZywgRFdPUkQgZHdVc2VyLCBEV09SRCBkdzEsIERXT1JEIGR3MikKewogICAgICAgIElEaXJlY3RTb3VuZEltcGwqIFRoaXMgPSAoSURpcmVjdFNvdW5kSW1wbCopZHdVc2VyOwoJVFJBQ0UoIiglcCwleCwlbHgsJWx4LCVseClcbiIsaHdvLG1zZyxkd1VzZXIsZHcxLGR3Mik7CglUUkFDRSgiZW50ZXJpbmcgYXQgJWxkLCBtc2c9JTA4eCglcylcbiIsIEdldFRpY2tDb3VudCgpLCBtc2csIAoJCW1zZz09TU1fV09NX0RPTkUgPyAiTU1fV09NX0RPTkUiIDogbXNnPT1NTV9XT01fQ0xPU0UgPyAiTU1fV09NX0NMT1NFIiA6IAoJCW1zZz09TU1fV09NX09QRU4gPyAiTU1fV09NX09QRU4iIDogIlVOS05PV04iKTsKCWlmIChtc2cgPT0gTU1fV09NX0RPTkUpIHsKCQlEV09SRCBpbnEsIG1peHEsIGZyYWdsZW4sIGJ1ZmxlbiwgcHdwbGF5LCBwbGF5cG9zLCBtaXhwb3M7CgkJaWYgKFRoaXMtPnB3cXVldWUgPT0gKERXT1JEKS0xKSB7CgkJCVRSQUNFKCJjb21wbGV0ZWQgZHVlIHRvIHJlc2V0XG4iKTsKCQkJcmV0dXJuOwoJCX0KLyogaXQgY291bGQgYmUgYSBiYWQgaWRlYSB0byBlbnRlciBjcml0aWNhbCBzZWN0aW9uIGhlcmUuLi4gaWYgdGhlcmUncyBsb2NrIGNvbnRlbnRpb24sCiAqIHRoZSByZXN1bHRpbmcgc2NoZWR1bGluZyBkZWxheXMgbWlnaHQgb2JzdHJ1Y3QgdGhlIHdpbm1tIHBsYXllciB0aHJlYWQgKi8KI2lmZGVmIFNZTkNfQ0FMTEJBQ0sKCQlFbnRlckNyaXRpY2FsU2VjdGlvbigmKFRoaXMtPm1peGxvY2spKTsKI2VuZGlmCgkJLyogcmV0cmlldmUgY3VycmVudCB2YWx1ZXMgKi8KCQlmcmFnbGVuID0gVGhpcy0+ZnJhZ2xlbjsKCQlidWZsZW4gPSBUaGlzLT5idWZsZW47CgkJcHdwbGF5ID0gVGhpcy0+cHdwbGF5OwoJCXBsYXlwb3MgPSBwd3BsYXkgKiBmcmFnbGVuOwoJCW1peHBvcyA9IFRoaXMtPm1peHBvczsKCQkvKiBjaGVjayByZW1haW5pbmcgbWl4ZWQgZGF0YSAqLwoJCWlucSA9ICgobWl4cG9zIDwgcGxheXBvcykgPyBidWZsZW4gOiAwKSArIG1peHBvcyAtIHBsYXlwb3M7CgkJbWl4cSA9IGlucSAvIGZyYWdsZW47CgkJaWYgKChpbnEgLSAobWl4cSAqIGZyYWdsZW4pKSA+IDApIG1peHErKzsKCQkvKiBjb21wbGV0ZSB0aGUgcGxheWluZyBidWZmZXIgKi8KCQlUUkFDRSgiZG9uZSBwbGF5aW5nIHByaW1hcnkgcG9zPSVsZFxuIiwgcGxheXBvcyk7CgkJcHdwbGF5Kys7CgkJaWYgKHB3cGxheSA+PSBEU19IRUxfRlJBR1MpIHB3cGxheSA9IDA7CgkJLyogd3JpdGUgbmV3IHZhbHVlcyAqLwoJCVRoaXMtPnB3cGxheSA9IHB3cGxheTsKCQlUaGlzLT5wd3F1ZXVlLS07CgkJLyogcXVldWUgbmV3IGJ1ZmZlciBpZiB3ZSBoYXZlIGRhdGEgZm9yIGl0ICovCgkJaWYgKGlucT4xKSBEU09VTkRfV2F2ZVF1ZXVlKFRoaXMsIGlucS0xKTsKI2lmZGVmIFNZTkNfQ0FMTEJBQ0sKCQlMZWF2ZUNyaXRpY2FsU2VjdGlvbigmKFRoaXMtPm1peGxvY2spKTsKI2VuZGlmCgl9CglUUkFDRSgiY29tcGxldGVkXG4iKTsKfQo=