LyogJFhGcmVlODYkICovIC8qIC0qLSBtb2RlOiBjOyBjLWJhc2ljLW9mZnNldDogMyAtKi0gKi8KLyoKICogQ29weXJpZ2h0IDIwMDAgR2FyZXRoIEh1Z2hlcwogKiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYQogKiBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlICJTb2Z0d2FyZSIpLAogKiB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uCiAqIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLAogKiBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUKICogU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKICoKICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgKGluY2x1ZGluZyB0aGUgbmV4dAogKiBwYXJhZ3JhcGgpIHNoYWxsIGJlIGluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlCiAqIFNvZnR3YXJlLgogKgogKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgogKiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gIElOIE5PIEVWRU5UIFNIQUxMCiAqIEdBUkVUSCBIVUdIRVMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSCiAqIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOCiAqIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuCiAqLwoKLyoKICogQXV0aG9yczoKICoJR2FyZXRoIEh1Z2hlcyA8Z2FyZXRoQHZhbGludXguY29tPgogKglMZWlmIERlbGdhc3MgPGxkZWxnYXNzQHJldGluYWxidXJuLm5ldD4KICoJSm9z6SBGb25zZWNhIDxqX3JfZm9uc2VjYUB5YWhvby5jby51az4KICovCgojaW5jbHVkZSAiZ2xoZWFkZXIuaCIKI2luY2x1ZGUgImltcG9ydHMuaCIKI2luY2x1ZGUgImNvbnRleHQuaCIKI2luY2x1ZGUgIm1hY3Jvcy5oIgojaW5jbHVkZSAidGV4Zm9ybWF0LmgiCgojaW5jbHVkZSAibWFjaDY0X2NvbnRleHQuaCIKI2luY2x1ZGUgIm1hY2g2NF9pb2N0bC5oIgojaW5jbHVkZSAibWFjaDY0X3N0YXRlLmgiCiNpbmNsdWRlICJtYWNoNjRfdmIuaCIKI2luY2x1ZGUgIm1hY2g2NF90cmlzLmgiCiNpbmNsdWRlICJtYWNoNjRfdGV4LmgiCgpzdGF0aWMgdm9pZCBtYWNoNjRTZXRUZXhJbWFnZXMoIG1hY2g2NENvbnRleHRQdHIgbW1lc2EsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cnVjdCBnbF90ZXh0dXJlX29iamVjdCAqdE9iaiApCnsKICAgbWFjaDY0VGV4T2JqUHRyIHQgPSAobWFjaDY0VGV4T2JqUHRyKSB0T2JqLT5Ecml2ZXJEYXRhOwogICBzdHJ1Y3QgZ2xfdGV4dHVyZV9pbWFnZSAqYmFzZUltYWdlID0gdE9iai0+SW1hZ2VbMF1bdE9iai0+QmFzZUxldmVsXTsKICAgaW50IHRvdGFsU2l6ZTsKCiAgIGFzc2VydCh0KTsKICAgYXNzZXJ0KGJhc2VJbWFnZSk7CgogICBpZiAoIE1BQ0g2NF9ERUJVRyAmIERFQlVHX1ZFUkJPU0VfQVBJICkKICAgICAgZnByaW50Ziggc3RkZXJyLCAiJXMoICVwIClcbiIsIF9fRlVOQ1RJT05fXywgdE9iaiApOwoKICAgc3dpdGNoIChiYXNlSW1hZ2UtPlRleEZvcm1hdC0+TWVzYUZvcm1hdCkgewogICBjYXNlIE1FU0FfRk9STUFUX0FSR0I4ODg4OgogICAgICB0LT50ZXh0dXJlRm9ybWF0ID0gTUFDSDY0X0RBVEFUWVBFX0FSR0I4ODg4OwogICAgICBicmVhazsKICAgY2FzZSBNRVNBX0ZPUk1BVF9BUkdCNDQ0NDoKICAgICAgdC0+dGV4dHVyZUZvcm1hdCA9IE1BQ0g2NF9EQVRBVFlQRV9BUkdCNDQ0NDsKICAgICAgYnJlYWs7CiAgIGNhc2UgTUVTQV9GT1JNQVRfUkdCNTY1OgogICAgICB0LT50ZXh0dXJlRm9ybWF0ID0gTUFDSDY0X0RBVEFUWVBFX1JHQjU2NTsKICAgICAgYnJlYWs7CiAgIGNhc2UgTUVTQV9GT1JNQVRfQVJHQjE1NTU6CiAgICAgIHQtPnRleHR1cmVGb3JtYXQgPSBNQUNINjRfREFUQVRZUEVfQVJHQjE1NTU7CiAgICAgIGJyZWFrOwogICBjYXNlIE1FU0FfRk9STUFUX1JHQjMzMjoKICAgICAgdC0+dGV4dHVyZUZvcm1hdCA9IE1BQ0g2NF9EQVRBVFlQRV9SR0IzMzI7CiAgICAgIGJyZWFrOwogICBjYXNlIE1FU0FfRk9STUFUX1JHQjg4ODoKICAgICAgdC0+dGV4dHVyZUZvcm1hdCA9IE1BQ0g2NF9EQVRBVFlQRV9SR0I4OwogICAgICBicmVhazsKICAgY2FzZSBNRVNBX0ZPUk1BVF9DSTg6CiAgICAgIHQtPnRleHR1cmVGb3JtYXQgPSBNQUNINjRfREFUQVRZUEVfQ0k4OwogICAgICBicmVhazsKICAgY2FzZSBNRVNBX0ZPUk1BVF9ZQ0JDUjoKICAgICAgdC0+dGV4dHVyZUZvcm1hdCA9IE1BQ0g2NF9EQVRBVFlQRV9ZVllVNDIyOwogICAgICBicmVhazsKICAgY2FzZSBNRVNBX0ZPUk1BVF9ZQ0JDUl9SRVY6CiAgICAgIHQtPnRleHR1cmVGb3JtYXQgPSBNQUNINjRfREFUQVRZUEVfVllVWTQyMjsKICAgICAgYnJlYWs7CiAgIGRlZmF1bHQ6CiAgICAgIF9tZXNhX3Byb2JsZW0obW1lc2EtPmdsQ3R4LCAiQmFkIHRleHR1cmUgZm9ybWF0IGluICVzIiwgX19GVU5DVElPTl9fKTsKICAgfTsKCiAgIHRvdGFsU2l6ZSA9ICggYmFzZUltYWdlLT5IZWlnaHQgKgoJCSBiYXNlSW1hZ2UtPldpZHRoICoKCQkgYmFzZUltYWdlLT5UZXhGb3JtYXQtPlRleGVsQnl0ZXMgKTsKCiAgIHRvdGFsU2l6ZSA9ICh0b3RhbFNpemUgKyAzMSkgJiB+MzE7CgogICB0LT5iYXNlLnRvdGFsU2l6ZSA9IHRvdGFsU2l6ZTsKICAgdC0+YmFzZS5maXJzdExldmVsID0gdE9iai0+QmFzZUxldmVsOwogICB0LT5iYXNlLmxhc3RMZXZlbCA9IHRPYmotPkJhc2VMZXZlbDsKCiAgIC8qIFNldCB0aGUgdGV4dHVyZSBmb3JtYXQgKi8KICAgaWYgKCAoIGJhc2VJbWFnZS0+X0Jhc2VGb3JtYXQgPT0gR0xfUkdCQSApIHx8CgkoIGJhc2VJbWFnZS0+X0Jhc2VGb3JtYXQgPT0gR0xfQUxQSEEgKSB8fAoJKCBiYXNlSW1hZ2UtPl9CYXNlRm9ybWF0ID09IEdMX0xVTUlOQU5DRV9BTFBIQSApICkgewogICAgICB0LT5oYXNBbHBoYSA9IDE7CiAgIH0gZWxzZSB7CiAgICAgIHQtPmhhc0FscGhhID0gMDsKICAgfQoKICAgdC0+d2lkdGhMb2cyID0gYmFzZUltYWdlLT5XaWR0aExvZzI7CiAgIHQtPmhlaWdodExvZzIgPSBiYXNlSW1hZ2UtPkhlaWdodExvZzI7CiAgIHQtPm1heExvZzIgPSBiYXNlSW1hZ2UtPk1heExvZzI7Cn0KCnN0YXRpYyB2b2lkIG1hY2g2NFVwZGF0ZVRleHR1cmVFbnYoIEdMY29udGV4dCAqY3R4LCBpbnQgdW5pdCApCnsKICAgbWFjaDY0Q29udGV4dFB0ciBtbWVzYSA9IE1BQ0g2NF9DT05URVhUKGN0eCk7CiAgIEdMaW50IHNvdXJjZSA9IG1tZXNhLT50bXVfc291cmNlW3VuaXRdOwogICBjb25zdCBzdHJ1Y3QgZ2xfdGV4dHVyZV91bml0ICp0ZXhVbml0ID0gJmN0eC0+VGV4dHVyZS5Vbml0W3NvdXJjZV07CiAgIGNvbnN0IHN0cnVjdCBnbF90ZXh0dXJlX29iamVjdCAqdE9iaiA9IHRleFVuaXQtPl9DdXJyZW50OwogICBjb25zdCBHTGVudW0gZm9ybWF0ID0gdE9iai0+SW1hZ2VbMF1bdE9iai0+QmFzZUxldmVsXS0+X0Jhc2VGb3JtYXQ7CiAgIEdMdWludCBzID0gbW1lc2EtPnNldHVwLnNjYWxlXzNkX2NudGw7CgogICBpZiAoIE1BQ0g2NF9ERUJVRyAmIERFQlVHX1ZFUkJPU0VfQVBJICkgewogICAgICBmcHJpbnRmKCBzdGRlcnIsICIlcyggJXAsICVkIClcbiIsCgkgICAgICAgX19GVU5DVElPTl9fLCBjdHgsIHVuaXQgKTsKICAgfQoKLyogICAgICAgICAgICAgICAgIFJFUExBQ0UgIE1PRFVMQVRFICAgREVDQUwgICAgICAgICAgICAgIEdMX0JMRU5ECiAqCiAqIEFMUEhBICAgICAgICAgICBDID0gQ2YgICBDID0gQ2YgICAgIHVuZGVmICAgICAgICAgICAgICBDID0gQ2YKICogICAgICAgICAgICAgICAgIEEgPSBBdCAgIEEgPSBBZkF0ICAgICAgICAgICAgICAgICAgICAgIEEgPSBBZkF0CiAqCiAqIExVTUlOQU5DRSAgICAgICBDID0gQ3QgICBDID0gQ2ZDdCAgIHVuZGVmICAgICAgICAgICAgICBDID0gQ2YoMS1DdCkrQ2NDdCAKICogICAgICAgICAgICAgICAgIEEgPSBBZiAgIEEgPSBBZiAgICAgICAgICAgICAgICAgICAgICAgIEEgPSBBZgogKgogKiBMVU1JTkFOQ0VfQUxQSEEgQyA9IEN0ICAgQyA9IENmQ3QgICB1bmRlZiAgICAgICAgICAgICAgQyA9IENmKDEtQ3QpK0NjQ3QKICogICAgICAgICAgICAgICAgIEEgPSBBdCAgIEEgPSBBZkF0ICAgICAgICAgICAgICAgICAgICAgIEEgPSBBZkF0CiAqCiAqIElOVEVOU0lUWSAgICAgICBDID0gQ3QgICBDID0gQ2ZDdCAgIHVuZGVmICAgICAgICAgICAgICBDID0gQ2YoMS1DdCkrQ2NDdAogKiAgICAgICAgICAgICAgICAgQSA9IEF0ICAgQSA9IEFmQXQgICAgICAgICAgICAgICAgICAgICAgQSA9IEFmKDEtQXQpK0FjQXQKICoKICogUkdCICAgICAgICAgICAgIEMgPSBDdCAgIEMgPSBDZkN0ICAgQyA9IEN0ICAgICAgICAgICAgIEMgPSBDZigxLUN0KStDY0N0CiAqICAgICAgICAgICAgICAgICBBID0gQWYgICBBID0gQWYgICAgIEEgPSBBZiAgICAgICAgICAgICBBID0gQWYKICoKICogUkdCQSAgICAgICAgICAgIEMgPSBDdCAgIEMgPSBDZkN0ICAgQyA9IENmKDEtQXQpK0N0QXQgIEMgPSBDZigxLUN0KStDY0N0CiAqICAgICAgICAgICAgICAgICBBID0gQXQgICBBID0gQWZBdCAgIEEgPSBBZiAgICAgICAgICAgICBBID0gQWZBdCAKICovCgoKICAgaWYgKCB1bml0ID09IDAgKSB7CiAgICAgIHMgJj0gfk1BQ0g2NF9URVhfTElHSFRfRkNOX01BU0s7CgogICAgICAvKiBTZXQgdGhlIHRleHR1cmUgZW52aXJvbm1lbnQgc3RhdGUgCiAgICAgICAqIE5lZWQgdG8gdmVyaWZ5IHRoZXNlIGFyZSB3b3JraW5nIGNvcnJlY3RseSwgYnV0IHRoZQogICAgICAgKiB0ZXhlbnYgTWVzYSBkZW1vIHNlZW1zIHRvIHdvcmsuCiAgICAgICAqLwogICAgICBzd2l0Y2ggKCB0ZXhVbml0LT5FbnZNb2RlICkgewogICAgICBjYXNlIEdMX1JFUExBQ0U6Cgkgc3dpdGNoICggZm9ybWF0ICkgewoJIGNhc2UgR0xfQUxQSEE6CgkgY2FzZSBHTF9MVU1JTkFOQ0VfQUxQSEE6CgkgY2FzZSBHTF9JTlRFTlNJVFk6CgkgICAgLyogTm90IGNvbXBsaWFudCAtIGNhbid0IGdldCBBdCAqLwoJICAgIEZBTExCQUNLKCBtbWVzYSwgTUFDSDY0X0ZBTExCQUNLX1RFWFRVUkUsIEdMX1RSVUUgKTsKCSAgICBzIHw9IE1BQ0g2NF9URVhfTElHSFRfRkNOX01PRFVMQVRFOwoJICAgIGJyZWFrOwoJIGRlZmF1bHQ6CgkgICAgcyB8PSBNQUNINjRfVEVYX0xJR0hUX0ZDTl9SRVBMQUNFOwoJIH0KCSBicmVhazsKICAgICAgY2FzZSBHTF9NT0RVTEFURToKCSBzd2l0Y2ggKCBmb3JtYXQgKSB7CgkgY2FzZSBHTF9BTFBIQToKCSAgICBGQUxMQkFDSyggbW1lc2EsIE1BQ0g2NF9GQUxMQkFDS19URVhUVVJFLCBHTF9UUlVFICk7CgkgICAgcyB8PSBNQUNINjRfVEVYX0xJR0hUX0ZDTl9NT0RVTEFURTsKCSAgICBicmVhazsKCSBjYXNlIEdMX1JHQjoKCSBjYXNlIEdMX0xVTUlOQU5DRToKCSAgICAvKiBUaGVzZSBzaG91bGQgYmUgY29tcGxpYW50ICovCgkgICAgcyB8PSBNQUNINjRfVEVYX0xJR0hUX0ZDTl9NT0RVTEFURTsKCSAgICBicmVhazsKCSBjYXNlIEdMX0xVTUlOQU5DRV9BTFBIQToKCSBjYXNlIEdMX0lOVEVOU0lUWToKCSAgICBGQUxMQkFDSyggbW1lc2EsIE1BQ0g2NF9GQUxMQkFDS19URVhUVVJFLCBHTF9UUlVFICk7CgkgICAgcyB8PSBNQUNINjRfVEVYX0xJR0hUX0ZDTl9NT0RVTEFURTsKCSAgICBicmVhazsKCSBjYXNlIEdMX1JHQkE6CgkgICAgLyogU2hvdWxkIGZhbGxiYWNrIHdoZW4gYmxlbmRpbmcgZW5hYmxlZCBmb3IgY29tcGxldGUgY29tcGxpYW5jZSAqLwoJICAgIHMgfD0gTUFDSDY0X1RFWF9MSUdIVF9GQ05fTU9EVUxBVEU7CgkgICAgYnJlYWs7CgkgZGVmYXVsdDoKCSAgICBzIHw9IE1BQ0g2NF9URVhfTElHSFRfRkNOX01PRFVMQVRFOwoJIH0KCSBicmVhazsKICAgICAgY2FzZSBHTF9ERUNBTDoKCSBzd2l0Y2ggKCBmb3JtYXQgKSB7CgkgY2FzZSBHTF9SR0JBOiAKCSAgICBzIHw9IE1BQ0g2NF9URVhfTElHSFRfRkNOX0FMUEhBX0RFQ0FMOwoJICAgIGJyZWFrOwoJIGNhc2UgR0xfUkdCOgoJICAgIHMgfD0gTUFDSDY0X1RFWF9MSUdIVF9GQ05fUkVQTEFDRTsKCSAgICBicmVhazsKCSBjYXNlIEdMX0FMUEhBOgoJIGNhc2UgR0xfTFVNSU5BTkNFX0FMUEhBOgoJICAgIC8qIHVuZGVmaW5lZCAtIGRpc2FibGUgdGV4dHVyaW5nLCBwYXNzIGZyYWdtZW50IHVubW9kaWZpZWQgICovCgkgICAgLyogQWxzbywgcGFzcyBmcmFnbWVudCBhbHBoYSBpbnN0ZWFkIG9mIHRleHR1cmUgYWxwaGEgKi8KCSAgICBzICY9IH5NQUNINjRfVEVYX01BUF9BRU47CgkgICAgcyB8PSBNQUNINjRfVEVYVFVSRV9ESVNBQkxFOwoJICAgIHMgfD0gTUFDSDY0X1RFWF9MSUdIVF9GQ05fTU9EVUxBVEU7CgkgICAgYnJlYWs7CgkgY2FzZSBHTF9MVU1JTkFOQ0U6CgkgY2FzZSBHTF9JTlRFTlNJVFk6CgkgICAgLyogdW5kZWZpbmVkIC0gZGlzYWJsZSB0ZXh0dXJpbmcsIHBhc3MgZnJhZ21lbnQgdW5tb2RpZmllZCAgKi8KCSAgICBzIHw9IE1BQ0g2NF9URVhUVVJFX0RJU0FCTEU7CgkgICAgcyB8PSBNQUNINjRfVEVYX0xJR0hUX0ZDTl9NT0RVTEFURTsKCSAgICBicmVhazsKCSBkZWZhdWx0OgoJICAgIHMgfD0gTUFDSDY0X1RFWF9MSUdIVF9GQ05fTU9EVUxBVEU7CgkgfQoJIGJyZWFrOwogICAgICBjYXNlIEdMX0JMRU5EOgoJIC8qIEdMX0JMRU5EIG5vdCBzdXBwb3J0ZWQgYnkgUmFnZVBSTywgdXNlIHNvZnR3YXJlICovCgkgRkFMTEJBQ0soIG1tZXNhLCBNQUNINjRfRkFMTEJBQ0tfVEVYVFVSRSwgR0xfVFJVRSApOwoJIHMgfD0gTUFDSDY0X1RFWF9MSUdIVF9GQ05fTU9EVUxBVEU7CgkgYnJlYWs7CiAgICAgIGNhc2UgR0xfQUREOgogICAgICBjYXNlIEdMX0NPTUJJTkU6CgkgRkFMTEJBQ0soIG1tZXNhLCBNQUNINjRfRkFMTEJBQ0tfVEVYVFVSRSwgR0xfVFJVRSApOwoJIHMgfD0gTUFDSDY0X1RFWF9MSUdIVF9GQ05fTU9EVUxBVEU7CgkgYnJlYWs7CiAgICAgIGRlZmF1bHQ6CgkgcyB8PSBNQUNINjRfVEVYX0xJR0hUX0ZDTl9NT0RVTEFURTsKICAgICAgfQoKICAgICAgaWYgKCBtbWVzYS0+c2V0dXAuc2NhbGVfM2RfY250bCAhPSBzICkgewoJIG1tZXNhLT5zZXR1cC5zY2FsZV8zZF9jbnRsID0gczsKCSBtbWVzYS0+ZGlydHkgfD0gTUFDSDY0X1VQTE9BRF9TQ0FMRV8zRF9DTlRMOwogICAgICB9CgogICB9IGVsc2UgewogICAgICAvKiBibGVuZCA9IDAsIG1vZHVsYXRlID0gMSAtIGluaXRpYWxpemUgdG8gYmxlbmQgKi8KICAgICAgbW1lc2EtPnNldHVwLnRleF9jbnRsICY9IH5NQUNINjRfQ09NUF9DT01CSU5FX01PRFVMQVRFOwogICAgICAvKiBTZXQgdGhlIHRleHR1cmUgY29tcG9zaXRlIGZ1bmN0aW9uIGZvciBtdWx0aXRleHR1cmluZyovCiAgICAgIHN3aXRjaCAoIHRleFVuaXQtPkVudk1vZGUgKSB7CiAgICAgIGNhc2UgR0xfQkxFTkQ6CgkgLyogR0xfQkxFTkQgbm90IHN1cHBvcnRlZCBieSBSYWdlUFJPLCB1c2Ugc29mdHdhcmUgKi8KCSBGQUxMQkFDSyggbW1lc2EsIE1BQ0g2NF9GQUxMQkFDS19URVhUVVJFLCBHTF9UUlVFICk7CgkgbW1lc2EtPnNldHVwLnRleF9jbnRsIHw9IE1BQ0g2NF9DT01QX0NPTUJJTkVfTU9EVUxBVEU7CgkgYnJlYWs7CiAgICAgIGNhc2UgR0xfTU9EVUxBVEU6CgkgLyogU2hvdWxkIGZhbGxiYWNrIHdoZW4gYmxlbmRpbmcgZW5hYmxlZCBmb3IgY29tcGxldGUgY29tcGxpYW5jZSAqLwoJIG1tZXNhLT5zZXR1cC50ZXhfY250bCB8PSBNQUNINjRfQ09NUF9DT01CSU5FX01PRFVMQVRFOwoJIGJyZWFrOwogICAgICBjYXNlIEdMX1JFUExBQ0U6Cgkgc3dpdGNoICggZm9ybWF0ICkgewoJIGNhc2UgR0xfQUxQSEE6CgkgICAgbW1lc2EtPnNldHVwLnRleF9jbnRsIHw9IE1BQ0g2NF9DT01QX0NPTUJJTkVfTU9EVUxBVEU7CgkgICAgYnJlYWs7CgkgZGVmYXVsdDogLyogbm90IHN1cHBvcnRlZCBieSBSYWdlUFJPICovCgkgICAgRkFMTEJBQ0soIG1tZXNhLCBNQUNINjRfRkFMTEJBQ0tfVEVYVFVSRSwgR0xfVFJVRSApOwoJICAgIG1tZXNhLT5zZXR1cC50ZXhfY250bCB8PSBNQUNINjRfQ09NUF9DT01CSU5FX01PRFVMQVRFOwoJIH0KCSBicmVhazsKICAgICAgY2FzZSBHTF9ERUNBTDoKCSBzd2l0Y2ggKCBmb3JtYXQgKSB7CgkgY2FzZSBHTF9BTFBIQToKCSBjYXNlIEdMX0xVTUlOQU5DRToKCSBjYXNlIEdMX0xVTUlOQU5DRV9BTFBIQToKCSBjYXNlIEdMX0lOVEVOU0lUWToKCSAgICAvKiB1bmRlZmluZWQsIGRpc2FibGUgY29tcG9zaXRpbmcgYW5kIHBhc3MgZnJhZ21lbnQgdW5tb2RpZmllZCAqLwoJICAgIG1tZXNhLT5zZXR1cC50ZXhfY250bCAmPSB+TUFDSDY0X1RFWFRVUkVfQ09NUE9TSVRFOwoJICAgIGJyZWFrOwoJIGRlZmF1bHQ6IC8qIG5vdCBzdXBwb3J0ZWQgYnkgUmFnZVBSTyAqLwoJICAgIEZBTExCQUNLKCBtbWVzYSwgTUFDSDY0X0ZBTExCQUNLX1RFWFRVUkUsIEdMX1RSVUUgKTsKCSAgICBtbWVzYS0+c2V0dXAudGV4X2NudGwgfD0gTUFDSDY0X0NPTVBfQ09NQklORV9NT0RVTEFURTsKCSB9CgkgYnJlYWs7CiAgICAgIGNhc2UgR0xfQUREOgogICAgICBjYXNlIEdMX0NPTUJJTkU6CgkgRkFMTEJBQ0soIG1tZXNhLCBNQUNINjRfRkFMTEJBQ0tfVEVYVFVSRSwgR0xfVFJVRSApOwoJIG1tZXNhLT5zZXR1cC50ZXhfY250bCB8PSBNQUNINjRfQ09NUF9DT01CSU5FX01PRFVMQVRFOwoJIGJyZWFrOwogICAgICBkZWZhdWx0OgoJIG1tZXNhLT5zZXR1cC50ZXhfY250bCB8PSBNQUNINjRfQ09NUF9DT01CSU5FX01PRFVMQVRFOwogICAgICB9CiAgIH0KfQoKCnN0YXRpYyB2b2lkIG1hY2g2NFVwZGF0ZVRleHR1cmVVbml0KCBHTGNvbnRleHQgKmN0eCwgaW50IHVuaXQgKQp7CiAgIG1hY2g2NENvbnRleHRQdHIgbW1lc2EgPSBNQUNINjRfQ09OVEVYVChjdHgpOwogICBpbnQgc291cmNlID0gbW1lc2EtPnRtdV9zb3VyY2VbdW5pdF07CiAgIGNvbnN0IHN0cnVjdCBnbF90ZXh0dXJlX3VuaXQgKnRleFVuaXQgPSAmY3R4LT5UZXh0dXJlLlVuaXRbc291cmNlXTsKICAgY29uc3Qgc3RydWN0IGdsX3RleHR1cmVfb2JqZWN0ICp0T2JqID0gY3R4LT5UZXh0dXJlLlVuaXRbc291cmNlXS5fQ3VycmVudDsKICAgbWFjaDY0VGV4T2JqUHRyIHQgPSB0T2JqLT5Ecml2ZXJEYXRhOwogICBHTHVpbnQgZCA9IG1tZXNhLT5zZXR1cC5kcF9waXhfd2lkdGg7CiAgIEdMdWludCBzID0gbW1lc2EtPnNldHVwLnNjYWxlXzNkX2NudGw7CgogICBhc3NlcnQodW5pdCA9PSAwIHx8IHVuaXQgPT0gMSk7ICAvKiBvbmx5IHR3byB0ZXggdW5pdHMgKi8KCiAgIGlmICggTUFDSDY0X0RFQlVHICYgREVCVUdfVkVSQk9TRV9BUEkgKSB7CiAgICAgIGZwcmludGYoIHN0ZGVyciwgIiVzKCAlcCwgJWQgKSBlbmFibGVkPTB4JXggMHgleFxuIiwKCSAgICAgICBfX0ZVTkNUSU9OX18sIGN0eCwgdW5pdCwgY3R4LT5UZXh0dXJlLlVuaXRbMF0uX1JlYWxseUVuYWJsZWQsCgkgICAgICAgY3R4LT5UZXh0dXJlLlVuaXRbMV0uX1JlYWxseUVuYWJsZWQpOwogICB9CgogICBpZiAodGV4VW5pdC0+X1JlYWxseUVuYWJsZWQgJiAoVEVYVFVSRV8xRF9CSVQgfCBURVhUVVJFXzJEX0JJVCkpIHsKCiAgICAgIGFzc2VydCh0KTsgIC8qIHNob3VsZCBoYXZlIGRyaXZlciB0ZXggZGF0YSBieSBub3cgKi8KCiAgICAgIC8qIEZhbGxiYWNrIGlmIHRoZXJlJ3MgYSB0ZXh0dXJlIGJvcmRlciAqLwogICAgICBpZiAoIHRPYmotPkltYWdlWzBdW3RPYmotPkJhc2VMZXZlbF0tPkJvcmRlciA+IDAgKSB7CiAgICAgICAgIEZBTExCQUNLKCBtbWVzYSwgTUFDSDY0X0ZBTExCQUNLX1RFWFRVUkUsIEdMX1RSVUUgKTsKICAgICAgICAgcmV0dXJuOwogICAgICB9CgogICAgICAvKiBVcGxvYWQgdGV4aW1hZ2VzICovCiAgICAgIGlmICh0LT5iYXNlLmRpcnR5X2ltYWdlc1swXSkgewogICAgICAgICBtYWNoNjRTZXRUZXhJbWFnZXMoIG1tZXNhLCB0T2JqICk7CgkgbW1lc2EtPmRpcnR5IHw9IChNQUNINjRfVVBMT0FEX1RFWDBJTUFHRSA8PCB1bml0KTsKICAgICAgfQoKICAgICAgLyogQmluZCB0byB0aGUgZ2l2ZW4gdGV4dHVyZSB1bml0ICovCiAgICAgIG1tZXNhLT5DdXJyZW50VGV4T2JqW3VuaXRdID0gdDsKICAgICAgdC0+YmFzZS5ib3VuZCB8PSAoMSA8PCB1bml0KTsKCiAgICAgIGlmICggdC0+YmFzZS5tZW1CbG9jayApCiAgICAgICAgIGRyaVVwZGF0ZVRleHR1cmVMUlUoIChkcmlUZXh0dXJlT2JqZWN0ICopIHQgKTsgLyogWFhYOiBzaG91bGQgYmUgbG9ja2VkISAqLwoKICAgICAgLyogcmVnaXN0ZXIgc2V0dXAgKi8KICAgICAgaWYgKCB1bml0ID09IDAgKSB7CiAgICAgICAgIGQgJj0gfk1BQ0g2NF9TQ0FMRV9QSVhfV0lEVEhfTUFTSzsKICAgICAgICAgZCB8PSAodC0+dGV4dHVyZUZvcm1hdCA8PCAyOCk7CiAgIAogICAgICAgICBzICY9IH4oTUFDSDY0X1RFWFRVUkVfRElTQUJMRSB8CgkJTUFDSDY0X1RFWF9DQUNIRV9TUExJVCB8CgkJTUFDSDY0X1RFWF9CTEVORF9GQ05fTUFTSyB8CgkJTUFDSDY0X1RFWF9NQVBfQUVOKTsKICAgCiAgICAgICAgIGlmICggbW1lc2EtPm11bHRpdGV4ICkgewoJICAgIHMgfD0gTUFDSDY0X1RFWF9CTEVORF9GQ05fVFJJTElORUFSIHwgTUFDSDY0X1RFWF9DQUNIRV9TUExJVDsKICAgICAgICAgfSBlbHNlIGlmICggdC0+QmlsaW5lYXJNaW4gKSB7CgkgICAgcyB8PSBNQUNINjRfVEVYX0JMRU5EX0ZDTl9MSU5FQVI7CiAgICAgICAgIH0gZWxzZSB7CgkgICAgcyB8PSBNQUNINjRfVEVYX0JMRU5EX0ZDTl9ORUFSRVNUOwogICAgICAgICB9CiAgICAgICAgIGlmICggdC0+QmlsaW5lYXJNYWcgKSB7CgkgICAgcyB8PSAgTUFDSDY0X0JJTElORUFSX1RFWF9FTjsKICAgICAgICAgfSBlbHNlIHsKCSAgICBzICY9IH5NQUNINjRfQklMSU5FQVJfVEVYX0VOOwogICAgICAgICB9CiAgIAogICAgICAgICBpZiAoIHQtPmhhc0FscGhhICkgewoJICAgIHMgfD0gTUFDSDY0X1RFWF9NQVBfQUVOOwogICAgICAgICB9CiAgIAogICAgICAgICBtbWVzYS0+c2V0dXAudGV4X2NudGwgJj0gfihNQUNINjRfVEVYVFVSRV9DTEFNUF9TIHwKCQkJCSAgICBNQUNINjRfVEVYVFVSRV9DTEFNUF9UIHwKCQkJCSAgICBNQUNINjRfU0VDT05EQVJZX1NUVyk7CiAgIAogICAgICAgICBpZiAoIHQtPkNsYW1wUyApIHsKCSAgICBtbWVzYS0+c2V0dXAudGV4X2NudGwgfD0gTUFDSDY0X1RFWFRVUkVfQ0xBTVBfUzsKICAgICAgICAgfQogICAgICAgICBpZiAoIHQtPkNsYW1wVCApIHsKCSAgICBtbWVzYS0+c2V0dXAudGV4X2NudGwgfD0gTUFDSDY0X1RFWFRVUkVfQ0xBTVBfVDsKICAgICAgICAgfQogICAKICAgICAgICAgbW1lc2EtPnNldHVwLnRleF9zaXplX3BpdGNoIHw9ICgodC0+d2lkdGhMb2cyICA8PCAwKSB8CgkJCQkJICh0LT5tYXhMb2cyICAgIDw8IDQpIHwKCQkJCQkgKHQtPmhlaWdodExvZzIgPDwgOCkpOwogICAgICB9IGVsc2UgewogICAgICAgICAKICAgICAgICAgLyogRW5hYmxlIHRleHR1cmUgbWFwcGluZyBtb2RlICovCiAgICAgICAgIHMgJj0gfk1BQ0g2NF9URVhUVVJFX0RJU0FCTEU7CiAgIAogICAgICAgICBkICY9IH5NQUNINjRfQ09NUE9TSVRFX1BJWF9XSURUSF9NQVNLOwogICAgICAgICBkIHw9ICh0LT50ZXh0dXJlRm9ybWF0IDw8IDQpOwogICAKICAgICAgICAgbW1lc2EtPnNldHVwLnRleF9jbnRsICY9IH4oTUFDSDY0X0NPTVBfQUxQSEEgfAoJCQkJICAgIE1BQ0g2NF9TRUNfVEVYX0NMQU1QX1MgfAoJCQkJICAgIE1BQ0g2NF9TRUNfVEVYX0NMQU1QX1QpOwogICAgICAgICBtbWVzYS0+c2V0dXAudGV4X2NudGwgfD0gKE1BQ0g2NF9URVhUVVJFX0NPTVBPU0lURSB8CgkJCQkgICBNQUNINjRfU0VDT05EQVJZX1NUVyk7CiAgIAogICAgICAgICBpZiAoIHQtPkJpbGluZWFyTWluICkgewoJICAgIG1tZXNhLT5zZXR1cC50ZXhfY250bCB8PSBNQUNINjRfQ09NUF9CTEVORF9CSUxJTkVBUjsKICAgICAgICAgfSBlbHNlIHsKCSAgICBtbWVzYS0+c2V0dXAudGV4X2NudGwgJj0gfk1BQ0g2NF9DT01QX0JMRU5EX0JJTElORUFSOwogICAgICAgICB9CiAgICAgICAgIGlmICggdC0+QmlsaW5lYXJNYWcgKSB7CgkgICAgbW1lc2EtPnNldHVwLnRleF9jbnRsIHw9ICBNQUNINjRfQ09NUF9GSUxURVJfQklMSU5FQVI7CiAgICAgICAgIH0gZWxzZSB7CgkgICAgbW1lc2EtPnNldHVwLnRleF9jbnRsICY9IH5NQUNINjRfQ09NUF9GSUxURVJfQklMSU5FQVI7CiAgICAgICAgIH0KICAgICAgICAgCiAgICAgICAgIGlmICggdC0+aGFzQWxwaGEgKSB7CgkgICAgbW1lc2EtPnNldHVwLnRleF9jbnRsIHw9IE1BQ0g2NF9DT01QX0FMUEhBOwogICAgICAgICB9CiAgICAgICAgIGlmICggdC0+Q2xhbXBTICkgewoJICAgIG1tZXNhLT5zZXR1cC50ZXhfY250bCB8PSBNQUNINjRfU0VDX1RFWF9DTEFNUF9TOwogICAgICAgICB9CiAgICAgICAgIGlmICggdC0+Q2xhbXBUICkgewoJICAgIG1tZXNhLT5zZXR1cC50ZXhfY250bCB8PSBNQUNINjRfU0VDX1RFWF9DTEFNUF9UOwogICAgICAgICB9CiAgIAogICAgICAgICBtbWVzYS0+c2V0dXAudGV4X3NpemVfcGl0Y2ggfD0gKCh0LT53aWR0aExvZzIgIDw8IDE2KSB8CgkJCQkJICh0LT5tYXhMb2cyICAgIDw8IDIwKSB8CgkJCQkJICh0LT5oZWlnaHRMb2cyIDw8IDI0KSk7CiAgICAgIH0KICAgCiAgICAgIGlmICggbW1lc2EtPnNldHVwLnNjYWxlXzNkX2NudGwgIT0gcyApIHsKICAgICAgICAgbW1lc2EtPnNldHVwLnNjYWxlXzNkX2NudGwgPSBzOwogICAgICAgICBtbWVzYS0+ZGlydHkgfD0gTUFDSDY0X1VQTE9BRF9TQ0FMRV8zRF9DTlRMOwogICAgICB9CiAgIAogICAgICBpZiAoIG1tZXNhLT5zZXR1cC5kcF9waXhfd2lkdGggIT0gZCApIHsKICAgICAgICAgbW1lc2EtPnNldHVwLmRwX3BpeF93aWR0aCA9IGQ7CiAgICAgICAgIG1tZXNhLT5kaXJ0eSB8PSBNQUNINjRfVVBMT0FEX0RQX1BJWF9XSURUSDsKICAgICAgfSAgCiAgIH0KICAgZWxzZSBpZiAodGV4VW5pdC0+X1JlYWxseUVuYWJsZWQpIHsKICAgICAgLyogM0Qgb3IgY3ViZSBtYXAgdGV4dHVyZSBlbmFibGVkIC0gZmFsbGJhY2sgKi8KICAgICAgRkFMTEJBQ0soIG1tZXNhLCBNQUNINjRfRkFMTEJBQ0tfVEVYVFVSRSwgR0xfVFJVRSApOwogICB9CiAgIGVsc2UgewogICAgICAvKiB0ZXh0dXJlIHVuaXQgZGlzYWJsZWQgKi8KICAgfQp9CgoKLyogVXBkYXRlIHRoZSBoYXJkd2FyZSB0ZXh0dXJlIHN0YXRlICovCnZvaWQgbWFjaDY0VXBkYXRlVGV4dHVyZVN0YXRlKCBHTGNvbnRleHQgKmN0eCApCnsKICAgbWFjaDY0Q29udGV4dFB0ciBtbWVzYSA9IE1BQ0g2NF9DT05URVhUKGN0eCk7CgogICBpZiAoIE1BQ0g2NF9ERUJVRyAmIERFQlVHX1ZFUkJPU0VfQVBJICkgewogICAgICBmcHJpbnRmKCBzdGRlcnIsICIlcyggJXAgKSBlbj0weCV4IDB4JXhcbiIsCgkgICAgICAgX19GVU5DVElPTl9fLCBjdHgsIGN0eC0+VGV4dHVyZS5Vbml0WzBdLl9SZWFsbHlFbmFibGVkLAoJICAgICAgIGN0eC0+VGV4dHVyZS5Vbml0WzFdLl9SZWFsbHlFbmFibGVkKTsKICAgfQoKICAgLyogQ2xlYXIgYW55IHRleHR1cmluZyBmYWxsYmFja3MgKi8KICAgRkFMTEJBQ0soIG1tZXNhLCBNQUNINjRfRkFMTEJBQ0tfVEVYVFVSRSwgR0xfRkFMU0UgKTsKCiAgIC8qIFVuYmluZCBhbnkgY3VycmVudGx5IGJvdW5kIHRleHR1cmVzICovCiAgIGlmICggbW1lc2EtPkN1cnJlbnRUZXhPYmpbMF0gKSBtbWVzYS0+Q3VycmVudFRleE9ialswXS0+YmFzZS5ib3VuZCA9IDA7CiAgIGlmICggbW1lc2EtPkN1cnJlbnRUZXhPYmpbMV0gKSBtbWVzYS0+Q3VycmVudFRleE9ialsxXS0+YmFzZS5ib3VuZCA9IDA7CiAgIG1tZXNhLT5DdXJyZW50VGV4T2JqWzBdID0gTlVMTDsKICAgbW1lc2EtPkN1cnJlbnRUZXhPYmpbMV0gPSBOVUxMOwoKICAgLyogRGlzYWJsZSBhbGwgdGV4dHVyaW5nIHVudGlsIGl0IGlzIGtub3duIHRvIGJlIGdvb2QgKi8KICAgbW1lc2EtPnNldHVwLnNjYWxlXzNkX2NudGwgIHw9ICBNQUNINjRfVEVYVFVSRV9ESVNBQkxFOwogICBtbWVzYS0+c2V0dXAuc2NhbGVfM2RfY250bCAgJj0gfk1BQ0g2NF9URVhfTUFQX0FFTjsKICAgbW1lc2EtPnNldHVwLnRleF9jbnRsICAgICAgICY9IH5NQUNINjRfVEVYVFVSRV9DT01QT1NJVEU7CgogICBtbWVzYS0+c2V0dXAudGV4X3NpemVfcGl0Y2ggPSAweDAwMDAwMDAwOwoKICAgbW1lc2EtPnRtdV9zb3VyY2VbMF0gPSAwOwogICBtbWVzYS0+dG11X3NvdXJjZVsxXSA9IDE7CiAgIG1tZXNhLT5tdWx0aXRleCA9IDA7CgogICBpZiAoY3R4LT5UZXh0dXJlLl9FbmFibGVkVW5pdHMgJiAweDIpIHsKICAgICAgIC8qIHVuaXQgMSBlbmFibGVkICovCiAgICAgICBpZiAoY3R4LT5UZXh0dXJlLl9FbmFibGVkVW5pdHMgJiAweDEpIHsKCSAgLyogdW5pdHMgMCBhbmQgMSBlbmFibGVkICovCgkgIG1tZXNhLT5tdWx0aXRleCA9IDE7CgkgIG1hY2g2NFVwZGF0ZVRleHR1cmVVbml0KCBjdHgsIDAgKTsKCSAgbWFjaDY0VXBkYXRlVGV4dHVyZUVudiggY3R4LCAwICk7CgkgIG1hY2g2NFVwZGF0ZVRleHR1cmVVbml0KCBjdHgsIDEgKTsKCSAgbWFjaDY0VXBkYXRlVGV4dHVyZUVudiggY3R4LCAxICk7CiAgICAgICB9IGVsc2UgewoJICBtbWVzYS0+dG11X3NvdXJjZVswXSA9IDE7CgkgIG1tZXNhLT50bXVfc291cmNlWzFdID0gMDsKCSAgbWFjaDY0VXBkYXRlVGV4dHVyZVVuaXQoIGN0eCwgMCApOwoJICBtYWNoNjRVcGRhdGVUZXh0dXJlRW52KCBjdHgsIDAgKTsKICAgICAgIH0KICAgfSBlbHNlIGlmIChjdHgtPlRleHR1cmUuX0VuYWJsZWRVbml0cyAmIDB4MSkgewogICAgICAvKiBvbmx5IHVuaXQgMCBlbmFibGVkICovIAogICAgICBtYWNoNjRVcGRhdGVUZXh0dXJlVW5pdCggY3R4LCAwICk7CiAgICAgIG1hY2g2NFVwZGF0ZVRleHR1cmVFbnYoIGN0eCwgMCApOwogICB9CgogICBtbWVzYS0+ZGlydHkgfD0gKE1BQ0g2NF9VUExPQURfU0NBTEVfM0RfQ05UTCB8CgkJICAgIE1BQ0g2NF9VUExPQURfVEVYVFVSRSk7Cn0KCgovKiBEdWUgdG8gdGhlIHdheSB3ZSBtdXN0IHByb2dyYW0gdGV4dHVyZSBzdGF0ZSBpbnRvIHRoZSBSYWdlIFBybywKICogd2UgbXVzdCBsZWF2ZSB0aGVzZSBjYWxjdWxhdGlvbnMgdG8gdGhlIGFic29sdXRlIGxhc3QgbWludXRlLgogKi8Kdm9pZCBtYWNoNjRFbWl0VGV4U3RhdGVMb2NrZWQoIG1hY2g2NENvbnRleHRQdHIgbW1lc2EsCgkJCSAgICAgICBtYWNoNjRUZXhPYmpQdHIgdDAsCgkJCSAgICAgICBtYWNoNjRUZXhPYmpQdHIgdDEgKQp7CiAgIGRybV9tYWNoNjRfc2FyZWFfdCAqc2FyZWEgPSBtbWVzYS0+c2FyZWE7CiAgIGRybV9tYWNoNjRfY29udGV4dF9yZWdzX3QgKnJlZ3MgPSAmKG1tZXNhLT5zZXR1cCk7CgogICAvKiBmb3IgbXVsdGl0ZXgsIGJvdGggdGV4dHVyZXMgbXVzdCBiZSBsb2NhbCBvciBBR1AgKi8KICAgaWYgKCB0MCAmJiB0MSApCiAgICAgIGFzc2VydCh0MC0+aGVhcCA9PSB0MS0+aGVhcCk7CgogICBpZiAoIHQwICkgewogICAgICBpZiAodDAtPmhlYXAgPT0gTUFDSDY0X0NBUkRfSEVBUCkgewojaWYgRU5BQkxFX1BFUkZfQk9YRVMKCSBtbWVzYS0+Y190ZXhzcmNfY2FyZCsrOwojZW5kaWYKCSBtbWVzYS0+c2V0dXAudGV4X2NudGwgJj0gfk1BQ0g2NF9URVhfU1JDX0FHUDsKICAgICAgfSBlbHNlIHsKI2lmIEVOQUJMRV9QRVJGX0JPWEVTCgkgbW1lc2EtPmNfdGV4c3JjX2FncCsrOwojZW5kaWYKCSBtbWVzYS0+c2V0dXAudGV4X2NudGwgfD0gTUFDSDY0X1RFWF9TUkNfQUdQOwogICAgICB9CiAgICAgIG1tZXNhLT5zZXR1cC50ZXhfb2Zmc2V0ID0gdDAtPmJ1ZkFkZHI7CiAgIH0KCiAgIGlmICggdDEgKSB7CiAgICAgIG1tZXNhLT5zZXR1cC5zZWNvbmRhcnlfdGV4X29mZiA9IHQxLT5idWZBZGRyOwogICB9CgogICBtZW1jcHkoICZzYXJlYS0+Y29udGV4dF9zdGF0ZS50ZXhfc2l6ZV9waXRjaCwgJnJlZ3MtPnRleF9zaXplX3BpdGNoLAoJICAgTUFDSDY0X05SX1RFWFRVUkVfUkVHUyAqIHNpemVvZihHTHVpbnQpICk7Cn0KCg==