LyoKICogIENvcHlyaWdodAkxOTk0CUVyaWMgWW91bmRhbGUgJiBFcmlrIEJvcwogKiAgQ29weXJpZ2h0CTE5OTUJTWFydGluIHZvbiBM9ndpcwogKiAgQ29weXJpZ2h0ICAgMTk5Ni05OCBNYXJjdXMgTWVpc3NuZXIKICoKICoJYmFzZWQgb24gRXJpYyBZb3VuZGFsZSdzIHBlLXRlc3QgYW5kOgogKglmdHAubWljcm9zb2Z0LmNvbTovZGV2ZWxvcHIvTVNETi9PY3RDRC9QRUZJTEUuWklQCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KLyogTm90ZXM6CiAqIEJlZm9yZSB5b3Ugc3RhcnQgY2hhbmdpbmcgc29tZXRoaW5nIGluIHRoaXMgZmlsZSBiZSBhd2FyZSBvZiB0aGUgZm9sbG93aW5nOgogKgogKiAtIFRoZXJlIGFyZSBzZXZlcmFsIGZ1bmN0aW9ucyBjYWxsZWQgcmVjdXJzaXZlbHkuIEluIGEgdmVyeSBzdWJ0bGUgYW5kCiAqICAgb2JzY3VyZSB3YXkuIERMTHMgY2FuIHJlZmVyZW5jZSBlYWNoIG90aGVyIHJlY3Vyc2l2ZWx5IGV0Yy4KICogLSBJZiB5b3Ugd2FudCB0byBlbmhhbmNlLCBzcGVlZCB1cCBvciBjbGVhbiB1cCBzb21ldGhpbmcgaW4gaGVyZSwgdGhpbmsKICogICB0d2ljZSBXSFkgaXQgaXMgaW1wbGVtZW50ZWQgaW4gdGhhdCBzdHJhbmdlIHdheS4gVGhlcmUgaXMgdXN1YWxseSBhIHJlYXNvbi4KICogICBUaG91Z2ggc29tZXRpbWVzIGl0IG1pZ2h0IGp1c3QgYmUgbGF6eW5lc3MgOykKICogLSBJbiBQRV9NYXBJbWFnZSwgcmlnaHQgYmVmb3JlIFBFX2ZpeHVwX2ltcG9ydHMoKSBhbGwgZXh0ZXJuYWwgYW5kIGludGVybmFsCiAqICAgc3RhdGUgTVVTVCBiZSBjb3JyZWN0IHNpbmNlIHRoaXMgZnVuY3Rpb24gY2FuIGJlIGNhbGxlZCB3aXRoIHRoZSBTQU1FIGltYWdlCiAqICAgQUdBSU4uIChUaGF0cyByZWN1cnNpb24gZm9yIHlvdS4pIFRoYXQgbWVhbnMgTU9EUkVGLm1vZHVsZSBhbmQKICogICBORV9NT0RVTEUubW9kdWxlMzIuCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgoKI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaWZkZWYgSEFWRV9TWVNfTU1BTl9ICiNpbmNsdWRlIDxzeXMvbW1hbi5oPgojZW5kaWYKI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSAid2luZS93aW5iYXNlMTYuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJzbm9vcC5oIgojaW5jbHVkZSAid2luZS9zZXJ2ZXIuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKHdpbjMyKTsKV0lORV9ERUNMQVJFX0RFQlVHX0NIQU5ORUwoZGVsYXlobHApOwpXSU5FX0RFQ0xBUkVfREVCVUdfQ0hBTk5FTChmaXh1cCk7CldJTkVfREVDTEFSRV9ERUJVR19DSEFOTkVMKG1vZHVsZSk7CldJTkVfREVDTEFSRV9ERUJVR19DSEFOTkVMKHJlbGF5KTsKV0lORV9ERUNMQVJFX0RFQlVHX0NIQU5ORUwoc2VnbWVudCk7CgoKLyogY29udmVydCBQRSBpbWFnZSBWaXJ0dWFsQWRkcmVzcyB0byBSZWFsIEFkZHJlc3MgKi8KaW5saW5lIHN0YXRpYyB2b2lkICpnZXRfcnZhKCBITU9EVUxFIG1vZHVsZSwgRFdPUkQgdmEgKQp7CiAgICByZXR1cm4gKHZvaWQgKikoKGNoYXIgKiltb2R1bGUgKyB2YSk7Cn0KCiNkZWZpbmUgQWRqdXN0UHRyKHB0cixkZWx0YSkgKChjaGFyICopKHB0cikgKyAoZGVsdGEpKQoKdm9pZCBkdW1wX2V4cG9ydHMoIEhNT0RVTEUgaE1vZHVsZSApCnsKICBjaGFyCQkqTW9kdWxlOwogIGludAkJaSwgajsKICBXT1JECQkqb3JkaW5hbDsKICBEV09SRAkJKmZ1bmN0aW9uLCpmdW5jdGlvbnM7CiAgRFdPUkQgKm5hbWU7CiAgSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSAqcGVfZXhwb3J0czsKICBEV09SRCBydmFfc3RhcnQsIHNpemU7CgogIHBlX2V4cG9ydHMgPSBSdGxJbWFnZURpcmVjdG9yeUVudHJ5VG9EYXRhKCBoTW9kdWxlLCBUUlVFLCBJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhQT1JULCAmc2l6ZSApOwogIHJ2YV9zdGFydCA9IChjaGFyICopcGVfZXhwb3J0cyAtIChjaGFyICopaE1vZHVsZTsKCiAgTW9kdWxlID0gZ2V0X3J2YShoTW9kdWxlLCBwZV9leHBvcnRzLT5OYW1lKTsKICBEUFJJTlRGKCIqKioqKioqRVhQT1JUIERBVEEqKioqKioqXG4iKTsKICBEUFJJTlRGKCJNb2R1bGUgbmFtZSBpcyAlcywgJWxkIGZ1bmN0aW9ucywgJWxkIG5hbWVzXG4iLAogICAgICAgICAgTW9kdWxlLCBwZV9leHBvcnRzLT5OdW1iZXJPZkZ1bmN0aW9ucywgcGVfZXhwb3J0cy0+TnVtYmVyT2ZOYW1lcyk7CgogIG9yZGluYWwgPSBnZXRfcnZhKGhNb2R1bGUsIHBlX2V4cG9ydHMtPkFkZHJlc3NPZk5hbWVPcmRpbmFscyk7CiAgZnVuY3Rpb25zID0gZnVuY3Rpb24gPSBnZXRfcnZhKGhNb2R1bGUsIHBlX2V4cG9ydHMtPkFkZHJlc3NPZkZ1bmN0aW9ucyk7CiAgbmFtZSA9IGdldF9ydmEoaE1vZHVsZSwgcGVfZXhwb3J0cy0+QWRkcmVzc09mTmFtZXMpOwoKICBEUFJJTlRGKCIgT3JkICAgIFJWQSAgICAgQWRkciAgIE5hbWVcbiIgKTsKICBmb3IgKGk9MDtpPHBlX2V4cG9ydHMtPk51bWJlck9mRnVuY3Rpb25zO2krKywgZnVuY3Rpb24rKykKICB7CiAgICAgIGlmICghKmZ1bmN0aW9uKSBjb250aW51ZTsgIC8qIE5vIHN1Y2ggZnVuY3Rpb24gKi8KICAgICAgRFBSSU5URiggIiU0bGQgJTA4bHggJXAiLCBpICsgcGVfZXhwb3J0cy0+QmFzZSwgKmZ1bmN0aW9uLCBnZXRfcnZhKGhNb2R1bGUsICpmdW5jdGlvbikgKTsKICAgICAgLyogQ2hlY2sgaWYgd2UgaGF2ZSBhIG5hbWUgZm9yIGl0ICovCiAgICAgIGZvciAoaiA9IDA7IGogPCBwZV9leHBvcnRzLT5OdW1iZXJPZk5hbWVzOyBqKyspCiAgICAgICAgICBpZiAob3JkaW5hbFtqXSA9PSBpKQogICAgICAgICAgewogICAgICAgICAgICAgIERQUklOVEYoICIgICVzIiwgKGNoYXIqKWdldF9ydmEoaE1vZHVsZSwgbmFtZVtqXSkgKTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgaWYgKCgqZnVuY3Rpb24gPj0gcnZhX3N0YXJ0KSAmJiAoKmZ1bmN0aW9uIDw9IHJ2YV9zdGFydCArIHNpemUpKQoJICBEUFJJTlRGKCIgKGZvcndhcmRlZCAtPiAlcykiLCAoY2hhciAqKWdldF9ydmEoaE1vZHVsZSwgKmZ1bmN0aW9uKSk7CiAgICAgIERQUklOVEYoIlxuIik7CiAgfQp9CgovKiBMb29rIHVwIHRoZSBzcGVjaWZpZWQgZnVuY3Rpb24gb3Igb3JkaW5hbCBpbiB0aGUgZXhwb3J0IGxpc3Q6CiAqIElmIGl0IGlzIGEgc3RyaW5nOgogKiAJLSBsb29rIHVwIHRoZSBuYW1lIGluIHRoZSBuYW1lIGxpc3QuCiAqCS0gbG9vayB1cCB0aGUgb3JkaW5hbCB3aXRoIHRoYXQgaW5kZXguCiAqCS0gdXNlIHRoZSBvcmRpbmFsIGFzIG9mZnNldCBpbnRvIHRoZSBmdW5jdGlvbmxpc3QKICogSWYgaXQgaXMgYW4gb3JkaW5hbDoKICoJLSB1c2Ugb3JkaW5hbC1wZV9leHBvcnQtPkJhc2UgYXMgb2Zmc2V0IGludG8gdGhlIGZ1bmN0aW9uIGxpc3QKICovCnN0YXRpYyBGQVJQUk9DIFBFX0ZpbmRFeHBvcnRlZEZ1bmN0aW9uKAoJV0lORV9NT0RSRUYgKndtLAkvKiBbaW5dIFdJTkUgbW9kcmVmZXJlbmNlICovCglMUENTVFIgZnVuY05hbWUsCS8qIFtpbl0gZnVuY3Rpb24gbmFtZSAqLwogICAgICAgIGludCBoaW50LAogICAgICAgIEJPT0wgc25vb3AgKQp7CglXT1JECQkJCSogb3JkaW5hbHM7CglEV09SRAkJCQkqIGZ1bmN0aW9uOwoJaW50CQkJCWksIG9yZGluYWw7CglEV09SRAkJCQlydmFfc3RhcnQsIGFkZHI7CgljaGFyCQkJCSogZm9yd2FyZDsKICAgICAgICBEV09SRCAqbmFtZTsKICAgICAgICBjaGFyICplbmFtZSA9IE5VTEw7CiAgICAgICAgRkFSUFJPQyBwcm9jOwogICAgICAgIElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkgKmV4cG9ydHM7CiAgICAgICAgRFdPUkQgZXhwX3NpemU7CgogICAgICAgIGlmICghKGV4cG9ydHMgPSBSdGxJbWFnZURpcmVjdG9yeUVudHJ5VG9EYXRhKCB3bS0+bW9kdWxlLCBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhQT1JULCAmZXhwX3NpemUgKSkpCiAgICAgICAgICAgIHJldHVybiBOVUxMOwoKICAgICAgICBpZiAoSElXT1JEKGZ1bmNOYW1lKSkgVFJBQ0UoIiglcylcbiIsZnVuY05hbWUpOwogICAgICAgIGVsc2UgVFJBQ0UoIiglZClcbiIsTE9XT1JEKGZ1bmNOYW1lKSk7CgoJb3JkaW5hbHM9IGdldF9ydmEod20tPm1vZHVsZSwgZXhwb3J0cy0+QWRkcmVzc09mTmFtZU9yZGluYWxzKTsKCWZ1bmN0aW9uPSBnZXRfcnZhKHdtLT5tb2R1bGUsIGV4cG9ydHMtPkFkZHJlc3NPZkZ1bmN0aW9ucyk7CgluYW1lICAgID0gZ2V0X3J2YSh3bS0+bW9kdWxlLCBleHBvcnRzLT5BZGRyZXNzT2ZOYW1lcyk7Cglmb3J3YXJkID0gTlVMTDsKICAgICAgICBydmFfc3RhcnQgPSAoY2hhciAqKWV4cG9ydHMgLSAoY2hhciAqKXdtLT5tb2R1bGU7CgoJaWYgKEhJV09SRChmdW5jTmFtZSkpCiAgICAgICAgewogICAgICAgICAgICBpbnQgbWluID0gMCwgbWF4ID0gZXhwb3J0cy0+TnVtYmVyT2ZOYW1lcyAtIDE7CgogICAgICAgICAgICAvKiBmaXJzdCBjaGVjayB0aGUgaGludCAqLwogICAgICAgICAgICBpZiAoaGludCA+PSAwICYmIGhpbnQgPD0gbWF4KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBlbmFtZSA9IGdldF9ydmEod20tPm1vZHVsZSwgbmFtZVtoaW50XSk7CiAgICAgICAgICAgICAgICBpZiAoIXN0cmNtcCggZW5hbWUsIGZ1bmNOYW1lICkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgb3JkaW5hbCA9IG9yZGluYWxzW2hpbnRdOwogICAgICAgICAgICAgICAgICAgIGdvdG8gZm91bmQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIHRoZW4gZG8gYSBiaW5hcnkgc2VhcmNoICovCiAgICAgICAgICAgIHdoaWxlIChtaW4gPD0gbWF4KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpbnQgcmVzLCBwb3MgPSAobWluICsgbWF4KSAvIDI7CiAgICAgICAgICAgICAgICBlbmFtZSA9IGdldF9ydmEod20tPm1vZHVsZSwgbmFtZVtwb3NdKTsKICAgICAgICAgICAgICAgIGlmICghKHJlcyA9IHN0cmNtcCggZW5hbWUsIGZ1bmNOYW1lICkpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIG9yZGluYWwgPSBvcmRpbmFsc1twb3NdOwogICAgICAgICAgICAgICAgICAgIGdvdG8gZm91bmQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAocmVzID4gMCkgbWF4ID0gcG9zIC0gMTsKICAgICAgICAgICAgICAgIGVsc2UgbWluID0gcG9zICsgMTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gTlVMTDsKCX0KICAgICAgICBlbHNlICAvKiBmaW5kIGJ5IG9yZGluYWwgKi8KICAgICAgICB7CiAgICAgICAgICAgIG9yZGluYWwgPSBMT1dPUkQoZnVuY05hbWUpIC0gZXhwb3J0cy0+QmFzZTsKICAgICAgICAgICAgaWYgKHNub29wICYmIG5hbWUpICAvKiBuZWVkIHRvIGZpbmQgYSBuYW1lIGZvciBpdCAqLwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgZXhwb3J0cy0+TnVtYmVyT2ZOYW1lczsgaSsrKQogICAgICAgICAgICAgICAgICAgIGlmIChvcmRpbmFsc1tpXSA9PSBvcmRpbmFsKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgZW5hbWUgPSBnZXRfcnZhKHdtLT5tb2R1bGUsIG5hbWVbaV0pOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCX0KCiBmb3VuZDoKICAgICAgICBpZiAob3JkaW5hbCA+PSBleHBvcnRzLT5OdW1iZXJPZkZ1bmN0aW9ucykKICAgICAgICB7CiAgICAgICAgICAgIFRSQUNFKCIJb3JkaW5hbCAlbGQgb3V0IG9mIHJhbmdlIVxuIiwgb3JkaW5hbCArIGV4cG9ydHMtPkJhc2UgKTsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgfQogICAgICAgIGFkZHIgPSBmdW5jdGlvbltvcmRpbmFsXTsKICAgICAgICBpZiAoIWFkZHIpIHJldHVybiBOVUxMOwoKICAgICAgICBwcm9jID0gZ2V0X3J2YSh3bS0+bW9kdWxlLCBhZGRyKTsKICAgICAgICBpZiAoKChjaGFyICopcHJvYyA8IChjaGFyICopZXhwb3J0cykgfHwgKChjaGFyICopcHJvYyA+PSAoY2hhciAqKWV4cG9ydHMgKyBleHBfc2l6ZSkpCiAgICAgICAgewogICAgICAgICAgICBpZiAoc25vb3ApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICghZW5hbWUpIGVuYW1lID0gIkAiOwogICAgICAgICAgICAgICAgcHJvYyA9IFNOT09QX0dldFByb2NBZGRyZXNzKHdtLT5tb2R1bGUsZW5hbWUsb3JkaW5hbCxwcm9jKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gcHJvYzsKICAgICAgICB9CiAgICAgICAgZWxzZSAgLyogZm9yd2FyZCBlbnRyeSBwb2ludCAqLwogICAgICAgIHsKICAgICAgICAgICAgICAgIFdJTkVfTU9EUkVGICp3bV9mdzsKICAgICAgICAgICAgICAgIGNoYXIgKmZvcndhcmQgPSAoY2hhciAqKXByb2M7CgkJY2hhciBtb2R1bGVbMjU2XTsKCQljaGFyICplbmQgPSBzdHJjaHIoZm9yd2FyZCwgJy4nKTsKCgkJaWYgKCFlbmQpIHJldHVybiBOVUxMOwogICAgICAgICAgICAgICAgaWYgKGVuZCAtIGZvcndhcmQgPj0gc2l6ZW9mKG1vZHVsZSkpIHJldHVybiBOVUxMOwogICAgICAgICAgICAgICAgbWVtY3B5KCBtb2R1bGUsIGZvcndhcmQsIGVuZCAtIGZvcndhcmQgKTsKCQltb2R1bGVbZW5kLWZvcndhcmRdID0gMDsKICAgICAgICAgICAgICAgIGlmICghKHdtX2Z3ID0gTU9EVUxFX0ZpbmRNb2R1bGUoIG1vZHVsZSApKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBFUlIoIm1vZHVsZSBub3QgZm91bmQgZm9yIGZvcndhcmQgJyVzJyB1c2VkIGJ5ICclcydcbiIsIGZvcndhcmQsIHdtLT5tb2RuYW1lICk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgICAgICAgICB9CgkJaWYgKCEocHJvYyA9IE1PRFVMRV9HZXRQcm9jQWRkcmVzcyggd21fZnctPm1vZHVsZSwgZW5kICsgMSwgLTEsIHNub29wICkpKQogICAgICAgICAgICAgICAgICAgIEVSUigiZnVuY3Rpb24gbm90IGZvdW5kIGZvciBmb3J3YXJkICclcycgdXNlZCBieSAnJXMnLiBJZiB5b3UgYXJlIHVzaW5nIGJ1aWx0aW4gJyVzJywgdHJ5IHVzaW5nIHRoZSBuYXRpdmUgb25lIGluc3RlYWQuXG4iLCBmb3J3YXJkLCB3bS0+bW9kbmFtZSwgd20tPm1vZG5hbWUgKTsKCQlyZXR1cm4gcHJvYzsKCX0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCVBFX2ZpeHVwX2ltcG9ydHMKICovCkRXT1JEIFBFX2ZpeHVwX2ltcG9ydHMoIFdJTkVfTU9EUkVGICp3bSApCnsKICAgIGludCBpLGNoYXJhY3RlcmlzdGljc19kZXRlY3Rpb249MTsKICAgIElNQUdFX0lNUE9SVF9ERVNDUklQVE9SICppbXBvcnRzLCAqcGVfaW1wOwogICAgRFdPUkQgc2l6ZTsKCiAgICBpbXBvcnRzID0gUnRsSW1hZ2VEaXJlY3RvcnlFbnRyeVRvRGF0YSggd20tPm1vZHVsZSwgVFJVRSwgSU1BR0VfRElSRUNUT1JZX0VOVFJZX0lNUE9SVCwgJnNpemUgKTsKCiAgICAvKiBmaXJzdCwgY291bnQgdGhlIG51bWJlciBvZiBpbXBvcnRlZCBub24taW50ZXJuYWwgbW9kdWxlcyAqLwogICAgcGVfaW1wID0gaW1wb3J0czsKICAgIGlmICghcGVfaW1wKSByZXR1cm4gMDsKCiAgICAvKiBPSywgbm93IGR1bXAgdGhlIGltcG9ydCBsaXN0ICovCiAgICBUUkFDRSgiRHVtcGluZyBpbXBvcnRzIGxpc3RcbiIpOwoKICAgIC8qIFdlIGFzc3VtZSB0aGF0IHdlIGhhdmUgYXQgbGVhc3Qgb25lIGltcG9ydCB3aXRoICEwIGNoYXJhY3RlcmlzdGljcyBhbmQKICAgICAqIGRldGVjdCBicm9rZW4gaW1wb3J0cyB3aXRoIGFsbCBjaGFyYWN0ZXJpc3RpY3MgMCAobm90YWJseSBCb3JsYW5kKSBhbmQKICAgICAqIHN3aXRjaCB0aGUgZGV0ZWN0aW9uIG9mZiBmb3IgdGhlbS4KICAgICAqLwogICAgZm9yIChpID0gMDsgcGVfaW1wLT5OYW1lIDsgcGVfaW1wKyspIHsKCWlmICghaSAmJiAhcGVfaW1wLT51LkNoYXJhY3RlcmlzdGljcykKCQljaGFyYWN0ZXJpc3RpY3NfZGV0ZWN0aW9uID0gMDsKCWlmIChjaGFyYWN0ZXJpc3RpY3NfZGV0ZWN0aW9uICYmICFwZV9pbXAtPnUuQ2hhcmFjdGVyaXN0aWNzKQoJCWJyZWFrOwoJaSsrOwogICAgfQogICAgaWYgKCFpKSByZXR1cm4gMDsgIC8qIG5vIGltcG9ydHMgKi8KCiAgICAvKiBBbGxvY2F0ZSBtb2R1bGUgZGVwZW5kZW5jeSBsaXN0ICovCiAgICB3bS0+bkRlcHMgPSBpOwogICAgd20tPmRlcHMgID0gSGVhcEFsbG9jKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBpKnNpemVvZihXSU5FX01PRFJFRiAqKSApOwoKICAgIC8qIGxvYWQgdGhlIGltcG9ydGVkIG1vZHVsZXMuIFRoZXkgYXJlIGF1dG9tYXRpY2FsbHkKICAgICAqIGFkZGVkIHRvIHRoZSBtb2RyZWYgbGlzdCBvZiB0aGUgcHJvY2Vzcy4KICAgICAqLwoKICAgIGZvciAoaSA9IDAsIHBlX2ltcCA9IGltcG9ydHM7IHBlX2ltcC0+TmFtZSA7IHBlX2ltcCsrKSB7CiAgICAJV0lORV9NT0RSRUYJCSp3bUltcDsKCUlNQUdFX0lNUE9SVF9CWV9OQU1FCSpwZV9uYW1lOwoJUElNQUdFX1RIVU5LX0RBVEEJaW1wb3J0X2xpc3QsdGh1bmtfbGlzdDsKIAljaGFyCQkJKm5hbWUgPSBnZXRfcnZhKHdtLT5tb2R1bGUsIHBlX2ltcC0+TmFtZSk7CgoJaWYgKGNoYXJhY3RlcmlzdGljc19kZXRlY3Rpb24gJiYgIXBlX2ltcC0+dS5DaGFyYWN0ZXJpc3RpY3MpCgkJYnJlYWs7CgoJd21JbXAgPSBNT0RVTEVfTG9hZExpYnJhcnlFeEEoIG5hbWUsIDAsIDAgKTsKCWlmICghd21JbXApIHsKCSAgICBFUlJfKG1vZHVsZSkoIk1vZHVsZSAoZmlsZSkgJXMgKHdoaWNoIGlzIG5lZWRlZCBieSAlcykgbm90IGZvdW5kXG4iLCBuYW1lLCB3bS0+ZmlsZW5hbWUpOwoJICAgIHJldHVybiAxOwoJfQogICAgICAgIHdtLT5kZXBzW2krK10gPSB3bUltcDsKCgkvKiBGSVhNRTogZm9yd2FyZGVyIGVudHJpZXMgLi4uICovCgoJaWYgKHBlX2ltcC0+dS5PcmlnaW5hbEZpcnN0VGh1bmsgIT0gMCkgeyAvKiBvcmlnaW5hbCBNUyBzdHlsZSAqLwoJICAgIFRSQUNFKCJNaWNyb3NvZnQgc3R5bGUgaW1wb3J0cyB1c2VkXG4iKTsKCSAgICBpbXBvcnRfbGlzdCA9IGdldF9ydmEod20tPm1vZHVsZSwgKERXT1JEKXBlX2ltcC0+dS5PcmlnaW5hbEZpcnN0VGh1bmspOwoJICAgIHRodW5rX2xpc3QgPSBnZXRfcnZhKHdtLT5tb2R1bGUsIChEV09SRClwZV9pbXAtPkZpcnN0VGh1bmspOwoKCSAgICB3aGlsZSAoaW1wb3J0X2xpc3QtPnUxLk9yZGluYWwpIHsKCQlpZiAoSU1BR0VfU05BUF9CWV9PUkRJTkFMKGltcG9ydF9saXN0LT51MS5PcmRpbmFsKSkgewoJCSAgICBpbnQgb3JkaW5hbCA9IElNQUdFX09SRElOQUwoaW1wb3J0X2xpc3QtPnUxLk9yZGluYWwpOwoKCQkgICAgVFJBQ0UoIi0tLSBPcmRpbmFsICVzLCVkXG4iLCBuYW1lLCBvcmRpbmFsKTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249KFBEV09SRClNT0RVTEVfR2V0UHJvY0FkZHJlc3MoCiAgICAgICAgICAgICAgICAgICAgICAgIHdtSW1wLT5tb2R1bGUsIChMUENTVFIpb3JkaW5hbCwgLTEsIFRSVUUKCQkgICAgKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCQlFUlIoIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCBpbXBvcnRlZCBmcm9tICVzLCBzZXR0aW5nIHRvIDB4ZGVhZGJlZWZcbiIsCgkJCQluYW1lLCBvcmRpbmFsLCB3bS0+ZmlsZW5hbWUgKTsKICAgICAgICAgICAgICAgICAgICAgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24gPSAoUERXT1JEKTB4ZGVhZGJlZWY7CgkJICAgIH0KCQl9IGVsc2UgewkJLyogaW1wb3J0IGJ5IG5hbWUgKi8KCQkgICAgcGVfbmFtZSA9IGdldF9ydmEod20tPm1vZHVsZSwgKERXT1JEKWltcG9ydF9saXN0LT51MS5BZGRyZXNzT2ZEYXRhKTsKCQkgICAgVFJBQ0UoIi0tLSAlcyAlcy4lZFxuIiwgcGVfbmFtZS0+TmFtZSwgbmFtZSwgcGVfbmFtZS0+SGludCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPShQRFdPUkQpTU9EVUxFX0dldFByb2NBZGRyZXNzKAogICAgICAgICAgICAgICAgICAgICAgICB3bUltcC0+bW9kdWxlLCBwZV9uYW1lLT5OYW1lLCBwZV9uYW1lLT5IaW50LCBUUlVFCgkJICAgICk7CgkJICAgIGlmICghdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24pIHsKCQkJRVJSKCJObyBpbXBsZW1lbnRhdGlvbiBmb3IgJXMuJWQoJXMpIGltcG9ydGVkIGZyb20gJXMsIHNldHRpbmcgdG8gMHhkZWFkYmVlZlxuIiwKCQkJCW5hbWUscGVfbmFtZS0+SGludCxwZV9uYW1lLT5OYW1lLHdtLT5maWxlbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uID0gKFBEV09SRCkweGRlYWRiZWVmOwoJCSAgICB9CgkJfQoJCWltcG9ydF9saXN0Kys7CgkJdGh1bmtfbGlzdCsrOwoJICAgIH0KCX0gZWxzZSB7CS8qIEJvcmxhbmQgc3R5bGUgKi8KCSAgICBUUkFDRSgiQm9ybGFuZCBzdHlsZSBpbXBvcnRzIHVzZWRcbiIpOwoJICAgIHRodW5rX2xpc3QgPSBnZXRfcnZhKHdtLT5tb2R1bGUsIChEV09SRClwZV9pbXAtPkZpcnN0VGh1bmspOwoJICAgIHdoaWxlICh0aHVua19saXN0LT51MS5PcmRpbmFsKSB7CgkJaWYgKElNQUdFX1NOQVBfQllfT1JESU5BTCh0aHVua19saXN0LT51MS5PcmRpbmFsKSkgewoJCSAgICAvKiBub3Qgc3VyZSBhYm91dCB0aGlzIGJyYW5jaCwgYnV0IGl0IHNlZW1zIHRvIHdvcmsgKi8KCQkgICAgaW50IG9yZGluYWwgPSBJTUFHRV9PUkRJTkFMKHRodW5rX2xpc3QtPnUxLk9yZGluYWwpOwoKCQkgICAgVFJBQ0UoIi0tLSBPcmRpbmFsICVzLiVkXG4iLG5hbWUsb3JkaW5hbCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPShQRFdPUkQpTU9EVUxFX0dldFByb2NBZGRyZXNzKAogICAgICAgICAgICAgICAgICAgICAgICB3bUltcC0+bW9kdWxlLCAoTFBDU1RSKSBvcmRpbmFsLCAtMSwgVFJVRQoJCSAgICApOwoJCSAgICBpZiAoIXRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uKSB7CgkJCUVSUigiTm8gaW1wbGVtZW50YXRpb24gZm9yICVzLiVkIGltcG9ydGVkIGZyb20gJXMsIHNldHRpbmcgdG8gMHhkZWFkYmVlZlxuIiwKCQkJCW5hbWUsb3JkaW5hbCwgd20tPmZpbGVuYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24gPSAoUERXT1JEKTB4ZGVhZGJlZWY7CgkJICAgIH0KCQl9IGVsc2UgewoJCSAgICBwZV9uYW1lPWdldF9ydmEod20tPm1vZHVsZSwgKERXT1JEKXRodW5rX2xpc3QtPnUxLkFkZHJlc3NPZkRhdGEpOwoJCSAgICBUUkFDRSgiLS0tICVzICVzLiVkXG4iLAoJCSAgIAkJICBwZV9uYW1lLT5OYW1lLG5hbWUscGVfbmFtZS0+SGludCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPShQRFdPUkQpTU9EVUxFX0dldFByb2NBZGRyZXNzKAogICAgICAgICAgICAgICAgICAgICAgICB3bUltcC0+bW9kdWxlLCBwZV9uYW1lLT5OYW1lLCBwZV9uYW1lLT5IaW50LCBUUlVFCgkJICAgICk7CgkJICAgIGlmICghdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24pIHsKCQkgICAgCUVSUigiTm8gaW1wbGVtZW50YXRpb24gZm9yICVzLiVkKCVzKSBpbXBvcnRlZCBmcm9tICVzLCBzZXR0aW5nIHRvIDB4ZGVhZGJlZWZcbiIsCgkJCQluYW1lLCBwZV9uYW1lLT5IaW50LCBwZV9uYW1lLT5OYW1lLCB3bS0+ZmlsZW5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICB0aHVua19saXN0LT51MS5GdW5jdGlvbiA9IChQRFdPUkQpMHhkZWFkYmVlZjsKCQkgICAgfQoJCX0KCQl0aHVua19saXN0Kys7CgkgICAgfQoJfQogICAgfQogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQkJUEVfTG9hZEltYWdlCiAqIExvYWQgb25lIFBFIGZvcm1hdCBETEwvRVhFIGludG8gbWVtb3J5CiAqCiAqIFVubHVja2lseSB3ZSBjYW4ndCBqdXN0IG1tYXAgdGhlIHNlY3Rpb25zIHdoZXJlIHdlIHdhbnQgdGhlbSwgZm9yCiAqIChhdCBsZWFzdCkgTGludXggZG9lcyBvbmx5IHN1cHBvcnQgb2Zmc2V0cyB3aGljaCBhcmUgcGFnZS1hbGlnbmVkLgogKgogKiBCVVQgd2UgaGF2ZSB0byBtYXAgdGhlIHdob2xlIGltYWdlIGFueXdheSwgZm9yIFdpbjMyIHByb2dyYW1zIHNvbWV0aW1lcwogKiB3YW50IHRvIGFjY2VzcyB0aGVtLiAoSE1PRFVMRSBwb2ludHMgdG8gdGhlIHN0YXJ0IG9mIGl0KQogKi8KSE1PRFVMRSBQRV9Mb2FkSW1hZ2UoIEhBTkRMRSBoRmlsZSwgTFBDU1RSIGZpbGVuYW1lLCBEV09SRCBmbGFncyApCnsKICAgIElNQUdFX05UX0hFQURFUlMgKm50OwogICAgSE1PRFVMRSBoTW9kdWxlOwogICAgSEFORExFIG1hcHBpbmc7CiAgICB2b2lkICpiYXNlOwoKICAgIFRSQUNFXyhtb2R1bGUpKCAibG9hZGluZyAlc1xuIiwgZmlsZW5hbWUgKTsKCiAgICBtYXBwaW5nID0gQ3JlYXRlRmlsZU1hcHBpbmdBKCBoRmlsZSwgTlVMTCwgU0VDX0lNQUdFLCAwLCAwLCBOVUxMICk7CiAgICBpZiAoIW1hcHBpbmcpIHJldHVybiAwOwogICAgYmFzZSA9IE1hcFZpZXdPZkZpbGUoIG1hcHBpbmcsIEZJTEVfTUFQX1JFQUQsIDAsIDAsIDAgKTsKICAgIENsb3NlSGFuZGxlKCBtYXBwaW5nICk7CiAgICBpZiAoIWJhc2UpIHJldHVybiAwOwoKICAgIC8qIHZpcnVzIGNoZWNrICovCgogICAgaE1vZHVsZSA9IChITU9EVUxFKWJhc2U7CiAgICBudCA9IFJ0bEltYWdlTnRIZWFkZXIoIGhNb2R1bGUgKTsKCiAgICBpZiAobnQtPk9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQpCiAgICB7CiAgICAgICAgaWYgKCFSdGxJbWFnZVJ2YVRvU2VjdGlvbiggbnQsIGhNb2R1bGUsIG50LT5PcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50ICkpCiAgICAgICAgICAgIE1FU1NBR0UoIlZJUlVTIFdBUk5JTkc6IFBFIG1vZHVsZSBoYXMgYW4gaW52YWxpZCBlbnRyeXBvaW50ICgweCUwOGx4KSAiCiAgICAgICAgICAgICAgICAgICAgIm91dHNpZGUgYWxsIHNlY3Rpb25zIChwb3NzaWJseSBpbmZlY3RlZCBieSBUY2hlcm5vYnlsL1NwYWNlRmlsbGVyIHZpcnVzKSFcbiIsCiAgICAgICAgICAgICAgICAgICAgbnQtPk9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQgKTsKICAgIH0KCiAgICByZXR1cm4gaE1vZHVsZTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgICAgIFBFX0NyZWF0ZU1vZHVsZQogKgogKiBDcmVhdGUgV0lORV9NT0RSRUYgc3RydWN0dXJlIGZvciBsb2FkZWQgSE1PRFVMRSwgbGluayBpdCBpbnRvCiAqIHByb2Nlc3MgbW9kcmVmX2xpc3QsIGFuZCBmaXh1cCBhbGwgaW1wb3J0cy4KICoKICogTm90ZTogaE1vZHVsZSBtdXN0IHBvaW50IHRvIGEgY29ycmVjdGx5IGFsbG9jYXRlZCBQRSBpbWFnZSwKICogICAgICAgd2l0aCBiYXNlIHJlbG9jYXRpb25zIGFwcGxpZWQ7IHRoZSAxNi1iaXQgZHVtbXkgbW9kdWxlCiAqICAgICAgIGFzc29jaWF0ZWQgdG8gaE1vZHVsZSBtdXN0IGFscmVhZHkgZXhpc3QuCiAqCiAqIE5vdGU6IFRoaXMgcm91dGluZSBtdXN0IGFsd2F5cyBiZSBjYWxsZWQgaW4gdGhlIGNvbnRleHQgb2YgdGhlCiAqICAgICAgIHByb2Nlc3MgdGhhdCBpcyB0byBvd24gdGhlIG1vZHVsZSB0byBiZSBjcmVhdGVkLgogKgogKiBOb3RlOiBBc3N1bWVzIHRoYXQgdGhlIHByb2Nlc3MgY3JpdGljYWwgc2VjdGlvbiBpcyBoZWxkCiAqLwpXSU5FX01PRFJFRiAqUEVfQ3JlYXRlTW9kdWxlKCBITU9EVUxFIGhNb2R1bGUsIExQQ1NUUiBmaWxlbmFtZSwgRFdPUkQgZmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRSBoRmlsZSwgQk9PTCBidWlsdGluICkKewogICAgSU1BR0VfTlRfSEVBREVSUyAqbnQ7CiAgICBJTUFHRV9EQVRBX0RJUkVDVE9SWSAqZGlyOwogICAgSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSAqcGVfZXhwb3J0ID0gTlVMTDsKICAgIFdJTkVfTU9EUkVGICp3bTsKICAgIEhNT0RVTEUxNiBoTW9kdWxlMTY7CgogICAgLyogUmV0cmlldmUgRGF0YURpcmVjdG9yeSBlbnRyaWVzICovCgogICAgbnQgPSBSdGxJbWFnZU50SGVhZGVyKGhNb2R1bGUpOwogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVDsKICAgIGlmIChkaXItPlNpemUpIHBlX2V4cG9ydCA9IGdldF9ydmEoaE1vZHVsZSwgZGlyLT5WaXJ0dWFsQWRkcmVzcyk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYQ0VQVElPTjsKICAgIGlmIChkaXItPlNpemUpIEZJWE1FKCJFeGNlcHRpb24gZGlyZWN0b3J5IGlnbm9yZWRcbiIgKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfU0VDVVJJVFk7CiAgICBpZiAoZGlyLT5TaXplKSBGSVhNRSgiU2VjdXJpdHkgZGlyZWN0b3J5IGlnbm9yZWRcbiIgKTsKCiAgICAvKiBJTUFHRV9ESVJFQ1RPUllfRU5UUllfQkFTRVJFTE9DIGhhbmRsZWQgaW4gUEVfTG9hZEltYWdlICovCiAgICAvKiBJTUFHRV9ESVJFQ1RPUllfRU5UUllfREVCVUcgaGFuZGxlZCBieSBkZWJ1Z2dlciAqLwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9HTE9CQUxQVFI7CiAgICBpZiAoZGlyLT5TaXplKSBGSVhNRSgiR2xvYmFsIFBvaW50ZXIgKE1JUFMpIGlnbm9yZWRcbiIgKTsKCiAgICAvKiBJTUFHRV9ESVJFQ1RPUllfRU5UUllfVExTIGhhbmRsZWQgaW4gUEVfVGxzSW5pdCAqLwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9MT0FEX0NPTkZJRzsKICAgIGlmIChkaXItPlNpemUpIEZJWE1FKCJMb2FkIENvbmZpZ3VyYXRpb24gZGlyZWN0b3J5IGlnbm9yZWRcbiIgKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfQk9VTkRfSU1QT1JUOwogICAgaWYgKGRpci0+U2l6ZSkgVFJBQ0UoIkJvdW5kIEltcG9ydCBkaXJlY3RvcnkgaWdub3JlZFxuIiApOwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9JQVQ7CiAgICBpZiAoZGlyLT5TaXplKSBUUkFDRSgiSW1wb3J0IEFkZHJlc3MgVGFibGUgZGlyZWN0b3J5IGlnbm9yZWRcbiIgKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfREVMQVlfSU1QT1JUOwogICAgaWYgKGRpci0+U2l6ZSkKICAgIHsKICAgICAgICBUUkFDRSgiRGVsYXllZCBpbXBvcnQsIHN0dWIgY2FsbHMgTG9hZExpYnJhcnlcbiIgKTsKICAgICAgICAvKgogICAgICAgICAqIE5vdGhpbmcgdG8gZG8gaGVyZS4KICAgICAgICAgKi8KCiNpZmRlZiBJbWdEZWxheURlc2NyCiAgICAgICAgLyoKICAgICAgICAgKiBUaGlzIGNvZGUgaXMgdXNlZnVsIHRvIG9ic2VydmUgd2hhdCB0aGUgaGVjayBpcyBnb2luZyBvbi4KICAgICAgICAgKi8KICAgICAgICB7CiAgICAgICAgICAgIEltZ0RlbGF5RGVzY3IgKnBlX2RlbGF5ID0gTlVMTDsKICAgICAgICAgICAgcGVfZGVsYXkgPSBnZXRfcnZhKGhNb2R1bGUsIGRpci0+VmlydHVhbEFkZHJlc3MpOwogICAgICAgICAgICBUUkFDRV8oZGVsYXlobHApKCJwZV9kZWxheS0+Z3JBdHRycyA9ICUwOHhcbiIsIHBlX2RlbGF5LT5nckF0dHJzKTsKICAgICAgICAgICAgVFJBQ0VfKGRlbGF5aGxwKSgicGVfZGVsYXktPnN6TmFtZSA9ICVzXG4iLCBwZV9kZWxheS0+c3pOYW1lKTsKICAgICAgICAgICAgVFJBQ0VfKGRlbGF5aGxwKSgicGVfZGVsYXktPnBobW9kID0gJTA4eFxuIiwgcGVfZGVsYXktPnBobW9kKTsKICAgICAgICAgICAgVFJBQ0VfKGRlbGF5aGxwKSgicGVfZGVsYXktPnBJQVQgPSAlMDh4XG4iLCBwZV9kZWxheS0+cElBVCk7CiAgICAgICAgICAgIFRSQUNFXyhkZWxheWhscCkoInBlX2RlbGF5LT5wSU5UID0gJTA4eFxuIiwgcGVfZGVsYXktPnBJTlQpOwogICAgICAgICAgICBUUkFDRV8oZGVsYXlobHApKCJwZV9kZWxheS0+cEJvdW5kSUFUID0gJTA4eFxuIiwgcGVfZGVsYXktPnBCb3VuZElBVCk7CiAgICAgICAgICAgIFRSQUNFXyhkZWxheWhscCkoInBlX2RlbGF5LT5wVW5sb2FkSUFUID0gJTA4eFxuIiwgcGVfZGVsYXktPnBVbmxvYWRJQVQpOwogICAgICAgICAgICBUUkFDRV8oZGVsYXlobHApKCJwZV9kZWxheS0+ZHdUaW1lU3RhbXAgPSAlMDh4XG4iLCBwZV9kZWxheS0+ZHdUaW1lU3RhbXApOwogICAgICAgIH0KI2VuZGlmIC8qIEltZ0RlbGF5RGVzY3IgKi8KICAgIH0KCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfQ09NX0RFU0NSSVBUT1I7CiAgICBpZiAoZGlyLT5TaXplKSBGSVhNRSgiVW5rbm93biBkaXJlY3RvcnkgMTQgaWdub3JlZFxuIiApOwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5KzE1OwogICAgaWYgKGRpci0+U2l6ZSkgRklYTUUoIlVua25vd24gZGlyZWN0b3J5IDE1IGlnbm9yZWRcbiIgKTsKCiAgICAvKiBDcmVhdGUgMTYtYml0IGR1bW15IG1vZHVsZSAqLwoKICAgIGlmICgoaE1vZHVsZTE2ID0gTU9EVUxFX0NyZWF0ZUR1bW15TW9kdWxlKCBmaWxlbmFtZSwgaE1vZHVsZSApKSA8IDMyKQogICAgewogICAgICAgIFNldExhc3RFcnJvciggKERXT1JEKWhNb2R1bGUxNiApOwkvKiBUaGlzIHNob3VsZCBnaXZlIHRoZSBjb3JyZWN0IGVycm9yICovCiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgLyogQWxsb2NhdGUgYW5kIGZpbGwgV0lORV9NT0RSRUYgKi8KCiAgICBpZiAoISh3bSA9IE1PRFVMRV9BbGxvY01vZFJlZiggaE1vZHVsZSwgZmlsZW5hbWUgKSkpCiAgICB7CiAgICAgICAgRnJlZUxpYnJhcnkxNiggaE1vZHVsZTE2ICk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CiAgICB3bS0+aER1bW15TW9kID0gaE1vZHVsZTE2OwoKICAgIGlmICggYnVpbHRpbiApCiAgICB7CiAgICAgICAgTkVfTU9EVUxFICpwTW9kdWxlID0gKE5FX01PRFVMRSAqKUdsb2JhbExvY2sxNiggaE1vZHVsZTE2ICk7CiAgICAgICAgcE1vZHVsZS0+ZmxhZ3MgfD0gTkVfRkZMQUdTX0JVSUxUSU47CiAgICAgICAgd20tPmZsYWdzIHw9IFdJTkVfTU9EUkVGX0lOVEVSTkFMOwogICAgfQogICAgZWxzZSBpZiAoIGZsYWdzICYgRE9OVF9SRVNPTFZFX0RMTF9SRUZFUkVOQ0VTICkKICAgICAgICB3bS0+ZmxhZ3MgfD0gV0lORV9NT0RSRUZfRE9OVF9SRVNPTFZFX1JFRlM7CgogICAgd20tPmZpbmRfZXhwb3J0ID0gUEVfRmluZEV4cG9ydGVkRnVuY3Rpb247CgogICAgLyogRHVtcCBFeHBvcnRzICovCgogICAgaWYgKHBlX2V4cG9ydCAmJiBUUkFDRV9PTih3aW4zMikpCiAgICAgICAgZHVtcF9leHBvcnRzKCBoTW9kdWxlICk7CgogICAgLyogRml4dXAgSW1wb3J0cyAqLwoKICAgIGlmICghKHdtLT5mbGFncyAmIFdJTkVfTU9EUkVGX0RPTlRfUkVTT0xWRV9SRUZTKSAmJgogICAgICAgIFBFX2ZpeHVwX2ltcG9ydHMoIHdtICkpCiAgICB7CiAgICAgICAgLyogcmVtb3ZlIGVudHJ5IGZyb20gbW9kcmVmIGNoYWluICovCgogICAgICAgIGlmICggIXdtLT5wcmV2ICkKICAgICAgICAgICAgTU9EVUxFX21vZHJlZl9saXN0ID0gd20tPm5leHQ7CiAgICAgICAgZWxzZQogICAgICAgICAgICB3bS0+cHJldi0+bmV4dCA9IHdtLT5uZXh0OwoKICAgICAgICBpZiAoIHdtLT5uZXh0ICkgd20tPm5leHQtPnByZXYgPSB3bS0+cHJldjsKICAgICAgICB3bS0+bmV4dCA9IHdtLT5wcmV2ID0gTlVMTDsKCiAgICAgICAgLyogRklYTUU6IHRoZXJlIGFyZSBzZXZlcmFsIG1vcmUgZGFuZ2xpbmcgcmVmZXJlbmNlcwogICAgICAgICAqIGxlZnQuIEluY2x1ZGluZyBkbGxzIGxvYWRlZCBieSB0aGlzIGRsbCBiZWZvcmUgdGhlCiAgICAgICAgICogZmFpbGVkIG9uZS4gVW5yb2xsaW5nIGlzIHJhdGhlciBkaWZmaWN1bHQgd2l0aCB0aGUKICAgICAgICAgKiBjdXJyZW50IHN0cnVjdHVyZSBhbmQgd2UgY2FuIGxlYXZlIHRoZW0gbHlpbmcKICAgICAgICAgKiBhcm91bmQgd2l0aCBubyBwcm9ibGVtcywgc28gd2UgZG9uJ3QgY2FyZS4KICAgICAgICAgKiBBcyB0aGVzZSBtaWdodCByZWZlcmVuY2Ugb3VyIHdtLCB3ZSBkb24ndCBmcmVlIGl0LgogICAgICAgICAqLwogICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBpZiAoIWJ1aWx0aW4gJiYgcGVfZXhwb3J0KQogICAgICAgIFNOT09QX1JlZ2lzdGVyRExMKCBoTW9kdWxlLCB3bS0+bW9kbmFtZSwgcGVfZXhwb3J0LT5CYXNlLCBwZV9leHBvcnQtPk51bWJlck9mRnVuY3Rpb25zICk7CgogICAgLyogU2VuZCBETEwgbG9hZCBldmVudCAqLwogICAgLyogd2UgZG9uJ3QgbmVlZCB0byBzZW5kIGEgZGxsIGV2ZW50IGZvciB0aGUgbWFpbiBleGUgKi8KCiAgICBpZiAobnQtPkZpbGVIZWFkZXIuQ2hhcmFjdGVyaXN0aWNzICYgSU1BR0VfRklMRV9ETEwpCiAgICB7CiAgICAgICAgaWYgKGhGaWxlKQogICAgICAgIHsKICAgICAgICAgICAgVUlOVCBkcml2ZV90eXBlID0gR2V0RHJpdmVUeXBlQSggd20tPnNob3J0X2ZpbGVuYW1lICk7CiAgICAgICAgICAgIC8qIGRvbid0IGtlZXAgdGhlIGZpbGUgaGFuZGxlIG9wZW4gb24gcmVtb3ZhYmxlIG1lZGlhICovCiAgICAgICAgICAgIGlmIChkcml2ZV90eXBlID09IERSSVZFX1JFTU9WQUJMRSB8fCBkcml2ZV90eXBlID09IERSSVZFX0NEUk9NKSBoRmlsZSA9IDA7CiAgICAgICAgfQogICAgICAgIFNFUlZFUl9TVEFSVF9SRVEoIGxvYWRfZGxsICkKICAgICAgICB7CiAgICAgICAgICAgIHJlcS0+aGFuZGxlICAgICA9IGhGaWxlOwogICAgICAgICAgICByZXEtPmJhc2UgICAgICAgPSAodm9pZCAqKWhNb2R1bGU7CiAgICAgICAgICAgIHJlcS0+c2l6ZSAgICAgICA9IG50LT5PcHRpb25hbEhlYWRlci5TaXplT2ZJbWFnZTsKICAgICAgICAgICAgcmVxLT5kYmdfb2Zmc2V0ID0gbnQtPkZpbGVIZWFkZXIuUG9pbnRlclRvU3ltYm9sVGFibGU7CiAgICAgICAgICAgIHJlcS0+ZGJnX3NpemUgICA9IG50LT5GaWxlSGVhZGVyLk51bWJlck9mU3ltYm9sczsKICAgICAgICAgICAgcmVxLT5uYW1lICAgICAgID0gJndtLT5maWxlbmFtZTsKICAgICAgICAgICAgd2luZV9zZXJ2ZXJfYWRkX2RhdGEoIHJlcSwgd20tPmZpbGVuYW1lLCBzdHJsZW4od20tPmZpbGVuYW1lKSApOwogICAgICAgICAgICB3aW5lX3NlcnZlcl9jYWxsKCByZXEgKTsKICAgICAgICB9CiAgICAgICAgU0VSVkVSX0VORF9SRVE7CiAgICB9CgogICAgcmV0dXJuIHdtOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFRoZSBQRSBMaWJyYXJ5IExvYWRlciBmcm9udGVuZC4KICogRklYTUU6IGhhbmRsZSB0aGUgZmxhZ3MuCiAqLwpXSU5FX01PRFJFRiAqUEVfTG9hZExpYnJhcnlFeEEgKExQQ1NUUiBuYW1lLCBEV09SRCBmbGFncykKewoJSE1PRFVMRQkJaE1vZHVsZTMyOwoJV0lORV9NT0RSRUYJKndtOwoJSEFORExFCQloRmlsZTsKCgloRmlsZSA9IENyZWF0ZUZpbGVBKCBuYW1lLCBHRU5FUklDX1JFQUQsIEZJTEVfU0hBUkVfUkVBRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCBPUEVOX0VYSVNUSU5HLCAwLCAwICk7CglpZiAoIGhGaWxlID09IElOVkFMSURfSEFORExFX1ZBTFVFICkgcmV0dXJuIE5VTEw7CgoJLyogTG9hZCBQRSBtb2R1bGUgKi8KCWhNb2R1bGUzMiA9IFBFX0xvYWRJbWFnZSggaEZpbGUsIG5hbWUsIGZsYWdzICk7CglpZiAoIWhNb2R1bGUzMikKCXsKICAgICAgICAgICAgICAgIENsb3NlSGFuZGxlKCBoRmlsZSApOwoJCXJldHVybiBOVUxMOwoJfQoKCS8qIENyZWF0ZSAzMi1iaXQgTU9EUkVGICovCglpZiAoICEod20gPSBQRV9DcmVhdGVNb2R1bGUoIGhNb2R1bGUzMiwgbmFtZSwgZmxhZ3MsIGhGaWxlLCBGQUxTRSApKSApCgl7CgkJRVJSKCAiY2FuJ3QgbG9hZCAlc1xuIiwgbmFtZSApOwogICAgICAgICAgICAgICAgQ2xvc2VIYW5kbGUoIGhGaWxlICk7CgkJU2V0TGFzdEVycm9yKCBFUlJPUl9PVVRPRk1FTU9SWSApOwoJCXJldHVybiBOVUxMOwoJfQoKICAgICAgICBDbG9zZUhhbmRsZSggaEZpbGUgKTsKCXJldHVybiB3bTsKfQoKCi8qIENhbGxlZCBpZiB0aGUgbGlicmFyeSBpcyBsb2FkZWQgb3IgZnJlZWQuCiAqIE5PVEU6IGlmIGEgdGhyZWFkIGF0dGFjaGVzIGEgRExMLCB0aGUgY3VycmVudCB0aHJlYWQgd2lsbCBvbmx5IGRvCiAqIERMTF9QUk9DRVNTX0FUVEFDSC4gT25seSBuZXdseSBjcmVhdGVkIHRocmVhZHMgZG8gRExMX1RIUkVBRF9BVFRBQ0gKICogKFNESykKICovCnR5cGVkZWYgRFdPUkQgKENBTExCQUNLICpETExFTlRSWVBST0MpKEhNT0RVTEUsRFdPUkQsTFBWT0lEKTsKCkJPT0wgUEVfSW5pdERMTCggSE1PRFVMRSBtb2R1bGUsIERXT1JEIHR5cGUsIExQVk9JRCBscFJlc2VydmVkICkKewogICAgQk9PTCByZXR2ID0gVFJVRTsKICAgIElNQUdFX05UX0hFQURFUlMgKm50ID0gUnRsSW1hZ2VOdEhlYWRlcihtb2R1bGUpOwoKICAgIC8qIElzIHRoaXMgYSBsaWJyYXJ5PyBBbmQgaGFzIGl0IGdvdCBhbiBlbnRyeXBvaW50PyAqLwogICAgaWYgKG50ICYmIChudC0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9GSUxFX0RMTCkgJiYKICAgICAgICAobnQtPk9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQpKQogICAgewogICAgICAgIERMTEVOVFJZUFJPQyBlbnRyeSA9ICh2b2lkKikoKGNoYXIqKW1vZHVsZSArIG50LT5PcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50KTsKICAgICAgICBpZiAoVFJBQ0VfT04ocmVsYXkpKQogICAgICAgICAgICBEUFJJTlRGKCIlMDhseDpDYWxsIFBFIERMTCAocHJvYz0lcCxtb2R1bGU9JTA4eCx0eXBlPSVsZCxyZXM9JXApXG4iLAogICAgICAgICAgICAgICAgICAgIEdldEN1cnJlbnRUaHJlYWRJZCgpLCBlbnRyeSwgbW9kdWxlLCB0eXBlLCBscFJlc2VydmVkICk7CiAgICAgICAgcmV0diA9IGVudHJ5KCBtb2R1bGUsIHR5cGUsIGxwUmVzZXJ2ZWQgKTsKICAgICAgICBpZiAoVFJBQ0VfT04ocmVsYXkpKQogICAgICAgICAgICBEUFJJTlRGKCIlMDhseDpSZXQgIFBFIERMTCAocHJvYz0lcCxtb2R1bGU9JTA4eCx0eXBlPSVsZCxyZXM9JXApIHJldHZhbD0leFxuIiwKICAgICAgICAgICAgICAgICAgICBHZXRDdXJyZW50VGhyZWFkSWQoKSwgZW50cnksIG1vZHVsZSwgdHlwZSwgbHBSZXNlcnZlZCwgcmV0diApOwogICAgfQoKICAgIHJldHVybiByZXR2Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCVBFX0luaXRUbHMJCQkoaW50ZXJuYWwpCiAqCiAqIElmIGluY2x1ZGVkLCBpbml0aWFsaXNlcyB0aGUgdGhyZWFkIGxvY2FsIHN0b3JhZ2VzIG9mIG1vZHVsZXMuCiAqIFBvaW50ZXJzIGluIHRob3NlIHN0cnVjdHMgYXJlIG5vdCBSVkFzIGJ1dCByZWFsIHBvaW50ZXJzIHdoaWNoIGhhdmUgYmVlbgogKiByZWxvY2F0ZWQgYnkgZG9fcmVsb2NhdGlvbnMoKSBhbHJlYWR5LgogKi8Kc3RhdGljIExQVk9JRApfZml4dXBfYWRkcmVzcyhQSU1BR0VfT1BUSU9OQUxfSEVBREVSIG9wdCxpbnQgZGVsdGEsTFBWT0lEIGFkZHIpIHsKCWlmICgJKChEV09SRClhZGRyPm9wdC0+SW1hZ2VCYXNlKSAmJgoJCSgoRFdPUkQpYWRkcjxvcHQtPkltYWdlQmFzZStvcHQtPlNpemVPZkltYWdlKQoJKQoJCS8qIHRoZSBhZGRyZXNzIGhhcyBub3QgYmVlbiByZWxvY2F0ZWQhICovCgkJcmV0dXJuIChMUFZPSUQpKCgoRFdPUkQpYWRkcikrZGVsdGEpOwoJZWxzZQoJCS8qIHRoZSBhZGRyZXNzIGhhcyBiZWVuIHJlbG9jYXRlZCBhbHJlYWR5ICovCgkJcmV0dXJuIGFkZHI7Cn0Kdm9pZCBQRV9Jbml0VGxzKCB2b2lkICkKewoJV0lORV9NT0RSRUYJCSp3bTsKCUlNQUdFX05UX0hFQURFUlMJKnBlaDsKCURXT1JECQkJc2l6ZSxkYXRhc2l6ZSxkaXJzaXplOwoJTFBWT0lECQkJbWVtOwoJUElNQUdFX1RMU19ESVJFQ1RPUlkJcGRpcjsKICAgICAgICBpbnQgZGVsdGE7CgoJZm9yICh3bSA9IE1PRFVMRV9tb2RyZWZfbGlzdDt3bTt3bT13bS0+bmV4dCkgewogICAgICAgICAgICAgICAgcGVoID0gUnRsSW1hZ2VOdEhlYWRlcih3bS0+bW9kdWxlKTsKICAgICAgICAgICAgICAgIHBkaXIgPSBSdGxJbWFnZURpcmVjdG9yeUVudHJ5VG9EYXRhKCB3bS0+bW9kdWxlLCBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElNQUdFX0RJUkVDVE9SWV9FTlRSWV9UTFMsICZkaXJzaXplICk7CiAgICAgICAgICAgICAgICBpZiAoIXBkaXIpIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgZGVsdGEgPSAoY2hhciAqKXdtLT5tb2R1bGUgLSAoY2hhciAqKXBlaC0+T3B0aW9uYWxIZWFkZXIuSW1hZ2VCYXNlOwoKCQlpZiAoIHdtLT50bHNpbmRleCA9PSAtMSApIHsKCQkJTFBEV09SRCB4YWRkcjsKCQkJd20tPnRsc2luZGV4ID0gVGxzQWxsb2MoKTsKCQkJeGFkZHIgPSBfZml4dXBfYWRkcmVzcygmKHBlaC0+T3B0aW9uYWxIZWFkZXIpLGRlbHRhLAoJCQkJCXBkaXItPkFkZHJlc3NPZkluZGV4CgkJCSk7CgkJCSp4YWRkcj13bS0+dGxzaW5kZXg7CgkJfQoJCWRhdGFzaXplPSBwZGlyLT5FbmRBZGRyZXNzT2ZSYXdEYXRhLXBkaXItPlN0YXJ0QWRkcmVzc09mUmF3RGF0YTsKCQlzaXplCT0gZGF0YXNpemUgKyBwZGlyLT5TaXplT2ZaZXJvRmlsbDsKCQltZW09VmlydHVhbEFsbG9jKDAsc2l6ZSxNRU1fUkVTRVJWRXxNRU1fQ09NTUlULFBBR0VfUkVBRFdSSVRFKTsKCQltZW1jcHkobWVtLF9maXh1cF9hZGRyZXNzKCYocGVoLT5PcHRpb25hbEhlYWRlciksZGVsdGEsKExQVk9JRClwZGlyLT5TdGFydEFkZHJlc3NPZlJhd0RhdGEpLGRhdGFzaXplKTsKCQlpZiAocGRpci0+QWRkcmVzc09mQ2FsbEJhY2tzKSB7CgkJICAgICBQSU1BR0VfVExTX0NBTExCQUNLICpjYnM7CgoJCSAgICAgY2JzID0gX2ZpeHVwX2FkZHJlc3MoJihwZWgtPk9wdGlvbmFsSGVhZGVyKSxkZWx0YSxwZGlyLT5BZGRyZXNzT2ZDYWxsQmFja3MpOwoJCSAgICAgaWYgKCpjYnMpCgkJICAgICAgIEZJWE1FKCJUTFMgQ2FsbGJhY2tzIGFyZW4ndCBnb2luZyB0byBiZSBjYWxsZWRcbiIpOwoJCX0KCgkJVGxzU2V0VmFsdWUoIHdtLT50bHNpbmRleCwgbWVtICk7Cgl9Cn0K