LyogCiAqICBDb3B5cmlnaHQJMTk5NAlFcmljIFlvdW5kYWxlICYgRXJpayBCb3MKICogIENvcHlyaWdodAkxOTk1CU1hcnRpbiB2b24gTPZ3aXMKICogIENvcHlyaWdodCAgIDE5OTYtOTggTWFyY3VzIE1laXNzbmVyCiAqCiAqCWJhc2VkIG9uIEVyaWMgWW91bmRhbGUncyBwZS10ZXN0IGFuZDoKICoKICoJZnRwLm1pY3Jvc29mdC5jb206L3B1Yi9kZXZlbG9wZXIvTVNETi9DRDgvUEVGSUxFLlpJUAogKiBtYWtlIHRoYXQ6CiAqCWZ0cC5taWNyb3NvZnQuY29tOi9kZXZlbG9wci9NU0ROL09jdENEL1BFRklMRS5aSVAKICovCi8qIE5vdGVzOgogKiBCZWZvcmUgeW91IHN0YXJ0IGNoYW5naW5nIHNvbWV0aGluZyBpbiB0aGlzIGZpbGUgYmUgYXdhcmUgb2YgdGhlIGZvbGxvd2luZzoKICoKICogLSBUaGVyZSBhcmUgc2V2ZXJhbCBmdW5jdGlvbnMgY2FsbGVkIHJlY3Vyc2l2ZWx5LiBJbiBhIHZlcnkgc3VidGxlIGFuZCAKICogICBvYnNjdXJlIHdheS4gRExMcyBjYW4gcmVmZXJlbmNlIGVhY2ggb3RoZXIgcmVjdXJzaXZlbHkgZXRjLgogKiAtIElmIHlvdSB3YW50IHRvIGVuaGFuY2UsIHNwZWVkIHVwIG9yIGNsZWFuIHVwIHNvbWV0aGluZyBpbiBoZXJlLCB0aGluawogKiAgIHR3aWNlIFdIWSBpdCBpcyBpbXBsZW1lbnRlZCBpbiB0aGF0IHN0cmFuZ2Ugd2F5LiBUaGVyZSBpcyB1c3VhbGx5IGEgcmVhc29uLgogKiAgIFRob3VnaCBzb21ldGltZXMgaXQgbWlnaHQganVzdCBiZSBsYXp5bmVzcyA7KQogKiAtIEluIFBFX01hcEltYWdlLCByaWdodCBiZWZvcmUgZml4dXBfaW1wb3J0cygpIGFsbCBleHRlcm5hbCBhbmQgaW50ZXJuYWwgCiAqICAgc3RhdGUgTVVTVCBiZSBjb3JyZWN0IHNpbmNlIHRoaXMgZnVuY3Rpb24gY2FuIGJlIGNhbGxlZCB3aXRoIHRoZSBTQU1FIGltYWdlCiAqICAgQUdBSU4uIChUaGF0cyByZWN1cnNpb24gZm9yIHlvdS4pIFRoYXQgbWVhbnMgTU9EUkVGLm1vZHVsZSBhbmQKICogICBORV9NT0RVTEUubW9kdWxlMzIuCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgoKI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaWZkZWYgSEFWRV9TWVNfTU1BTl9ICiNpbmNsdWRlIDxzeXMvbW1hbi5oPgojZW5kaWYKI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSAid2luZS93aW5iYXNlMTYuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJzbm9vcC5oIgojaW5jbHVkZSAic2VydmVyLmgiCiNpbmNsdWRlICJkZWJ1Z3Rvb2xzLmgiCgpERUZBVUxUX0RFQlVHX0NIQU5ORUwod2luMzIpOwpERUNMQVJFX0RFQlVHX0NIQU5ORUwoZGVsYXlobHApOwpERUNMQVJFX0RFQlVHX0NIQU5ORUwoZml4dXApOwpERUNMQVJFX0RFQlVHX0NIQU5ORUwobW9kdWxlKTsKREVDTEFSRV9ERUJVR19DSEFOTkVMKHJlbGF5KTsKREVDTEFSRV9ERUJVR19DSEFOTkVMKHNlZ21lbnQpOwoKCnN0YXRpYyBJTUFHRV9FWFBPUlRfRElSRUNUT1JZICpnZXRfZXhwb3J0cyggSE1PRFVMRSBobW9kICkKewogICAgSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSAqcmV0ID0gTlVMTDsKICAgIElNQUdFX0RBVEFfRElSRUNUT1JZICpkaXIgPSBQRV9IRUFERVIoaG1vZCktPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIElNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlQ7CiAgICBpZiAoZGlyLT5TaXplICYmIGRpci0+VmlydHVhbEFkZHJlc3MpCiAgICAgICAgcmV0ID0gKElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkgKikoKGNoYXIgKilobW9kICsgZGlyLT5WaXJ0dWFsQWRkcmVzcyk7CiAgICByZXR1cm4gcmV0Owp9CgpzdGF0aWMgSU1BR0VfSU1QT1JUX0RFU0NSSVBUT1IgKmdldF9pbXBvcnRzKCBITU9EVUxFIGhtb2QgKQp7CiAgICBJTUFHRV9JTVBPUlRfREVTQ1JJUFRPUiAqcmV0ID0gTlVMTDsKICAgIElNQUdFX0RBVEFfRElSRUNUT1JZICpkaXIgPSBQRV9IRUFERVIoaG1vZCktPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIElNQUdFX0RJUkVDVE9SWV9FTlRSWV9JTVBPUlQ7CiAgICBpZiAoZGlyLT5TaXplICYmIGRpci0+VmlydHVhbEFkZHJlc3MpCiAgICAgICAgcmV0ID0gKElNQUdFX0lNUE9SVF9ERVNDUklQVE9SICopKChjaGFyICopaG1vZCArIGRpci0+VmlydHVhbEFkZHJlc3MpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qIGNvbnZlcnQgUEUgaW1hZ2UgVmlydHVhbEFkZHJlc3MgdG8gUmVhbCBBZGRyZXNzICovCiNkZWZpbmUgUlZBKHgpICgodm9pZCAqKSgoY2hhciAqKWxvYWRfYWRkcisodW5zaWduZWQgaW50KSh4KSkpCgojZGVmaW5lIEFkanVzdFB0cihwdHIsZGVsdGEpICgoY2hhciAqKShwdHIpICsgKGRlbHRhKSkKCnZvaWQgZHVtcF9leHBvcnRzKCBITU9EVUxFIGhNb2R1bGUgKQp7IAogIGNoYXIJCSpNb2R1bGU7CiAgaW50CQlpLCBqOwogIFdPUkQJCSpvcmRpbmFsOwogIERXT1JECQkqZnVuY3Rpb24sKmZ1bmN0aW9uczsKICBCWVRFCQkqKm5hbWU7CiAgdW5zaWduZWQgaW50IGxvYWRfYWRkciA9IGhNb2R1bGU7CgogIERXT1JEIHJ2YV9zdGFydCA9IFBFX0hFQURFUihoTW9kdWxlKS0+T3B0aW9uYWxIZWFkZXIKICAgICAgICAgICAgICAgICAgIC5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlRdLlZpcnR1YWxBZGRyZXNzOwogIERXT1JEIHJ2YV9lbmQgPSBydmFfc3RhcnQgKyBQRV9IRUFERVIoaE1vZHVsZSktPk9wdGlvbmFsSGVhZGVyCiAgICAgICAgICAgICAgICAgICAuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhQT1JUXS5TaXplOwogIElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkgKnBlX2V4cG9ydHMgPSAoSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSopUlZBKHJ2YV9zdGFydCk7CgogIE1vZHVsZSA9IChjaGFyKilSVkEocGVfZXhwb3J0cy0+TmFtZSk7CiAgVFJBQ0UoIioqKioqKipFWFBPUlQgREFUQSoqKioqKipcbiIpOwogIFRSQUNFKCJNb2R1bGUgbmFtZSBpcyAlcywgJWxkIGZ1bmN0aW9ucywgJWxkIG5hbWVzXG4iLCAKICAgICAgICBNb2R1bGUsIHBlX2V4cG9ydHMtPk51bWJlck9mRnVuY3Rpb25zLCBwZV9leHBvcnRzLT5OdW1iZXJPZk5hbWVzKTsKCiAgb3JkaW5hbCA9IFJWQShwZV9leHBvcnRzLT5BZGRyZXNzT2ZOYW1lT3JkaW5hbHMpOwogIGZ1bmN0aW9ucyA9IGZ1bmN0aW9uID0gUlZBKHBlX2V4cG9ydHMtPkFkZHJlc3NPZkZ1bmN0aW9ucyk7CiAgbmFtZSA9IFJWQShwZV9leHBvcnRzLT5BZGRyZXNzT2ZOYW1lcyk7CgogIFRSQUNFKCIgT3JkICAgIFJWQSAgICAgQWRkciAgIE5hbWVcbiIgKTsKICBmb3IgKGk9MDtpPHBlX2V4cG9ydHMtPk51bWJlck9mRnVuY3Rpb25zO2krKywgZnVuY3Rpb24rKykKICB7CiAgICAgIGlmICghKmZ1bmN0aW9uKSBjb250aW51ZTsgIC8qIE5vIHN1Y2ggZnVuY3Rpb24gKi8KICAgICAgaWYgKFRSQUNFX09OKHdpbjMyKSkKICAgICAgewoJRFBSSU5URiggIiU0bGQgJTA4bHggJXAiLCBpICsgcGVfZXhwb3J0cy0+QmFzZSwgKmZ1bmN0aW9uLCBSVkEoKmZ1bmN0aW9uKSApOwoJLyogQ2hlY2sgaWYgd2UgaGF2ZSBhIG5hbWUgZm9yIGl0ICovCglmb3IgKGogPSAwOyBqIDwgcGVfZXhwb3J0cy0+TnVtYmVyT2ZOYW1lczsgaisrKQogICAgICAgICAgaWYgKG9yZGluYWxbal0gPT0gaSkKICAgICAgICAgIHsKICAgICAgICAgICAgICBEUFJJTlRGKCAiICAlcyIsIChjaGFyKilSVkEobmFtZVtqXSkgKTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KCWlmICgoKmZ1bmN0aW9uID49IHJ2YV9zdGFydCkgJiYgKCpmdW5jdGlvbiA8PSBydmFfZW5kKSkKCSAgRFBSSU5URigiIChmb3J3YXJkZWQgLT4gJXMpIiwgKGNoYXIgKilSVkEoKmZ1bmN0aW9uKSk7CglEUFJJTlRGKCJcbiIpOwogICAgICB9CiAgfQp9CgovKiBMb29rIHVwIHRoZSBzcGVjaWZpZWQgZnVuY3Rpb24gb3Igb3JkaW5hbCBpbiB0aGUgZXhwb3J0bGlzdDoKICogSWYgaXQgaXMgYSBzdHJpbmc6CiAqIAktIGxvb2sgdXAgdGhlIG5hbWUgaW4gdGhlIE5hbWUgbGlzdC4gCiAqCS0gbG9vayB1cCB0aGUgb3JkaW5hbCB3aXRoIHRoYXQgaW5kZXguCiAqCS0gdXNlIHRoZSBvcmRpbmFsIGFzIG9mZnNldCBpbnRvIHRoZSBmdW5jdGlvbmxpc3QKICogSWYgaXQgaXMgYSBvcmRpbmFsOgogKgktIHVzZSBvcmRpbmFsLXBlX2V4cG9ydC0+QmFzZSBhcyBvZmZzZXQgaW50byB0aGUgZnVuY3Rpb25saXN0CiAqLwpzdGF0aWMgRkFSUFJPQyBQRV9GaW5kRXhwb3J0ZWRGdW5jdGlvbiggCglXSU5FX01PRFJFRiAqd20sCS8qIFtpbl0gV0lORSBtb2RyZWZlcmVuY2UgKi8KCUxQQ1NUUiBmdW5jTmFtZSwJLyogW2luXSBmdW5jdGlvbiBuYW1lICovCiAgICAgICAgQk9PTCBzbm9vcCApCnsKCVdPUkQJCQkJKiBvcmRpbmFsczsKCURXT1JECQkJCSogZnVuY3Rpb247CglCWVRFCQkJCSoqIG5hbWUsICplbmFtZSA9IE5VTEw7CglpbnQJCQkJaSwgb3JkaW5hbDsKCXVuc2lnbmVkIGludAkJCWxvYWRfYWRkciA9IHdtLT5tb2R1bGU7CglEV09SRAkJCQlydmFfc3RhcnQsIHJ2YV9lbmQsIGFkZHI7CgljaGFyCQkJCSogZm9yd2FyZDsKCUlNQUdFX0VYUE9SVF9ESVJFQ1RPUlkgKmV4cG9ydHMgPSBnZXRfZXhwb3J0cyh3bS0+bW9kdWxlKTsKCglpZiAoSElXT1JEKGZ1bmNOYW1lKSkKCQlUUkFDRSgiKCVzKVxuIixmdW5jTmFtZSk7CgllbHNlCgkJVFJBQ0UoIiglZClcbiIsKGludClmdW5jTmFtZSk7CglpZiAoIWV4cG9ydHMpIHsKCQkvKiBOb3QgYSBmYXRhbCBwcm9ibGVtLCBzb21lIGFwcHMgZG8KCQkgKiBHZXRQcm9jQWRkcmVzcygwLCJSZWdpc3RlclBlbkFwcCIpIHdoaWNoIHRyaWdnZXJzIHRoaXMKCQkgKiBjYXNlLgoJCSAqLwoJCVdBUk4oIk1vZHVsZSAlMDh4KCVzKS9NT0RSRUYgJXAgZG9lc24ndCBoYXZlIGEgZXhwb3J0cyB0YWJsZS5cbiIsd20tPm1vZHVsZSx3bS0+bW9kbmFtZSx3bSk7CgkJcmV0dXJuIE5VTEw7Cgl9CglvcmRpbmFscz0gUlZBKGV4cG9ydHMtPkFkZHJlc3NPZk5hbWVPcmRpbmFscyk7CglmdW5jdGlvbj0gUlZBKGV4cG9ydHMtPkFkZHJlc3NPZkZ1bmN0aW9ucyk7CgluYW1lCT0gUlZBKGV4cG9ydHMtPkFkZHJlc3NPZk5hbWVzKTsKCWZvcndhcmQgPSBOVUxMOwoJcnZhX3N0YXJ0ID0gUEVfSEVBREVSKHdtLT5tb2R1bGUpLT5PcHRpb25hbEhlYWRlcgoJCS5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlRdLlZpcnR1YWxBZGRyZXNzOwoJcnZhX2VuZCA9IHJ2YV9zdGFydCArIFBFX0hFQURFUih3bS0+bW9kdWxlKS0+T3B0aW9uYWxIZWFkZXIKCQkuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhQT1JUXS5TaXplOwoKCWlmIChISVdPUkQoZnVuY05hbWUpKQogICAgICAgIHsKICAgICAgICAgICAgLyogZmlyc3QgdHJ5IGEgYmluYXJ5IHNlYXJjaCAqLwogICAgICAgICAgICBpbnQgbWluID0gMCwgbWF4ID0gZXhwb3J0cy0+TnVtYmVyT2ZOYW1lcyAtIDE7CiAgICAgICAgICAgIHdoaWxlIChtaW4gPD0gbWF4KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpbnQgcmVzLCBwb3MgPSAobWluICsgbWF4KSAvIDI7CiAgICAgICAgICAgICAgICBlbmFtZSA9IFJWQShuYW1lW3Bvc10pOwogICAgICAgICAgICAgICAgaWYgKCEocmVzID0gc3RyY21wKCBlbmFtZSwgZnVuY05hbWUgKSkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgb3JkaW5hbCA9IG9yZGluYWxzW3Bvc107CiAgICAgICAgICAgICAgICAgICAgZ290byBmb3VuZDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChyZXMgPiAwKSBtYXggPSBwb3MgLSAxOwogICAgICAgICAgICAgICAgZWxzZSBtaW4gPSBwb3MgKyAxOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qIG5vdyB0cnkgYSBsaW5lYXIgc2VhcmNoIGluIGNhc2UgdGhlIG5hbWVzIGFyZW4ndCBzb3J0ZWQgcHJvcGVybHkgKi8KICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGV4cG9ydHMtPk51bWJlck9mTmFtZXM7IGkrKykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZW5hbWUgPSBSVkEobmFtZVtpXSk7CiAgICAgICAgICAgICAgICBpZiAoIXN0cmNtcCggZW5hbWUsIGZ1bmNOYW1lICkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgRVJSKCAiJXMuJXMgcmVxdWlyZWQgYSBsaW5lYXIgc2VhcmNoXG4iLCB3bS0+bW9kbmFtZSwgZnVuY05hbWUgKTsKICAgICAgICAgICAgICAgICAgICBvcmRpbmFsID0gb3JkaW5hbHNbaV07CiAgICAgICAgICAgICAgICAgICAgZ290byBmb3VuZDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gTlVMTDsKCX0KICAgICAgICBlbHNlICAvKiBmaW5kIGJ5IG9yZGluYWwgKi8KICAgICAgICB7CiAgICAgICAgICAgIG9yZGluYWwgPSBMT1dPUkQoZnVuY05hbWUpIC0gZXhwb3J0cy0+QmFzZTsKICAgICAgICAgICAgaWYgKHNub29wICYmIG5hbWUpICAvKiBuZWVkIHRvIGZpbmQgYSBuYW1lIGZvciBpdCAqLwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgZXhwb3J0cy0+TnVtYmVyT2ZOYW1lczsgaSsrKQogICAgICAgICAgICAgICAgICAgIGlmIChvcmRpbmFsc1tpXSA9PSBvcmRpbmFsKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgZW5hbWUgPSBSVkEobmFtZVtpXSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoJfQoKIGZvdW5kOgogICAgICAgIGlmIChvcmRpbmFsID49IGV4cG9ydHMtPk51bWJlck9mRnVuY3Rpb25zKQogICAgICAgIHsKICAgICAgICAgICAgVFJBQ0UoIglvcmRpbmFsICVsZCBvdXQgb2YgcmFuZ2UhXG4iLCBvcmRpbmFsICsgZXhwb3J0cy0+QmFzZSApOwogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICB9CiAgICAgICAgYWRkciA9IGZ1bmN0aW9uW29yZGluYWxdOwogICAgICAgIGlmICghYWRkcikgcmV0dXJuIE5VTEw7CiAgICAgICAgaWYgKChhZGRyIDwgcnZhX3N0YXJ0KSB8fCAoYWRkciA+PSBydmFfZW5kKSkKICAgICAgICB7CiAgICAgICAgICAgIEZBUlBST0MgcHJvYyA9IFJWQShhZGRyKTsKICAgICAgICAgICAgaWYgKHNub29wKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoIWVuYW1lKSBlbmFtZSA9ICJAIjsKICAgICAgICAgICAgICAgIHByb2MgPSBTTk9PUF9HZXRQcm9jQWRkcmVzcyh3bS0+bW9kdWxlLGVuYW1lLG9yZGluYWwscHJvYyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHByb2M7CiAgICAgICAgfQogICAgICAgIGVsc2UgIC8qIGZvcndhcmQgZW50cnkgcG9pbnQgKi8KICAgICAgICB7CiAgICAgICAgICAgICAgICBXSU5FX01PRFJFRiAqd21fZnc7CiAgICAgICAgICAgICAgICBGQVJQUk9DIHByb2M7CiAgICAgICAgICAgICAgICBjaGFyICpmb3J3YXJkID0gUlZBKGFkZHIpOwoJCWNoYXIgbW9kdWxlWzI1Nl07CgkJY2hhciAqZW5kID0gc3RyY2hyKGZvcndhcmQsICcuJyk7CgoJCWlmICghZW5kKSByZXR1cm4gTlVMTDsKICAgICAgICAgICAgICAgIGlmIChlbmQgLSBmb3J3YXJkID49IHNpemVvZihtb2R1bGUpKSByZXR1cm4gTlVMTDsKICAgICAgICAgICAgICAgIG1lbWNweSggbW9kdWxlLCBmb3J3YXJkLCBlbmQgLSBmb3J3YXJkICk7CgkJbW9kdWxlW2VuZC1mb3J3YXJkXSA9IDA7CiAgICAgICAgICAgICAgICBpZiAoISh3bV9mdyA9IE1PRFVMRV9GaW5kTW9kdWxlKCBtb2R1bGUgKSkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgRVJSKCJtb2R1bGUgbm90IGZvdW5kIGZvciBmb3J3YXJkICclcycgdXNlZCBieSAnJXMnXG4iLCBmb3J3YXJkLCB3bS0+bW9kbmFtZSApOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgICAgICAgICAgfQoJCWlmICghKHByb2MgPSBNT0RVTEVfR2V0UHJvY0FkZHJlc3MoIHdtX2Z3LT5tb2R1bGUsIGVuZCArIDEsIHNub29wICkpKQogICAgICAgICAgICAgICAgICAgIEVSUigiZnVuY3Rpb24gbm90IGZvdW5kIGZvciBmb3J3YXJkICclcycgdXNlZCBieSAnJXMnLiBJZiB5b3UgYXJlIHVzaW5nIGJ1aWx0aW4gJyVzJywgdHJ5IHVzaW5nIHRoZSBuYXRpdmUgb25lIGluc3RlYWQuXG4iLCBmb3J3YXJkLCB3bS0+bW9kbmFtZSwgd20tPm1vZG5hbWUgKTsKCQlyZXR1cm4gcHJvYzsKCX0KfQoKRFdPUkQgZml4dXBfaW1wb3J0cyggV0lORV9NT0RSRUYgKndtICkKewogICAgSU1BR0VfSU1QT1JUX0RFU0NSSVBUT1IJKnBlX2ltcDsKICAgIHVuc2lnbmVkIGludCBsb2FkX2FkZHIJPSB3bS0+bW9kdWxlOwogICAgaW50CQkJCWksY2hhcmFjdGVyaXN0aWNzX2RldGVjdGlvbj0xOwogICAgSU1BR0VfSU1QT1JUX0RFU0NSSVBUT1IgKmltcG9ydHMgPSBnZXRfaW1wb3J0cyh3bS0+bW9kdWxlKTsKCiAgICAvKiBmaXJzdCwgY291bnQgdGhlIG51bWJlciBvZiBpbXBvcnRlZCBub24taW50ZXJuYWwgbW9kdWxlcyAqLwogICAgcGVfaW1wID0gaW1wb3J0czsKICAgIGlmICghcGVfaW1wKSByZXR1cm4gMDsKCiAgICAvKiBPSywgbm93IGR1bXAgdGhlIGltcG9ydCBsaXN0ICovCiAgICBUUkFDRSgiRHVtcGluZyBpbXBvcnRzIGxpc3RcbiIpOwoKICAgIC8qIFdlIGFzc3VtZSB0aGF0IHdlIGhhdmUgYXQgbGVhc3Qgb25lIGltcG9ydCB3aXRoICEwIGNoYXJhY3RlcmlzdGljcyBhbmQKICAgICAqIGRldGVjdCBicm9rZW4gaW1wb3J0cyB3aXRoIGFsbCBjaGFyYWN0ZXJpc3RpY3MgMCAobm90YWJseSBCb3JsYW5kKSBhbmQKICAgICAqIHN3aXRjaCB0aGUgZGV0ZWN0aW9uIG9mZiBmb3IgdGhlbS4KICAgICAqLwogICAgZm9yIChpID0gMDsgcGVfaW1wLT5OYW1lIDsgcGVfaW1wKyspIHsKCWlmICghaSAmJiAhcGVfaW1wLT51LkNoYXJhY3RlcmlzdGljcykKCQljaGFyYWN0ZXJpc3RpY3NfZGV0ZWN0aW9uID0gMDsKCWlmIChjaGFyYWN0ZXJpc3RpY3NfZGV0ZWN0aW9uICYmICFwZV9pbXAtPnUuQ2hhcmFjdGVyaXN0aWNzKQoJCWJyZWFrOwoJaSsrOwogICAgfQogICAgaWYgKCFpKSByZXR1cm4gMDsgIC8qIG5vIGltcG9ydHMgKi8KCiAgICAvKiBBbGxvY2F0ZSBtb2R1bGUgZGVwZW5kZW5jeSBsaXN0ICovCiAgICB3bS0+bkRlcHMgPSBpOwogICAgd20tPmRlcHMgID0gSGVhcEFsbG9jKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBpKnNpemVvZihXSU5FX01PRFJFRiAqKSApOwoKICAgIC8qIGxvYWQgdGhlIGltcG9ydGVkIG1vZHVsZXMuIFRoZXkgYXJlIGF1dG9tYXRpY2FsbHkgCiAgICAgKiBhZGRlZCB0byB0aGUgbW9kcmVmIGxpc3Qgb2YgdGhlIHByb2Nlc3MuCiAgICAgKi8KIAogICAgZm9yIChpID0gMCwgcGVfaW1wID0gaW1wb3J0czsgcGVfaW1wLT5OYW1lIDsgcGVfaW1wKyspIHsKICAgIAlXSU5FX01PRFJFRgkJKndtSW1wOwoJSU1BR0VfSU1QT1JUX0JZX05BTUUJKnBlX25hbWU7CglQSU1BR0VfVEhVTktfREFUQQlpbXBvcnRfbGlzdCx0aHVua19saXN0OwogCWNoYXIJCQkqbmFtZSA9IChjaGFyICopIFJWQShwZV9pbXAtPk5hbWUpOwoKCWlmIChjaGFyYWN0ZXJpc3RpY3NfZGV0ZWN0aW9uICYmICFwZV9pbXAtPnUuQ2hhcmFjdGVyaXN0aWNzKQoJCWJyZWFrOwoKCXdtSW1wID0gTU9EVUxFX0xvYWRMaWJyYXJ5RXhBKCBuYW1lLCAwLCAwICk7CglpZiAoIXdtSW1wKSB7CgkgICAgRVJSXyhtb2R1bGUpKCJNb2R1bGUgKGZpbGUpICVzIG5lZWRlZCBieSAlcyBub3QgZm91bmRcbiIsIG5hbWUsIHdtLT5maWxlbmFtZSk7CgkgICAgcmV0dXJuIDE7Cgl9CiAgICAgICAgd20tPmRlcHNbaSsrXSA9IHdtSW1wOwoKCS8qIEZJWE1FOiBmb3J3YXJkZXIgZW50cmllcyAuLi4gKi8KCglpZiAocGVfaW1wLT51Lk9yaWdpbmFsRmlyc3RUaHVuayAhPSAwKSB7IC8qIG9yaWdpbmFsIE1TIHN0eWxlICovCgkgICAgVFJBQ0UoIk1pY3Jvc29mdCBzdHlsZSBpbXBvcnRzIHVzZWRcbiIpOwoJICAgIGltcG9ydF9saXN0ID0oUElNQUdFX1RIVU5LX0RBVEEpIFJWQShwZV9pbXAtPnUuT3JpZ2luYWxGaXJzdFRodW5rKTsKCSAgICB0aHVua19saXN0ID0gKFBJTUFHRV9USFVOS19EQVRBKSBSVkEocGVfaW1wLT5GaXJzdFRodW5rKTsKCgkgICAgd2hpbGUgKGltcG9ydF9saXN0LT51MS5PcmRpbmFsKSB7CgkJaWYgKElNQUdFX1NOQVBfQllfT1JESU5BTChpbXBvcnRfbGlzdC0+dTEuT3JkaW5hbCkpIHsKCQkgICAgaW50IG9yZGluYWwgPSBJTUFHRV9PUkRJTkFMKGltcG9ydF9saXN0LT51MS5PcmRpbmFsKTsKCgkJICAgIFRSQUNFKCItLS0gT3JkaW5hbCAlcywlZFxuIiwgbmFtZSwgb3JkaW5hbCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPShQRFdPUkQpTU9EVUxFX0dldFByb2NBZGRyZXNzKAogICAgICAgICAgICAgICAgICAgICAgICB3bUltcC0+bW9kdWxlLCAoTFBDU1RSKW9yZGluYWwsIFRSVUUKCQkgICAgKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCQlFUlIoIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCBpbXBvcnRlZCBmcm9tICVzLCBzZXR0aW5nIHRvIDB4ZGVhZGJlZWZcbiIsCgkJCQluYW1lLCBvcmRpbmFsLCB3bS0+ZmlsZW5hbWUgKTsKICAgICAgICAgICAgICAgICAgICAgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24gPSAoUERXT1JEKTB4ZGVhZGJlZWY7CgkJICAgIH0KCQl9IGVsc2UgewkJLyogaW1wb3J0IGJ5IG5hbWUgKi8KCQkgICAgcGVfbmFtZSA9IChQSU1BR0VfSU1QT1JUX0JZX05BTUUpUlZBKGltcG9ydF9saXN0LT51MS5BZGRyZXNzT2ZEYXRhKTsKCQkgICAgVFJBQ0UoIi0tLSAlcyAlcy4lZFxuIiwgcGVfbmFtZS0+TmFtZSwgbmFtZSwgcGVfbmFtZS0+SGludCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPShQRFdPUkQpTU9EVUxFX0dldFByb2NBZGRyZXNzKAogICAgICAgICAgICAgICAgICAgICAgICB3bUltcC0+bW9kdWxlLCBwZV9uYW1lLT5OYW1lLCBUUlVFCgkJICAgICk7CgkJICAgIGlmICghdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24pIHsKCQkJRVJSKCJObyBpbXBsZW1lbnRhdGlvbiBmb3IgJXMuJWQoJXMpIGltcG9ydGVkIGZyb20gJXMsIHNldHRpbmcgdG8gMHhkZWFkYmVlZlxuIiwKCQkJCW5hbWUscGVfbmFtZS0+SGludCxwZV9uYW1lLT5OYW1lLHdtLT5maWxlbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uID0gKFBEV09SRCkweGRlYWRiZWVmOwoJCSAgICB9CgkJfQoJCWltcG9ydF9saXN0Kys7CgkJdGh1bmtfbGlzdCsrOwoJICAgIH0KCX0gZWxzZSB7CS8qIEJvcmxhbmQgc3R5bGUgKi8KCSAgICBUUkFDRSgiQm9ybGFuZCBzdHlsZSBpbXBvcnRzIHVzZWRcbiIpOwoJICAgIHRodW5rX2xpc3QgPSAoUElNQUdFX1RIVU5LX0RBVEEpIFJWQShwZV9pbXAtPkZpcnN0VGh1bmspOwoJICAgIHdoaWxlICh0aHVua19saXN0LT51MS5PcmRpbmFsKSB7CgkJaWYgKElNQUdFX1NOQVBfQllfT1JESU5BTCh0aHVua19saXN0LT51MS5PcmRpbmFsKSkgewoJCSAgICAvKiBub3Qgc3VyZSBhYm91dCB0aGlzIGJyYW5jaCwgYnV0IGl0IHNlZW1zIHRvIHdvcmsgKi8KCQkgICAgaW50IG9yZGluYWwgPSBJTUFHRV9PUkRJTkFMKHRodW5rX2xpc3QtPnUxLk9yZGluYWwpOwoKCQkgICAgVFJBQ0UoIi0tLSBPcmRpbmFsICVzLiVkXG4iLG5hbWUsb3JkaW5hbCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPShQRFdPUkQpTU9EVUxFX0dldFByb2NBZGRyZXNzKAogICAgICAgICAgICAgICAgICAgICAgICB3bUltcC0+bW9kdWxlLCAoTFBDU1RSKSBvcmRpbmFsLCBUUlVFCgkJICAgICk7CgkJICAgIGlmICghdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24pIHsKCQkJRVJSKCJObyBpbXBsZW1lbnRhdGlvbiBmb3IgJXMuJWQgaW1wb3J0ZWQgZnJvbSAlcywgc2V0dGluZyB0byAweGRlYWRiZWVmXG4iLAoJCQkJbmFtZSxvcmRpbmFsLCB3bS0+ZmlsZW5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICB0aHVua19saXN0LT51MS5GdW5jdGlvbiA9IChQRFdPUkQpMHhkZWFkYmVlZjsKCQkgICAgfQoJCX0gZWxzZSB7CgkJICAgIHBlX25hbWU9KFBJTUFHRV9JTVBPUlRfQllfTkFNRSkgUlZBKHRodW5rX2xpc3QtPnUxLkFkZHJlc3NPZkRhdGEpOwoJCSAgICBUUkFDRSgiLS0tICVzICVzLiVkXG4iLAoJCSAgIAkJICBwZV9uYW1lLT5OYW1lLG5hbWUscGVfbmFtZS0+SGludCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPShQRFdPUkQpTU9EVUxFX0dldFByb2NBZGRyZXNzKAogICAgICAgICAgICAgICAgICAgICAgICB3bUltcC0+bW9kdWxlLCBwZV9uYW1lLT5OYW1lLCBUUlVFCgkJICAgICk7CgkJICAgIGlmICghdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24pIHsKCQkgICAgCUVSUigiTm8gaW1wbGVtZW50YXRpb24gZm9yICVzLiVkKCVzKSBpbXBvcnRlZCBmcm9tICVzLCBzZXR0aW5nIHRvIDB4ZGVhZGJlZWZcbiIsCgkJCQluYW1lLCBwZV9uYW1lLT5IaW50LCBwZV9uYW1lLT5OYW1lLCB3bS0+ZmlsZW5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICB0aHVua19saXN0LT51MS5GdW5jdGlvbiA9IChQRFdPUkQpMHhkZWFkYmVlZjsKCQkgICAgfQoJCX0KCQl0aHVua19saXN0Kys7CgkgICAgfQoJfQogICAgfQogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgZG9fcmVsb2NhdGlvbnMKICoKICogQXBwbHkgdGhlIHJlbG9jYXRpb25zIHRvIGEgbWFwcGVkIFBFIGltYWdlCiAqLwpzdGF0aWMgaW50IGRvX3JlbG9jYXRpb25zKCBjaGFyICpiYXNlLCBjb25zdCBJTUFHRV9OVF9IRUFERVJTICpudCwgY29uc3QgY2hhciAqZmlsZW5hbWUgKQp7CiAgICBjb25zdCBJTUFHRV9EQVRBX0RJUkVDVE9SWSAqZGlyOwogICAgY29uc3QgSU1BR0VfQkFTRV9SRUxPQ0FUSU9OICpyZWw7CiAgICBpbnQgZGVsdGEgPSBiYXNlIC0gKGNoYXIgKiludC0+T3B0aW9uYWxIZWFkZXIuSW1hZ2VCYXNlOwoKICAgIGRpciA9ICZudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfQkFTRVJFTE9DXTsKICAgIHJlbCA9IChJTUFHRV9CQVNFX1JFTE9DQVRJT04gKikoYmFzZSArIGRpci0+VmlydHVhbEFkZHJlc3MpOwoKICAgIFdBUk4oIkluZm86IGJhc2UgcmVsb2NhdGlvbnMgbmVlZGVkIGZvciAlc1xuIiwgZmlsZW5hbWUpOwogICAgaWYgKCFkaXItPlZpcnR1YWxBZGRyZXNzIHx8ICFkaXItPlNpemUpCiAgICB7CiAgICAgICAgaWYgKG50LT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2UgPT0gMHg0MDAwMDApCiAgICAgICAgICAgIEVSUigiU3RhbmRhcmQgbG9hZCBhZGRyZXNzIGZvciBhIFdpbjMyIHByb2dyYW0gbm90IGF2YWlsYWJsZSAtIHBhdGNoZWQga2VybmVsID9cbiIpOwogICAgICAgIEVSUiggIkZBVEFMOiBOZWVkIHRvIHJlbG9jYXRlICVzLCBidXQgbm8gcmVsb2NhdGlvbiByZWNvcmRzIHByZXNlbnQgKCVzKS4gVHJ5IHRvIHJ1biB0aGF0IGZpbGUgZGlyZWN0bHkgIVxuIiwKICAgICAgICAgICAgIGZpbGVuYW1lLAogICAgICAgICAgICAgKG50LT5GaWxlSGVhZGVyLkNoYXJhY3RlcmlzdGljcyZJTUFHRV9GSUxFX1JFTE9DU19TVFJJUFBFRCk/CiAgICAgICAgICAgICAic3RyaXBwZWQgZHVyaW5nIGxpbmsiIDogInVua25vd24gcmVhc29uIiApOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIC8qIEZJWE1FOiBJZiB3ZSBuZWVkIHRvIHJlbG9jYXRlIGEgc3lzdGVtIERMTCAoYmFzZSA+IDJHQikgd2Ugc2hvdWxkCiAgICAgKiAgICAgICAgcmVhbGx5IG1ha2Ugc3VyZSB0aGF0IHRoZSAqbmV3KiBiYXNlIGFkZHJlc3MgaXMgYWxzbyA+IDJHQi4KICAgICAqICAgICAgICBTb21lIERMTHMgcmVhbGx5IGNoZWNrIHRoZSBNU0Igb2YgdGhlIG1vZHVsZSBoYW5kbGUgOi0vCiAgICAgKi8KICAgIGlmICgobnQtPk9wdGlvbmFsSGVhZGVyLkltYWdlQmFzZSAmIDB4ODAwMDAwMDApICYmICEoKERXT1JEKWJhc2UgJiAweDgwMDAwMDAwKSkKICAgICAgICBFUlIoICJGb3JjZWQgdG8gcmVsb2NhdGUgc3lzdGVtIERMTCAoYmFzZSA+IDJHQikuIFRoaXMgaXMgbm90IGdvb2QuXG4iICk7CgogICAgZm9yICggOyAoKGNoYXIgKilyZWwgPCBiYXNlICsgZGlyLT5WaXJ0dWFsQWRkcmVzcyArIGRpci0+U2l6ZSkgJiYgcmVsLT5WaXJ0dWFsQWRkcmVzczsKICAgICAgICAgIHJlbCA9IChJTUFHRV9CQVNFX1JFTE9DQVRJT04qKSgoY2hhciopcmVsICsgcmVsLT5TaXplT2ZCbG9jaykpCiAgICB7CiAgICAgICAgY2hhciAqcGFnZSA9IGJhc2UgKyByZWwtPlZpcnR1YWxBZGRyZXNzOwogICAgICAgIGludCBpLCBjb3VudCA9IChyZWwtPlNpemVPZkJsb2NrIC0gOCkgLyBzaXplb2YocmVsLT5UeXBlT2Zmc2V0KTsKCiAgICAgICAgaWYgKCFjb3VudCkgY29udGludWU7CgogICAgICAgIC8qIHNhbml0eSBjaGVja3MgKi8KICAgICAgICBpZiAoKGNoYXIgKilyZWwgKyByZWwtPlNpemVPZkJsb2NrID4gYmFzZSArIGRpci0+VmlydHVhbEFkZHJlc3MgKyBkaXItPlNpemUgfHwKICAgICAgICAgICAgcGFnZSA+IGJhc2UgKyBudC0+T3B0aW9uYWxIZWFkZXIuU2l6ZU9mSW1hZ2UpCiAgICAgICAgewogICAgICAgICAgICBFUlJfKG1vZHVsZSkoImludmFsaWQgcmVsb2NhdGlvbiAlcCwlbHgsJWxkIGF0ICVwLCVseCwlbHhcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICByZWwsIHJlbC0+VmlydHVhbEFkZHJlc3MsIHJlbC0+U2l6ZU9mQmxvY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICBiYXNlLCBkaXItPlZpcnR1YWxBZGRyZXNzLCBkaXItPlNpemUgKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQoKICAgICAgICBUUkFDRV8obW9kdWxlKSgiJWxkIHJlbG9jYXRpb25zIGZvciBwYWdlICVseFxuIiwgcmVsLT5TaXplT2ZCbG9jaywgcmVsLT5WaXJ0dWFsQWRkcmVzcyk7CgogICAgICAgIC8qIHBhdGNoaW5nIGluIHJldmVyc2Ugb3JkZXIgKi8KICAgICAgICBmb3IgKGkgPSAwIDsgaSA8IGNvdW50OyBpKyspCiAgICAgICAgewogICAgICAgICAgICBpbnQgb2Zmc2V0ID0gcmVsLT5UeXBlT2Zmc2V0W2ldICYgMHhGRkY7CiAgICAgICAgICAgIGludCB0eXBlID0gcmVsLT5UeXBlT2Zmc2V0W2ldID4+IDEyOwogICAgICAgICAgICBzd2l0Y2godHlwZSkKICAgICAgICAgICAgewogICAgICAgICAgICBjYXNlIElNQUdFX1JFTF9CQVNFRF9BQlNPTFVURToKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIElNQUdFX1JFTF9CQVNFRF9ISUdIOgogICAgICAgICAgICAgICAgKihzaG9ydCopKHBhZ2Urb2Zmc2V0KSArPSBISVdPUkQoZGVsdGEpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgSU1BR0VfUkVMX0JBU0VEX0xPVzoKICAgICAgICAgICAgICAgICooc2hvcnQqKShwYWdlK29mZnNldCkgKz0gTE9XT1JEKGRlbHRhKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIElNQUdFX1JFTF9CQVNFRF9ISUdITE9XOgogICAgICAgICAgICAgICAgKihpbnQqKShwYWdlK29mZnNldCkgKz0gZGVsdGE7CiAgICAgICAgICAgICAgICAvKiBGSVhNRTogaWYgdGhpcyBpcyBhbiBleHBvcnRlZCBhZGRyZXNzLCBmaXJlIHVwIGVuaGFuY2VkIGxvZ2ljICovCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIEZJWE1FXyhtb2R1bGUpKCJVbmtub3duL3Vuc3VwcG9ydGVkIGZpeHVwIHR5cGUgJWQuXG4iLCB0eXBlKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIDE7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJCVBFX0xvYWRJbWFnZQogKiBMb2FkIG9uZSBQRSBmb3JtYXQgRExML0VYRSBpbnRvIG1lbW9yeQogKiAKICogVW5sdWNraWx5IHdlIGNhbid0IGp1c3QgbW1hcCB0aGUgc2VjdGlvbnMgd2hlcmUgd2Ugd2FudCB0aGVtLCBmb3IgCiAqIChhdCBsZWFzdCkgTGludXggZG9lcyBvbmx5IHN1cHBvcnQgb2Zmc2V0cyB3aGljaCBhcmUgcGFnZS1hbGlnbmVkLgogKgogKiBCVVQgd2UgaGF2ZSB0byBtYXAgdGhlIHdob2xlIGltYWdlIGFueXdheSwgZm9yIFdpbjMyIHByb2dyYW1zIHNvbWV0aW1lcwogKiB3YW50IHRvIGFjY2VzcyB0aGVtLiAoSE1PRFVMRTMyIHBvaW50IHRvIHRoZSBzdGFydCBvZiBpdCkKICovCkhNT0RVTEUgUEVfTG9hZEltYWdlKCBIQU5ETEUgaEZpbGUsIExQQ1NUUiBmaWxlbmFtZSwgRFdPUkQgZmxhZ3MgKQp7CiAgICBJTUFHRV9OVF9IRUFERVJTICpudDsKICAgIEhNT0RVTEUgaE1vZHVsZTsKICAgIEhBTkRMRSBtYXBwaW5nOwogICAgdm9pZCAqYmFzZTsKCiAgICBUUkFDRV8obW9kdWxlKSggImxvYWRpbmcgJXNcbiIsIGZpbGVuYW1lICk7CgogICAgbWFwcGluZyA9IENyZWF0ZUZpbGVNYXBwaW5nQSggaEZpbGUsIE5VTEwsIFNFQ19JTUFHRSwgMCwgMCwgTlVMTCApOwogICAgaWYgKCFtYXBwaW5nKSByZXR1cm4gMDsKICAgIGJhc2UgPSBNYXBWaWV3T2ZGaWxlKCBtYXBwaW5nLCBGSUxFX01BUF9SRUFELCAwLCAwLCAwICk7CiAgICBDbG9zZUhhbmRsZSggbWFwcGluZyApOwogICAgaWYgKCFiYXNlKSByZXR1cm4gMDsKCiAgICBoTW9kdWxlID0gKEhNT0RVTEUpYmFzZTsKICAgIGlmIChmbGFncyAmIExPQURfTElCUkFSWV9BU19EQVRBRklMRSkgcmV0dXJuIGhNb2R1bGU7ICAvKiBub3RoaW5nIGVsc2UgdG8gZG8gKi8KCiAgICAvKiBwZXJmb3JtIGJhc2UgcmVsb2NhdGlvbiwgaWYgbmVjZXNzYXJ5ICovCgogICAgbnQgPSBQRV9IRUFERVIoIGhNb2R1bGUgKTsKICAgIGlmIChoTW9kdWxlICE9IG50LT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2UpCiAgICB7CiAgICAgICAgaWYgKCFkb19yZWxvY2F0aW9ucyggYmFzZSwgbnQsIGZpbGVuYW1lICkpCiAgICAgICAgewogICAgICAgICAgICBVbm1hcFZpZXdPZkZpbGUoIGJhc2UgKTsKICAgICAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9CQURfRVhFX0ZPUk1BVCApOwogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICB9CgogICAgLyogdmlydXMgY2hlY2sgKi8KCiAgICBpZiAobnQtPk9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQpCiAgICB7CiAgICAgICAgaW50IGk7CiAgICAgICAgSU1BR0VfU0VDVElPTl9IRUFERVIgKnNlYyA9IChJTUFHRV9TRUNUSU9OX0hFQURFUiopKChjaGFyKikmbnQtPk9wdGlvbmFsSGVhZGVyICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnQtPkZpbGVIZWFkZXIuU2l6ZU9mT3B0aW9uYWxIZWFkZXIpOwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBudC0+RmlsZUhlYWRlci5OdW1iZXJPZlNlY3Rpb25zOyBpKyssIHNlYysrKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKG50LT5PcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50IDwgc2VjLT5WaXJ0dWFsQWRkcmVzcykKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICBpZiAobnQtPk9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQgPCBzZWMtPlZpcnR1YWxBZGRyZXNzK3NlYy0+U2l6ZU9mUmF3RGF0YSkKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBpZiAoaSA9PSBudC0+RmlsZUhlYWRlci5OdW1iZXJPZlNlY3Rpb25zKQogICAgICAgICAgICBNRVNTQUdFKCJWSVJVUyBXQVJOSU5HOiBQRSBtb2R1bGUgaGFzIGFuIGludmFsaWQgZW50cnlwb2ludCAoMHglMDhseCkgIgogICAgICAgICAgICAgICAgICAgICJvdXRzaWRlIGFsbCBzZWN0aW9ucyAocG9zc2libHkgaW5mZWN0ZWQgYnkgVGNoZXJub2J5bC9TcGFjZUZpbGxlciB2aXJ1cykhXG4iLAogICAgICAgICAgICAgICAgICAgIG50LT5PcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50ICk7CiAgICB9CgogICAgcmV0dXJuIGhNb2R1bGU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgICAgICBQRV9DcmVhdGVNb2R1bGUKICoKICogQ3JlYXRlIFdJTkVfTU9EUkVGIHN0cnVjdHVyZSBmb3IgbG9hZGVkIEhNT0RVTEUzMiwgbGluayBpdCBpbnRvCiAqIHByb2Nlc3MgbW9kcmVmX2xpc3QsIGFuZCBmaXh1cCBhbGwgaW1wb3J0cy4KICoKICogTm90ZTogaE1vZHVsZSBtdXN0IHBvaW50IHRvIGEgY29ycmVjdGx5IGFsbG9jYXRlZCBQRSBpbWFnZSwKICogICAgICAgd2l0aCBiYXNlIHJlbG9jYXRpb25zIGFwcGxpZWQ7IHRoZSAxNi1iaXQgZHVtbXkgbW9kdWxlCiAqICAgICAgIGFzc29jaWF0ZWQgdG8gaE1vZHVsZSBtdXN0IGFscmVhZHkgZXhpc3QuCiAqCiAqIE5vdGU6IFRoaXMgcm91dGluZSBtdXN0IGFsd2F5cyBiZSBjYWxsZWQgaW4gdGhlIGNvbnRleHQgb2YgdGhlCiAqICAgICAgIHByb2Nlc3MgdGhhdCBpcyB0byBvd24gdGhlIG1vZHVsZSB0byBiZSBjcmVhdGVkLgogKgogKiBOb3RlOiBBc3N1bWVzIHRoYXQgdGhlIHByb2Nlc3MgY3JpdGljYWwgc2VjdGlvbiBpcyBoZWxkCiAqLwpXSU5FX01PRFJFRiAqUEVfQ3JlYXRlTW9kdWxlKCBITU9EVUxFIGhNb2R1bGUsIExQQ1NUUiBmaWxlbmFtZSwgRFdPUkQgZmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRSBoRmlsZSwgQk9PTCBidWlsdGluICkKewogICAgRFdPUkQgbG9hZF9hZGRyID0gKERXT1JEKWhNb2R1bGU7ICAvKiBmb3IgUlZBICovCiAgICBJTUFHRV9OVF9IRUFERVJTICpudCA9IFBFX0hFQURFUihoTW9kdWxlKTsKICAgIElNQUdFX0RBVEFfRElSRUNUT1JZICpkaXI7CiAgICBJTUFHRV9FWFBPUlRfRElSRUNUT1JZICpwZV9leHBvcnQgPSBOVUxMOwogICAgV0lORV9NT0RSRUYgKndtOwogICAgSE1PRFVMRTE2IGhNb2R1bGUxNjsKCiAgICAvKiBSZXRyaWV2ZSBEYXRhRGlyZWN0b3J5IGVudHJpZXMgKi8KCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhQT1JUOwogICAgaWYgKGRpci0+U2l6ZSkKICAgICAgICBwZV9leHBvcnQgPSAoUElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkpUlZBKGRpci0+VmlydHVhbEFkZHJlc3MpOwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWENFUFRJT047CiAgICBpZiAoZGlyLT5TaXplKSBGSVhNRSgiRXhjZXB0aW9uIGRpcmVjdG9yeSBpZ25vcmVkXG4iICk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX1NFQ1VSSVRZOwogICAgaWYgKGRpci0+U2l6ZSkgRklYTUUoIlNlY3VyaXR5IGRpcmVjdG9yeSBpZ25vcmVkXG4iICk7CgogICAgLyogSU1BR0VfRElSRUNUT1JZX0VOVFJZX0JBU0VSRUxPQyBoYW5kbGVkIGluIFBFX0xvYWRJbWFnZSAqLwogICAgLyogSU1BR0VfRElSRUNUT1JZX0VOVFJZX0RFQlVHIGhhbmRsZWQgYnkgZGVidWdnZXIgKi8KCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfR0xPQkFMUFRSOwogICAgaWYgKGRpci0+U2l6ZSkgRklYTUUoIkdsb2JhbCBQb2ludGVyIChNSVBTKSBpZ25vcmVkXG4iICk7CgogICAgLyogSU1BR0VfRElSRUNUT1JZX0VOVFJZX1RMUyBoYW5kbGVkIGluIFBFX1Rsc0luaXQgKi8KCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfTE9BRF9DT05GSUc7CiAgICBpZiAoZGlyLT5TaXplKSBGSVhNRSgiTG9hZCBDb25maWd1cmF0aW9uIGRpcmVjdG9yeSBpZ25vcmVkXG4iICk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0JPVU5EX0lNUE9SVDsKICAgIGlmIChkaXItPlNpemUpIFRSQUNFKCJCb3VuZCBJbXBvcnQgZGlyZWN0b3J5IGlnbm9yZWRcbiIgKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfSUFUOwogICAgaWYgKGRpci0+U2l6ZSkgVFJBQ0UoIkltcG9ydCBBZGRyZXNzIFRhYmxlIGRpcmVjdG9yeSBpZ25vcmVkXG4iICk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0RFTEFZX0lNUE9SVDsKICAgIGlmIChkaXItPlNpemUpCiAgICB7CgkJVFJBQ0UoIkRlbGF5ZWQgaW1wb3J0LCBzdHViIGNhbGxzIExvYWRMaWJyYXJ5XG4iICk7CgkJLyoKCQkgKiBOb3RoaW5nIHRvIGRvIGhlcmUuCgkJICovCgojaWZkZWYgSW1nRGVsYXlEZXNjcgoJCS8qCgkJICogVGhpcyBjb2RlIGlzIHVzZWZ1bCB0byBvYnNlcnZlIHdoYXQgdGhlIGhlY2sgaXMgZ29pbmcgb24uCgkJICovCgkJewoJCUltZ0RlbGF5RGVzY3IgKnBlX2RlbGF5ID0gTlVMTDsKICAgICAgICBwZV9kZWxheSA9IChQSW1nRGVsYXlEZXNjcilSVkEoZGlyLT5WaXJ0dWFsQWRkcmVzcyk7CiAgICAgICAgVFJBQ0VfKGRlbGF5aGxwKSgicGVfZGVsYXktPmdyQXR0cnMgPSAlMDh4XG4iLCBwZV9kZWxheS0+Z3JBdHRycyk7CiAgICAgICAgVFJBQ0VfKGRlbGF5aGxwKSgicGVfZGVsYXktPnN6TmFtZSA9ICVzXG4iLCBwZV9kZWxheS0+c3pOYW1lKTsKICAgICAgICBUUkFDRV8oZGVsYXlobHApKCJwZV9kZWxheS0+cGhtb2QgPSAlMDh4XG4iLCBwZV9kZWxheS0+cGhtb2QpOwogICAgICAgIFRSQUNFXyhkZWxheWhscCkoInBlX2RlbGF5LT5wSUFUID0gJTA4eFxuIiwgcGVfZGVsYXktPnBJQVQpOwogICAgICAgIFRSQUNFXyhkZWxheWhscCkoInBlX2RlbGF5LT5wSU5UID0gJTA4eFxuIiwgcGVfZGVsYXktPnBJTlQpOwogICAgICAgIFRSQUNFXyhkZWxheWhscCkoInBlX2RlbGF5LT5wQm91bmRJQVQgPSAlMDh4XG4iLCBwZV9kZWxheS0+cEJvdW5kSUFUKTsKICAgICAgICBUUkFDRV8oZGVsYXlobHApKCJwZV9kZWxheS0+cFVubG9hZElBVCA9ICUwOHhcbiIsIHBlX2RlbGF5LT5wVW5sb2FkSUFUKTsKICAgICAgICBUUkFDRV8oZGVsYXlobHApKCJwZV9kZWxheS0+ZHdUaW1lU3RhbXAgPSAlMDh4XG4iLCBwZV9kZWxheS0+ZHdUaW1lU3RhbXApOwogICAgICAgIH0KI2VuZGlmIC8qIEltZ0RlbGF5RGVzY3IgKi8KCX0KCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfQ09NX0RFU0NSSVBUT1I7CiAgICBpZiAoZGlyLT5TaXplKSBGSVhNRSgiVW5rbm93biBkaXJlY3RvcnkgMTQgaWdub3JlZFxuIiApOwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5KzE1OwogICAgaWYgKGRpci0+U2l6ZSkgRklYTUUoIlVua25vd24gZGlyZWN0b3J5IDE1IGlnbm9yZWRcbiIgKTsKCiAgICAvKiBDcmVhdGUgMTYtYml0IGR1bW15IG1vZHVsZSAqLwoKICAgIGlmICgoaE1vZHVsZTE2ID0gTU9EVUxFX0NyZWF0ZUR1bW15TW9kdWxlKCBmaWxlbmFtZSwgaE1vZHVsZSApKSA8IDMyKQogICAgewogICAgICAgIFNldExhc3RFcnJvciggKERXT1JEKWhNb2R1bGUxNiApOwkvKiBUaGlzIHNob3VsZCBnaXZlIHRoZSBjb3JyZWN0IGVycm9yICovCiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgLyogQWxsb2NhdGUgYW5kIGZpbGwgV0lORV9NT0RSRUYgKi8KCiAgICBpZiAoISh3bSA9IE1PRFVMRV9BbGxvY01vZFJlZiggaE1vZHVsZSwgZmlsZW5hbWUgKSkpCiAgICB7CiAgICAgICAgRnJlZUxpYnJhcnkxNiggaE1vZHVsZTE2ICk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CiAgICB3bS0+aER1bW15TW9kID0gaE1vZHVsZTE2OwoKICAgIGlmICggYnVpbHRpbiApIAogICAgewogICAgICAgIE5FX01PRFVMRSAqcE1vZHVsZSA9IChORV9NT0RVTEUgKilHbG9iYWxMb2NrMTYoIGhNb2R1bGUxNiApOwogICAgICAgIHBNb2R1bGUtPmZsYWdzIHw9IE5FX0ZGTEFHU19CVUlMVElOOwogICAgICAgIHdtLT5mbGFncyB8PSBXSU5FX01PRFJFRl9JTlRFUk5BTDsKICAgIH0KCiAgICBpZiAoIGZsYWdzICYgRE9OVF9SRVNPTFZFX0RMTF9SRUZFUkVOQ0VTICkKICAgICAgICB3bS0+ZmxhZ3MgfD0gV0lORV9NT0RSRUZfRE9OVF9SRVNPTFZFX1JFRlM7CgogICAgd20tPmZpbmRfZXhwb3J0ID0gUEVfRmluZEV4cG9ydGVkRnVuY3Rpb247CgogICAgLyogRHVtcCBFeHBvcnRzICovCgogICAgaWYgKCBwZV9leHBvcnQgKQogICAgICAgIGR1bXBfZXhwb3J0cyggaE1vZHVsZSApOwoKICAgIC8qIEZpeHVwIEltcG9ydHMgKi8KCiAgICBpZiAoISh3bS0+ZmxhZ3MgJiBXSU5FX01PRFJFRl9ET05UX1JFU09MVkVfUkVGUykgJiYgZml4dXBfaW1wb3J0cyggd20gKSkKICAgIHsKICAgICAgICAvKiByZW1vdmUgZW50cnkgZnJvbSBtb2RyZWYgY2hhaW4gKi8KCiAgICAgICAgaWYgKCAhd20tPnByZXYgKQogICAgICAgICAgICBNT0RVTEVfbW9kcmVmX2xpc3QgPSB3bS0+bmV4dDsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHdtLT5wcmV2LT5uZXh0ID0gd20tPm5leHQ7CgogICAgICAgIGlmICggd20tPm5leHQgKSB3bS0+bmV4dC0+cHJldiA9IHdtLT5wcmV2OwogICAgICAgIHdtLT5uZXh0ID0gd20tPnByZXYgPSBOVUxMOwoKICAgICAgICAvKiBGSVhNRTogdGhlcmUgYXJlIHNldmVyYWwgbW9yZSBkYW5nbGluZyByZWZlcmVuY2VzCiAgICAgICAgICogbGVmdC4gSW5jbHVkaW5nIGRsbHMgbG9hZGVkIGJ5IHRoaXMgZGxsIGJlZm9yZSB0aGUKICAgICAgICAgKiBmYWlsZWQgb25lLiBVbnJvbGxpbmcgaXMgcmF0aGVyIGRpZmZpY3VsdCB3aXRoIHRoZQogICAgICAgICAqIGN1cnJlbnQgc3RydWN0dXJlIGFuZCB3ZSBjYW4gbGVhdmUgaXQgdGhlbSBseWluZwogICAgICAgICAqIGFyb3VuZCB3aXRoIG5vIHByb2JsZW1zLCBzbyB3ZSBkb24ndCBjYXJlLgogICAgICAgICAqIEFzIHRoZXNlIG1pZ2h0IHJlZmVyZW5jZSBvdXIgd20sIHdlIGRvbid0IGZyZWUgaXQuCiAgICAgICAgICovCiAgICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIGlmIChwZV9leHBvcnQpCiAgICAgICAgU05PT1BfUmVnaXN0ZXJETEwoIGhNb2R1bGUsIHdtLT5tb2RuYW1lLCBwZV9leHBvcnQtPk51bWJlck9mRnVuY3Rpb25zICk7CgogICAgLyogU2VuZCBETEwgbG9hZCBldmVudCAqLwogICAgLyogd2UgZG9uJ3QgbmVlZCB0byBzZW5kIGEgZGxsIGV2ZW50IGZvciB0aGUgbWFpbiBleGUgKi8KCiAgICBpZiAobnQtPkZpbGVIZWFkZXIuQ2hhcmFjdGVyaXN0aWNzICYgSU1BR0VfRklMRV9ETEwpCiAgICB7CiAgICAgICAgU0VSVkVSX1NUQVJUX1JFUSggbG9hZF9kbGwgKQogICAgICAgIHsKICAgICAgICAgICAgcmVxLT5oYW5kbGUgICAgID0gaEZpbGU7CiAgICAgICAgICAgIHJlcS0+YmFzZSAgICAgICA9ICh2b2lkICopaE1vZHVsZTsKICAgICAgICAgICAgcmVxLT5kYmdfb2Zmc2V0ID0gbnQtPkZpbGVIZWFkZXIuUG9pbnRlclRvU3ltYm9sVGFibGU7CiAgICAgICAgICAgIHJlcS0+ZGJnX3NpemUgICA9IG50LT5GaWxlSGVhZGVyLk51bWJlck9mU3ltYm9sczsKICAgICAgICAgICAgcmVxLT5uYW1lICAgICAgID0gJndtLT5maWxlbmFtZTsKICAgICAgICAgICAgU0VSVkVSX0NBTEwoKTsKICAgICAgICB9CiAgICAgICAgU0VSVkVSX0VORF9SRVE7CiAgICB9CgogICAgcmV0dXJuIHdtOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFRoZSBQRSBMaWJyYXJ5IExvYWRlciBmcm9udGVuZC4gCiAqIEZJWE1FOiBoYW5kbGUgdGhlIGZsYWdzLgogKi8KV0lORV9NT0RSRUYgKlBFX0xvYWRMaWJyYXJ5RXhBIChMUENTVFIgbmFtZSwgRFdPUkQgZmxhZ3MpCnsKCUhNT0RVTEUJCWhNb2R1bGUzMjsKCVdJTkVfTU9EUkVGCSp3bTsKCUhBTkRMRQkJaEZpbGU7CiAgICAgICAKCWhGaWxlID0gQ3JlYXRlRmlsZUEoIG5hbWUsIEdFTkVSSUNfUkVBRCwgRklMRV9TSEFSRV9SRUFELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIE9QRU5fRVhJU1RJTkcsIDAsIDAgKTsKCWlmICggaEZpbGUgPT0gSU5WQUxJRF9IQU5ETEVfVkFMVUUgKSByZXR1cm4gTlVMTDsKCQoJLyogTG9hZCBQRSBtb2R1bGUgKi8KCWhNb2R1bGUzMiA9IFBFX0xvYWRJbWFnZSggaEZpbGUsIG5hbWUsIGZsYWdzICk7CglpZiAoIWhNb2R1bGUzMikKCXsKICAgICAgICAgICAgICAgIENsb3NlSGFuZGxlKCBoRmlsZSApOwoJCXJldHVybiBOVUxMOwoJfQoKCS8qIENyZWF0ZSAzMi1iaXQgTU9EUkVGICovCglpZiAoICEod20gPSBQRV9DcmVhdGVNb2R1bGUoIGhNb2R1bGUzMiwgbmFtZSwgZmxhZ3MsIGhGaWxlLCBGQUxTRSApKSApCgl7CgkJRVJSKCAiY2FuJ3QgbG9hZCAlc1xuIiwgbmFtZSApOwogICAgICAgICAgICAgICAgQ2xvc2VIYW5kbGUoIGhGaWxlICk7CgkJU2V0TGFzdEVycm9yKCBFUlJPUl9PVVRPRk1FTU9SWSApOwoJCXJldHVybiBOVUxMOwoJfQoKICAgICAgICBDbG9zZUhhbmRsZSggaEZpbGUgKTsKCXJldHVybiB3bTsKfQoKCi8qIENhbGxlZCBpZiB0aGUgbGlicmFyeSBpcyBsb2FkZWQgb3IgZnJlZWQuCiAqIE5PVEU6IGlmIGEgdGhyZWFkIGF0dGFjaGVzIGEgRExMLCB0aGUgY3VycmVudCB0aHJlYWQgd2lsbCBvbmx5IGRvCiAqIERMTF9QUk9DRVNTX0FUVEFDSC4gT25seSBuZXcgY3JlYXRlZCB0aHJlYWRzIGRvIERMTF9USFJFQURfQVRUQUNICiAqIChTREspCiAqLwp0eXBlZGVmIERXT1JEIENBTExCQUNLKCpETExFTlRSWVBST0MpKEhNT0RVTEUsRFdPUkQsTFBWT0lEKTsKCkJPT0wgUEVfSW5pdERMTCggSE1PRFVMRSBtb2R1bGUsIERXT1JEIHR5cGUsIExQVk9JRCBscFJlc2VydmVkICkKewogICAgQk9PTCByZXR2ID0gVFJVRTsKICAgIElNQUdFX05UX0hFQURFUlMgKm50ID0gUEVfSEVBREVSKG1vZHVsZSk7CgogICAgLyogSXMgdGhpcyBhIGxpYnJhcnk/IEFuZCBoYXMgaXQgZ290IGFuIGVudHJ5cG9pbnQ/ICovCiAgICBpZiAoKG50LT5GaWxlSGVhZGVyLkNoYXJhY3RlcmlzdGljcyAmIElNQUdFX0ZJTEVfRExMKSAmJgogICAgICAgIChudC0+T3B0aW9uYWxIZWFkZXIuQWRkcmVzc09mRW50cnlQb2ludCkpCiAgICB7CiAgICAgICAgRExMRU5UUllQUk9DIGVudHJ5ID0gKHZvaWQqKSgoY2hhciopbW9kdWxlICsgbnQtPk9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQpOwogICAgICAgIFRSQUNFXyhyZWxheSkoIkNhbGxUbzMyKGVudHJ5cHJvYz0lcCxtb2R1bGU9JTA4eCx0eXBlPSVsZCxyZXM9JXApXG4iLAogICAgICAgICAgICAgICAgICAgICAgIGVudHJ5LCBtb2R1bGUsIHR5cGUsIGxwUmVzZXJ2ZWQgKTsKCiAgICAgICAgcmV0diA9IGVudHJ5KCBtb2R1bGUsIHR5cGUsIGxwUmVzZXJ2ZWQgKTsKICAgIH0KCiAgICByZXR1cm4gcmV0djsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKglQRV9Jbml0VGxzCQkJKGludGVybmFsKQogKgogKiBJZiBpbmNsdWRlZCwgaW5pdGlhbGlzZXMgdGhlIHRocmVhZCBsb2NhbCBzdG9yYWdlcyBvZiBtb2R1bGVzLgogKiBQb2ludGVycyBpbiB0aG9zZSBzdHJ1Y3RzIGFyZSBub3QgUlZBcyBidXQgcmVhbCBwb2ludGVycyB3aGljaCBoYXZlIGJlZW4KICogcmVsb2NhdGVkIGJ5IGRvX3JlbG9jYXRpb25zKCkgYWxyZWFkeS4KICovCnN0YXRpYyBMUFZPSUQKX2ZpeHVwX2FkZHJlc3MoUElNQUdFX09QVElPTkFMX0hFQURFUiBvcHQsaW50IGRlbHRhLExQVk9JRCBhZGRyKSB7CglpZiAoCSgoRFdPUkQpYWRkcj5vcHQtPkltYWdlQmFzZSkgJiYKCQkoKERXT1JEKWFkZHI8b3B0LT5JbWFnZUJhc2Urb3B0LT5TaXplT2ZJbWFnZSkKCSkKCQkvKiB0aGUgYWRkcmVzcyBoYXMgbm90IGJlZW4gcmVsb2NhdGVkISAqLwoJCXJldHVybiAoTFBWT0lEKSgoKERXT1JEKWFkZHIpK2RlbHRhKTsKCWVsc2UKCQkvKiB0aGUgYWRkcmVzcyBoYXMgYmVlbiByZWxvY2F0ZWQgYWxyZWFkeSAqLwoJCXJldHVybiBhZGRyOwp9CnZvaWQgUEVfSW5pdFRscyggdm9pZCApCnsKCVdJTkVfTU9EUkVGCQkqd207CglJTUFHRV9OVF9IRUFERVJTCSpwZWg7CglEV09SRAkJCXNpemUsZGF0YXNpemU7CglMUFZPSUQJCQltZW07CglQSU1BR0VfVExTX0RJUkVDVE9SWQlwZGlyOwogICAgICAgIGludCBkZWx0YTsKCQoJZm9yICh3bSA9IE1PRFVMRV9tb2RyZWZfbGlzdDt3bTt3bT13bS0+bmV4dCkgewoJCXBlaCA9IFBFX0hFQURFUih3bS0+bW9kdWxlKTsKCQlkZWx0YSA9IHdtLT5tb2R1bGUgLSBwZWgtPk9wdGlvbmFsSGVhZGVyLkltYWdlQmFzZTsKCQlpZiAoIXBlaC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9GSUxFX1RIUkVBRF9MT0NBTF9TVE9SQUdFXS5WaXJ0dWFsQWRkcmVzcykKCQkJY29udGludWU7CgkJcGRpciA9IChMUFZPSUQpKHdtLT5tb2R1bGUgKyBwZWgtPk9wdGlvbmFsSGVhZGVyLgoJCQlEYXRhRGlyZWN0b3J5W0lNQUdFX0ZJTEVfVEhSRUFEX0xPQ0FMX1NUT1JBR0VdLlZpcnR1YWxBZGRyZXNzKTsKCQkKCQkKCQlpZiAoIHdtLT50bHNpbmRleCA9PSAtMSApIHsKCQkJTFBEV09SRCB4YWRkcjsKCQkJd20tPnRsc2luZGV4ID0gVGxzQWxsb2MoKTsKCQkJeGFkZHIgPSBfZml4dXBfYWRkcmVzcygmKHBlaC0+T3B0aW9uYWxIZWFkZXIpLGRlbHRhLAoJCQkJCXBkaXItPkFkZHJlc3NPZkluZGV4CgkJCSk7CgkJCSp4YWRkcj13bS0+dGxzaW5kZXg7CgkJfQoJCWRhdGFzaXplPSBwZGlyLT5FbmRBZGRyZXNzT2ZSYXdEYXRhLXBkaXItPlN0YXJ0QWRkcmVzc09mUmF3RGF0YTsKCQlzaXplCT0gZGF0YXNpemUgKyBwZGlyLT5TaXplT2ZaZXJvRmlsbDsKCQltZW09VmlydHVhbEFsbG9jKDAsc2l6ZSxNRU1fUkVTRVJWRXxNRU1fQ09NTUlULFBBR0VfUkVBRFdSSVRFKTsKCQltZW1jcHkobWVtLF9maXh1cF9hZGRyZXNzKCYocGVoLT5PcHRpb25hbEhlYWRlciksZGVsdGEsKExQVk9JRClwZGlyLT5TdGFydEFkZHJlc3NPZlJhd0RhdGEpLGRhdGFzaXplKTsKCQlpZiAocGRpci0+QWRkcmVzc09mQ2FsbEJhY2tzKSB7CgkJICAgICBQSU1BR0VfVExTX0NBTExCQUNLICpjYnM7IAoKCQkgICAgIGNicyA9IF9maXh1cF9hZGRyZXNzKCYocGVoLT5PcHRpb25hbEhlYWRlciksZGVsdGEscGRpci0+QWRkcmVzc09mQ2FsbEJhY2tzKTsKCQkgICAgIGlmICgqY2JzKQoJCSAgICAgICBGSVhNRSgiVExTIENhbGxiYWNrcyBhcmVuJ3QgZ29pbmcgdG8gYmUgY2FsbGVkXG4iKTsKCQl9CgoJCVRsc1NldFZhbHVlKCB3bS0+dGxzaW5kZXgsIG1lbSApOwoJfQp9Cgo=