LyogIAkJCURpcmVjdFNvdW5kCiAqCiAqIENvcHlyaWdodCAxOTk4IE1hcmN1cyBNZWlzc25lcgogKiBDb3B5cmlnaHQgMTk5OCBSb2IgUmlnZ3MKICogQ29weXJpZ2h0IDIwMDAtMjAwMiBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMsIEluYy4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAgMDIxMTEtMTMwNyAgVVNBCiAqLwoKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CiNpbmNsdWRlIDxtYXRoLmg+CS8qIEluc29tbmlhIC0gcG93KCkgZnVuY3Rpb24gKi8KCiNkZWZpbmUgTk9OQU1FTEVTU1NUUlVDVAojZGVmaW5lIE5PTkFNRUxFU1NVTklPTgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJtbXN5c3RlbS5oIgojaW5jbHVkZSAid2lucmVnLmgiCiNpbmNsdWRlICJ3aW50ZXJubC5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgojaW5jbHVkZSAiZHNvdW5kLmgiCiNpbmNsdWRlICJkc2RyaXZlci5oIgojaW5jbHVkZSAiZHNvdW5kX3ByaXZhdGUuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGRzb3VuZCk7Cgp2b2lkIERTT1VORF9SZWNhbGNWb2xQYW4oUERTVk9MVU1FUEFOIHZvbHBhbikKewoJZG91YmxlIHRlbXA7CglUUkFDRSgiKCVwKVxuIix2b2xwYW4pOwoKCVRSQUNFKCJWb2w9JWxkIFBhbj0lbGRcbiIsIHZvbHBhbi0+bFZvbHVtZSwgdm9scGFuLT5sUGFuKTsKCS8qIHRoZSBBbXBGYWN0b3JzIGFyZSBleHByZXNzZWQgaW4gMTYuMTYgZml4ZWQgcG9pbnQgKi8KCXZvbHBhbi0+ZHdWb2xBbXBGYWN0b3IgPSAoVUxPTkcpIChwb3coMi4wLCB2b2xwYW4tPmxWb2x1bWUgLyA2MDAuMCkgKiAweGZmZmYpOwoJLyogRklYTUU6IGR3UGFue0xlZnR8UmlnaHR9QW1wRmFjdG9yICovCgoJLyogRklYTUU6IHVzZSBjYWxjdWxhdGVkIHZvbCBhbmQgcGFuIGFtcGZhY3RvcnMgKi8KCXRlbXAgPSAoZG91YmxlKSAodm9scGFuLT5sVm9sdW1lIC0gKHZvbHBhbi0+bFBhbiA+IDAgPyB2b2xwYW4tPmxQYW4gOiAwKSk7Cgl2b2xwYW4tPmR3VG90YWxMZWZ0QW1wRmFjdG9yID0gKFVMT05HKSAocG93KDIuMCwgdGVtcCAvIDYwMC4wKSAqIDB4ZmZmZik7Cgl0ZW1wID0gKGRvdWJsZSkgKHZvbHBhbi0+bFZvbHVtZSArICh2b2xwYW4tPmxQYW4gPCAwID8gdm9scGFuLT5sUGFuIDogMCkpOwoJdm9scGFuLT5kd1RvdGFsUmlnaHRBbXBGYWN0b3IgPSAoVUxPTkcpIChwb3coMi4wLCB0ZW1wIC8gNjAwLjApICogMHhmZmZmKTsKCglUUkFDRSgibGVmdCA9ICVseCwgcmlnaHQgPSAlbHhcbiIsIHZvbHBhbi0+ZHdUb3RhbExlZnRBbXBGYWN0b3IsIHZvbHBhbi0+ZHdUb3RhbFJpZ2h0QW1wRmFjdG9yKTsKfQoKdm9pZCBEU09VTkRfQW1wRmFjdG9yVG9Wb2xQYW4oUERTVk9MVU1FUEFOIHZvbHBhbikKewogICAgZG91YmxlIGxlZnQscmlnaHQ7CiAgICBUUkFDRSgiKCVwKVxuIix2b2xwYW4pOwoKICAgIFRSQUNFKCJsZWZ0PSVseCwgcmlnaHQ9JWx4XG4iLHZvbHBhbi0+ZHdUb3RhbExlZnRBbXBGYWN0b3Isdm9scGFuLT5kd1RvdGFsUmlnaHRBbXBGYWN0b3IpOwogICAgaWYgKHZvbHBhbi0+ZHdUb3RhbExlZnRBbXBGYWN0b3I9PTApCiAgICAgICAgbGVmdD0tMTAwMDA7CiAgICBlbHNlCiAgICAgICAgbGVmdD02MDAgKiBsb2coKChkb3VibGUpdm9scGFuLT5kd1RvdGFsTGVmdEFtcEZhY3RvcikgLyAweGZmZmYpIC8gbG9nKDIpOwogICAgaWYgKHZvbHBhbi0+ZHdUb3RhbFJpZ2h0QW1wRmFjdG9yPT0wKQogICAgICAgIHJpZ2h0PS0xMDAwMDsKICAgIGVsc2UKICAgICAgICByaWdodD02MDAgKiBsb2coKChkb3VibGUpdm9scGFuLT5kd1RvdGFsUmlnaHRBbXBGYWN0b3IpIC8gMHhmZmZmKSAvIGxvZygyKTsKICAgIGlmIChsZWZ0PHJpZ2h0KQogICAgewogICAgICAgIHZvbHBhbi0+bFZvbHVtZT1yaWdodDsKICAgICAgICB2b2xwYW4tPmR3Vm9sQW1wRmFjdG9yPXZvbHBhbi0+ZHdUb3RhbFJpZ2h0QW1wRmFjdG9yOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHZvbHBhbi0+bFZvbHVtZT1sZWZ0OwogICAgICAgIHZvbHBhbi0+ZHdWb2xBbXBGYWN0b3I9dm9scGFuLT5kd1RvdGFsTGVmdEFtcEZhY3RvcjsKICAgIH0KICAgIGlmICh2b2xwYW4tPmxWb2x1bWUgPCAtMTAwMDApCiAgICAgICAgdm9scGFuLT5sVm9sdW1lPS0xMDAwMDsKICAgIHZvbHBhbi0+bFBhbj1yaWdodC1sZWZ0OwogICAgaWYgKHZvbHBhbi0+bFBhbiA8IC0xMDAwMCkKICAgICAgICB2b2xwYW4tPmxQYW49LTEwMDAwOwoKICAgIFRSQUNFKCJWb2w9JWxkIFBhbj0lbGRcbiIsIHZvbHBhbi0+bFZvbHVtZSwgdm9scGFuLT5sUGFuKTsKfQoKdm9pZCBEU09VTkRfUmVjYWxjRm9ybWF0KElEaXJlY3RTb3VuZEJ1ZmZlckltcGwgKmRzYikKewoJRFdPUkQgc3c7CglUUkFDRSgiKCVwKVxuIixkc2IpOwoKCXN3ID0gZHNiLT5wd2Z4LT5uQ2hhbm5lbHMgKiAoZHNiLT5wd2Z4LT53Qml0c1BlclNhbXBsZSAvIDgpOwoJLyogY2FsY3VsYXRlIHRoZSAxMG1zIHdyaXRlIGxlYWQgKi8KCWRzYi0+d3JpdGVsZWFkID0gKGRzYi0+ZnJlcSAvIDEwMCkgKiBzdzsKfQoKdm9pZCBEU09VTkRfQ2hlY2tFdmVudChJRGlyZWN0U291bmRCdWZmZXJJbXBsICpkc2IsIGludCBsZW4pCnsKCWludAkJCWk7CglEV09SRAkJCW9mZnNldDsKCUxQRFNCUE9TSVRJT05OT1RJRlkJZXZlbnQ7CglUUkFDRSgiKCVwLCVkKVxuIixkc2IsbGVuKTsKCglpZiAoZHNiLT5ucm9mbm90aWZpZXMgPT0gMCkKCQlyZXR1cm47CgoJVFJBQ0UoIiglcCkgYnVmbGVuID0gJWxkLCBwbGF5cG9zID0gJWxkLCBsZW4gPSAlZFxuIiwKCQlkc2IsIGRzYi0+YnVmbGVuLCBkc2ItPnBsYXlwb3MsIGxlbik7Cglmb3IgKGkgPSAwOyBpIDwgZHNiLT5ucm9mbm90aWZpZXMgOyBpKyspIHsKCQlldmVudCA9IGRzYi0+bm90aWZpZXMgKyBpOwoJCW9mZnNldCA9IGV2ZW50LT5kd09mZnNldDsKCQlUUkFDRSgiY2hlY2tpbmcgJWQsIHBvc2l0aW9uICVsZCwgZXZlbnQgPSAlcFxuIiwKCQkJaSwgb2Zmc2V0LCBldmVudC0+aEV2ZW50Tm90aWZ5KTsKCQkvKiBEU0JQTl9PRkZTRVRTVE9QIGhhcyB0byBiZSB0aGUgbGFzdCBlbGVtZW50LiBTbyB0aGlzIGlzICovCgkJLyogT0suIFtJbnNpZGUgRGlyZWN0WCwgcDI3NF0gKi8KCQkvKiAgKi8KCQkvKiBUaGlzIGFsc28gbWVhbnMgd2UgY2FuJ3Qgc29ydCB0aGUgZW50cmllcyBieSBvZmZzZXQsICovCgkJLyogYmVjYXVzZSBEU0JQTl9PRkZTRVRTVE9QID09IC0xICovCgkJaWYgKG9mZnNldCA9PSBEU0JQTl9PRkZTRVRTVE9QKSB7CgkJCWlmIChkc2ItPnN0YXRlID09IFNUQVRFX1NUT1BQRUQpIHsKCQkJCVNldEV2ZW50KGV2ZW50LT5oRXZlbnROb3RpZnkpOwoJCQkJVFJBQ0UoInNpZ25hbGxlZCBldmVudCAlcCAoJWQpXG4iLCBldmVudC0+aEV2ZW50Tm90aWZ5LCBpKTsKCQkJCXJldHVybjsKCQkJfSBlbHNlCgkJCQlyZXR1cm47CgkJfQoJCWlmICgoZHNiLT5wbGF5cG9zICsgbGVuKSA+PSBkc2ItPmJ1ZmxlbikgewoJCQlpZiAoKG9mZnNldCA8ICgoZHNiLT5wbGF5cG9zICsgbGVuKSAlIGRzYi0+YnVmbGVuKSkgfHwKCQkJICAgIChvZmZzZXQgPj0gZHNiLT5wbGF5cG9zKSkgewoJCQkJVFJBQ0UoInNpZ25hbGxlZCBldmVudCAlcCAoJWQpXG4iLCBldmVudC0+aEV2ZW50Tm90aWZ5LCBpKTsKCQkJCVNldEV2ZW50KGV2ZW50LT5oRXZlbnROb3RpZnkpOwoJCQl9CgkJfSBlbHNlIHsKCQkJaWYgKChvZmZzZXQgPj0gZHNiLT5wbGF5cG9zKSAmJiAob2Zmc2V0IDwgKGRzYi0+cGxheXBvcyArIGxlbikpKSB7CgkJCQlUUkFDRSgic2lnbmFsbGVkIGV2ZW50ICVwICglZClcbiIsIGV2ZW50LT5oRXZlbnROb3RpZnksIGkpOwoJCQkJU2V0RXZlbnQoZXZlbnQtPmhFdmVudE5vdGlmeSk7CgkJCX0KCQl9Cgl9Cn0KCi8qIFdBViBmb3JtYXQgaW5mbyBjYW4gYmUgZm91bmQgYXQ6CiAqCiAqICAgIGh0dHA6Ly93d3cuY3dpLm5sL2Z0cC9hdWRpby9BdWRpb0Zvcm1hdHMucGFydDIKICogICAgZnRwOi8vZnRwLmN3aS5ubC9wdWIvYXVkaW8vUklGRi1mb3JtYXQKICoKICogSW1wb3J0IHBvaW50cyB0byByZW1lbWJlcjoKICogICAgOC1iaXQgV0FWIGlzIHVuc2lnbmVkCiAqICAgIDE2LWJpdCBXQVYgaXMgc2lnbmVkCiAqLwogLyogVXNlIHRoZSBzYW1lIGZvcm11bGFzIGFzIHBjbWNvbnZlcnRlci5jICovCnN0YXRpYyBpbmxpbmUgSU5UMTYgY3Z0VTh0b1MxNihCWVRFIGIpCnsKICAgIHJldHVybiAoc2hvcnQpKChiKyhiIDw8IDgpKS0zMjc2OCk7Cn0KCnN0YXRpYyBpbmxpbmUgQllURSBjdnRTMTZ0b1U4KElOVDE2IHMpCnsKICAgIHJldHVybiAocyA+PiA4KSBeICh1bnNpZ25lZCBjaGFyKTB4ODA7Cn0KCnN0YXRpYyBpbmxpbmUgdm9pZCBjcF9maWVsZHMoY29uc3QgSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiLCBCWVRFICppYnVmLCBCWVRFICpvYnVmICkKewogICAgICAgIElOVCBmbCxmcjsKCiAgICAgICAgaWYgKGRzYi0+cHdmeC0+d0JpdHNQZXJTYW1wbGUgPT0gOCkgIHsKICAgICAgICAgICAgICAgIGlmIChkc2ItPmRzb3VuZC0+cHdmeC0+d0JpdHNQZXJTYW1wbGUgPT0gOCAmJgogICAgICAgICAgICAgICAgICAgIGRzYi0+ZHNvdW5kLT5wd2Z4LT5uQ2hhbm5lbHMgPT0gZHNiLT5wd2Z4LT5uQ2hhbm5lbHMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogYXZvaWQgbmVlZGxlc3MgOC0+MTYtPjggY29udmVyc2lvbiAqLwogICAgICAgICAgICAgICAgICAgICAgICAqb2J1Zj0qaWJ1ZjsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRzYi0+cHdmeC0+bkNoYW5uZWxzPT0yKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoob2J1ZisxKT0qKGlidWYrMSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGZsID0gY3Z0VTh0b1MxNigqaWJ1Zik7CiAgICAgICAgICAgICAgICBmciA9IChkc2ItPnB3ZngtPm5DaGFubmVscz09MiA/IGN2dFU4dG9TMTYoKihpYnVmICsgMSkpIDogZmwpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBmbCA9ICooKElOVDE2ICopaWJ1Zik7CiAgICAgICAgICAgICAgICBmciA9IChkc2ItPnB3ZngtPm5DaGFubmVscz09MiA/ICooKChJTlQxNiAqKWlidWYpICsgMSkgIDogZmwpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGRzYi0+ZHNvdW5kLT5wd2Z4LT5uQ2hhbm5lbHMgPT0gMikgewogICAgICAgICAgICAgICAgaWYgKGRzYi0+ZHNvdW5kLT5wd2Z4LT53Qml0c1BlclNhbXBsZSA9PSA4KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICpvYnVmID0gY3Z0UzE2dG9VOChmbCk7CiAgICAgICAgICAgICAgICAgICAgICAgICoob2J1ZiArIDEpID0gY3Z0UzE2dG9VOChmcik7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChkc2ItPmRzb3VuZC0+cHdmeC0+d0JpdHNQZXJTYW1wbGUgPT0gMTYpIHsKICAgICAgICAgICAgICAgICAgICAgICAgKigoSU5UMTYgKilvYnVmKSA9IGZsOwogICAgICAgICAgICAgICAgICAgICAgICAqKCgoSU5UMTYgKilvYnVmKSArIDEpID0gZnI7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKGRzYi0+ZHNvdW5kLT5wd2Z4LT5uQ2hhbm5lbHMgPT0gMSkgewogICAgICAgICAgICAgICAgZmwgPSAoZmwgKyBmcikgPj4gMTsKICAgICAgICAgICAgICAgIGlmIChkc2ItPmRzb3VuZC0+cHdmeC0+d0JpdHNQZXJTYW1wbGUgPT0gOCkgewogICAgICAgICAgICAgICAgICAgICAgICAqb2J1ZiA9IGN2dFMxNnRvVTgoZmwpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoZHNiLT5kc291bmQtPnB3ZngtPndCaXRzUGVyU2FtcGxlID09IDE2KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICooKElOVDE2ICopb2J1ZikgPSBmbDsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQogICAgICAgIH0KfQoKLyogTm93IHdpdGggUGVyZmVjdFBpdGNoICh0bSkgdGVjaG5vbG9neSAqLwpzdGF0aWMgSU5UIERTT1VORF9NaXhlck5vcm0oSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiLCBCWVRFICpidWYsIElOVCBsZW4pCnsKCUlOVAlpLCBzaXplLCBpcG9zLCBpbGVuOwoJQllURQkqaWJwLCAqb2JwOwoJSU5UCWlBZHZhbmNlID0gZHNiLT5wd2Z4LT5uQmxvY2tBbGlnbjsKCUlOVAlvQWR2YW5jZSA9IGRzYi0+ZHNvdW5kLT5wd2Z4LT5uQmxvY2tBbGlnbjsKCglpYnAgPSBkc2ItPmJ1ZmZlci0+bWVtb3J5ICsgZHNiLT5idWZfbWl4cG9zOwoJb2JwID0gYnVmOwoKCVRSQUNFKCIoJXAsICVwLCAlcCksIGJ1Zl9taXhwb3M9JWxkXG4iLCBkc2IsIGlicCwgb2JwLCBkc2ItPmJ1Zl9taXhwb3MpOwoJLyogQ2hlY2sgZm9yIHRoZSBiZXN0IGNhc2UgKi8KCWlmICgoZHNiLT5mcmVxID09IGRzYi0+ZHNvdW5kLT5wd2Z4LT5uU2FtcGxlc1BlclNlYykgJiYKCSAgICAoZHNiLT5wd2Z4LT53Qml0c1BlclNhbXBsZSA9PSBkc2ItPmRzb3VuZC0+cHdmeC0+d0JpdHNQZXJTYW1wbGUpICYmCgkgICAgKGRzYi0+cHdmeC0+bkNoYW5uZWxzID09IGRzYi0+ZHNvdW5kLT5wd2Z4LT5uQ2hhbm5lbHMpKSB7CgkgICAgICAgIElOVCBieXRlc2xlZnQgPSBkc2ItPmJ1ZmxlbiAtIGRzYi0+YnVmX21peHBvczsKCQlUUkFDRSgiKCVwKSBCZXN0IGNhc2VcbiIsIGRzYik7CgkgICAgCWlmIChsZW4gPD0gYnl0ZXNsZWZ0ICkKCQkJQ29weU1lbW9yeShvYnAsIGlicCwgbGVuKTsKCQllbHNlIHsgLyogd3JhcCAqLwoJCQlDb3B5TWVtb3J5KG9icCwgaWJwLCBieXRlc2xlZnQpOwoJCQlDb3B5TWVtb3J5KG9icCArIGJ5dGVzbGVmdCwgZHNiLT5idWZmZXItPm1lbW9yeSwgbGVuIC0gYnl0ZXNsZWZ0KTsKCQl9CgkJcmV0dXJuIGxlbjsKCX0KCgkvKiBDaGVjayBmb3Igc2FtZSBzYW1wbGUgcmF0ZSAqLwoJaWYgKGRzYi0+ZnJlcSA9PSBkc2ItPmRzb3VuZC0+cHdmeC0+blNhbXBsZXNQZXJTZWMpIHsKCQlUUkFDRSgiKCVwKSBTYW1lIHNhbXBsZSByYXRlICVsZCA9IHByaW1hcnkgJWxkXG4iLCBkc2IsCgkJCWRzYi0+ZnJlcSwgZHNiLT5kc291bmQtPnB3ZngtPm5TYW1wbGVzUGVyU2VjKTsKCQlpbGVuID0gMDsKCQlmb3IgKGkgPSAwOyBpIDwgbGVuOyBpICs9IG9BZHZhbmNlKSB7CgkJCWNwX2ZpZWxkcyhkc2IsIGlicCwgb2JwICk7CgkJCWlicCArPSBpQWR2YW5jZTsKCQkJaWxlbiArPSBpQWR2YW5jZTsKCQkJb2JwICs9IG9BZHZhbmNlOwoJCQlpZiAoaWJwID49IChCWVRFICopKGRzYi0+YnVmZmVyLT5tZW1vcnkgKyBkc2ItPmJ1ZmxlbikpCgkJCQlpYnAgPSBkc2ItPmJ1ZmZlci0+bWVtb3J5OwkvKiB3cmFwICovCgkJfQoJCXJldHVybiAoaWxlbik7Cgl9CgoJLyogTWl4IGluIGRpZmZlcmVudCBzYW1wbGUgcmF0ZXMgKi8KCS8qICovCgkvKiBOZXcgUGVyZmVjdFBpdGNoKHRtKSBUZWNobm9sb2d5IChjKSAxOTk4IFJvYiBSaWdncyAqLwoJLyogUGF0ZW50IFBlbmRpbmcgOi1dICovCgoJLyogUGF0ZW50IGVuaGFuY2VtZW50cyAoYykgMjAwMCBPdmUgS+V2ZW4sCgkgKiBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMgSW5jLiAqLwoKCS8qIEZJWE1FKCIoJXApIEFkanVzdGluZyBmcmVxdWVuY3k6ICVsZCAtPiAlbGQgKG5lZWQgb3B0aW1pemF0aW9uKVxuIiwKCSAgIGRzYiwgZHNiLT5mcmVxLCBkc2ItPmRzb3VuZC0+cHdmeC0+blNhbXBsZXNQZXJTZWMpOyAqLwoKCXNpemUgPSBsZW4gLyBvQWR2YW5jZTsKCWlsZW4gPSAwOwoJaXBvcyA9IGRzYi0+YnVmX21peHBvczsKCWZvciAoaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKICAgICAgICAgICAgICAgIGNwX2ZpZWxkcyhkc2IsIChkc2ItPmJ1ZmZlci0+bWVtb3J5ICsgaXBvcyksIG9icCk7CgkJb2JwICs9IG9BZHZhbmNlOwoJCWRzYi0+ZnJlcUFjYyArPSBkc2ItPmZyZXFBZGp1c3Q7CgkJaWYgKGRzYi0+ZnJlcUFjYyA+PSAoMTw8RFNPVU5EX0ZSRVFTSElGVCkpIHsKCQkJVUxPTkcgYWR2ID0gKGRzYi0+ZnJlcUFjYz4+RFNPVU5EX0ZSRVFTSElGVCkgKiBpQWR2YW5jZTsKCQkJZHNiLT5mcmVxQWNjICY9ICgxPDxEU09VTkRfRlJFUVNISUZUKS0xOwoJCQlpcG9zICs9IGFkdjsgaWxlbiArPSBhZHY7CgkJCWlwb3MgJT0gZHNiLT5idWZsZW47CgkJfQoJfQoJcmV0dXJuIGlsZW47Cn0KCnN0YXRpYyB2b2lkIERTT1VORF9NaXhlclZvbChJRGlyZWN0U291bmRCdWZmZXJJbXBsICpkc2IsIEJZVEUgKmJ1ZiwgSU5UIGxlbikKewoJSU5UCWk7CglCWVRFCSpicGMgPSBidWY7CglJTlQxNgkqYnBzID0gKElOVDE2ICopIGJ1ZjsKCglUUkFDRSgiKCVwLCVwLCVkKVxuIixkc2IsYnVmLGxlbik7CglUUkFDRSgibGVmdCA9ICVseCwgcmlnaHQgPSAlbHhcbiIsIGRzYi0+Y3ZvbHBhbi5kd1RvdGFsTGVmdEFtcEZhY3RvciwgCgkJZHNiLT5jdm9scGFuLmR3VG90YWxSaWdodEFtcEZhY3Rvcik7CgoJaWYgKCghKGRzYi0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19DVFJMUEFOKSB8fCAoZHNiLT5jdm9scGFuLmxQYW4gPT0gMCkpICYmCgkgICAgKCEoZHNiLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX0NUUkxWT0xVTUUpIHx8IChkc2ItPmN2b2xwYW4ubFZvbHVtZSA9PSAwKSkgJiYKCSAgICAhKGRzYi0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19DVFJMM0QpKQoJCXJldHVybjsJCS8qIE5vdGhpbmcgdG8gZG8gKi8KCgkvKiBJZiB3ZSBlbmQgdXAgd2l0aCBzb21lIGJvem8gY29kZXIgdXNpbmcgcGFubmluZyBvciAzRCBzb3VuZCAqLwoJLyogd2l0aCBhIG1vbm8gcHJpbWFyeSBidWZmZXIsIGl0IGNvdWxkIHNvdW5kIHZlcnkgd2VpcmQgdXNpbmcgKi8KCS8qIHRoaXMgbWV0aG9kLiBPaCB3ZWxsLCB0b3VnaCBwYXRvb3RpZXMuICovCgoJc3dpdGNoIChkc2ItPmRzb3VuZC0+cHdmeC0+d0JpdHNQZXJTYW1wbGUpIHsKCWNhc2UgODoKCQkvKiA4LWJpdCBXQVYgaXMgdW5zaWduZWQsIGJ1dCB3ZSBuZWVkIHRvIG9wZXJhdGUgKi8KCQkvKiBvbiBzaWduZWQgZGF0YSBmb3IgdGhpcyB0byB3b3JrIHByb3Blcmx5ICovCgkJc3dpdGNoIChkc2ItPmRzb3VuZC0+cHdmeC0+bkNoYW5uZWxzKSB7CgkJY2FzZSAxOgoJCQlmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKCQkJCUlOVCB2YWwgPSAqYnBjIC0gMTI4OwoJCQkJdmFsID0gKHZhbCAqIGRzYi0+Y3ZvbHBhbi5kd1RvdGFsTGVmdEFtcEZhY3RvcikgPj4gMTY7CgkJCQkqYnBjID0gdmFsICsgMTI4OwoJCQkJYnBjKys7CgkJCX0KCQkJYnJlYWs7CgkJY2FzZSAyOgoJCQlmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKz0yKSB7CgkJCQlJTlQgdmFsID0gKmJwYyAtIDEyODsKCQkJCXZhbCA9ICh2YWwgKiBkc2ItPmN2b2xwYW4uZHdUb3RhbExlZnRBbXBGYWN0b3IpID4+IDE2OwoJCQkJKmJwYysrID0gdmFsICsgMTI4OwoJCQkJdmFsID0gKmJwYyAtIDEyODsKCQkJCXZhbCA9ICh2YWwgKiBkc2ItPmN2b2xwYW4uZHdUb3RhbFJpZ2h0QW1wRmFjdG9yKSA+PiAxNjsKCQkJCSpicGMgPSB2YWwgKyAxMjg7CgkJCQlicGMrKzsKCQkJfQoJCQlicmVhazsKCQlkZWZhdWx0OgoJCQlGSVhNRSgiZG9lc24ndCBzdXBwb3J0ICVkIGNoYW5uZWxzXG4iLCBkc2ItPmRzb3VuZC0+cHdmeC0+bkNoYW5uZWxzKTsKCQkJYnJlYWs7CgkJfQoJCWJyZWFrOwoJY2FzZSAxNjoKCQkvKiAxNi1iaXQgV0FWIGlzIHNpZ25lZCAtLSBtdWNoIGJldHRlciAqLwoJCXN3aXRjaCAoZHNiLT5kc291bmQtPnB3ZngtPm5DaGFubmVscykgewoJCWNhc2UgMToKCQkJZm9yIChpID0gMDsgaSA8IGxlbjsgaSArPSAyKSB7CgkJCQkqYnBzID0gKCpicHMgKiBkc2ItPmN2b2xwYW4uZHdUb3RhbExlZnRBbXBGYWN0b3IpID4+IDE2OwoJCQkJYnBzKys7CgkJCX0KCQkJYnJlYWs7CgkJY2FzZSAyOgoJCQlmb3IgKGkgPSAwOyBpIDwgbGVuOyBpICs9IDQpIHsKCQkJCSpicHMgPSAoKmJwcyAqIGRzYi0+Y3ZvbHBhbi5kd1RvdGFsTGVmdEFtcEZhY3RvcikgPj4gMTY7CgkJCQlicHMrKzsKCQkJCSpicHMgPSAoKmJwcyAqIGRzYi0+Y3ZvbHBhbi5kd1RvdGFsUmlnaHRBbXBGYWN0b3IpID4+IDE2OwoJCQkJYnBzKys7CgkJCX0KCQkJYnJlYWs7CgkJZGVmYXVsdDoKCQkJRklYTUUoImRvZXNuJ3Qgc3VwcG9ydCAlZCBjaGFubmVsc1xuIiwgZHNiLT5kc291bmQtPnB3ZngtPm5DaGFubmVscyk7CgkJCWJyZWFrOwoJCX0KCQlicmVhazsKCWRlZmF1bHQ6CgkJRklYTUUoImRvZXNuJ3Qgc3VwcG9ydCAlZCBiaXQgc2FtcGxlc1xuIiwgZHNiLT5kc291bmQtPnB3ZngtPndCaXRzUGVyU2FtcGxlKTsKCQlicmVhazsKCX0KfQoKc3RhdGljIExQQllURSBEU09VTkRfdG1wYnVmZmVyKElEaXJlY3RTb3VuZEltcGwgKmRzb3VuZCwgRFdPUkQgbGVuKQp7CiAgICBUUkFDRSgiKCVwLCVsZClcbiIsZHNvdW5kLGxlbik7CgogICAgaWYgKGxlbiA+IGRzb3VuZC0+dG1wX2J1ZmZlcl9sZW4pIHsKICAgICAgICBpZiAoZHNvdW5kLT50bXBfYnVmZmVyKQogICAgICAgICAgICBkc291bmQtPnRtcF9idWZmZXIgPSBIZWFwUmVBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBkc291bmQtPnRtcF9idWZmZXIsIGxlbik7CiAgICAgICAgZWxzZQogICAgICAgICAgICBkc291bmQtPnRtcF9idWZmZXIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuKTsKCiAgICAgICAgZHNvdW5kLT50bXBfYnVmZmVyX2xlbiA9IGxlbjsKICAgIH0KCiAgICByZXR1cm4gZHNvdW5kLT50bXBfYnVmZmVyOwp9CgpzdGF0aWMgRFdPUkQgRFNPVU5EX01peEluQnVmZmVyKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwgKmRzYiwgRFdPUkQgd3JpdGVwb3MsIERXT1JEIGZyYWdsZW4pCnsKCUlOVAlpLCBsZW4sIGlsZW4sIGZpZWxkLCBuQmxvY2tBbGlnbiwgdG9kbzsKCUJZVEUJKmJ1ZiwgKmlidWY7CgoJVFJBQ0UoIiglcCwlbGQsJWxkKVxuIixkc2Isd3JpdGVwb3MsZnJhZ2xlbik7CgoJbGVuID0gZnJhZ2xlbjsKCWlmICghKGRzYi0+cGxheWZsYWdzICYgRFNCUExBWV9MT09QSU5HKSkgewoJCUlOVCB0ZW1wID0gTXVsRGl2KGRzYi0+ZHNvdW5kLT5wd2Z4LT5uQXZnQnl0ZXNQZXJTZWMsIGRzYi0+YnVmbGVuLAoJCQlkc2ItPm5BdmdCeXRlc1BlclNlYykgLQoJCQlNdWxEaXYoZHNiLT5kc291bmQtPnB3ZngtPm5BdmdCeXRlc1BlclNlYywgZHNiLT5idWZfbWl4cG9zLAoJCQlkc2ItPm5BdmdCeXRlc1BlclNlYyk7CgkJbGVuID0gbWluKGxlbiwgdGVtcCk7Cgl9CgluQmxvY2tBbGlnbiA9IGRzYi0+ZHNvdW5kLT5wd2Z4LT5uQmxvY2tBbGlnbjsKCWxlbiA9IGxlbiAvIG5CbG9ja0FsaWduICogbkJsb2NrQWxpZ247CS8qIGRhdGEgYWxpZ25tZW50ICovCgoJaWYgKGxlbiA9PSAwKSB7CgkJLyogVGhpcyBzaG91bGQgb25seSBoYXBwZW4gaWYgd2UgYXJlbid0IGxvb3BpbmcgYW5kIHRlbXAgPCBuQmxvY2tBbGlnbiAqLwoJCXJldHVybiAwOwoJfQoKCWlmICgoYnVmID0gaWJ1ZiA9IERTT1VORF90bXBidWZmZXIoZHNiLT5kc291bmQsIGxlbikpID09IE5VTEwpCgkJcmV0dXJuIDA7CgoJVFJBQ0UoIk1peEluQnVmZmVyICglcCkgbGVuID0gJWQsIGRlc3QgPSAlbGRcbiIsIGRzYiwgbGVuLCB3cml0ZXBvcyk7CgoJaWxlbiA9IERTT1VORF9NaXhlck5vcm0oZHNiLCBpYnVmLCBsZW4pOwoJaWYgKChkc2ItPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfQ1RSTFBBTikgfHwKCSAgICAoZHNiLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX0NUUkxWT0xVTUUpIHx8CgkgICAgKGRzYi0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19DVFJMM0QpKQoJCURTT1VORF9NaXhlclZvbChkc2IsIGlidWYsIGxlbik7CgoJaWYgKGRzYi0+ZHNvdW5kLT5wd2Z4LT53Qml0c1BlclNhbXBsZSA9PSA4KSB7CgkJQllURQkqb2J1ZiA9IGRzYi0+ZHNvdW5kLT5idWZmZXIgKyB3cml0ZXBvczsKCgkJaWYgKCh3cml0ZXBvcyArIGxlbikgPD0gZHNiLT5kc291bmQtPmJ1ZmxlbikKCQkJdG9kbyA9IGxlbjsKCQllbHNlCgkJCXRvZG8gPSBkc2ItPmRzb3VuZC0+YnVmbGVuIC0gd3JpdGVwb3M7CgoJCWZvciAoaSA9IDA7IGkgPCB0b2RvOyBpKyspIHsKCQkJLyogOC1iaXQgV0FWIGlzIHVuc2lnbmVkICovCgkJCWZpZWxkID0gKCppYnVmKysgLSAxMjgpOwoJCQlmaWVsZCArPSAoKm9idWYgLSAxMjgpOwoJCQlpZiAoZmllbGQgPiAxMjcpIGZpZWxkID0gMTI3OwoJCQllbHNlIGlmIChmaWVsZCA8IC0xMjgpIGZpZWxkID0gLTEyODsKCQkJKm9idWYrKyA9IGZpZWxkICsgMTI4OwoJCX0KIAoJCWlmICh0b2RvIDwgbGVuKSB7CgkJCXRvZG8gPSBsZW4gLSB0b2RvOwoJCQlvYnVmID0gZHNiLT5kc291bmQtPmJ1ZmZlcjsKCgkJCWZvciAoaSA9IDA7IGkgPCB0b2RvOyBpKyspIHsKCQkJCS8qIDgtYml0IFdBViBpcyB1bnNpZ25lZCAqLwoJCQkJZmllbGQgPSAoKmlidWYrKyAtIDEyOCk7CgkJCQlmaWVsZCArPSAoKm9idWYgLSAxMjgpOwoJCQkJaWYgKGZpZWxkID4gMTI3KSBmaWVsZCA9IDEyNzsKCQkJCWVsc2UgaWYgKGZpZWxkIDwgLTEyOCkgZmllbGQgPSAtMTI4OwoJCQkJKm9idWYrKyA9IGZpZWxkICsgMTI4OwoJCQl9CgkJfQogICAgICAgIH0gZWxzZSB7CgkJSU5UMTYJKmlidWZzLCAqb2J1ZnM7CgoJCWlidWZzID0gKElOVDE2ICopIGlidWY7CgkJb2J1ZnMgPSAoSU5UMTYgKikoZHNiLT5kc291bmQtPmJ1ZmZlciArIHdyaXRlcG9zKTsKCgkJaWYgKCh3cml0ZXBvcyArIGxlbikgPD0gZHNiLT5kc291bmQtPmJ1ZmxlbikKCQkJdG9kbyA9IGxlbiAvIDI7CgkJZWxzZQoJCQl0b2RvID0gKGRzYi0+ZHNvdW5kLT5idWZsZW4gLSB3cml0ZXBvcykgLyAyOwoKCQlmb3IgKGkgPSAwOyBpIDwgdG9kbzsgaSsrKSB7CgkJCS8qIDE2LWJpdCBXQVYgaXMgc2lnbmVkICovCgkJCWZpZWxkID0gKmlidWZzKys7CgkJCWZpZWxkICs9ICpvYnVmczsKCQkJaWYgKGZpZWxkID4gMzI3NjcpIGZpZWxkID0gMzI3Njc7CgkJCWVsc2UgaWYgKGZpZWxkIDwgLTMyNzY4KSBmaWVsZCA9IC0zMjc2ODsKCQkJKm9idWZzKysgPSBmaWVsZDsKCQl9CgoJCWlmICh0b2RvIDwgKGxlbiAvIDIpKSB7CgkJCXRvZG8gPSAobGVuIC8gMikgLSB0b2RvOwoJCQlvYnVmcyA9IChJTlQxNiAqKWRzYi0+ZHNvdW5kLT5idWZmZXI7CgoJCQlmb3IgKGkgPSAwOyBpIDwgdG9kbzsgaSsrKSB7CgkJCQkvKiAxNi1iaXQgV0FWIGlzIHNpZ25lZCAqLwoJCQkJZmllbGQgPSAqaWJ1ZnMrKzsKCQkJCWZpZWxkICs9ICpvYnVmczsKCQkJCWlmIChmaWVsZCA+IDMyNzY3KSBmaWVsZCA9IDMyNzY3OwoJCQkJZWxzZSBpZiAoZmllbGQgPCAtMzI3NjgpIGZpZWxkID0gLTMyNzY4OwoJCQkJKm9idWZzKysgPSBmaWVsZDsKCQkJfQoJCX0KICAgICAgICB9CgoJaWYgKGRzYi0+bGVhZGluICYmIChkc2ItPnN0YXJ0cG9zID4gZHNiLT5idWZfbWl4cG9zKSAmJiAoZHNiLT5zdGFydHBvcyA8PSBkc2ItPmJ1Zl9taXhwb3MgKyBpbGVuKSkgewoJCS8qIEhBQ0suLi4gbGVhZGluIHNob3VsZCBiZSByZXNldCB3aGVuIHRoZSBQTEFZIHBvc2l0aW9uIHJlYWNoZXMgdGhlIHN0YXJ0cG9zLAoJCSAqIG5vdCB0aGUgTUlYIHBvc2l0aW9uLi4uIGJ1dCBpZiB0aGUgc291bmQgYnVmZmVyIGlzIGJpZ2dlciB0aGFuIG91ciBwcmVidWZmZXJpbmcKCQkgKiAod2hpY2ggbXVzdCBiZSB0aGUgY2FzZSBmb3IgdGhlIHN0cmVhbWluZyBidWZmZXJzIHRoYXQgbmVlZCB0aGlzIGhhY2sgYW55d2F5KQoJCSAqIHBsdXMgRFNfSEVMX01BUkdJTiBvciBlcXVpdmFsZW50LCB0aGVuIHRoaXMgb3VnaHQgdG8gd29yayBhbnl3YXkuICovCgkJZHNiLT5sZWFkaW4gPSBGQUxTRTsKCX0KCglkc2ItPmJ1Zl9taXhwb3MgKz0gaWxlbjsKCglpZiAoZHNiLT5idWZfbWl4cG9zID49IGRzYi0+YnVmbGVuKSB7CgkJaWYgKGRzYi0+cGxheWZsYWdzICYgRFNCUExBWV9MT09QSU5HKSB7CgkJCS8qIHdyYXAgKi8KCQkJZHNiLT5idWZfbWl4cG9zICU9IGRzYi0+YnVmbGVuOwoJCQlpZiAoZHNiLT5sZWFkaW4gJiYgKGRzYi0+c3RhcnRwb3MgPD0gZHNiLT5idWZfbWl4cG9zKSkKCQkJCWRzYi0+bGVhZGluID0gRkFMU0U7IC8qIEhBQ0s6IHNlZSBhYm92ZSAqLwoJCX0KCX0KCglyZXR1cm4gbGVuOwp9CgpzdGF0aWMgdm9pZCBEU09VTkRfUGhhc2VDYW5jZWwoSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiLCBEV09SRCB3cml0ZXBvcywgRFdPUkQgbGVuKQp7CglJTlQgICAgIGlsZW4sIGZpZWxkLCBuQmxvY2tBbGlnbjsKCVVJTlQgICAgaSwgdG9kbzsKCUJZVEUJKmJ1ZiwgKmlidWY7CgoJVFJBQ0UoIiglcCwlbGQsJWxkKVxuIixkc2Isd3JpdGVwb3MsbGVuKTsKCgluQmxvY2tBbGlnbiA9IGRzYi0+ZHNvdW5kLT5wd2Z4LT5uQmxvY2tBbGlnbjsKCWxlbiA9IGxlbiAvIG5CbG9ja0FsaWduICogbkJsb2NrQWxpZ247ICAvKiBkYXRhIGFsaWdubWVudCAqLwoKCWlmICgoYnVmID0gaWJ1ZiA9IERTT1VORF90bXBidWZmZXIoZHNiLT5kc291bmQsIGxlbikpID09IE5VTEwpCgkJcmV0dXJuOwoKCVRSQUNFKCJQaGFzZUNhbmNlbCAoJXApIGxlbiA9ICVsZCwgZGVzdCA9ICVsZFxuIiwgZHNiLCBsZW4sIHdyaXRlcG9zKTsKCglpbGVuID0gRFNPVU5EX01peGVyTm9ybShkc2IsIGlidWYsIGxlbik7CglpZiAoKGRzYi0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19DVFJMUEFOKSB8fAoJICAgIChkc2ItPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfQ1RSTFZPTFVNRSkgfHwKCSAgICAoZHNiLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX0NUUkwzRCkpCgkJRFNPVU5EX01peGVyVm9sKGRzYiwgaWJ1ZiwgbGVuKTsKCgkvKiBzdWJ0cmFjdCBpbnN0ZWFkIG9mIGFkZCwgdG8gcGhhc2Ugb3V0IHByZW1peGVkIGRhdGEgKi8KCWlmIChkc2ItPmRzb3VuZC0+cHdmeC0+d0JpdHNQZXJTYW1wbGUgPT0gOCkgewoJCUJZVEUJKm9idWYgPSBkc2ItPmRzb3VuZC0+YnVmZmVyICsgd3JpdGVwb3M7CgoJCWlmICgod3JpdGVwb3MgKyBsZW4pIDw9IGRzYi0+ZHNvdW5kLT5idWZsZW4pCgkJCXRvZG8gPSBsZW47CgkJZWxzZQoJCQl0b2RvID0gZHNiLT5kc291bmQtPmJ1ZmxlbiAtIHdyaXRlcG9zOwoKCQlmb3IgKGkgPSAwOyBpIDwgdG9kbzsgaSsrKSB7CgkJCS8qIDgtYml0IFdBViBpcyB1bnNpZ25lZCAqLwoJCQlmaWVsZCA9ICgqaWJ1ZisrIC0gMTI4KTsKCQkJZmllbGQgLT0gKCpvYnVmIC0gMTI4KTsKCQkJaWYgKGZpZWxkID4gMTI3KSBmaWVsZCA9IDEyNzsKCQkJZWxzZSBpZiAoZmllbGQgPCAtMTI4KSBmaWVsZCA9IC0xMjg7CgkJCSpvYnVmKysgPSBmaWVsZCArIDEyODsKCQl9CiAKCQlpZiAodG9kbyA8IGxlbikgewoJCQl0b2RvID0gbGVuIC0gdG9kbzsKCQkJb2J1ZiA9IGRzYi0+ZHNvdW5kLT5idWZmZXI7CgoJCQlmb3IgKGkgPSAwOyBpIDwgdG9kbzsgaSsrKSB7CgkJCQkvKiA4LWJpdCBXQVYgaXMgdW5zaWduZWQgKi8KCQkJCWZpZWxkID0gKCppYnVmKysgLSAxMjgpOwoJCQkJZmllbGQgLT0gKCpvYnVmIC0gMTI4KTsKCQkJCWlmIChmaWVsZCA+IDEyNykgZmllbGQgPSAxMjc7CgkJCQllbHNlIGlmIChmaWVsZCA8IC0xMjgpIGZpZWxkID0gLTEyODsKCQkJCSpvYnVmKysgPSBmaWVsZCArIDEyODsKCQkJfQoJCX0KICAgICAgICB9IGVsc2UgewoJCUlOVDE2CSppYnVmcywgKm9idWZzOwoKCQlpYnVmcyA9IChJTlQxNiAqKSBpYnVmOwoJCW9idWZzID0gKElOVDE2ICopKGRzYi0+ZHNvdW5kLT5idWZmZXIgKyB3cml0ZXBvcyk7CgoJCWlmICgod3JpdGVwb3MgKyBsZW4pIDw9IGRzYi0+ZHNvdW5kLT5idWZsZW4pCgkJCXRvZG8gPSBsZW4gLyAyOwoJCWVsc2UKCQkJdG9kbyA9IChkc2ItPmRzb3VuZC0+YnVmbGVuIC0gd3JpdGVwb3MpIC8gMjsKCgkJZm9yIChpID0gMDsgaSA8IHRvZG87IGkrKykgewoJCQkvKiAxNi1iaXQgV0FWIGlzIHNpZ25lZCAqLwoJCQlmaWVsZCA9ICppYnVmcysrOwoJCQlmaWVsZCAtPSAqb2J1ZnM7CgkJCWlmIChmaWVsZCA+IDMyNzY3KSBmaWVsZCA9IDMyNzY3OwoJCQllbHNlIGlmIChmaWVsZCA8IC0zMjc2OCkgZmllbGQgPSAtMzI3Njg7CgkJCSpvYnVmcysrID0gZmllbGQ7CgkJfQoKCQlpZiAodG9kbyA8IChsZW4gLyAyKSkgewoJCQl0b2RvID0gKGxlbiAvIDIpIC0gdG9kbzsKCQkJb2J1ZnMgPSAoSU5UMTYgKilkc2ItPmRzb3VuZC0+YnVmZmVyOwoKCQkJZm9yIChpID0gMDsgaSA8IHRvZG87IGkrKykgewoJCQkJLyogMTYtYml0IFdBViBpcyBzaWduZWQgKi8KCQkJCWZpZWxkID0gKmlidWZzKys7CgkJCQlmaWVsZCAtPSAqb2J1ZnM7CgkJCQlpZiAoZmllbGQgPiAzMjc2NykgZmllbGQgPSAzMjc2NzsKCQkJCWVsc2UgaWYgKGZpZWxkIDwgLTMyNzY4KSBmaWVsZCA9IC0zMjc2ODsKCQkJCSpvYnVmcysrID0gZmllbGQ7CgkJCX0KCQl9CiAgICAgICAgfQp9CgpzdGF0aWMgdm9pZCBEU09VTkRfTWl4Q2FuY2VsKElEaXJlY3RTb3VuZEJ1ZmZlckltcGwgKmRzYiwgRFdPUkQgd3JpdGVwb3MsIEJPT0wgY2FuY2VsKQp7CglEV09SRCAgIHNpemUsIGZsZW4sIGxlbiwgbnBvcywgbmxlbjsKCUlOVAlpQWR2YW5jZSA9IGRzYi0+cHdmeC0+bkJsb2NrQWxpZ247CglJTlQJb0FkdmFuY2UgPSBkc2ItPmRzb3VuZC0+cHdmeC0+bkJsb2NrQWxpZ247CgkvKiBkZXRlcm1pbmUgYW1vdW50IG9mIHByZW1peGVkIGRhdGEgdG8gY2FuY2VsICovCglEV09SRCBwcmltYXJ5X2RvbmUgPQoJCSgoZHNiLT5wcmltYXJ5X21peHBvcyA8IHdyaXRlcG9zKSA/IGRzYi0+ZHNvdW5kLT5idWZsZW4gOiAwKSArCgkJZHNiLT5wcmltYXJ5X21peHBvcyAtIHdyaXRlcG9zOwoKCVRSQUNFKCIoJXAsICVsZCksIGJ1Zl9taXhwb3M9JWxkXG4iLCBkc2IsIHdyaXRlcG9zLCBkc2ItPmJ1Zl9taXhwb3MpOwoKCS8qIGJhY2t0cmFjayB0aGUgbWl4IHBvc2l0aW9uICovCglzaXplID0gcHJpbWFyeV9kb25lIC8gb0FkdmFuY2U7CglmbGVuID0gc2l6ZSAqIGRzYi0+ZnJlcUFkanVzdDsKCWxlbiA9IChmbGVuID4+IERTT1VORF9GUkVRU0hJRlQpICogaUFkdmFuY2U7CglmbGVuICY9ICgxPDxEU09VTkRfRlJFUVNISUZUKS0xOwoJd2hpbGUgKGRzYi0+ZnJlcUFjYyA8IGZsZW4pIHsKCQlsZW4gKz0gaUFkdmFuY2U7CgkJZHNiLT5mcmVxQWNjICs9IDE8PERTT1VORF9GUkVRU0hJRlQ7Cgl9CglsZW4gJT0gZHNiLT5idWZsZW47CglucG9zID0gKChkc2ItPmJ1Zl9taXhwb3MgPCBsZW4pID8gZHNiLT5idWZsZW4gOiAwKSArCgkJZHNiLT5idWZfbWl4cG9zIC0gbGVuOwoJaWYgKGRzYi0+bGVhZGluICYmIChkc2ItPnN0YXJ0cG9zID4gbnBvcykgJiYgKGRzYi0+c3RhcnRwb3MgPD0gbnBvcyArIGxlbikpIHsKCQkvKiBzdG9wIGJhY2t0cmFja2luZyBhdCBzdGFydHBvcyAqLwoJCW5wb3MgPSBkc2ItPnN0YXJ0cG9zOwoJCWxlbiA9ICgoZHNiLT5idWZfbWl4cG9zIDwgbnBvcykgPyBkc2ItPmJ1ZmxlbiA6IDApICsKCQkJZHNiLT5idWZfbWl4cG9zIC0gbnBvczsKCQlmbGVuID0gZHNiLT5mcmVxQWNjOwoJCW5sZW4gPSBsZW4gLyBkc2ItPnB3ZngtPm5CbG9ja0FsaWduOwoJCW5sZW4gPSAoKG5sZW4gPDwgRFNPVU5EX0ZSRVFTSElGVCkgKyBmbGVuKSAvIGRzYi0+ZnJlcUFkanVzdDsKCQlubGVuICo9IGRzYi0+ZHNvdW5kLT5wd2Z4LT5uQmxvY2tBbGlnbjsKCQl3cml0ZXBvcyA9CgkJCSgoZHNiLT5wcmltYXJ5X21peHBvcyA8IG5sZW4pID8gZHNiLT5kc291bmQtPmJ1ZmxlbiA6IDApICsKCQkJZHNiLT5wcmltYXJ5X21peHBvcyAtIG5sZW47Cgl9CgoJZHNiLT5mcmVxQWNjIC09IGZsZW47Cglkc2ItPmJ1Zl9taXhwb3MgPSBucG9zOwoJZHNiLT5wcmltYXJ5X21peHBvcyA9IHdyaXRlcG9zOwoKCVRSQUNFKCJuZXcgYnVmX21peHBvcz0lbGQsIHByaW1hcnlfbWl4cG9zPSVsZCAobGVuPSVsZClcbiIsCgkgICAgICBkc2ItPmJ1Zl9taXhwb3MsIGRzYi0+cHJpbWFyeV9taXhwb3MsIGxlbik7CgoJaWYgKGNhbmNlbCkgRFNPVU5EX1BoYXNlQ2FuY2VsKGRzYiwgd3JpdGVwb3MsIGxlbik7Cn0KCnZvaWQgRFNPVU5EX01peENhbmNlbEF0KElEaXJlY3RTb3VuZEJ1ZmZlckltcGwgKmRzYiwgRFdPUkQgYnVmX3dyaXRlcG9zKQp7CiNpZiAwCglEV09SRCAgIGksIHNpemUsIGZsZW4sIGxlbiwgbnBvcywgbmxlbjsKCUlOVAlpQWR2YW5jZSA9IGRzYi0+cHdmeC0+bkJsb2NrQWxpZ247CglJTlQJb0FkdmFuY2UgPSBkc2ItPmRzb3VuZC0+cHdmeC0+bkJsb2NrQWxpZ247CgkvKiBkZXRlcm1pbmUgYW1vdW50IG9mIHByZW1peGVkIGRhdGEgdG8gY2FuY2VsICovCglEV09SRCBidWZfZG9uZSA9CgkJKChkc2ItPmJ1Zl9taXhwb3MgPCBidWZfd3JpdGVwb3MpID8gZHNiLT5idWZsZW4gOiAwKSArCgkJZHNiLT5idWZfbWl4cG9zIC0gYnVmX3dyaXRlcG9zOwojZW5kaWYKCglXQVJOKCIoJXAsICVsZCksIGJ1Zl9taXhwb3M9JWxkXG4iLCBkc2IsIGJ1Zl93cml0ZXBvcywgZHNiLT5idWZfbWl4cG9zKTsKCS8qIHNpbmNlIHRoaXMgaXMgbm90IGltcGxlbWVudGVkIHlldCwganVzdCBjYW5jZWwgKkFMTCogcHJlYnVmZmVyaW5nIGZvciBub3cKCSAqICh3aGljaCBpcyBmYXN0ZXIgYW55d2F5IHdoZW4gdGhlcmUncyBvbmx5IGEgc2luZ2xlIHNlY29uZGFyeSBidWZmZXIpICovCglkc2ItPmRzb3VuZC0+bmVlZF9yZW1peCA9IFRSVUU7Cn0KCnZvaWQgRFNPVU5EX0ZvcmNlUmVtaXgoSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiKQp7CglUUkFDRSgiKCVwKVxuIixkc2IpOwoJRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRzYi0+bG9jayk7CglpZiAoZHNiLT5zdGF0ZSA9PSBTVEFURV9QTEFZSU5HKSB7CiNpZiAwIC8qIHRoaXMgbWF5IG5vdCBiZSBxdWl0ZSByZWxpYWJsZSB5ZXQgKi8KCQlkc2ItPm5lZWRfcmVtaXggPSBUUlVFOwojZWxzZQoJCWRzYi0+ZHNvdW5kLT5uZWVkX3JlbWl4ID0gVFJVRTsKI2VuZGlmCgl9CglMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZHNiLT5sb2NrKTsKfQoKc3RhdGljIERXT1JEIERTT1VORF9NaXhPbmUoSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiLCBEV09SRCBwbGF5cG9zLCBEV09SRCB3cml0ZXBvcywgRFdPUkQgbWl4bGVuKQp7CglEV09SRCBsZW4sIHNsZW47CgkvKiBkZXRlcm1pbmUgdGhpcyBidWZmZXIncyB3cml0ZSBwb3NpdGlvbiAqLwoJRFdPUkQgYnVmX3dyaXRlcG9zID0gRFNPVU5EX0NhbGNQbGF5UG9zaXRpb24oZHNiLCBkc2ItPnN0YXRlICYgZHNiLT5kc291bmQtPnN0YXRlLCB3cml0ZXBvcywKCQkJCQkJICAgICB3cml0ZXBvcywgZHNiLT5wcmltYXJ5X21peHBvcywgZHNiLT5idWZfbWl4cG9zKTsKCS8qIGRldGVybWluZSBob3cgbXVjaCBhbHJlYWR5LW1peGVkIGRhdGEgZXhpc3RzICovCglEV09SRCBidWZfZG9uZSA9CgkJKChkc2ItPmJ1Zl9taXhwb3MgPCBidWZfd3JpdGVwb3MpID8gZHNiLT5idWZsZW4gOiAwKSArCgkJZHNiLT5idWZfbWl4cG9zIC0gYnVmX3dyaXRlcG9zOwoJRFdPUkQgcHJpbWFyeV9kb25lID0KCQkoKGRzYi0+cHJpbWFyeV9taXhwb3MgPCB3cml0ZXBvcykgPyBkc2ItPmRzb3VuZC0+YnVmbGVuIDogMCkgKwoJCWRzYi0+cHJpbWFyeV9taXhwb3MgLSB3cml0ZXBvczsKCURXT1JEIGFkdl9kb25lID0KCQkoKGRzYi0+ZHNvdW5kLT5taXhwb3MgPCB3cml0ZXBvcykgPyBkc2ItPmRzb3VuZC0+YnVmbGVuIDogMCkgKwoJCWRzYi0+ZHNvdW5kLT5taXhwb3MgLSB3cml0ZXBvczsKCURXT1JEIHBsYXllZCA9CgkJKChidWZfd3JpdGVwb3MgPCBkc2ItPnBsYXlwb3MpID8gZHNiLT5idWZsZW4gOiAwKSArCgkJYnVmX3dyaXRlcG9zIC0gZHNiLT5wbGF5cG9zOwoJRFdPUkQgYnVmX2xlZnQgPSBkc2ItPmJ1ZmxlbiAtIGJ1Zl93cml0ZXBvczsKCWludCBzdGlsbF9iZWhpbmQ7CgoJVFJBQ0UoIiglcCwlbGQsJWxkLCVsZClcbiIsZHNiLHBsYXlwb3Msd3JpdGVwb3MsbWl4bGVuKTsKCVRSQUNFKCJidWZfd3JpdGVwb3M9JWxkLCBwcmltYXJ5X3dyaXRlcG9zPSVsZFxuIiwgYnVmX3dyaXRlcG9zLCB3cml0ZXBvcyk7CglUUkFDRSgiYnVmX2RvbmU9JWxkLCBwcmltYXJ5X2RvbmU9JWxkXG4iLCBidWZfZG9uZSwgcHJpbWFyeV9kb25lKTsKCVRSQUNFKCJidWZfbWl4cG9zPSVsZCwgcHJpbWFyeV9taXhwb3M9JWxkLCBtaXhsZW49JWxkXG4iLCBkc2ItPmJ1Zl9taXhwb3MsIGRzYi0+cHJpbWFyeV9taXhwb3MsCgkgICAgICBtaXhsZW4pOwoJVFJBQ0UoImxvb3Bpbmc9JWxkLCBzdGFydHBvcz0lbGQsIGxlYWRpbj0lbGRcbiIsIGRzYi0+cGxheWZsYWdzLCBkc2ItPnN0YXJ0cG9zLCBkc2ItPmxlYWRpbik7CgoJLyogY2hlY2sgZm9yIG5vdGlmaWNhdGlvbiBwb3NpdGlvbnMgKi8KCWlmIChkc2ItPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfQ1RSTFBPU0lUSU9OTk9USUZZICYmCgkgICAgZHNiLT5zdGF0ZSAhPSBTVEFURV9TVEFSVElORykgewoJCURTT1VORF9DaGVja0V2ZW50KGRzYiwgcGxheWVkKTsKCX0KCgkvKiBzYXZlIHdyaXRlIHBvc2l0aW9uIGZvciBub24tR0VUQ1VSUkVOVFBPU0lUSU9OMi4uLiAqLwoJZHNiLT5wbGF5cG9zID0gYnVmX3dyaXRlcG9zOwoKCS8qIGNoZWNrIHdoZXRoZXIgQ2FsY1BsYXlQb3NpdGlvbiBkZXRlY3RlZCBhIG1peGluZyB1bmRlcnJ1biAqLwoJaWYgKChidWZfZG9uZSA9PSAwKSAmJiAoZHNiLT5wcmltYXJ5X21peHBvcyAhPSB3cml0ZXBvcykpIHsKCQkvKiBpdCBkaWQsIGJ1dCBkaWQgd2UgaGF2ZSBtb3JlIHRvIHBsYXk/ICovCgkJaWYgKChkc2ItPnBsYXlmbGFncyAmIERTQlBMQVlfTE9PUElORykgfHwKCQkgICAgKGRzYi0+YnVmX21peHBvcyA8IGRzYi0+YnVmbGVuKSkgewoJCQkvKiB5ZXMsIGhhdmUgdG8gcmVjb3ZlciAqLwoJCQlFUlIoInVuZGVycnVuIG9uIHNvdW5kIGJ1ZmZlciAlcFxuIiwgZHNiKTsKCQkJVFJBQ0UoInJlY292ZXJpbmcgZnJvbSB1bmRlcnJ1bjogcHJpbWFyeV9taXhwb3M9JWxkXG4iLCB3cml0ZXBvcyk7CgkJfQoJCWRzYi0+cHJpbWFyeV9taXhwb3MgPSB3cml0ZXBvczsKCQlwcmltYXJ5X2RvbmUgPSAwOwoJfQoJLyogZGV0ZXJtaW5lIGhvdyBmYXIgYWhlYWQgd2Ugc2hvdWxkIG1peCAqLwoJaWYgKCgoZHNiLT5wbGF5ZmxhZ3MgJiBEU0JQTEFZX0xPT1BJTkcpIHx8CgkgICAgIChkc2ItPmxlYWRpbiAmJiAoZHNiLT5wcm9iYWJseV92YWxpZF90byAhPSAwKSkpICYmCgkgICAgIShkc2ItPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfU1RBVElDKSkgewoJCS8qIGlmIHRoaXMgaXMgYSBzdHJlYW1pbmcgYnVmZmVyLCBpdCB0eXBpY2FsbHkgbWVhbnMgdGhhdAoJCSAqIHdlIHNob3VsZCBkZWZlciBtaXhpbmcgcGFzdCBwcm9iYWJseV92YWxpZF90byBhcyBsb25nCgkJICogYXMgd2UgY2FuLCB0byBhdm9pZCB1bm5lY2Vzc2FyeSByZW1peGluZyAqLwoJCS8qIHRoZSBoZWF2eS1sb29raW5nIGNhbGN1bGF0aW9ucyBzaG91bGRuJ3QgYmUgdGhhdCBiYWQsCgkJICogYXMgYW55IGdhbWUgaXNuJ3QgbGlrZWx5IHRvIGJlIGhhdmUgbW9yZSB0aGFuIDEgb3IgMgoJCSAqIHN0cmVhbWluZyBidWZmZXJzIGluIHVzZSBhdCBhbnkgdGltZSBhbnl3YXkuLi4gKi8KCQlEV09SRCBwcm9iYWJseV92YWxpZF9sZWZ0ID0KCQkJKGRzYi0+cHJvYmFibHlfdmFsaWRfdG8gPT0gKERXT1JEKS0xKSA/IGRzYi0+YnVmbGVuIDoKCQkJKChkc2ItPnByb2JhYmx5X3ZhbGlkX3RvIDwgYnVmX3dyaXRlcG9zKSA/IGRzYi0+YnVmbGVuIDogMCkgKwoJCQlkc2ItPnByb2JhYmx5X3ZhbGlkX3RvIC0gYnVmX3dyaXRlcG9zOwoJCS8qIGNoZWNrIGZvciBsZWFkaW4gY29uZGl0aW9uICovCgkJaWYgKChwcm9iYWJseV92YWxpZF9sZWZ0ID09IDApICYmCgkJICAgIChkc2ItPnByb2JhYmx5X3ZhbGlkX3RvID09IGRzYi0+c3RhcnRwb3MpICYmCgkJICAgIGRzYi0+bGVhZGluKQoJCQlwcm9iYWJseV92YWxpZF9sZWZ0ID0gZHNiLT5idWZsZW47CgkJVFJBQ0UoInN0cmVhbWluZyBidWZmZXIgcHJvYmFibHlfdmFsaWRfdG89JWxkLCBwcm9iYWJseV92YWxpZF9sZWZ0PSVsZFxuIiwKCQkgICAgICBkc2ItPnByb2JhYmx5X3ZhbGlkX3RvLCBwcm9iYWJseV92YWxpZF9sZWZ0KTsKCQkvKiBjaGVjayB3aGV0aGVyIHRoZSBhcHAncyB0aW1lIGlzIGFscmVhZHkgdXAgKi8KCQlpZiAocHJvYmFibHlfdmFsaWRfbGVmdCA8IGRzYi0+d3JpdGVsZWFkKSB7CgkJCVdBUk4oInByb2JhYmx5X3ZhbGlkX3RvIG5vdyB3aXRoaW4gd3JpdGVsZWFkLCBwb3NzaWJsZSBzdHJlYW1pbmcgdW5kZXJydW5cbiIpOwoJCQkvKiBvbmNlIHdlIHBhc3MgdGhlIHBvaW50IG9mIG5vIHJldHVybiwKCQkJICogbm8gcmVhc29uIHRvIGhvbGQgYmFjayBhbnltb3JlICovCgkJCWRzYi0+cHJvYmFibHlfdmFsaWRfdG8gPSAoRFdPUkQpLTE7CgkJCS8qIHdlIGp1c3QgaGF2ZSB0byBnbyBhaGVhZCBhbmQgbWl4IHdoYXQgd2UgaGF2ZSwKCQkJICogdGhlcmUncyBubyB0ZWxsaW5nIHdoYXQgdGhlIGFwcCBpcyB0aGlua2luZyBhbnl3YXkgKi8KCQl9IGVsc2UgewoJCQkvKiBhZGp1c3QgZm9yIG91ciBmcmVxdWVuY3kgYW5kIG91ciBzYW1wbGUgc2l6ZSAqLwoJCQlwcm9iYWJseV92YWxpZF9sZWZ0ID0gTXVsRGl2KHByb2JhYmx5X3ZhbGlkX2xlZnQsCgkJCQkJCSAgICAgMSA8PCBEU09VTkRfRlJFUVNISUZULAoJCQkJCQkgICAgIGRzYi0+cHdmeC0+bkJsb2NrQWxpZ24gKiBkc2ItPmZyZXFBZGp1c3QpICoKCQkJCSAgICAgICAgICAgICAgZHNiLT5kc291bmQtPnB3ZngtPm5CbG9ja0FsaWduOwoJCQkvKiBjaGVjayB3aGV0aGVyIHRvIGNsaXAgbWl4X2xlbiAqLwoJCQlpZiAocHJvYmFibHlfdmFsaWRfbGVmdCA8IG1peGxlbikgewoJCQkJVFJBQ0UoImNsaXBwaW5nIHRvIHByb2JhYmx5X3ZhbGlkX2xlZnQ9JWxkXG4iLCBwcm9iYWJseV92YWxpZF9sZWZ0KTsKCQkJCW1peGxlbiA9IHByb2JhYmx5X3ZhbGlkX2xlZnQ7CgkJCX0KCQl9Cgl9CgkvKiBjdXQgbWl4bGVuIHdpdGggd2hhdCdzIGFscmVhZHkgYmVlbiBtaXhlZCAqLwoJaWYgKG1peGxlbiA8IHByaW1hcnlfZG9uZSkgewoJCS8qIGh1aD8gYW5kIHN0aWxsIENhbGNQbGF5UG9zaXRpb24gZGlkbid0CgkJICogZGV0ZWN0IGFuIHVuZGVycnVuPyAqLwoJCUZJWE1FKCJwcm9ibGVtIHdpdGggdW5kZXJydW4gZGV0ZWN0aW9uIChtaXhsZW49JWxkIDwgcHJpbWFyeV9kb25lPSVsZClcbiIsIG1peGxlbiwgcHJpbWFyeV9kb25lKTsKCQlyZXR1cm4gMDsKCX0KCWxlbiA9IG1peGxlbiAtIHByaW1hcnlfZG9uZTsKCVRSQUNFKCJyZW1haW5pbmcgbWl4bGVuPSVsZFxuIiwgbGVuKTsKCglpZiAobGVuIDwgZHNiLT5kc291bmQtPmZyYWdsZW4pIHsKCQkvKiBzbWFsbGVyIHRoYW4gYSBmcmFnbWVudCwgd2FpdCB1bnRpbCBpdCBnZXRzIGxhcmdlcgoJCSAqIGJlZm9yZSB3ZSB0YWtlIHRoZSBtaXhpbmcgb3ZlcmhlYWQgKi8KCQlUUkFDRSgibWl4bGVuIG5vdCB3b3J0aCBpdCwgZGVmZXJyaW5nIG1peGluZ1xuIik7CgkJc3RpbGxfYmVoaW5kID0gMTsKCQlnb3RvIHBvc3RfbWl4OwoJfQoKCS8qIG9rLCB3ZSBrbm93IGhvdyBtdWNoIHRvIG1peCwgbGV0J3MgZ28gKi8KCXN0aWxsX2JlaGluZCA9IChhZHZfZG9uZSA+IHByaW1hcnlfZG9uZSk7Cgl3aGlsZSAobGVuKSB7CgkJc2xlbiA9IGRzYi0+ZHNvdW5kLT5idWZsZW4gLSBkc2ItPnByaW1hcnlfbWl4cG9zOwoJCWlmIChzbGVuID4gbGVuKSBzbGVuID0gbGVuOwoJCXNsZW4gPSBEU09VTkRfTWl4SW5CdWZmZXIoZHNiLCBkc2ItPnByaW1hcnlfbWl4cG9zLCBzbGVuKTsKCgkJaWYgKChkc2ItPnByaW1hcnlfbWl4cG9zIDwgZHNiLT5kc291bmQtPm1peHBvcykgJiYKCQkgICAgKGRzYi0+cHJpbWFyeV9taXhwb3MgKyBzbGVuID49IGRzYi0+ZHNvdW5kLT5taXhwb3MpKQoJCQlzdGlsbF9iZWhpbmQgPSBGQUxTRTsKCgkJZHNiLT5wcmltYXJ5X21peHBvcyArPSBzbGVuOyBsZW4gLT0gc2xlbjsKCQlkc2ItPnByaW1hcnlfbWl4cG9zICU9IGRzYi0+ZHNvdW5kLT5idWZsZW47CgoJCWlmICgoZHNiLT5zdGF0ZSA9PSBTVEFURV9TVE9QUEVEKSB8fCAhc2xlbikgYnJlYWs7Cgl9CglUUkFDRSgibmV3IHByaW1hcnlfbWl4cG9zPSVsZCwgcHJpbWFyeV9hZHZiYXNlPSVsZFxuIiwgZHNiLT5wcmltYXJ5X21peHBvcywgZHNiLT5kc291bmQtPm1peHBvcyk7CglUUkFDRSgibWl4ZWQgZGF0YSBsZW49JWxkLCBzdGlsbF9iZWhpbmQ9JWRcbiIsIG1peGxlbi1sZW4sIHN0aWxsX2JlaGluZCk7Cgpwb3N0X21peDoKCS8qIGNoZWNrIGlmIGJ1ZmZlciBzaG91bGQgYmUgY29uc2lkZXJlZCBjb21wbGV0ZSAqLwoJaWYgKGJ1Zl9sZWZ0IDwgZHNiLT53cml0ZWxlYWQgJiYKCSAgICAhKGRzYi0+cGxheWZsYWdzICYgRFNCUExBWV9MT09QSU5HKSkgewoJCWRzYi0+c3RhdGUgPSBTVEFURV9TVE9QUEVEOwoJCWRzYi0+cGxheXBvcyA9IDA7CgkJZHNiLT5sYXN0X3BsYXlwb3MgPSAwOwoJCWRzYi0+YnVmX21peHBvcyA9IDA7CgkJZHNiLT5sZWFkaW4gPSBGQUxTRTsKCQlEU09VTkRfQ2hlY2tFdmVudChkc2IsIGJ1Zl9sZWZ0KTsKCX0KCgkvKiByZXR1cm4gaG93IGZhciB3ZSB0aGluayB0aGUgcHJpbWFyeSBidWZmZXIgY2FuCgkgKiBhZHZhbmNlIGl0cyB1bmRlcnJ1biBkZXRlY3Rvci4uLiovCglpZiAoc3RpbGxfYmVoaW5kKSByZXR1cm4gMDsKCWlmICgobWl4bGVuIC0gbGVuKSA8IHByaW1hcnlfZG9uZSkgcmV0dXJuIDA7CglzbGVuID0gKChkc2ItPnByaW1hcnlfbWl4cG9zIDwgZHNiLT5kc291bmQtPm1peHBvcykgPwoJCWRzYi0+ZHNvdW5kLT5idWZsZW4gOiAwKSArIGRzYi0+cHJpbWFyeV9taXhwb3MgLQoJCWRzYi0+ZHNvdW5kLT5taXhwb3M7CglpZiAoc2xlbiA+IG1peGxlbikgewoJCS8qIHRoZSBwcmltYXJ5X2RvbmUgYW5kIHN0aWxsX2JlaGluZCBjaGVja3MgYWJvdmUgc2hvdWxkIGhhdmUgd29ya2VkICovCgkJRklYTUUoInByb2JsZW0gd2l0aCBhZHZhbmNlbWVudCBjYWxjdWxhdGlvbiAoYWR2bGVuPSVsZCA+IG1peGxlbj0lbGQpXG4iLCBzbGVuLCBtaXhsZW4pOwoJCXNsZW4gPSAwOwoJfQoJcmV0dXJuIHNsZW47Cn0KCnN0YXRpYyBEV09SRCBEU09VTkRfTWl4VG9QcmltYXJ5KElEaXJlY3RTb3VuZEltcGwgKmRzb3VuZCwgRFdPUkQgcGxheXBvcywgRFdPUkQgd3JpdGVwb3MsIERXT1JEIG1peGxlbiwgQk9PTCByZWNvdmVyKQp7CglJTlQJCQlpLCBsZW4sIG1heGxlbiA9IDA7CglJRGlyZWN0U291bmRCdWZmZXJJbXBsCSpkc2I7CgoJVFJBQ0UoIiglbGQsJWxkLCVsZCwlZClcbiIsIHBsYXlwb3MsIHdyaXRlcG9zLCBtaXhsZW4sIHJlY292ZXIpOwoJZm9yIChpID0gMDsgaSA8IGRzb3VuZC0+bnJvZmJ1ZmZlcnM7IGkrKykgewoJCWRzYiA9IGRzb3VuZC0+YnVmZmVyc1tpXTsKCgkJaWYgKGRzYi0+YnVmbGVuICYmIGRzYi0+c3RhdGUgJiYgIWRzYi0+aHdidWYpIHsKCQkJVFJBQ0UoIkNoZWNraW5nICVwLCBtaXhsZW49JWxkXG4iLCBkc2IsIG1peGxlbik7CgkJCUVudGVyQ3JpdGljYWxTZWN0aW9uKCYoZHNiLT5sb2NrKSk7CgkJCWlmIChkc2ItPnN0YXRlID09IFNUQVRFX1NUT1BQSU5HKSB7CgkJCQlEU09VTkRfTWl4Q2FuY2VsKGRzYiwgd3JpdGVwb3MsIFRSVUUpOwoJCQkJZHNiLT5zdGF0ZSA9IFNUQVRFX1NUT1BQRUQ7CgkJCQlEU09VTkRfQ2hlY2tFdmVudChkc2IsIDApOwoJCQl9IGVsc2UgewoJCQkJaWYgKChkc2ItPnN0YXRlID09IFNUQVRFX1NUQVJUSU5HKSB8fCByZWNvdmVyKSB7CgkJCQkJZHNiLT5wcmltYXJ5X21peHBvcyA9IHdyaXRlcG9zOwoJCQkJCWRzYi0+Y3ZvbHBhbiA9IGRzYi0+dm9scGFuOwoJCQkJCWRzYi0+bmVlZF9yZW1peCA9IEZBTFNFOwoJCQkJfQoJCQkJZWxzZSBpZiAoZHNiLT5uZWVkX3JlbWl4KSB7CgkJCQkJRFNPVU5EX01peENhbmNlbChkc2IsIHdyaXRlcG9zLCBUUlVFKTsKCQkJCQlkc2ItPmN2b2xwYW4gPSBkc2ItPnZvbHBhbjsKCQkJCQlkc2ItPm5lZWRfcmVtaXggPSBGQUxTRTsKCQkJCX0KCQkJCWxlbiA9IERTT1VORF9NaXhPbmUoZHNiLCBwbGF5cG9zLCB3cml0ZXBvcywgbWl4bGVuKTsKCQkJCWlmIChkc2ItPnN0YXRlID09IFNUQVRFX1NUQVJUSU5HKQoJCQkJCWRzYi0+c3RhdGUgPSBTVEFURV9QTEFZSU5HOwoJCQkJbWF4bGVuID0gKGxlbiA+IG1heGxlbikgPyBsZW4gOiBtYXhsZW47CgkJCX0KCQkJTGVhdmVDcml0aWNhbFNlY3Rpb24oJihkc2ItPmxvY2spKTsKCQl9Cgl9CgoJcmV0dXJuIG1heGxlbjsKfQoKc3RhdGljIHZvaWQgRFNPVU5EX01peFJlc2V0KElEaXJlY3RTb3VuZEltcGwgKmRzb3VuZCwgRFdPUkQgd3JpdGVwb3MpCnsKCUlOVAkJCWk7CglJRGlyZWN0U291bmRCdWZmZXJJbXBsCSpkc2I7CglpbnQgbmZpbGxlcjsKCglUUkFDRSgiKCVsZClcbiIsIHdyaXRlcG9zKTsKCgkvKiB0aGUgc291bmQgb2Ygc2lsZW5jZSAqLwoJbmZpbGxlciA9IGRzb3VuZC0+cHdmeC0+d0JpdHNQZXJTYW1wbGUgPT0gOCA/IDEyOCA6IDA7CgoJLyogcmVzZXQgYWxsIGJ1ZmZlciBtaXggcG9zaXRpb25zICovCglmb3IgKGkgPSAwOyBpIDwgZHNvdW5kLT5ucm9mYnVmZmVyczsgaSsrKSB7CgkJZHNiID0gZHNvdW5kLT5idWZmZXJzW2ldOwoKCQlpZiAoZHNiLT5idWZsZW4gJiYgZHNiLT5zdGF0ZSAmJiAhZHNiLT5od2J1ZikgewoJCQlUUkFDRSgiUmVzZXR0aW5nICVwXG4iLCBkc2IpOwoJCQlFbnRlckNyaXRpY2FsU2VjdGlvbigmKGRzYi0+bG9jaykpOwoJCQlpZiAoZHNiLT5zdGF0ZSA9PSBTVEFURV9TVE9QUElORykgewoJCQkJZHNiLT5zdGF0ZSA9IFNUQVRFX1NUT1BQRUQ7CgkJCX0KCQkJZWxzZSBpZiAoZHNiLT5zdGF0ZSA9PSBTVEFURV9TVEFSVElORykgewoJCQkJLyogbm90aGluZyAqLwoJCQl9IGVsc2UgewoJCQkJRFNPVU5EX01peENhbmNlbChkc2IsIHdyaXRlcG9zLCBGQUxTRSk7CgkJCQlkc2ItPmN2b2xwYW4gPSBkc2ItPnZvbHBhbjsKCQkJCWRzYi0+bmVlZF9yZW1peCA9IEZBTFNFOwoJCQl9CgkJCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCYoZHNiLT5sb2NrKSk7CgkJfQoJfQoKCS8qIHdpcGUgb3V0IHByZW1peGVkIGRhdGEgKi8KCWlmIChkc291bmQtPm1peHBvcyA8IHdyaXRlcG9zKSB7CgkJRmlsbE1lbW9yeShkc291bmQtPmJ1ZmZlciArIHdyaXRlcG9zLCBkc291bmQtPmJ1ZmxlbiAtIHdyaXRlcG9zLCBuZmlsbGVyKTsKCQlGaWxsTWVtb3J5KGRzb3VuZC0+YnVmZmVyLCBkc291bmQtPm1peHBvcywgbmZpbGxlcik7Cgl9IGVsc2UgewoJCUZpbGxNZW1vcnkoZHNvdW5kLT5idWZmZXIgKyB3cml0ZXBvcywgZHNvdW5kLT5taXhwb3MgLSB3cml0ZXBvcywgbmZpbGxlcik7Cgl9CgoJLyogcmVzZXQgcHJpbWFyeSBtaXggcG9zaXRpb24gKi8KCWRzb3VuZC0+bWl4cG9zID0gd3JpdGVwb3M7Cn0KCnN0YXRpYyB2b2lkIERTT1VORF9DaGVja1Jlc2V0KElEaXJlY3RTb3VuZEltcGwgKmRzb3VuZCwgRFdPUkQgd3JpdGVwb3MpCnsKCVRSQUNFKCIoJXAsJWxkKVxuIixkc291bmQsd3JpdGVwb3MpOwoJaWYgKGRzb3VuZC0+bmVlZF9yZW1peCkgewoJCURTT1VORF9NaXhSZXNldChkc291bmQsIHdyaXRlcG9zKTsKCQlkc291bmQtPm5lZWRfcmVtaXggPSBGQUxTRTsKCQkvKiBtYXhpbWl6ZSBIYWxmLUxpZmUgcGVyZm9ybWFuY2UgKi8KCQlkc291bmQtPnByZWJ1ZiA9IGRzX3NuZF9xdWV1ZV9taW47CgkJZHNvdW5kLT5wcmVjb3VudCA9IDA7Cgl9IGVsc2UgewoJCWRzb3VuZC0+cHJlY291bnQrKzsKCQlpZiAoZHNvdW5kLT5wcmVjb3VudCA+PSA0KSB7CgkJCWlmIChkc291bmQtPnByZWJ1ZiA8IGRzX3NuZF9xdWV1ZV9tYXgpCgkJCQlkc291bmQtPnByZWJ1ZisrOwoJCQlkc291bmQtPnByZWNvdW50ID0gMDsKCQl9Cgl9CglUUkFDRSgicHJlbWl4IGFkanVzdDogJWRcbiIsIGRzb3VuZC0+cHJlYnVmKTsKfQoKdm9pZCBEU09VTkRfV2F2ZVF1ZXVlKElEaXJlY3RTb3VuZEltcGwgKmRzb3VuZCwgRFdPUkQgbWl4cSkKewoJVFJBQ0UoIiglcCwlbGQpXG4iLGRzb3VuZCxtaXhxKTsKCWlmIChtaXhxICsgZHNvdW5kLT5wd3F1ZXVlID4gZHNfaGVsX3F1ZXVlKSBtaXhxID0gZHNfaGVsX3F1ZXVlIC0gZHNvdW5kLT5wd3F1ZXVlOwoJVFJBQ0UoInF1ZXVlaW5nICVsZCBidWZmZXJzLCBzdGFydGluZyBhdCAlZFxuIiwgbWl4cSwgZHNvdW5kLT5wd3dyaXRlKTsKCWZvciAoOyBtaXhxOyBtaXhxLS0pIHsKCQl3YXZlT3V0V3JpdGUoZHNvdW5kLT5od28sIGRzb3VuZC0+cHdhdmVbZHNvdW5kLT5wd3dyaXRlXSwgc2l6ZW9mKFdBVkVIRFIpKTsKCQlkc291bmQtPnB3d3JpdGUrKzsKCQlpZiAoZHNvdW5kLT5wd3dyaXRlID49IERTX0hFTF9GUkFHUykgZHNvdW5kLT5wd3dyaXRlID0gMDsKCQlkc291bmQtPnB3cXVldWUrKzsKCX0KfQoKLyogI2RlZmluZSBTWU5DX0NBTExCQUNLICovCgp2b2lkIERTT1VORF9QZXJmb3JtTWl4KElEaXJlY3RTb3VuZEltcGwgKmRzb3VuZCkKewoJaW50IG5maWxsZXI7CglCT09MIGZvcmNlZDsKCUhSRVNVTFQgaHJlczsKCglUUkFDRSgiKCVwKVxuIiwgZHNvdW5kKTsKCgkvKiB0aGUgc291bmQgb2Ygc2lsZW5jZSAqLwoJbmZpbGxlciA9IGRzb3VuZC0+cHdmeC0+d0JpdHNQZXJTYW1wbGUgPT0gOCA/IDEyOCA6IDA7CgoJLyogd2hldGhlciB0aGUgcHJpbWFyeSBpcyBmb3JjZWQgdG8gcGxheSBldmVuIHdpdGhvdXQgc2Vjb25kYXJ5IGJ1ZmZlcnMgKi8KCWZvcmNlZCA9ICgoZHNvdW5kLT5zdGF0ZSA9PSBTVEFURV9QTEFZSU5HKSB8fCAoZHNvdW5kLT5zdGF0ZSA9PSBTVEFURV9TVEFSVElORykpOwoKCWlmIChkc291bmQtPnByaW9sZXZlbCAhPSBEU1NDTF9XUklURVBSSU1BUlkpIHsKCQlCT09MIHBhdXNlZCA9ICgoZHNvdW5kLT5zdGF0ZSA9PSBTVEFURV9TVE9QUEVEKSB8fCAoZHNvdW5kLT5zdGF0ZSA9PSBTVEFURV9TVEFSVElORykpOwoJCS8qIEZJWE1FOiBkb2N1bWVudCB2YXJpYWJsZXMgKi8KIAkJRFdPUkQgcGxheXBvcywgd3JpdGVwb3MsIGlucSwgbWF4cSwgZnJhZzsKIAkJaWYgKGRzb3VuZC0+aHdidWYpIHsKCQkJaHJlcyA9IElEc0RyaXZlckJ1ZmZlcl9HZXRQb3NpdGlvbihkc291bmQtPmh3YnVmLCAmcGxheXBvcywgJndyaXRlcG9zKTsKCQkJaWYgKGhyZXMpIHsKCQkJICAgIFdBUk4oIklEc0RyaXZlckJ1ZmZlcl9HZXRQb3NpdGlvbiBmYWlsZWRcbiIpOwoJCQkgICAgcmV0dXJuOwoJCQl9CgkJCS8qIFdlbGwsIHdlICpjb3VsZCogZG8gSnVzdC1Jbi1UaW1lIG1peGluZyB1c2luZyB0aGUgd3JpdGVwb3MsCgkJCSAqIGJ1dCB0aGF0J3MgYSBsaXR0bGUgYml0IGFtYml0aW91cyBhbmQgdW5uZWNlc3NhcnkuLi4gKi8KCQkJLyogcmF0aGVyIGFkZCBvdXIgc2FmZXR5IG1hcmdpbiB0byB0aGUgd3JpdGVwb3MsIGlmIHdlJ3JlIHBsYXlpbmcgKi8KCQkJaWYgKCFwYXVzZWQpIHsKCQkJCXdyaXRlcG9zICs9IGRzb3VuZC0+d3JpdGVsZWFkOwoJCQkJd3JpdGVwb3MgJT0gZHNvdW5kLT5idWZsZW47CgkJCX0gZWxzZSB3cml0ZXBvcyA9IHBsYXlwb3M7CgkJfSBlbHNlIHsKIAkJCXBsYXlwb3MgPSBkc291bmQtPnB3cGxheSAqIGRzb3VuZC0+ZnJhZ2xlbjsKIAkJCXdyaXRlcG9zID0gcGxheXBvczsKIAkJCWlmICghcGF1c2VkKSB7CgkgCQkJd3JpdGVwb3MgKz0gZHNfaGVsX21hcmdpbiAqIGRzb3VuZC0+ZnJhZ2xlbjsKIAkJCQl3cml0ZXBvcyAlPSBkc291bmQtPmJ1ZmxlbjsKCSAJCX0KCQl9CgkJVFJBQ0UoInByaW1hcnkgcGxheXBvcz0lbGQsIHdyaXRlcG9zPSVsZCwgY2xycG9zPSVsZCwgbWl4cG9zPSVsZCwgYnVmbGVuPSVsZFxuIiwKCQkgICAgICBwbGF5cG9zLHdyaXRlcG9zLGRzb3VuZC0+cGxheXBvcyxkc291bmQtPm1peHBvcyxkc291bmQtPmJ1Zmxlbik7CgkJYXNzZXJ0KGRzb3VuZC0+cGxheXBvcyA8IGRzb3VuZC0+YnVmbGVuKTsKCQkvKiB3aXBlIG91dCBqdXN0LXBsYXllZCBzb3VuZCBkYXRhICovCgkJaWYgKHBsYXlwb3MgPCBkc291bmQtPnBsYXlwb3MpIHsKCQkJRmlsbE1lbW9yeShkc291bmQtPmJ1ZmZlciArIGRzb3VuZC0+cGxheXBvcywgZHNvdW5kLT5idWZsZW4gLSBkc291bmQtPnBsYXlwb3MsIG5maWxsZXIpOwoJCQlGaWxsTWVtb3J5KGRzb3VuZC0+YnVmZmVyLCBwbGF5cG9zLCBuZmlsbGVyKTsKCQl9IGVsc2UgewoJCQlGaWxsTWVtb3J5KGRzb3VuZC0+YnVmZmVyICsgZHNvdW5kLT5wbGF5cG9zLCBwbGF5cG9zIC0gZHNvdW5kLT5wbGF5cG9zLCBuZmlsbGVyKTsKCQl9CgkJZHNvdW5kLT5wbGF5cG9zID0gcGxheXBvczsKCgkJRW50ZXJDcml0aWNhbFNlY3Rpb24oJihkc291bmQtPm1peGxvY2spKTsKCgkJLyogcmVzZXQgbWl4aW5nIGlmIG5lY2Vzc2FyeSAqLwoJCURTT1VORF9DaGVja1Jlc2V0KGRzb3VuZCwgd3JpdGVwb3MpOwoKCQkvKiBjaGVjayBob3cgbXVjaCBwcmVidWZmZXJpbmcgaXMgbGVmdCAqLwoJCWlucSA9IGRzb3VuZC0+bWl4cG9zOwoJCWlmIChpbnEgPCB3cml0ZXBvcykKCQkJaW5xICs9IGRzb3VuZC0+YnVmbGVuOwoJCWlucSAtPSB3cml0ZXBvczsKCgkJLyogZmluZCB0aGUgbWF4aW11bSB3ZSBjYW4gcHJlYnVmZmVyICovCgkJaWYgKCFwYXVzZWQpIHsKCQkJbWF4cSA9IHBsYXlwb3M7CgkJCWlmIChtYXhxIDwgd3JpdGVwb3MpCgkJCQltYXhxICs9IGRzb3VuZC0+YnVmbGVuOwoJCQltYXhxIC09IHdyaXRlcG9zOwoJCX0gZWxzZSBtYXhxID0gZHNvdW5kLT5idWZsZW47CgoJCS8qIGNsaXAgbWF4cSB0byBkc291bmQtPnByZWJ1ZiAqLwoJCWZyYWcgPSBkc291bmQtPnByZWJ1ZiAqIGRzb3VuZC0+ZnJhZ2xlbjsKCQlpZiAobWF4cSA+IGZyYWcpIG1heHEgPSBmcmFnOwoKCQkvKiBjaGVjayBmb3IgY29uc2lzdGVuY3kgKi8KCQlpZiAoaW5xID4gbWF4cSkgewoJCQkvKiB0aGUgcGxheWJhY2sgcG9zaXRpb24gbXVzdCBoYXZlIHBhc3NlZCBvdXIgbGFzdAoJCQkgKiBtaXhlZCBwb3NpdGlvbiwgaS5lLiBpdCdzIGFuIHVuZGVycnVuLCBvciB3ZSBoYXZlCgkJCSAqIG5vdGhpbmcgbW9yZSB0byBwbGF5ICovCgkJCVRSQUNFKCJyZWFjaGVkIGVuZCBvZiBtaXhlZCBkYXRhIChpbnE9JWxkLCBtYXhxPSVsZClcbiIsIGlucSwgbWF4cSk7CgkJCWlucSA9IDA7CgkJCS8qIHN0b3AgdGhlIHBsYXliYWNrIG5vdywgdG8gYWxsb3cgYnVmZmVycyB0byByZWZpbGwgKi8KCQkJaWYgKGRzb3VuZC0+c3RhdGUgPT0gU1RBVEVfUExBWUlORykgewoJCQkJZHNvdW5kLT5zdGF0ZSA9IFNUQVRFX1NUQVJUSU5HOwoJCQl9CgkJCWVsc2UgaWYgKGRzb3VuZC0+c3RhdGUgPT0gU1RBVEVfU1RPUFBJTkcpIHsKCQkJCWRzb3VuZC0+c3RhdGUgPSBTVEFURV9TVE9QUEVEOwoJCQl9CgkJCWVsc2UgewoJCQkJLyogaG93IGNhbiB3ZSBoYXZlIGFuIHVuZGVycnVuIGlmIHdlIGFyZW4ndCBwbGF5aW5nPyAqLwoJCQkJV0FSTigidW5leHBlY3RlZCBwcmltYXJ5IHN0YXRlICglbGQpXG4iLCBkc291bmQtPnN0YXRlKTsKCQkJfQojaWZkZWYgU1lOQ19DQUxMQkFDSwoJCQkvKiBEU09VTkRfY2FsbGJhY2sgbWF5IG5lZWQgdGhpcyBsb2NrICovCgkJCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCYoZHNvdW5kLT5taXhsb2NrKSk7CiNlbmRpZgoJCQlpZiAoRFNPVU5EX1ByaW1hcnlTdG9wKGRzb3VuZCkgIT0gRFNfT0spCgkJCQlXQVJOKCJEU09VTkRfUHJpbWFyeVN0b3AgZmFpbGVkXG4iKTsKI2lmZGVmIFNZTkNfQ0FMTEJBQ0sKCQkJRW50ZXJDcml0aWNhbFNlY3Rpb24oJihkc291bmQtPm1peGxvY2spKTsKI2VuZGlmCgkJCWlmIChkc291bmQtPmh3YnVmKSB7CgkJCQkvKiB0aGUgU3RvcCBpcyBzdXBwb3NlZCB0byByZXNldCBwbGF5IHBvc2l0aW9uIHRvIGJlZ2lubmluZyBvZiBidWZmZXIgKi8KCQkJCS8qIHVuZm9ydHVuYXRlbHksIE9TUyBpcyBub3QgYWJsZSB0byBkbyBzbywgc28gZ2V0IGN1cnJlbnQgcG9pbnRlciAqLwoJCQkJaHJlcyA9IElEc0RyaXZlckJ1ZmZlcl9HZXRQb3NpdGlvbihkc291bmQtPmh3YnVmLCAmcGxheXBvcywgTlVMTCk7CgkJCQlpZiAoaHJlcykgewoJCQkJCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCYoZHNvdW5kLT5taXhsb2NrKSk7CgkJCQkJV0FSTigiSURzRHJpdmVyQnVmZmVyX0dldFBvc2l0aW9uIGZhaWxlZFxuIik7CgkJCQkJcmV0dXJuOwoJCQkJfQoJCQl9IGVsc2UgewoJIAkJCXBsYXlwb3MgPSBkc291bmQtPnB3cGxheSAqIGRzb3VuZC0+ZnJhZ2xlbjsKCQkJfQoJCQl3cml0ZXBvcyA9IHBsYXlwb3M7CgkJCWRzb3VuZC0+cGxheXBvcyA9IHBsYXlwb3M7CgkJCWRzb3VuZC0+bWl4cG9zID0gd3JpdGVwb3M7CgkJCWlucSA9IDA7CgkJCW1heHEgPSBkc291bmQtPmJ1ZmxlbjsKCQkJaWYgKG1heHEgPiBmcmFnKSBtYXhxID0gZnJhZzsKCQkJRmlsbE1lbW9yeShkc291bmQtPmJ1ZmZlciwgZHNvdW5kLT5idWZsZW4sIG5maWxsZXIpOwoJCQlwYXVzZWQgPSBUUlVFOwoJCX0KCgkJLyogZG8gdGhlIG1peGluZyAqLwoJCWZyYWcgPSBEU09VTkRfTWl4VG9QcmltYXJ5KGRzb3VuZCwgcGxheXBvcywgd3JpdGVwb3MsIG1heHEsIHBhdXNlZCk7CgkJaWYgKGZvcmNlZCkgZnJhZyA9IG1heHEgLSBpbnE7CgkJZHNvdW5kLT5taXhwb3MgKz0gZnJhZzsKCQlkc291bmQtPm1peHBvcyAlPSBkc291bmQtPmJ1ZmxlbjsKCgkJaWYgKGZyYWcpIHsKCQkJLyogYnVmZmVycyBoYXZlIGJlZW4gZmlsbGVkLCByZXN0YXJ0IHBsYXliYWNrICovCgkJCWlmIChkc291bmQtPnN0YXRlID09IFNUQVRFX1NUQVJUSU5HKSB7CgkJCQlkc291bmQtPnN0YXRlID0gU1RBVEVfUExBWUlORzsKCQkJfQoJCQllbHNlIGlmIChkc291bmQtPnN0YXRlID09IFNUQVRFX1NUT1BQRUQpIHsKCQkJCS8qIHRoZSBkc291bmQgaXMgc3VwcG9zZWQgdG8gcGxheSBpZiB0aGVyZSdzIHNvbWV0aGluZyB0byBwbGF5CgkJCQkgKiBldmVuIGlmIGl0IGlzIHJlcG9ydGVkIGFzIHN0b3BwZWQsIHNvIGRvbid0IGxldCB0aGlzIGNvbmZ1c2UgeW91ICovCgkJCQlkc291bmQtPnN0YXRlID0gU1RBVEVfU1RPUFBJTkc7CgkJCX0KCQkJTGVhdmVDcml0aWNhbFNlY3Rpb24oJihkc291bmQtPm1peGxvY2spKTsKCQkJaWYgKHBhdXNlZCkgewoJCQkJaWYgKERTT1VORF9QcmltYXJ5UGxheShkc291bmQpICE9IERTX09LKQoJCQkJCVdBUk4oIkRTT1VORF9QcmltYXJ5UGxheSBmYWlsZWRcbiIpOwoJCQkJZWxzZQoJCQkJCVRSQUNFKCJzdGFydGluZyBwbGF5YmFja1xuIik7CgkJCX0KCQl9CgkJZWxzZQoJCQlMZWF2ZUNyaXRpY2FsU2VjdGlvbigmKGRzb3VuZC0+bWl4bG9jaykpOwoJfSBlbHNlIHsKCQkvKiBpbiB0aGUgRFNTQ0xfV1JJVEVQUklNQVJZIG1vZGUsIHRoZSBhcHAgaXMgdG90YWxseSBpbiBjaGFyZ2UuLi4gKi8KCQlpZiAoZHNvdW5kLT5zdGF0ZSA9PSBTVEFURV9TVEFSVElORykgewoJCQlpZiAoRFNPVU5EX1ByaW1hcnlQbGF5KGRzb3VuZCkgIT0gRFNfT0spCgkJCQlXQVJOKCJEU09VTkRfUHJpbWFyeVBsYXkgZmFpbGVkXG4iKTsKCQkJZWxzZQoJCQkJZHNvdW5kLT5zdGF0ZSA9IFNUQVRFX1BMQVlJTkc7CgkJfQoJCWVsc2UgaWYgKGRzb3VuZC0+c3RhdGUgPT0gU1RBVEVfU1RPUFBJTkcpIHsKCQkJaWYgKERTT1VORF9QcmltYXJ5U3RvcChkc291bmQpICE9IERTX09LKQoJCQkJV0FSTigiRFNPVU5EX1ByaW1hcnlTdG9wIGZhaWxlZFxuIik7CgkJCWVsc2UKCQkJCWRzb3VuZC0+c3RhdGUgPSBTVEFURV9TVE9QUEVEOwoJCX0KCX0KfQoKdm9pZCBDQUxMQkFDSyBEU09VTkRfdGltZXIoVUlOVCB0aW1lcklELCBVSU5UIG1zZywgRFdPUkQgZHdVc2VyLCBEV09SRCBkdzEsIERXT1JEIGR3MikKewogICAgICAgIElEaXJlY3RTb3VuZEltcGwqIFRoaXMgPSAoSURpcmVjdFNvdW5kSW1wbCopZHdVc2VyOwoJRFdPUkQgc3RhcnRfdGltZSA9ICBHZXRUaWNrQ291bnQoKTsKICAgICAgICBEV09SRCBlbmRfdGltZTsKCVRSQUNFKCIoJWQsJWQsMHglbHgsMHglbHgsMHglbHgpXG4iLHRpbWVySUQsbXNnLGR3VXNlcixkdzEsZHcyKTsKICAgICAgICBUUkFDRSgiZW50ZXJpbmcgYXQgJWxkXG4iLCBzdGFydF90aW1lKTsKCglpZiAoZHNvdW5kICE9IFRoaXMpIHsKCQlFUlIoImRzb3VuZCBkaWVkIHdpdGhvdXQga2lsbGluZyB1cz9cbiIpOwoJCXRpbWVLaWxsRXZlbnQodGltZXJJRCk7CgkJdGltZUVuZFBlcmlvZChEU19USU1FX1JFUyk7CgkJcmV0dXJuOwoJfQoKCVJ0bEFjcXVpcmVSZXNvdXJjZVNoYXJlZCgmKFRoaXMtPmJ1ZmZlcl9saXN0X2xvY2spLCBUUlVFKTsKCglpZiAoVGhpcy0+cmVmKQoJCURTT1VORF9QZXJmb3JtTWl4KFRoaXMpOwoKCVJ0bFJlbGVhc2VSZXNvdXJjZSgmKFRoaXMtPmJ1ZmZlcl9saXN0X2xvY2spKTsKCgllbmRfdGltZSA9IEdldFRpY2tDb3VudCgpOwoJVFJBQ0UoImNvbXBsZXRlZCBwcm9jZXNzaW5nIGF0ICVsZCwgZHVyYXRpb24gPSAlbGRcbiIsIGVuZF90aW1lLCBlbmRfdGltZSAtIHN0YXJ0X3RpbWUpOwp9Cgp2b2lkIENBTExCQUNLIERTT1VORF9jYWxsYmFjayhIV0FWRU9VVCBod28sIFVJTlQgbXNnLCBEV09SRCBkd1VzZXIsIERXT1JEIGR3MSwgRFdPUkQgZHcyKQp7CiAgICAgICAgSURpcmVjdFNvdW5kSW1wbCogVGhpcyA9IChJRGlyZWN0U291bmRJbXBsKilkd1VzZXI7CglUUkFDRSgiKCVwLCV4LCVseCwlbHgsJWx4KVxuIixod28sbXNnLGR3VXNlcixkdzEsZHcyKTsKCVRSQUNFKCJlbnRlcmluZyBhdCAlbGQsIG1zZz0lMDh4KCVzKVxuIiwgR2V0VGlja0NvdW50KCksIG1zZywgCgkJbXNnPT1NTV9XT01fRE9ORSA/ICJNTV9XT01fRE9ORSIgOiBtc2c9PU1NX1dPTV9DTE9TRSA/ICJNTV9XT01fQ0xPU0UiIDogCgkJbXNnPT1NTV9XT01fT1BFTiA/ICJNTV9XT01fT1BFTiIgOiAiVU5LTk9XTiIpOwoJaWYgKG1zZyA9PSBNTV9XT01fRE9ORSkgewoJCURXT1JEIGlucSwgbWl4cSwgZnJhZ2xlbiwgYnVmbGVuLCBwd3BsYXksIHBsYXlwb3MsIG1peHBvczsKCQlpZiAoVGhpcy0+cHdxdWV1ZSA9PSAoRFdPUkQpLTEpIHsKCQkJVFJBQ0UoImNvbXBsZXRlZCBkdWUgdG8gcmVzZXRcbiIpOwoJCQlyZXR1cm47CgkJfQovKiBpdCBjb3VsZCBiZSBhIGJhZCBpZGVhIHRvIGVudGVyIGNyaXRpY2FsIHNlY3Rpb24gaGVyZS4uLiBpZiB0aGVyZSdzIGxvY2sgY29udGVudGlvbiwKICogdGhlIHJlc3VsdGluZyBzY2hlZHVsaW5nIGRlbGF5cyBtaWdodCBvYnN0cnVjdCB0aGUgd2lubW0gcGxheWVyIHRocmVhZCAqLwojaWZkZWYgU1lOQ19DQUxMQkFDSwoJCUVudGVyQ3JpdGljYWxTZWN0aW9uKCYoVGhpcy0+bWl4bG9jaykpOwojZW5kaWYKCQkvKiByZXRyaWV2ZSBjdXJyZW50IHZhbHVlcyAqLwoJCWZyYWdsZW4gPSBUaGlzLT5mcmFnbGVuOwoJCWJ1ZmxlbiA9IFRoaXMtPmJ1ZmxlbjsKCQlwd3BsYXkgPSBUaGlzLT5wd3BsYXk7CgkJcGxheXBvcyA9IHB3cGxheSAqIGZyYWdsZW47CgkJbWl4cG9zID0gVGhpcy0+bWl4cG9zOwoJCS8qIGNoZWNrIHJlbWFpbmluZyBtaXhlZCBkYXRhICovCgkJaW5xID0gKChtaXhwb3MgPCBwbGF5cG9zKSA/IGJ1ZmxlbiA6IDApICsgbWl4cG9zIC0gcGxheXBvczsKCQltaXhxID0gaW5xIC8gZnJhZ2xlbjsKCQlpZiAoKGlucSAtIChtaXhxICogZnJhZ2xlbikpID4gMCkgbWl4cSsrOwoJCS8qIGNvbXBsZXRlIHRoZSBwbGF5aW5nIGJ1ZmZlciAqLwoJCVRSQUNFKCJkb25lIHBsYXlpbmcgcHJpbWFyeSBwb3M9JWxkXG4iLCBwbGF5cG9zKTsKCQlwd3BsYXkrKzsKCQlpZiAocHdwbGF5ID49IERTX0hFTF9GUkFHUykgcHdwbGF5ID0gMDsKCQkvKiB3cml0ZSBuZXcgdmFsdWVzICovCgkJVGhpcy0+cHdwbGF5ID0gcHdwbGF5OwoJCVRoaXMtPnB3cXVldWUtLTsKCQkvKiBxdWV1ZSBuZXcgYnVmZmVyIGlmIHdlIGhhdmUgZGF0YSBmb3IgaXQgKi8KCQlpZiAoaW5xPjEpIERTT1VORF9XYXZlUXVldWUoVGhpcywgaW5xLTEpOwojaWZkZWYgU1lOQ19DQUxMQkFDSwoJCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCYoVGhpcy0+bWl4bG9jaykpOwojZW5kaWYKCX0KCVRSQUNFKCJjb21wbGV0ZWRcbiIpOwp9Cg==