LyogCiAqICBDb3B5cmlnaHQJMTk5NAlFcmljIFlvdW5kYWxlICYgRXJpayBCb3MKICogIENvcHlyaWdodAkxOTk1CU1hcnRpbiB2b24gTPZ3aXMKICogIENvcHlyaWdodCAgIDE5OTYtOTggTWFyY3VzIE1laXNzbmVyCiAqCiAqCWJhc2VkIG9uIEVyaWMgWW91bmRhbGUncyBwZS10ZXN0IGFuZDoKICoKICoJZnRwLm1pY3Jvc29mdC5jb206L3B1Yi9kZXZlbG9wZXIvTVNETi9DRDgvUEVGSUxFLlpJUAogKiBtYWtlIHRoYXQ6CiAqCWZ0cC5taWNyb3NvZnQuY29tOi9kZXZlbG9wci9NU0ROL09jdENEL1BFRklMRS5aSVAKICovCi8qIE5vdGVzOgogKiBCZWZvcmUgeW91IHN0YXJ0IGNoYW5naW5nIHNvbWV0aGluZyBpbiB0aGlzIGZpbGUgYmUgYXdhcmUgb2YgdGhlIGZvbGxvd2luZzoKICoKICogLSBUaGVyZSBhcmUgc2V2ZXJhbCBmdW5jdGlvbnMgY2FsbGVkIHJlY3Vyc2l2ZWx5LiBJbiBhIHZlcnkgc3VidGxlIGFuZCAKICogICBvYnNjdXJlIHdheS4gRExMcyBjYW4gcmVmZXJlbmNlIGVhY2ggb3RoZXIgcmVjdXJzaXZlbHkgZXRjLgogKiAtIElmIHlvdSB3YW50IHRvIGVuaGFuY2UsIHNwZWVkIHVwIG9yIGNsZWFuIHVwIHNvbWV0aGluZyBpbiBoZXJlLCB0aGluawogKiAgIHR3aWNlIFdIWSBpdCBpcyBpbXBsZW1lbnRlZCBpbiB0aGF0IHN0cmFuZ2Ugd2F5LiBUaGVyZSBpcyB1c3VhbGx5IGEgcmVhc29uLgogKiAgIFRob3VnaCBzb21ldGltZXMgaXQgbWlnaHQganVzdCBiZSBsYXp5bmVzcyA7KQogKiAtIEluIFBFX01hcEltYWdlLCByaWdodCBiZWZvcmUgZml4dXBfaW1wb3J0cygpIGFsbCBleHRlcm5hbCBhbmQgaW50ZXJuYWwgCiAqICAgc3RhdGUgTVVTVCBiZSBjb3JyZWN0IHNpbmNlIHRoaXMgZnVuY3Rpb24gY2FuIGJlIGNhbGxlZCB3aXRoIHRoZSBTQU1FIGltYWdlCiAqICAgQUdBSU4uIChUaGF0cyByZWN1cnNpb24gZm9yIHlvdS4pIFRoYXQgbWVhbnMgTU9EUkVGLm1vZHVsZSBhbmQKICogICBORV9NT0RVTEUubW9kdWxlMzIuCiAqIC0gU29tZXRpbWVzLCB3ZSBjYW4ndCB1c2UgTGludXggbW1hcCgpIHRvIG1tYXAoKSB0aGUgaW1hZ2VzIGRpcmVjdGx5LgogKgogKiAgIFRoZSBwcm9ibGVtIGlzLCB0aGF0IHRoZXJlIGlzIG5vdCBkaXJlY3QgMToxIG1hcHBpbmcgZnJvbSBhIGRpc2tpbWFnZSBhbmQKICogICBhIG1lbW9yeWltYWdlLiBUaGUgaGVhZGVycyBhdCB0aGUgc3RhcnQgYXJlIG1hcHBlZCBsaW5lYXIsIGJ1dCB0aGUgc2VjdGlvbnMKICogICBhcmUgbm90LiBPbGRlciB4ODYgcGUgYmluYXJpZXMgYXJlIDUxMiBieXRlIGFsaWduZWQgaW4gZmlsZSBhbmQgNDA5NiBieXRlCiAqICAgYWxpZ25lZCBpbiBtZW1vcnkuIExpbnV4IGxpa2VzIHRoZW0gNDA5NiBieXRlIGFsaWduZWQgaW4gbWVtb3J5IChkdWUgdG8KICogICB4ODYgcGFnZXNpemUsIHRoaXMgY2Fubm90IGJlIGZpeGVkIHdpdGhvdXQgYSByYXRoZXIgbGFyZ2Uga2VybmVsIHJld3JpdGUpCiAqICAgYW5kICdibG9ja3NpemUnIGZpbGUtYWxpZ25lZCAob2Zmc2V0cykuIFNpbmNlIHdlIGhhdmUgNTEyLzEwMjQvMjA0OCAoQ0RST00pCiAqICAgYW5kIG90aGVyIGJ5dGUgYmxvY2tzaXplcywgd2UgY2FuJ3QgYWx3YXlzIGRvIHRoaXMuICBXZSAqY2FuKiBkbyB0aGlzIGZvcgogKiAgIG5ld2VyIHBlIGJpbmFyaWVzIHByb2R1Y2VkIGJ5IE1TVkMgNSBhbmQgbGF0ZXIsIHNpbmNlIHRoZXkgYXJlIGFsc28gYWxpZ25lZAogKiAgIHRvIDQwOTYgYnl0ZSBib3VuZGFyaWVzIG9uIGRpc2suCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgoKI2luY2x1ZGUgPGVycm5vLmg+CiNpbmNsdWRlIDxhc3NlcnQuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3lzL3N0YXQuaD4KI2lmZGVmIEhBVkVfU1lTX01NQU5fSAojaW5jbHVkZSA8c3lzL21tYW4uaD4KI2VuZGlmCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmUvd2luYmFzZTE2LmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAiY2FsbGJhY2suaCIKI2luY2x1ZGUgImZpbGUuaCIKI2luY2x1ZGUgImhlYXAuaCIKI2luY2x1ZGUgIm5lZXhlLmgiCiNpbmNsdWRlICJwcm9jZXNzLmgiCiNpbmNsdWRlICJ0aHJlYWQuaCIKI2luY2x1ZGUgIm1vZHVsZS5oIgojaW5jbHVkZSAiZ2xvYmFsLmgiCiNpbmNsdWRlICJ0YXNrLmgiCiNpbmNsdWRlICJzbm9vcC5oIgojaW5jbHVkZSAic2VydmVyLmgiCiNpbmNsdWRlICJkZWJ1Z3Rvb2xzLmgiCgpERUZBVUxUX0RFQlVHX0NIQU5ORUwod2luMzIpOwpERUNMQVJFX0RFQlVHX0NIQU5ORUwoZGVsYXlobHApOwpERUNMQVJFX0RFQlVHX0NIQU5ORUwoZml4dXApOwpERUNMQVJFX0RFQlVHX0NIQU5ORUwobW9kdWxlKTsKREVDTEFSRV9ERUJVR19DSEFOTkVMKHJlbGF5KTsKREVDTEFSRV9ERUJVR19DSEFOTkVMKHNlZ21lbnQpOwoKCnN0YXRpYyBJTUFHRV9FWFBPUlRfRElSRUNUT1JZICpnZXRfZXhwb3J0cyggSE1PRFVMRSBobW9kICkKewogICAgSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSAqcmV0ID0gTlVMTDsKICAgIElNQUdFX0RBVEFfRElSRUNUT1JZICpkaXIgPSBQRV9IRUFERVIoaG1vZCktPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIElNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlQ7CiAgICBpZiAoZGlyLT5TaXplICYmIGRpci0+VmlydHVhbEFkZHJlc3MpCiAgICAgICAgcmV0ID0gKElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkgKikoKGNoYXIgKilobW9kICsgZGlyLT5WaXJ0dWFsQWRkcmVzcyk7CiAgICByZXR1cm4gcmV0Owp9CgpzdGF0aWMgSU1BR0VfSU1QT1JUX0RFU0NSSVBUT1IgKmdldF9pbXBvcnRzKCBITU9EVUxFIGhtb2QgKQp7CiAgICBJTUFHRV9JTVBPUlRfREVTQ1JJUFRPUiAqcmV0ID0gTlVMTDsKICAgIElNQUdFX0RBVEFfRElSRUNUT1JZICpkaXIgPSBQRV9IRUFERVIoaG1vZCktPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIElNQUdFX0RJUkVDVE9SWV9FTlRSWV9JTVBPUlQ7CiAgICBpZiAoZGlyLT5TaXplICYmIGRpci0+VmlydHVhbEFkZHJlc3MpCiAgICAgICAgcmV0ID0gKElNQUdFX0lNUE9SVF9ERVNDUklQVE9SICopKChjaGFyICopaG1vZCArIGRpci0+VmlydHVhbEFkZHJlc3MpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qIGNvbnZlcnQgUEUgaW1hZ2UgVmlydHVhbEFkZHJlc3MgdG8gUmVhbCBBZGRyZXNzICovCiNkZWZpbmUgUlZBKHgpICgodm9pZCAqKSgoY2hhciAqKWxvYWRfYWRkcisodW5zaWduZWQgaW50KSh4KSkpCgojZGVmaW5lIEFkanVzdFB0cihwdHIsZGVsdGEpICgoY2hhciAqKShwdHIpICsgKGRlbHRhKSkKCnZvaWQgZHVtcF9leHBvcnRzKCBITU9EVUxFIGhNb2R1bGUgKQp7IAogIGNoYXIJCSpNb2R1bGU7CiAgaW50CQlpLCBqOwogIHVfc2hvcnQJKm9yZGluYWw7CiAgdV9sb25nCSpmdW5jdGlvbiwqZnVuY3Rpb25zOwogIHVfY2hhcgkqKm5hbWU7CiAgdW5zaWduZWQgaW50IGxvYWRfYWRkciA9IGhNb2R1bGU7CgogIERXT1JEIHJ2YV9zdGFydCA9IFBFX0hFQURFUihoTW9kdWxlKS0+T3B0aW9uYWxIZWFkZXIKICAgICAgICAgICAgICAgICAgIC5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlRdLlZpcnR1YWxBZGRyZXNzOwogIERXT1JEIHJ2YV9lbmQgPSBydmFfc3RhcnQgKyBQRV9IRUFERVIoaE1vZHVsZSktPk9wdGlvbmFsSGVhZGVyCiAgICAgICAgICAgICAgICAgICAuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhQT1JUXS5TaXplOwogIElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkgKnBlX2V4cG9ydHMgPSAoSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSopUlZBKHJ2YV9zdGFydCk7CgogIE1vZHVsZSA9IChjaGFyKilSVkEocGVfZXhwb3J0cy0+TmFtZSk7CiAgVFJBQ0UoIioqKioqKipFWFBPUlQgREFUQSoqKioqKipcbiIpOwogIFRSQUNFKCJNb2R1bGUgbmFtZSBpcyAlcywgJWxkIGZ1bmN0aW9ucywgJWxkIG5hbWVzXG4iLCAKICAgICAgICBNb2R1bGUsIHBlX2V4cG9ydHMtPk51bWJlck9mRnVuY3Rpb25zLCBwZV9leHBvcnRzLT5OdW1iZXJPZk5hbWVzKTsKCiAgb3JkaW5hbD0odV9zaG9ydCopIFJWQShwZV9leHBvcnRzLT5BZGRyZXNzT2ZOYW1lT3JkaW5hbHMpOwogIGZ1bmN0aW9ucz1mdW5jdGlvbj0odV9sb25nKikgUlZBKHBlX2V4cG9ydHMtPkFkZHJlc3NPZkZ1bmN0aW9ucyk7CiAgbmFtZT0odV9jaGFyKiopIFJWQShwZV9leHBvcnRzLT5BZGRyZXNzT2ZOYW1lcyk7CgogIFRSQUNFKCIgT3JkICAgIFJWQSAgICAgQWRkciAgIE5hbWVcbiIgKTsKICBmb3IgKGk9MDtpPHBlX2V4cG9ydHMtPk51bWJlck9mRnVuY3Rpb25zO2krKywgZnVuY3Rpb24rKykKICB7CiAgICAgIGlmICghKmZ1bmN0aW9uKSBjb250aW51ZTsgIC8qIE5vIHN1Y2ggZnVuY3Rpb24gKi8KICAgICAgaWYgKFRSQUNFX09OKHdpbjMyKSkKICAgICAgewoJRFBSSU5URiggIiU0bGQgJTA4bHggJXAiLCBpICsgcGVfZXhwb3J0cy0+QmFzZSwgKmZ1bmN0aW9uLCBSVkEoKmZ1bmN0aW9uKSApOwoJLyogQ2hlY2sgaWYgd2UgaGF2ZSBhIG5hbWUgZm9yIGl0ICovCglmb3IgKGogPSAwOyBqIDwgcGVfZXhwb3J0cy0+TnVtYmVyT2ZOYW1lczsgaisrKQogICAgICAgICAgaWYgKG9yZGluYWxbal0gPT0gaSkKICAgICAgICAgIHsKICAgICAgICAgICAgICBEUFJJTlRGKCAiICAlcyIsIChjaGFyKilSVkEobmFtZVtqXSkgKTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KCWlmICgoKmZ1bmN0aW9uID49IHJ2YV9zdGFydCkgJiYgKCpmdW5jdGlvbiA8PSBydmFfZW5kKSkKCSAgRFBSSU5URigiIChmb3J3YXJkZWQgLT4gJXMpIiwgKGNoYXIgKilSVkEoKmZ1bmN0aW9uKSk7CglEUFJJTlRGKCJcbiIpOwogICAgICB9CiAgfQp9CgovKiBMb29rIHVwIHRoZSBzcGVjaWZpZWQgZnVuY3Rpb24gb3Igb3JkaW5hbCBpbiB0aGUgZXhwb3J0bGlzdDoKICogSWYgaXQgaXMgYSBzdHJpbmc6CiAqIAktIGxvb2sgdXAgdGhlIG5hbWUgaW4gdGhlIE5hbWUgbGlzdC4gCiAqCS0gbG9vayB1cCB0aGUgb3JkaW5hbCB3aXRoIHRoYXQgaW5kZXguCiAqCS0gdXNlIHRoZSBvcmRpbmFsIGFzIG9mZnNldCBpbnRvIHRoZSBmdW5jdGlvbmxpc3QKICogSWYgaXQgaXMgYSBvcmRpbmFsOgogKgktIHVzZSBvcmRpbmFsLXBlX2V4cG9ydC0+QmFzZSBhcyBvZmZzZXQgaW50byB0aGUgZnVuY3Rpb25saXN0CiAqLwpzdGF0aWMgRkFSUFJPQyBQRV9GaW5kRXhwb3J0ZWRGdW5jdGlvbiggCglXSU5FX01PRFJFRiAqd20sCS8qIFtpbl0gV0lORSBtb2RyZWZlcmVuY2UgKi8KCUxQQ1NUUiBmdW5jTmFtZSwJLyogW2luXSBmdW5jdGlvbiBuYW1lICovCiAgICAgICAgQk9PTCBzbm9vcCApCnsKCXVfc2hvcnQJCQkJKiBvcmRpbmFsczsKCXVfbG9uZwkJCQkqIGZ1bmN0aW9uOwoJdV9jaGFyCQkJCSoqIG5hbWUsICplbmFtZSA9IE5VTEw7CglpbnQJCQkJaSwgb3JkaW5hbDsKCXVuc2lnbmVkIGludAkJCWxvYWRfYWRkciA9IHdtLT5tb2R1bGU7Cgl1X2xvbmcJCQkJcnZhX3N0YXJ0LCBydmFfZW5kLCBhZGRyOwoJY2hhcgkJCQkqIGZvcndhcmQ7CglJTUFHRV9FWFBPUlRfRElSRUNUT1JZICpleHBvcnRzID0gZ2V0X2V4cG9ydHMod20tPm1vZHVsZSk7CgoJaWYgKEhJV09SRChmdW5jTmFtZSkpCgkJVFJBQ0UoIiglcylcbiIsZnVuY05hbWUpOwoJZWxzZQoJCVRSQUNFKCIoJWQpXG4iLChpbnQpZnVuY05hbWUpOwoJaWYgKCFleHBvcnRzKSB7CgkJLyogTm90IGEgZmF0YWwgcHJvYmxlbSwgc29tZSBhcHBzIGRvCgkJICogR2V0UHJvY0FkZHJlc3MoMCwiUmVnaXN0ZXJQZW5BcHAiKSB3aGljaCB0cmlnZ2VycyB0aGlzCgkJICogY2FzZS4KCQkgKi8KCQlXQVJOKCJNb2R1bGUgJTA4eCglcykvTU9EUkVGICVwIGRvZXNuJ3QgaGF2ZSBhIGV4cG9ydHMgdGFibGUuXG4iLHdtLT5tb2R1bGUsd20tPm1vZG5hbWUsd20pOwoJCXJldHVybiBOVUxMOwoJfQoJb3JkaW5hbHM9ICh1X3Nob3J0KikgIFJWQShleHBvcnRzLT5BZGRyZXNzT2ZOYW1lT3JkaW5hbHMpOwoJZnVuY3Rpb249ICh1X2xvbmcqKSAgIFJWQShleHBvcnRzLT5BZGRyZXNzT2ZGdW5jdGlvbnMpOwoJbmFtZQk9ICh1X2NoYXIgKiopIFJWQShleHBvcnRzLT5BZGRyZXNzT2ZOYW1lcyk7Cglmb3J3YXJkID0gTlVMTDsKCXJ2YV9zdGFydCA9IFBFX0hFQURFUih3bS0+bW9kdWxlKS0+T3B0aW9uYWxIZWFkZXIKCQkuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhQT1JUXS5WaXJ0dWFsQWRkcmVzczsKCXJ2YV9lbmQgPSBydmFfc3RhcnQgKyBQRV9IRUFERVIod20tPm1vZHVsZSktPk9wdGlvbmFsSGVhZGVyCgkJLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVF0uU2l6ZTsKCglpZiAoSElXT1JEKGZ1bmNOYW1lKSkKICAgICAgICB7CiAgICAgICAgICAgIC8qIGZpcnN0IHRyeSBhIGJpbmFyeSBzZWFyY2ggKi8KICAgICAgICAgICAgaW50IG1pbiA9IDAsIG1heCA9IGV4cG9ydHMtPk51bWJlck9mTmFtZXMgLSAxOwogICAgICAgICAgICB3aGlsZSAobWluIDw9IG1heCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaW50IHJlcywgcG9zID0gKG1pbiArIG1heCkgLyAyOwogICAgICAgICAgICAgICAgZW5hbWUgPSBSVkEobmFtZVtwb3NdKTsKICAgICAgICAgICAgICAgIGlmICghKHJlcyA9IHN0cmNtcCggZW5hbWUsIGZ1bmNOYW1lICkpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIG9yZGluYWwgPSBvcmRpbmFsc1twb3NdOwogICAgICAgICAgICAgICAgICAgIGdvdG8gZm91bmQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAocmVzID4gMCkgbWF4ID0gcG9zIC0gMTsKICAgICAgICAgICAgICAgIGVsc2UgbWluID0gcG9zICsgMTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvKiBub3cgdHJ5IGEgbGluZWFyIHNlYXJjaCBpbiBjYXNlIHRoZSBuYW1lcyBhcmVuJ3Qgc29ydGVkIHByb3Blcmx5ICovCiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBleHBvcnRzLT5OdW1iZXJPZk5hbWVzOyBpKyspCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGVuYW1lID0gUlZBKG5hbWVbaV0pOwogICAgICAgICAgICAgICAgaWYgKCFzdHJjbXAoIGVuYW1lLCBmdW5jTmFtZSApKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEVSUiggIiVzLiVzIHJlcXVpcmVkIGEgbGluZWFyIHNlYXJjaFxuIiwgd20tPm1vZG5hbWUsIGZ1bmNOYW1lICk7CiAgICAgICAgICAgICAgICAgICAgb3JkaW5hbCA9IG9yZGluYWxzW2ldOwogICAgICAgICAgICAgICAgICAgIGdvdG8gZm91bmQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIE5VTEw7Cgl9CiAgICAgICAgZWxzZSAgLyogZmluZCBieSBvcmRpbmFsICovCiAgICAgICAgewogICAgICAgICAgICBvcmRpbmFsID0gTE9XT1JEKGZ1bmNOYW1lKSAtIGV4cG9ydHMtPkJhc2U7CiAgICAgICAgICAgIGlmIChzbm9vcCAmJiBuYW1lKSAgLyogbmVlZCB0byBmaW5kIGEgbmFtZSBmb3IgaXQgKi8KICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGV4cG9ydHMtPk51bWJlck9mTmFtZXM7IGkrKykKICAgICAgICAgICAgICAgICAgICBpZiAob3JkaW5hbHNbaV0gPT0gb3JkaW5hbCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGVuYW1lID0gUlZBKG5hbWVbaV0pOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCX0KCiBmb3VuZDoKICAgICAgICBpZiAob3JkaW5hbCA+PSBleHBvcnRzLT5OdW1iZXJPZkZ1bmN0aW9ucykKICAgICAgICB7CiAgICAgICAgICAgIFRSQUNFKCIJb3JkaW5hbCAlbGQgb3V0IG9mIHJhbmdlIVxuIiwgb3JkaW5hbCArIGV4cG9ydHMtPkJhc2UgKTsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgfQogICAgICAgIGFkZHIgPSBmdW5jdGlvbltvcmRpbmFsXTsKICAgICAgICBpZiAoIWFkZHIpIHJldHVybiBOVUxMOwogICAgICAgIGlmICgoYWRkciA8IHJ2YV9zdGFydCkgfHwgKGFkZHIgPj0gcnZhX2VuZCkpCiAgICAgICAgewogICAgICAgICAgICBGQVJQUk9DIHByb2MgPSBSVkEoYWRkcik7CiAgICAgICAgICAgIGlmIChzbm9vcCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCFlbmFtZSkgZW5hbWUgPSAiQCI7CiAgICAgICAgICAgICAgICBwcm9jID0gU05PT1BfR2V0UHJvY0FkZHJlc3Mod20tPm1vZHVsZSxlbmFtZSxvcmRpbmFsLHByb2MpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBwcm9jOwogICAgICAgIH0KICAgICAgICBlbHNlICAvKiBmb3J3YXJkIGVudHJ5IHBvaW50ICovCiAgICAgICAgewogICAgICAgICAgICAgICAgV0lORV9NT0RSRUYgKndtOwogICAgICAgICAgICAgICAgRkFSUFJPQyBwcm9jOwogICAgICAgICAgICAgICAgY2hhciAqZm9yd2FyZCA9IFJWQShhZGRyKTsKCQljaGFyIG1vZHVsZVsyNTZdOwoJCWNoYXIgKmVuZCA9IHN0cmNocihmb3J3YXJkLCAnLicpOwoKCQlpZiAoIWVuZCkgcmV0dXJuIE5VTEw7CiAgICAgICAgICAgICAgICBpZiAoZW5kIC0gZm9yd2FyZCA+PSBzaXplb2YobW9kdWxlKSkgcmV0dXJuIE5VTEw7CiAgICAgICAgICAgICAgICBtZW1jcHkoIG1vZHVsZSwgZm9yd2FyZCwgZW5kIC0gZm9yd2FyZCApOwoJCW1vZHVsZVtlbmQtZm9yd2FyZF0gPSAwOwogICAgICAgICAgICAgICAgaWYgKCEod20gPSBNT0RVTEVfRmluZE1vZHVsZSggbW9kdWxlICkpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEVSUigibW9kdWxlIG5vdCBmb3VuZCBmb3IgZm9yd2FyZCAnJXMnXG4iLCBmb3J3YXJkICk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgICAgICAgICB9CgkJaWYgKCEocHJvYyA9IE1PRFVMRV9HZXRQcm9jQWRkcmVzcyggd20tPm1vZHVsZSwgZW5kICsgMSwgc25vb3AgKSkpCiAgICAgICAgICAgICAgICAgICAgRVJSKCJmdW5jdGlvbiBub3QgZm91bmQgZm9yIGZvcndhcmQgJyVzJ1xuIiwgZm9yd2FyZCApOwoJCXJldHVybiBwcm9jOwoJfQp9CgpEV09SRCBmaXh1cF9pbXBvcnRzKCBXSU5FX01PRFJFRiAqd20gKQp7CiAgICBJTUFHRV9JTVBPUlRfREVTQ1JJUFRPUgkqcGVfaW1wOwogICAgdW5zaWduZWQgaW50IGxvYWRfYWRkcgk9IHdtLT5tb2R1bGU7CiAgICBpbnQJCQkJaSxjaGFyYWN0ZXJpc3RpY3NfZGV0ZWN0aW9uPTE7CiAgICBjaGFyCQkJKm1vZG5hbWU7CiAgICBJTUFHRV9FWFBPUlRfRElSRUNUT1JZICpleHBvcnRzID0gZ2V0X2V4cG9ydHMod20tPm1vZHVsZSk7CiAgICBJTUFHRV9JTVBPUlRfREVTQ1JJUFRPUiAqaW1wb3J0cyA9IGdldF9pbXBvcnRzKHdtLT5tb2R1bGUpOwogICAgCiAgICBpZiAoZXhwb3J0cykKICAgIAltb2RuYW1lID0gKGNoYXIqKSBSVkEoZXhwb3J0cy0+TmFtZSk7CiAgICBlbHNlCiAgICAgICAgbW9kbmFtZSA9ICI8dW5rbm93bj4iOwoKICAgIC8qIGZpcnN0LCBjb3VudCB0aGUgbnVtYmVyIG9mIGltcG9ydGVkIG5vbi1pbnRlcm5hbCBtb2R1bGVzICovCiAgICBwZV9pbXAgPSBpbXBvcnRzOwogICAgaWYgKCFwZV9pbXApIHJldHVybiAwOwoKICAgIC8qIE9LLCBub3cgZHVtcCB0aGUgaW1wb3J0IGxpc3QgKi8KICAgIFRSQUNFKCJEdW1waW5nIGltcG9ydHMgbGlzdFxuIik7CgogICAgLyogV2UgYXNzdW1lIHRoYXQgd2UgaGF2ZSBhdCBsZWFzdCBvbmUgaW1wb3J0IHdpdGggITAgY2hhcmFjdGVyaXN0aWNzIGFuZAogICAgICogZGV0ZWN0IGJyb2tlbiBpbXBvcnRzIHdpdGggYWxsIGNoYXJhY3RlcmlzdGljcyAwIChub3RhYmx5IEJvcmxhbmQpIGFuZAogICAgICogc3dpdGNoIHRoZSBkZXRlY3Rpb24gb2ZmIGZvciB0aGVtLgogICAgICovCiAgICBmb3IgKGkgPSAwOyBwZV9pbXAtPk5hbWUgOyBwZV9pbXArKykgewoJaWYgKCFpICYmICFwZV9pbXAtPnUuQ2hhcmFjdGVyaXN0aWNzKQoJCWNoYXJhY3RlcmlzdGljc19kZXRlY3Rpb24gPSAwOwoJaWYgKGNoYXJhY3RlcmlzdGljc19kZXRlY3Rpb24gJiYgIXBlX2ltcC0+dS5DaGFyYWN0ZXJpc3RpY3MpCgkJYnJlYWs7CglpKys7CiAgICB9CiAgICBpZiAoIWkpIHJldHVybiAwOyAgLyogbm8gaW1wb3J0cyAqLwoKICAgIC8qIEFsbG9jYXRlIG1vZHVsZSBkZXBlbmRlbmN5IGxpc3QgKi8KICAgIHdtLT5uRGVwcyA9IGk7CiAgICB3bS0+ZGVwcyAgPSBIZWFwQWxsb2MoIEdldFByb2Nlc3NIZWFwKCksIDAsIGkqc2l6ZW9mKFdJTkVfTU9EUkVGICopICk7CgogICAgLyogbG9hZCB0aGUgaW1wb3J0ZWQgbW9kdWxlcy4gVGhleSBhcmUgYXV0b21hdGljYWxseSAKICAgICAqIGFkZGVkIHRvIHRoZSBtb2RyZWYgbGlzdCBvZiB0aGUgcHJvY2Vzcy4KICAgICAqLwogCiAgICBmb3IgKGkgPSAwLCBwZV9pbXAgPSBpbXBvcnRzOyBwZV9pbXAtPk5hbWUgOyBwZV9pbXArKykgewogICAgCVdJTkVfTU9EUkVGCQkqd21JbXA7CglJTUFHRV9JTVBPUlRfQllfTkFNRQkqcGVfbmFtZTsKCVBJTUFHRV9USFVOS19EQVRBCWltcG9ydF9saXN0LHRodW5rX2xpc3Q7CiAJY2hhcgkJCSpuYW1lID0gKGNoYXIgKikgUlZBKHBlX2ltcC0+TmFtZSk7CgoJaWYgKGNoYXJhY3RlcmlzdGljc19kZXRlY3Rpb24gJiYgIXBlX2ltcC0+dS5DaGFyYWN0ZXJpc3RpY3MpCgkJYnJlYWs7CgoJd21JbXAgPSBNT0RVTEVfTG9hZExpYnJhcnlFeEEoIG5hbWUsIDAsIDAgKTsKCWlmICghd21JbXApIHsKCSAgICBFUlJfKG1vZHVsZSkoIk1vZHVsZSAoZmlsZSkgJXMgbmVlZGVkIGJ5ICVzIG5vdCBmb3VuZFxuIiwgbmFtZSwgd20tPmZpbGVuYW1lKTsKCSAgICByZXR1cm4gMTsKCX0KICAgICAgICB3bS0+ZGVwc1tpKytdID0gd21JbXA7CgoJLyogRklYTUU6IGZvcndhcmRlciBlbnRyaWVzIC4uLiAqLwoKCWlmIChwZV9pbXAtPnUuT3JpZ2luYWxGaXJzdFRodW5rICE9IDApIHsgLyogb3JpZ2luYWwgTVMgc3R5bGUgKi8KCSAgICBUUkFDRSgiTWljcm9zb2Z0IHN0eWxlIGltcG9ydHMgdXNlZFxuIik7CgkgICAgaW1wb3J0X2xpc3QgPShQSU1BR0VfVEhVTktfREFUQSkgUlZBKHBlX2ltcC0+dS5PcmlnaW5hbEZpcnN0VGh1bmspOwoJICAgIHRodW5rX2xpc3QgPSAoUElNQUdFX1RIVU5LX0RBVEEpIFJWQShwZV9pbXAtPkZpcnN0VGh1bmspOwoKCSAgICB3aGlsZSAoaW1wb3J0X2xpc3QtPnUxLk9yZGluYWwpIHsKCQlpZiAoSU1BR0VfU05BUF9CWV9PUkRJTkFMKGltcG9ydF9saXN0LT51MS5PcmRpbmFsKSkgewoJCSAgICBpbnQgb3JkaW5hbCA9IElNQUdFX09SRElOQUwoaW1wb3J0X2xpc3QtPnUxLk9yZGluYWwpOwoKCQkgICAgVFJBQ0UoIi0tLSBPcmRpbmFsICVzLCVkXG4iLCBuYW1lLCBvcmRpbmFsKTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249TU9EVUxFX0dldFByb2NBZGRyZXNzKAogICAgICAgICAgICAgICAgICAgICAgICB3bUltcC0+bW9kdWxlLCAoTFBDU1RSKW9yZGluYWwsIFRSVUUKCQkgICAgKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCQlFUlIoIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCwgc2V0dGluZyB0byAweGRlYWRiZWVmXG4iLAoJCQkJbmFtZSwgb3JkaW5hbCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uID0gKEZBUlBST0MpMHhkZWFkYmVlZjsKCQkgICAgfQoJCX0gZWxzZSB7CQkvKiBpbXBvcnQgYnkgbmFtZSAqLwoJCSAgICBwZV9uYW1lID0gKFBJTUFHRV9JTVBPUlRfQllfTkFNRSlSVkEoaW1wb3J0X2xpc3QtPnUxLkFkZHJlc3NPZkRhdGEpOwoJCSAgICBUUkFDRSgiLS0tICVzICVzLiVkXG4iLCBwZV9uYW1lLT5OYW1lLCBuYW1lLCBwZV9uYW1lLT5IaW50KTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249TU9EVUxFX0dldFByb2NBZGRyZXNzKAogICAgICAgICAgICAgICAgICAgICAgICB3bUltcC0+bW9kdWxlLCBwZV9uYW1lLT5OYW1lLCBUUlVFCgkJICAgICk7CgkJICAgIGlmICghdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24pIHsKCQkJRVJSKCJObyBpbXBsZW1lbnRhdGlvbiBmb3IgJXMuJWQoJXMpLCBzZXR0aW5nIHRvIDB4ZGVhZGJlZWZcbiIsCgkJCQluYW1lLHBlX25hbWUtPkhpbnQscGVfbmFtZS0+TmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uID0gKEZBUlBST0MpMHhkZWFkYmVlZjsKCQkgICAgfQoJCX0KCQlpbXBvcnRfbGlzdCsrOwoJCXRodW5rX2xpc3QrKzsKCSAgICB9Cgl9IGVsc2UgewkvKiBCb3JsYW5kIHN0eWxlICovCgkgICAgVFJBQ0UoIkJvcmxhbmQgc3R5bGUgaW1wb3J0cyB1c2VkXG4iKTsKCSAgICB0aHVua19saXN0ID0gKFBJTUFHRV9USFVOS19EQVRBKSBSVkEocGVfaW1wLT5GaXJzdFRodW5rKTsKCSAgICB3aGlsZSAodGh1bmtfbGlzdC0+dTEuT3JkaW5hbCkgewoJCWlmIChJTUFHRV9TTkFQX0JZX09SRElOQUwodGh1bmtfbGlzdC0+dTEuT3JkaW5hbCkpIHsKCQkgICAgLyogbm90IHN1cmUgYWJvdXQgdGhpcyBicmFuY2gsIGJ1dCBpdCBzZWVtcyB0byB3b3JrICovCgkJICAgIGludCBvcmRpbmFsID0gSU1BR0VfT1JESU5BTCh0aHVua19saXN0LT51MS5PcmRpbmFsKTsKCgkJICAgIFRSQUNFKCItLS0gT3JkaW5hbCAlcy4lZFxuIixuYW1lLG9yZGluYWwpOwoJCSAgICB0aHVua19saXN0LT51MS5GdW5jdGlvbj1NT0RVTEVfR2V0UHJvY0FkZHJlc3MoCiAgICAgICAgICAgICAgICAgICAgICAgIHdtSW1wLT5tb2R1bGUsIChMUENTVFIpIG9yZGluYWwsIFRSVUUKCQkgICAgKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCQlFUlIoIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCwgc2V0dGluZyB0byAweGRlYWRiZWVmXG4iLAoJCQkJbmFtZSxvcmRpbmFsKTsKICAgICAgICAgICAgICAgICAgICAgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24gPSAoRkFSUFJPQykweGRlYWRiZWVmOwoJCSAgICB9CgkJfSBlbHNlIHsKCQkgICAgcGVfbmFtZT0oUElNQUdFX0lNUE9SVF9CWV9OQU1FKSBSVkEodGh1bmtfbGlzdC0+dTEuQWRkcmVzc09mRGF0YSk7CgkJICAgIFRSQUNFKCItLS0gJXMgJXMuJWRcbiIsCgkJICAgCQkgIHBlX25hbWUtPk5hbWUsbmFtZSxwZV9uYW1lLT5IaW50KTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249TU9EVUxFX0dldFByb2NBZGRyZXNzKAogICAgICAgICAgICAgICAgICAgICAgICB3bUltcC0+bW9kdWxlLCBwZV9uYW1lLT5OYW1lLCBUUlVFCgkJICAgICk7CgkJICAgIGlmICghdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24pIHsKCQkgICAgCUVSUigiTm8gaW1wbGVtZW50YXRpb24gZm9yICVzLiVkLCBzZXR0aW5nIHRvIDB4ZGVhZGJlZWZcbiIsCgkJCQluYW1lLCBwZV9uYW1lLT5IaW50KTsKICAgICAgICAgICAgICAgICAgICAgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24gPSAoRkFSUFJPQykweGRlYWRiZWVmOwoJCSAgICB9CgkJfQoJCXRodW5rX2xpc3QrKzsKCSAgICB9Cgl9CiAgICB9CiAgICByZXR1cm4gMDsKfQoKc3RhdGljIGludCBjYWxjX3ZtYV9zaXplKCBITU9EVUxFIGhNb2R1bGUgKQp7CiAgICBpbnQgaSx2bWFfc2l6ZSA9IDA7CiAgICBJTUFHRV9TRUNUSU9OX0hFQURFUiAqcGVfc2VnID0gUEVfU0VDVElPTlMoaE1vZHVsZSk7CgogICAgVFJBQ0UoIkR1bXAgb2Ygc2VnbWVudCB0YWJsZVxuIik7CiAgICBUUkFDRSgiICAgTmFtZSAgICBWU3ogIFZhZGRyICAgICBTelJhdyAgIEZpbGVhZHIgICpSZWxvYyAqTGluZXVtICNSZWxvYyAjTGludW0gQ2hhclxuIik7CiAgICBmb3IgKGkgPSAwOyBpPCBQRV9IRUFERVIoaE1vZHVsZSktPkZpbGVIZWFkZXIuTnVtYmVyT2ZTZWN0aW9uczsgaSsrKQogICAgewogICAgICAgIFRSQUNFKCIlOHM6ICU0LjRseCAlOC44bHggJTguOGx4ICU4LjhseCAlOC44bHggJTguOGx4ICU0LjR4ICU0LjR4ICU4LjhseFxuIiwgCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPk5hbWUsIAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5NaXNjLlZpcnR1YWxTaXplLAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5WaXJ0dWFsQWRkcmVzcywKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+U2l6ZU9mUmF3RGF0YSwKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+UG9pbnRlclRvUmF3RGF0YSwKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+UG9pbnRlclRvUmVsb2NhdGlvbnMsCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPlBvaW50ZXJUb0xpbmVudW1iZXJzLAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5OdW1iZXJPZlJlbG9jYXRpb25zLAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5OdW1iZXJPZkxpbmVudW1iZXJzLAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5DaGFyYWN0ZXJpc3RpY3MpOwogICAgICAgIHZtYV9zaXplPW1heCh2bWFfc2l6ZSwgcGVfc2VnLT5WaXJ0dWFsQWRkcmVzcytwZV9zZWctPlNpemVPZlJhd0RhdGEpOwogICAgICAgIHZtYV9zaXplPW1heCh2bWFfc2l6ZSwgcGVfc2VnLT5WaXJ0dWFsQWRkcmVzcytwZV9zZWctPk1pc2MuVmlydHVhbFNpemUpOwogICAgICAgIHBlX3NlZysrOwogICAgfQogICAgcmV0dXJuIHZtYV9zaXplOwp9CgpzdGF0aWMgdm9pZCBkb19yZWxvY2F0aW9ucyggdW5zaWduZWQgaW50IGxvYWRfYWRkciwgSU1BR0VfQkFTRV9SRUxPQ0FUSU9OICpyICkKewogICAgaW50IGRlbHRhID0gbG9hZF9hZGRyIC0gUEVfSEVBREVSKGxvYWRfYWRkciktPk9wdGlvbmFsSGVhZGVyLkltYWdlQmFzZTsKICAgIGludAloZGVsdGEgPSAoZGVsdGEgPj4gMTYpICYgMHhGRkZGOwogICAgaW50CWxkZWx0YSA9IGRlbHRhICYgMHhGRkZGOwoKCWlmKGRlbHRhID09IDApCgkJLyogTm90aGluZyB0byBkbyAqLwoJCXJldHVybjsKCXdoaWxlKHItPlZpcnR1YWxBZGRyZXNzKQoJewoJCWNoYXIgKnBhZ2UgPSAoY2hhciopIFJWQShyLT5WaXJ0dWFsQWRkcmVzcyk7CgkJaW50IGNvdW50ID0gKHItPlNpemVPZkJsb2NrIC0gOCkvMjsKCQlpbnQgaTsKCQlUUkFDRV8oZml4dXApKCIleCByZWxvY2F0aW9ucyBmb3IgcGFnZSAlbHhcbiIsCgkJCWNvdW50LCByLT5WaXJ0dWFsQWRkcmVzcyk7CgkJLyogcGF0Y2hpbmcgaW4gcmV2ZXJzZSBvcmRlciAqLwoJCWZvcihpPTA7aTxjb3VudDtpKyspCgkJewoJCQlpbnQgb2Zmc2V0ID0gci0+VHlwZU9mZnNldFtpXSAmIDB4RkZGOwoJCQlpbnQgdHlwZSA9IHItPlR5cGVPZmZzZXRbaV0gPj4gMTI7CgkJCVRSQUNFXyhmaXh1cCkoInBhdGNoaW5nICV4IHR5cGUgJXhcbiIsIG9mZnNldCwgdHlwZSk7CgkJCXN3aXRjaCh0eXBlKQoJCQl7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0FCU09MVVRFOiBicmVhazsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfSElHSDoKCQkJCSooc2hvcnQqKShwYWdlK29mZnNldCkgKz0gaGRlbHRhOwoJCQkJYnJlYWs7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0xPVzoKCQkJCSooc2hvcnQqKShwYWdlK29mZnNldCkgKz0gbGRlbHRhOwoJCQkJYnJlYWs7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0hJR0hMT1c6CgkJCQkqKGludCopKHBhZ2Urb2Zmc2V0KSArPSBkZWx0YTsKCQkJCS8qIEZJWE1FOiBpZiB0aGlzIGlzIGFuIGV4cG9ydGVkIGFkZHJlc3MsIGZpcmUgdXAgZW5oYW5jZWQgbG9naWMgKi8KCQkJCWJyZWFrOwoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9ISUdIQURKOgoJCQkJRklYTUUoIkRvbid0IGtub3cgd2hhdCB0byBkbyB3aXRoIElNQUdFX1JFTF9CQVNFRF9ISUdIQURKXG4iKTsKCQkJCWJyZWFrOwoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9NSVBTX0pNUEFERFI6CgkJCQlGSVhNRSgiSXMgdGhpcyBhIE1JUFMgbWFjaGluZSA/Pz9cbiIpOwoJCQkJYnJlYWs7CgkJCWRlZmF1bHQ6CgkJCQlGSVhNRSgiVW5rbm93biBmaXh1cCB0eXBlICVkLlxuIiwgdHlwZSk7CgkJCQlicmVhazsKCQkJfQoJCX0KCQlyID0gKElNQUdFX0JBU0VfUkVMT0NBVElPTiopKChjaGFyKilyICsgci0+U2l6ZU9mQmxvY2spOwoJfQp9CgkJCgoJCgkKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQkJUEVfTG9hZEltYWdlCiAqIExvYWQgb25lIFBFIGZvcm1hdCBETEwvRVhFIGludG8gbWVtb3J5CiAqIAogKiBVbmx1Y2tpbHkgd2UgY2FuJ3QganVzdCBtbWFwIHRoZSBzZWN0aW9ucyB3aGVyZSB3ZSB3YW50IHRoZW0sIGZvciAKICogKGF0IGxlYXN0KSBMaW51eCBkb2VzIG9ubHkgc3VwcG9ydCBvZmZzZXRzIHdoaWNoIGFyZSBwYWdlLWFsaWduZWQuCiAqCiAqIEJVVCB3ZSBoYXZlIHRvIG1hcCB0aGUgd2hvbGUgaW1hZ2UgYW55d2F5LCBmb3IgV2luMzIgcHJvZ3JhbXMgc29tZXRpbWVzCiAqIHdhbnQgdG8gYWNjZXNzIHRoZW0uIChITU9EVUxFMzIgcG9pbnQgdG8gdGhlIHN0YXJ0IG9mIGl0KQogKi8KSE1PRFVMRSBQRV9Mb2FkSW1hZ2UoIEhBTkRMRSBoRmlsZSwgTFBDU1RSIGZpbGVuYW1lLCBEV09SRCBmbGFncyApCnsKICAgIEhNT0RVTEUJaE1vZHVsZTsKICAgIEhBTkRMRQltYXBwaW5nOwoKICAgIElNQUdFX05UX0hFQURFUlMgKm50OwogICAgSU1BR0VfU0VDVElPTl9IRUFERVIgKnBlX3NlYzsKICAgIElNQUdFX0RBVEFfRElSRUNUT1JZICpkaXI7CiAgICBCWV9IQU5ETEVfRklMRV9JTkZPUk1BVElPTiBiaGZpOwogICAgaW50CWksIHJhd3NpemUsIGxvd2VzdF92YSwgdm1hX3NpemUsIGZpbGVfc2l6ZSA9IDA7CiAgICBEV09SRCBsb2FkX2FkZHIgPSAwLCBhb2VwLCByZWxvYyA9IDA7CiAgICBzdHJ1Y3QgZ2V0X3JlYWRfZmRfcmVxdWVzdCAqcmVxID0gZ2V0X3JlcV9idWZmZXIoKTsKICAgIGludCB1bml4X2hhbmRsZSA9IC0xOwogICAgaW50IHBhZ2Vfc2l6ZSA9IFZJUlRVQUxfR2V0UGFnZVNpemUoKTsKCiAgICAvKiBSZXRyaWV2ZSBmaWxlIHNpemUgKi8KICAgIGlmICggR2V0RmlsZUluZm9ybWF0aW9uQnlIYW5kbGUoIGhGaWxlLCAmYmhmaSApICkgCiAgICAJZmlsZV9zaXplID0gYmhmaS5uRmlsZVNpemVMb3c7IC8qIEZJWE1FOiA2NCBiaXQgKi8KCiAgICAvKiBNYXAgdGhlIFBFIGZpbGUgc29tZXdoZXJlICovCiAgICBtYXBwaW5nID0gQ3JlYXRlRmlsZU1hcHBpbmdBKCBoRmlsZSwgTlVMTCwgUEFHRV9SRUFET05MWSB8IFNFQ19DT01NSVQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsIE5VTEwgKTsKICAgIGlmICghbWFwcGluZykKICAgIHsKICAgICAgICBXQVJOKCJDcmVhdGVGaWxlTWFwcGluZyBlcnJvciAlbGRcbiIsIEdldExhc3RFcnJvcigpICk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CiAgICBoTW9kdWxlID0gKEhNT0RVTEUpTWFwVmlld09mRmlsZSggbWFwcGluZywgRklMRV9NQVBfUkVBRCwgMCwgMCwgMCApOwogICAgQ2xvc2VIYW5kbGUoIG1hcHBpbmcgKTsKICAgIGlmICghaE1vZHVsZSkKICAgIHsKICAgICAgICBXQVJOKCJNYXBWaWV3T2ZGaWxlIGVycm9yICVsZFxuIiwgR2V0TGFzdEVycm9yKCkgKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KICAgIGlmICggKihXT1JEKiloTW9kdWxlICE9SU1BR0VfRE9TX1NJR05BVFVSRSkKICAgIHsKICAgICAgICBXQVJOKCIlcyBpbWFnZSBkb2Vzbid0IGhhdmUgRE9TIHNpZ25hdHVyZSwgYnV0IDB4JTA0eFxuIiwgZmlsZW5hbWUsKihXT1JEKiloTW9kdWxlKTsKICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX0JBRF9FWEVfRk9STUFUICk7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICBudCA9IFBFX0hFQURFUiggaE1vZHVsZSApOwoKICAgIC8qIENoZWNrIHNpZ25hdHVyZSAqLwogICAgaWYgKCBudC0+U2lnbmF0dXJlICE9IElNQUdFX05UX1NJR05BVFVSRSApCiAgICB7CiAgICAgICAgV0FSTigiJXMgaW1hZ2UgZG9lc24ndCBoYXZlIFBFIHNpZ25hdHVyZSwgYnV0IDB4JTA4bHhcbiIsIGZpbGVuYW1lLCBudC0+U2lnbmF0dXJlICk7CiAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9CQURfRVhFX0ZPUk1BVCApOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgLyogQ2hlY2sgYXJjaGl0ZWN0dXJlICovCiAgICBpZiAoIG50LT5GaWxlSGVhZGVyLk1hY2hpbmUgIT0gSU1BR0VfRklMRV9NQUNISU5FX0kzODYgKQogICAgewogICAgICAgIE1FU1NBR0UoIlRyeWluZyB0byBsb2FkIFBFIGltYWdlIGZvciB1bnN1cHBvcnRlZCBhcmNoaXRlY3R1cmUgKCIpOwogICAgICAgIHN3aXRjaCAobnQtPkZpbGVIZWFkZXIuTWFjaGluZSkKICAgICAgICB7CiAgICAgICAgY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfVU5LTk9XTjogTUVTU0FHRSgiVW5rbm93biIpOyBicmVhazsKICAgICAgICBjYXNlIElNQUdFX0ZJTEVfTUFDSElORV9JODYwOiAgICBNRVNTQUdFKCJJODYwIik7IGJyZWFrOwogICAgICAgIGNhc2UgSU1BR0VfRklMRV9NQUNISU5FX1IzMDAwOiAgIE1FU1NBR0UoIlIzMDAwIik7IGJyZWFrOwogICAgICAgIGNhc2UgSU1BR0VfRklMRV9NQUNISU5FX1I0MDAwOiAgIE1FU1NBR0UoIlI0MDAwIik7IGJyZWFrOwogICAgICAgIGNhc2UgSU1BR0VfRklMRV9NQUNISU5FX1IxMDAwMDogIE1FU1NBR0UoIlIxMDAwMCIpOyBicmVhazsKICAgICAgICBjYXNlIElNQUdFX0ZJTEVfTUFDSElORV9BTFBIQTogICBNRVNTQUdFKCJBbHBoYSIpOyBicmVhazsKICAgICAgICBjYXNlIElNQUdFX0ZJTEVfTUFDSElORV9QT1dFUlBDOiBNRVNTQUdFKCJQb3dlclBDIik7IGJyZWFrOwogICAgICAgIGRlZmF1bHQ6IE1FU1NBR0UoIlVua25vd24tJTA0eCIsIG50LT5GaWxlSGVhZGVyLk1hY2hpbmUpOyBicmVhazsKICAgICAgICB9CiAgICAgICAgTUVTU0FHRSgiKVxuIik7CiAgICAgICAgU2V0TGFzdEVycm9yKCBFUlJPUl9CQURfRVhFX0ZPUk1BVCApOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgLyogRmluZCBvdXQgaG93IGxhcmdlIHRoaXMgZXhlY3V0ZWFibGUgc2hvdWxkIGJlICovCiAgICBwZV9zZWMgPSBQRV9TRUNUSU9OUyggaE1vZHVsZSApOwogICAgcmF3c2l6ZSA9IDA7IGxvd2VzdF92YSA9IDB4MTAwMDA7CiAgICBmb3IgKGkgPSAwOyBpIDwgbnQtPkZpbGVIZWFkZXIuTnVtYmVyT2ZTZWN0aW9uczsgaSsrKSAKICAgIHsKICAgICAgICBpZiAobG93ZXN0X3ZhID4gcGVfc2VjW2ldLlZpcnR1YWxBZGRyZXNzKQogICAgICAgICAgIGxvd2VzdF92YSA9IHBlX3NlY1tpXS5WaXJ0dWFsQWRkcmVzczsKICAgIAlpZiAocGVfc2VjW2ldLkNoYXJhY3RlcmlzdGljcyAmIElNQUdFX1NDTl9DTlRfVU5JTklUSUFMSVpFRF9EQVRBKQoJICAgIGNvbnRpbnVlOwoJaWYgKHBlX3NlY1tpXS5Qb2ludGVyVG9SYXdEYXRhK3BlX3NlY1tpXS5TaXplT2ZSYXdEYXRhID4gcmF3c2l6ZSkKCSAgICByYXdzaXplID0gcGVfc2VjW2ldLlBvaW50ZXJUb1Jhd0RhdGErcGVfc2VjW2ldLlNpemVPZlJhd0RhdGE7CiAgICB9CiAKICAgIC8qIENoZWNrIGZpbGUgc2l6ZSAqLwogICAgaWYgKCBmaWxlX3NpemUgJiYgZmlsZV9zaXplIDwgcmF3c2l6ZSApCiAgICB7CiAgICAgICAgRVJSKCJQRSBtb2R1bGUgaXMgdG9vIHNtYWxsIChoZWFkZXI6ICVkLCBmaWxlc2l6ZTogJWQpLCAiCiAgICAgICAgICAgICAgICAgICAgInByb2JhYmx5IHRydW5jYXRlZCBkb3dubG9hZD9cbiIsIAogICAgICAgICAgICAgICAgICAgIHJhd3NpemUsIGZpbGVfc2l6ZSApOwogICAgICAgIFNldExhc3RFcnJvciggRVJST1JfQkFEX0VYRV9GT1JNQVQgKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIC8qIENoZWNrIGVudHJ5cG9pbnQgYWRkcmVzcyAqLwogICAgYW9lcCA9IG50LT5PcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50OwogICAgaWYgKGFvZXAgJiYgKGFvZXAgPCBsb3dlc3RfdmEpKQogICAgICAgIE1FU1NBR0UoIlZJUlVTIFdBUk5JTkc6ICclcycgaGFzIGFuIGludmFsaWQgZW50cnlwb2ludCAoMHglMDhseCkgIgogICAgICAgICAgICAgICAgICAgICAgImJlbG93IHRoZSBmaXJzdCB2aXJ0dWFsIGFkZHJlc3MgKDB4JTA4eCkgIgogICAgICAgICAgICAgICAgICAgICAgIihwb3NzaWJseSBpbmZlY3RlZCBieSBUY2hlcm5vYnlsL1NwYWNlRmlsbGVyIHZpcnVzKSFcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgZmlsZW5hbWUsIGFvZXAsIGxvd2VzdF92YSApOwoKCiNpZiAwCiAgICAvKiBGSVhNRTogIEhhY2shICBXaGlsZSB3ZSBkb24ndCByZWFsbHkgc3VwcG9ydCBzaGFyZWQgc2VjdGlvbnMgeWV0LAogICAgICogICAgICAgICB0aGlzIGNoZWNrcyBmb3IgdGhvc2Ugc3BlY2lhbCBjYXNlcyB3aGVyZSB0aGUgd2hvbGUgRExMCiAgICAgKiAgICAgICAgIGNvbnNpc3RzIG9ubHkgb2Ygc2hhcmVkIHNlY3Rpb25zIGFuZCBpcyBtYXBwZWQgaW50byB0aGUKICAgICAqICAgICAgICAgc2hhcmVkIGFkZHJlc3Mgc3BhY2UgPiAyR0IuICBJbiB0aGlzIGNhc2UsIHdlIGFzc3VtZSB0aGF0CiAgICAgKiAgICAgICAgIHRoZSBtb2R1bGUgZ290IG1hcHBlZCBhdCBpdHMgYmFzZSBhZGRyZXNzLiBUaHVzIHdlIHNpbXBseQogICAgICogICAgICAgICBjaGVjayB3aGV0aGVyIHRoZSBtb2R1bGUgaGFzIGFjdHVhbGx5IGJlZW4gbWFwcGVkIHRoZXJlCiAgICAgKiAgICAgICAgIGFuZCB1c2UgaXQsIGlmIHNvLiAgVGhpcyBpcyBuZWVkZWQgdG8gZ2V0IFdpbjk1IFVTRVIzMi5ETEwKICAgICAqICAgICAgICAgdG8gd29yayAodW50aWwgd2Ugc3VwcG9ydCBzaGFyZWQgc2VjdGlvbnMgcHJvcGVybHkpLgogICAgICovCgogICAgaWYgKCBudC0+T3B0aW9uYWxIZWFkZXIuSW1hZ2VCYXNlICYgMHg4MDAwMDAwMCApCiAgICB7CiAgICAgICAgSE1PRFVMRSBzaGFyZWRNb2QgPSAoSE1PRFVMRSludC0+T3B0aW9uYWxIZWFkZXIuSW1hZ2VCYXNlOyAKICAgICAgICBJTUFHRV9OVF9IRUFERVJTICpzaGFyZWROdCA9IChQSU1BR0VfTlRfSEVBREVSUykKICAgICAgICAgICAgICAgKCAoTFBCWVRFKXNoYXJlZE1vZCArICgoTFBCWVRFKW50IC0gKExQQllURSloTW9kdWxlKSApOwoKICAgICAgICAvKiBXZWxsLCB0aGlzIGNoZWNrIGlzIG5vdCByZWFsbHkgY29tcHJlaGVuc2l2ZSwgCiAgICAgICAgICAgYnV0IHNob3VsZCBiZSBnb29kIGVub3VnaCBmb3Igbm93IC4uLiAqLwogICAgICAgIGlmICggICAgIUlzQmFkUmVhZFB0ciggKExQQllURSlzaGFyZWRNb2QsIHNpemVvZihJTUFHRV9ET1NfSEVBREVSKSApCiAgICAgICAgICAgICAmJiBtZW1jbXAoIChMUEJZVEUpc2hhcmVkTW9kLCAoTFBCWVRFKWhNb2R1bGUsIHNpemVvZihJTUFHRV9ET1NfSEVBREVSKSApID09IDAKICAgICAgICAgICAgICYmICFJc0JhZFJlYWRQdHIoIHNoYXJlZE50LCBzaXplb2YoSU1BR0VfTlRfSEVBREVSUykgKQogICAgICAgICAgICAgJiYgbWVtY21wKCBzaGFyZWROdCwgbnQsIHNpemVvZihJTUFHRV9OVF9IRUFERVJTKSApID09IDAgKQogICAgICAgIHsKICAgICAgICAgICAgVW5tYXBWaWV3T2ZGaWxlKCAoTFBWT0lEKWhNb2R1bGUgKTsKICAgICAgICAgICAgcmV0dXJuIHNoYXJlZE1vZDsKICAgICAgICB9CiAgICB9CiNlbmRpZgoKICAgIC8qIEFsbG9jYXRlIG1lbW9yeSBmb3IgbW9kdWxlICovCiAgICBsb2FkX2FkZHIgPSBudC0+T3B0aW9uYWxIZWFkZXIuSW1hZ2VCYXNlOwogICAgdm1hX3NpemUgPSBjYWxjX3ZtYV9zaXplKCBoTW9kdWxlICk7CgogICAgbG9hZF9hZGRyID0gKERXT1JEKVZpcnR1YWxBbGxvYyggKHZvaWQqKWxvYWRfYWRkciwgdm1hX3NpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNRU1fUkVTRVJWRSB8IE1FTV9DT01NSVQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQQUdFX0VYRUNVVEVfUkVBRFdSSVRFICk7CiAgICBpZiAoIWxvYWRfYWRkcikKICAgIHsKICAgICAgICBsb2FkX2FkZHIgPSAoRFdPUkQpVmlydHVhbEFsbG9jKCBOVUxMLCB2bWFfc2l6ZSwKCQkJCQkgTUVNX1JFU0VSVkUgfCBNRU1fQ09NTUlULAoJCQkJCSBQQUdFX0VYRUNVVEVfUkVBRFdSSVRFICk7CglpZiAoIWxvYWRfYWRkcikKICAgICAgICB7CiAgICAgICAgICAgIEZJWE1FXyh3aW4zMikoCiAgICAgICAgICAgICAgICAgICAiRkFUQUw6IENvdWxkbid0IGxvYWQgbW9kdWxlICVzIChvdXQgb2YgbWVtb3J5LCAlZCBuZWVkZWQpIVxuIiwgZmlsZW5hbWUsIHZtYV9zaXplKTsKICAgICAgICAgICAgZ290byBlcnJvcjsKCX0KICAgIH0KCiAgICBpZiAobG9hZF9hZGRyICE9IG50LT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2UgJiYgIShmbGFncyAmIExPQURfTElCUkFSWV9BU19EQVRBRklMRSkpCiAgICB7CiAgICAgICAgLyogV2UgbmVlZCB0byBwZXJmb3JtIGJhc2UgcmVsb2NhdGlvbnMgKi8KICAgICAgICBXQVJOKCJJbmZvOiBiYXNlIHJlbG9jYXRpb25zIG5lZWRlZCBmb3IgJXNcbiIsIGZpbGVuYW1lKTsKCWRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9CQVNFUkVMT0M7CiAgICAgICAgaWYgKGRpci0+U2l6ZSkKICAgICAgICAgICAgcmVsb2MgPSBkaXItPlZpcnR1YWxBZGRyZXNzOwogICAgICAgIGVsc2UgCiAgICAgICAgewogICAgICAgICAgICBpZiAobnQtPk9wdGlvbmFsSGVhZGVyLkltYWdlQmFzZSA9PSAweDQwMDAwMCkKICAgICAgICAgICAgICAgIEVSUigiU3RhbmRhcmQgbG9hZCBhZGRyZXNzIGZvciBhIFdpbjMyIHByb2dyYW0gbm90IGF2YWlsYWJsZSAtIHBhdGNoZWQga2VybmVsID9cbiIpOwogICAgICAgICAgICBGSVhNRSggIkZBVEFMOiBOZWVkIHRvIHJlbG9jYXRlICVzLCBidXQgbm8gcmVsb2NhdGlvbiByZWNvcmRzIHByZXNlbnQgKCVzKS4gVHJ5IHRvIHJ1biB0aGF0IGZpbGUgZGlyZWN0bHkgIVxuIiwKICAgICAgICAgICAgICAgICAgIGZpbGVuYW1lLAogICAgICAgICAgICAgICAgICAgKG50LT5GaWxlSGVhZGVyLkNoYXJhY3RlcmlzdGljcyZJTUFHRV9GSUxFX1JFTE9DU19TVFJJUFBFRCk/CiAgICAgICAgICAgICAgICAgICAic3RyaXBwZWQgZHVyaW5nIGxpbmsiIDogInVua25vd24gcmVhc29uIiApOwogICAgICAgICAgICBTZXRMYXN0RXJyb3IoIEVSUk9SX0JBRF9FWEVfRk9STUFUICk7CiAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgfQoKICAgICAgICAvKiBGSVhNRTogSWYgd2UgbmVlZCB0byByZWxvY2F0ZSBhIHN5c3RlbSBETEwgKGJhc2UgPiAyR0IpIHdlIHNob3VsZAogICAgICAgICAqICAgICAgICByZWFsbHkgbWFrZSBzdXJlIHRoYXQgdGhlICpuZXcqIGJhc2UgYWRkcmVzcyBpcyBhbHNvID4gMkdCLgogICAgICAgICAqICAgICAgICBTb21lIERMTHMgcmVhbGx5IGNoZWNrIHRoZSBNU0Igb2YgdGhlIG1vZHVsZSBoYW5kbGUgOi0vCiAgICAgICAgICovCiAgICAgICAgaWYgKChudC0+T3B0aW9uYWxIZWFkZXIuSW1hZ2VCYXNlICYgMHg4MDAwMDAwMCkgJiYgIShsb2FkX2FkZHIgJiAweDgwMDAwMDAwKSkKICAgICAgICAgICAgRVJSKCAiRm9yY2VkIHRvIHJlbG9jYXRlIHN5c3RlbSBETEwgKGJhc2UgPiAyR0IpLiBUaGlzIGlzIG5vdCBnb29kLlxuIiApOwogICAgfQoKICAgIFRSQUNFKCJMb2FkIGFkZHIgaXMgJWx4IChiYXNlICVseCksIHJhbmdlICV4XG4iLAogICAgICAgICAgbG9hZF9hZGRyLCBudC0+T3B0aW9uYWxIZWFkZXIuSW1hZ2VCYXNlLCB2bWFfc2l6ZSApOwogICAgVFJBQ0VfKHNlZ21lbnQpKCJMb2FkaW5nICVzIGF0ICVseCwgcmFuZ2UgJXhcbiIsCiAgICAgICAgICAgICAgICAgICAgZmlsZW5hbWUsIGxvYWRfYWRkciwgdm1hX3NpemUgKTsKCiAgICByZXEtPmhhbmRsZSA9IGhGaWxlOwogICAgc2VydmVyX2NhbGxfZmQoIFJFUV9HRVRfUkVBRF9GRCwgLTEsICZ1bml4X2hhbmRsZSApOwogICAgaWYgKHVuaXhfaGFuZGxlID09IC0xKSBnb3RvIGVycm9yOwoKICAgIC8qIE1hcCB0aGUgaGVhZGVyICovCiAgICBpZiAoRklMRV9kb21tYXAoIHVuaXhfaGFuZGxlLCAodm9pZCAqKWxvYWRfYWRkciwgMCwgbnQtPk9wdGlvbmFsSGVhZGVyLlNpemVPZkhlYWRlcnMsCiAgICAgICAgICAgICAgICAgICAgIDAsIDAsIFBST1RfRVhFQyB8IFBST1RfV1JJVEUgfCBQUk9UX1JFQUQsCiAgICAgICAgICAgICAgICAgICAgIE1BUF9QUklWQVRFIHwgTUFQX0ZJWEVEICkgIT0gKHZvaWQqKWxvYWRfYWRkcikKICAgIHsKICAgICAgICBFUlJfKHdpbjMyKSggIkNyaXRpY2FsIEVycm9yOiBmYWlsZWQgdG8gbWFwIFBFIGhlYWRlciB0byBuZWNlc3NhcnkgYWRkcmVzcy5cbiIpOwkKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIC8qIENvcHkgc2VjdGlvbnMgaW50byBtb2R1bGUgaW1hZ2UgKi8KICAgIHBlX3NlYyA9IFBFX1NFQ1RJT05TKCBoTW9kdWxlICk7CiAgICBmb3IgKGkgPSAwOyBpIDwgbnQtPkZpbGVIZWFkZXIuTnVtYmVyT2ZTZWN0aW9uczsgaSsrLCBwZV9zZWMrKykKICAgIHsKICAgICAgICBpZiAoIXBlX3NlYy0+U2l6ZU9mUmF3RGF0YSB8fCAhcGVfc2VjLT5Qb2ludGVyVG9SYXdEYXRhKSBjb250aW51ZTsKICAgICAgICBUUkFDRSgiJXM6IG1tYXBpbmcgc2VjdGlvbiAlcyBhdCAlcCBvZmYgJWx4IHNpemUgJWx4LyVseFxuIiwKICAgICAgICAgICAgICBmaWxlbmFtZSwgcGVfc2VjLT5OYW1lLCAodm9pZCopUlZBKHBlX3NlYy0+VmlydHVhbEFkZHJlc3MpLAogICAgICAgICAgICAgIHBlX3NlYy0+UG9pbnRlclRvUmF3RGF0YSwgcGVfc2VjLT5TaXplT2ZSYXdEYXRhLCBwZV9zZWMtPk1pc2MuVmlydHVhbFNpemUgKTsKICAgICAgICBpZiAoRklMRV9kb21tYXAoIHVuaXhfaGFuZGxlLCAodm9pZCopUlZBKHBlX3NlYy0+VmlydHVhbEFkZHJlc3MpLAogICAgICAgICAgICAgICAgICAgICAgICAgMCwgcGVfc2VjLT5TaXplT2ZSYXdEYXRhLCAwLCBwZV9zZWMtPlBvaW50ZXJUb1Jhd0RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICBQUk9UX0VYRUMgfCBQUk9UX1dSSVRFIHwgUFJPVF9SRUFELAogICAgICAgICAgICAgICAgICAgICAgICAgTUFQX1BSSVZBVEUgfCBNQVBfRklYRUQgKSAhPSAodm9pZCopUlZBKHBlX3NlYy0+VmlydHVhbEFkZHJlc3MpKQogICAgICAgIHsKICAgICAgICAgICAgLyogV2UgZmFpbGVkIHRvIG1hcCB0byB0aGUgcmlnaHQgcGxhY2UgKGh1aD8pICovCiAgICAgICAgICAgIEVSUl8od2luMzIpKCAiQ3JpdGljYWwgRXJyb3I6IGZhaWxlZCB0byBtYXAgUEUgc2VjdGlvbiB0byBuZWNlc3NhcnkgYWRkcmVzcy5cbiIpOwogICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgIH0KICAgICAgICBpZiAoKHBlX3NlYy0+U2l6ZU9mUmF3RGF0YSA8IHBlX3NlYy0+TWlzYy5WaXJ0dWFsU2l6ZSkgJiYKICAgICAgICAgICAgKHBlX3NlYy0+U2l6ZU9mUmF3RGF0YSAmIChwYWdlX3NpemUtMSkpKQogICAgICAgIHsKICAgICAgICAgICAgRFdPUkQgZW5kID0gKHBlX3NlYy0+U2l6ZU9mUmF3RGF0YSAmIH4ocGFnZV9zaXplLTEpKSArIHBhZ2Vfc2l6ZTsKICAgICAgICAgICAgaWYgKGVuZCA+IHBlX3NlYy0+TWlzYy5WaXJ0dWFsU2l6ZSkgZW5kID0gcGVfc2VjLT5NaXNjLlZpcnR1YWxTaXplOwogICAgICAgICAgICBUUkFDRSgiY2xlYXJpbmcgJXAgLSAlcFxuIiwKICAgICAgICAgICAgICAgICAgUlZBKHBlX3NlYy0+VmlydHVhbEFkZHJlc3MpICsgcGVfc2VjLT5TaXplT2ZSYXdEYXRhLAogICAgICAgICAgICAgICAgICBSVkEocGVfc2VjLT5WaXJ0dWFsQWRkcmVzcykgKyBlbmQgKTsKICAgICAgICAgICAgbWVtc2V0KCAoY2hhciopUlZBKHBlX3NlYy0+VmlydHVhbEFkZHJlc3MpICsgcGVfc2VjLT5TaXplT2ZSYXdEYXRhLCAwLAogICAgICAgICAgICAgICAgICAgIGVuZCAtIHBlX3NlYy0+U2l6ZU9mUmF3RGF0YSApOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBQZXJmb3JtIGJhc2UgcmVsb2NhdGlvbiwgaWYgbmVjZXNzYXJ5ICovCiAgICBpZiAoIHJlbG9jICkKICAgICAgICBkb19yZWxvY2F0aW9ucyggbG9hZF9hZGRyLCAoSU1BR0VfQkFTRV9SRUxPQ0FUSU9OICopUlZBKHJlbG9jKSApOwoKICAgIC8qIFdlIGRvbid0IG5lZWQgdGhlIG9yaWduYWwgbWFwcGluZyBhbnkgbW9yZSAqLwogICAgVW5tYXBWaWV3T2ZGaWxlKCAoTFBWT0lEKWhNb2R1bGUgKTsKICAgIGNsb3NlKCB1bml4X2hhbmRsZSApOwogICAgcmV0dXJuIChITU9EVUxFKWxvYWRfYWRkcjsKCmVycm9yOgogICAgaWYgKHVuaXhfaGFuZGxlICE9IC0xKSBjbG9zZSggdW5peF9oYW5kbGUgKTsKICAgIGlmIChsb2FkX2FkZHIpIFZpcnR1YWxGcmVlKCAoTFBWT0lEKWxvYWRfYWRkciwgMCwgTUVNX1JFTEVBU0UgKTsKICAgIFVubWFwVmlld09mRmlsZSggKExQVk9JRCloTW9kdWxlICk7CiAgICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgICAgIFBFX0NyZWF0ZU1vZHVsZQogKgogKiBDcmVhdGUgV0lORV9NT0RSRUYgc3RydWN0dXJlIGZvciBsb2FkZWQgSE1PRFVMRTMyLCBsaW5rIGl0IGludG8KICogcHJvY2VzcyBtb2RyZWZfbGlzdCwgYW5kIGZpeHVwIGFsbCBpbXBvcnRzLgogKgogKiBOb3RlOiBoTW9kdWxlIG11c3QgcG9pbnQgdG8gYSBjb3JyZWN0bHkgYWxsb2NhdGVkIFBFIGltYWdlLAogKiAgICAgICB3aXRoIGJhc2UgcmVsb2NhdGlvbnMgYXBwbGllZDsgdGhlIDE2LWJpdCBkdW1teSBtb2R1bGUKICogICAgICAgYXNzb2NpYXRlZCB0byBoTW9kdWxlIG11c3QgYWxyZWFkeSBleGlzdC4KICoKICogTm90ZTogVGhpcyByb3V0aW5lIG11c3QgYWx3YXlzIGJlIGNhbGxlZCBpbiB0aGUgY29udGV4dCBvZiB0aGUKICogICAgICAgcHJvY2VzcyB0aGF0IGlzIHRvIG93biB0aGUgbW9kdWxlIHRvIGJlIGNyZWF0ZWQuCiAqCiAqIE5vdGU6IEFzc3VtZXMgdGhhdCB0aGUgcHJvY2VzcyBjcml0aWNhbCBzZWN0aW9uIGlzIGhlbGQKICovCldJTkVfTU9EUkVGICpQRV9DcmVhdGVNb2R1bGUoIEhNT0RVTEUgaE1vZHVsZSwgTFBDU1RSIGZpbGVuYW1lLCBEV09SRCBmbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEZJTEUgaEZpbGUsIEJPT0wgYnVpbHRpbiApCnsKICAgIERXT1JEIGxvYWRfYWRkciA9IChEV09SRCloTW9kdWxlOyAgLyogZm9yIFJWQSAqLwogICAgSU1BR0VfTlRfSEVBREVSUyAqbnQgPSBQRV9IRUFERVIoaE1vZHVsZSk7CiAgICBJTUFHRV9EQVRBX0RJUkVDVE9SWSAqZGlyOwogICAgSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSAqcGVfZXhwb3J0ID0gTlVMTDsKICAgIFdJTkVfTU9EUkVGICp3bTsKICAgIEhNT0RVTEUxNiBoTW9kdWxlMTY7CgogICAgLyogUmV0cmlldmUgRGF0YURpcmVjdG9yeSBlbnRyaWVzICovCgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVDsKICAgIGlmIChkaXItPlNpemUpCiAgICAgICAgcGVfZXhwb3J0ID0gKFBJTUFHRV9FWFBPUlRfRElSRUNUT1JZKVJWQShkaXItPlZpcnR1YWxBZGRyZXNzKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhDRVBUSU9OOwogICAgaWYgKGRpci0+U2l6ZSkgRklYTUUoIkV4Y2VwdGlvbiBkaXJlY3RvcnkgaWdub3JlZFxuIiApOwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9TRUNVUklUWTsKICAgIGlmIChkaXItPlNpemUpIEZJWE1FKCJTZWN1cml0eSBkaXJlY3RvcnkgaWdub3JlZFxuIiApOwoKICAgIC8qIElNQUdFX0RJUkVDVE9SWV9FTlRSWV9CQVNFUkVMT0MgaGFuZGxlZCBpbiBQRV9Mb2FkSW1hZ2UgKi8KICAgIC8qIElNQUdFX0RJUkVDVE9SWV9FTlRSWV9ERUJVRyBoYW5kbGVkIGJ5IGRlYnVnZ2VyICovCgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0dMT0JBTFBUUjsKICAgIGlmIChkaXItPlNpemUpIEZJWE1FKCJHbG9iYWwgUG9pbnRlciAoTUlQUykgaWdub3JlZFxuIiApOwoKICAgIC8qIElNQUdFX0RJUkVDVE9SWV9FTlRSWV9UTFMgaGFuZGxlZCBpbiBQRV9UbHNJbml0ICovCgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0xPQURfQ09ORklHOwogICAgaWYgKGRpci0+U2l6ZSkgRklYTUUoIkxvYWQgQ29uZmlndXJhdGlvbiBkaXJlY3RvcnkgaWdub3JlZFxuIiApOwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9CT1VORF9JTVBPUlQ7CiAgICBpZiAoZGlyLT5TaXplKSBUUkFDRSgiQm91bmQgSW1wb3J0IGRpcmVjdG9yeSBpZ25vcmVkXG4iICk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0lBVDsKICAgIGlmIChkaXItPlNpemUpIFRSQUNFKCJJbXBvcnQgQWRkcmVzcyBUYWJsZSBkaXJlY3RvcnkgaWdub3JlZFxuIiApOwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9ERUxBWV9JTVBPUlQ7CiAgICBpZiAoZGlyLT5TaXplKQogICAgewoJCVRSQUNFKCJEZWxheWVkIGltcG9ydCwgc3R1YiBjYWxscyBMb2FkTGlicmFyeVxuIiApOwoJCS8qCgkJICogTm90aGluZyB0byBkbyBoZXJlLgoJCSAqLwoKI2lmZGVmIEltZ0RlbGF5RGVzY3IKCQkvKgoJCSAqIFRoaXMgY29kZSBpcyB1c2VmdWwgdG8gb2JzZXJ2ZSB3aGF0IHRoZSBoZWNrIGlzIGdvaW5nIG9uLgoJCSAqLwoJCXsKCQlJbWdEZWxheURlc2NyICpwZV9kZWxheSA9IE5VTEw7CiAgICAgICAgcGVfZGVsYXkgPSAoUEltZ0RlbGF5RGVzY3IpUlZBKGRpci0+VmlydHVhbEFkZHJlc3MpOwogICAgICAgIFRSQUNFXyhkZWxheWhscCkoInBlX2RlbGF5LT5nckF0dHJzID0gJTA4eFxuIiwgcGVfZGVsYXktPmdyQXR0cnMpOwogICAgICAgIFRSQUNFXyhkZWxheWhscCkoInBlX2RlbGF5LT5zek5hbWUgPSAlc1xuIiwgcGVfZGVsYXktPnN6TmFtZSk7CiAgICAgICAgVFJBQ0VfKGRlbGF5aGxwKSgicGVfZGVsYXktPnBobW9kID0gJTA4eFxuIiwgcGVfZGVsYXktPnBobW9kKTsKICAgICAgICBUUkFDRV8oZGVsYXlobHApKCJwZV9kZWxheS0+cElBVCA9ICUwOHhcbiIsIHBlX2RlbGF5LT5wSUFUKTsKICAgICAgICBUUkFDRV8oZGVsYXlobHApKCJwZV9kZWxheS0+cElOVCA9ICUwOHhcbiIsIHBlX2RlbGF5LT5wSU5UKTsKICAgICAgICBUUkFDRV8oZGVsYXlobHApKCJwZV9kZWxheS0+cEJvdW5kSUFUID0gJTA4eFxuIiwgcGVfZGVsYXktPnBCb3VuZElBVCk7CiAgICAgICAgVFJBQ0VfKGRlbGF5aGxwKSgicGVfZGVsYXktPnBVbmxvYWRJQVQgPSAlMDh4XG4iLCBwZV9kZWxheS0+cFVubG9hZElBVCk7CiAgICAgICAgVFJBQ0VfKGRlbGF5aGxwKSgicGVfZGVsYXktPmR3VGltZVN0YW1wID0gJTA4eFxuIiwgcGVfZGVsYXktPmR3VGltZVN0YW1wKTsKICAgICAgICB9CiNlbmRpZiAvKiBJbWdEZWxheURlc2NyICovCgl9CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0NPTV9ERVNDUklQVE9SOwogICAgaWYgKGRpci0+U2l6ZSkgRklYTUUoIlVua25vd24gZGlyZWN0b3J5IDE0IGlnbm9yZWRcbiIgKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeSsxNTsKICAgIGlmIChkaXItPlNpemUpIEZJWE1FKCJVbmtub3duIGRpcmVjdG9yeSAxNSBpZ25vcmVkXG4iICk7CgogICAgLyogQ3JlYXRlIDE2LWJpdCBkdW1teSBtb2R1bGUgKi8KCiAgICBpZiAoKGhNb2R1bGUxNiA9IE1PRFVMRV9DcmVhdGVEdW1teU1vZHVsZSggZmlsZW5hbWUsIGhNb2R1bGUgKSkgPCAzMikKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoIChEV09SRCloTW9kdWxlMTYgKTsJLyogVGhpcyBzaG91bGQgZ2l2ZSB0aGUgY29ycmVjdCBlcnJvciAqLwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIC8qIEFsbG9jYXRlIGFuZCBmaWxsIFdJTkVfTU9EUkVGICovCgogICAgaWYgKCEod20gPSBNT0RVTEVfQWxsb2NNb2RSZWYoIGhNb2R1bGUsIGZpbGVuYW1lICkpKQogICAgewogICAgICAgIEZyZWVMaWJyYXJ5MTYoIGhNb2R1bGUxNiApOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIGlmICggYnVpbHRpbiApIAogICAgewogICAgICAgIE5FX01PRFVMRSAqcE1vZHVsZSA9IChORV9NT0RVTEUgKilHbG9iYWxMb2NrMTYoIGhNb2R1bGUxNiApOwogICAgICAgIHBNb2R1bGUtPmZsYWdzIHw9IE5FX0ZGTEFHU19CVUlMVElOOwogICAgICAgIHdtLT5mbGFncyB8PSBXSU5FX01PRFJFRl9JTlRFUk5BTDsKICAgIH0KCiAgICBpZiAoIGZsYWdzICYgRE9OVF9SRVNPTFZFX0RMTF9SRUZFUkVOQ0VTICkKICAgICAgICB3bS0+ZmxhZ3MgfD0gV0lORV9NT0RSRUZfRE9OVF9SRVNPTFZFX1JFRlM7CgogICAgd20tPmZpbmRfZXhwb3J0ID0gUEVfRmluZEV4cG9ydGVkRnVuY3Rpb247CgogICAgLyogRHVtcCBFeHBvcnRzICovCgogICAgaWYgKCBwZV9leHBvcnQgKQogICAgICAgIGR1bXBfZXhwb3J0cyggaE1vZHVsZSApOwoKICAgIC8qIFRoZSBleGVfbW9kcmVmIG11c3QgYmUgaW4gcGxhY2UsIGJlZm9yZSBpbXBsaWNpdCBsaW5rZWQgRExMcyBhcmUgbG9hZGVkIAogICAgICAgYnkgZml4dXBfaW1wb3J0cywgb3RoZXJ3aGlzZSBHZXRNb2R1bGVGaWxlTmFtZSB3aWxsIG5vdCB3b3JrIGFuZCBtb2R1bGVzIAogICAgICAgaW4gdGhlIGV4ZWN1dGFibGVzIGRpcmVjdG9yeSBjYW4gbm90IGJlIGZvdW5kICovCgogICAgaWYgKCEobnQtPkZpbGVIZWFkZXIuQ2hhcmFjdGVyaXN0aWNzICYgSU1BR0VfRklMRV9ETEwpKQogICAgewogICAgICBpZiAoIFBST0NFU1NfQ3VycmVudCgpLT5leGVfbW9kcmVmICkKCUZJWE1FKCAiVHJ5aW5nIHRvIGxvYWQgc2Vjb25kIC5FWEUgZmlsZTogJXNcbiIsIGZpbGVuYW1lICk7CiAgICAgIGVsc2UgIAogICAgICB7CglQUk9DRVNTX0N1cnJlbnQoKS0+ZXhlX21vZHJlZiA9IHdtOwogICAgICAgIFBST0NFU1NfQ3VycmVudCgpLT5tb2R1bGUgPSB3bS0+bW9kdWxlOwogICAgICB9CiAgICB9CgogICAgLyogRml4dXAgSW1wb3J0cyAqLwoKICAgIGlmICghKHdtLT5mbGFncyAmIFdJTkVfTU9EUkVGX0RPTlRfUkVTT0xWRV9SRUZTKSAmJiBmaXh1cF9pbXBvcnRzKCB3bSApKQogICAgewogICAgICAgIC8qIHJlbW92ZSBlbnRyeSBmcm9tIG1vZHJlZiBjaGFpbiAqLwoKICAgICAgICBpZiAoICF3bS0+cHJldiApCiAgICAgICAgICAgIFBST0NFU1NfQ3VycmVudCgpLT5tb2RyZWZfbGlzdCA9IHdtLT5uZXh0OwogICAgICAgIGVsc2UKICAgICAgICAgICAgd20tPnByZXYtPm5leHQgPSB3bS0+bmV4dDsKCiAgICAgICAgaWYgKCB3bS0+bmV4dCApIHdtLT5uZXh0LT5wcmV2ID0gd20tPnByZXY7CiAgICAgICAgd20tPm5leHQgPSB3bS0+cHJldiA9IE5VTEw7CgogICAgICAgIC8qIEZJWE1FOiB0aGVyZSBhcmUgc2V2ZXJhbCBtb3JlIGRhbmdsaW5nIHJlZmVyZW5jZXMKICAgICAgICAgKiBsZWZ0LiBJbmNsdWRpbmcgZGxscyBsb2FkZWQgYnkgdGhpcyBkbGwgYmVmb3JlIHRoZQogICAgICAgICAqIGZhaWxlZCBvbmUuIFVucm9sbGluZyBpcyByYXRoZXIgZGlmZmljdWx0IHdpdGggdGhlCiAgICAgICAgICogY3VycmVudCBzdHJ1Y3R1cmUgYW5kIHdlIGNhbiBsZWF2ZSBpdCB0aGVtIGx5aW5nCiAgICAgICAgICogYXJvdW5kIHdpdGggbm8gcHJvYmxlbXMsIHNvIHdlIGRvbid0IGNhcmUuCiAgICAgICAgICogQXMgdGhlc2UgbWlnaHQgcmVmZXJlbmNlIG91ciB3bSwgd2UgZG9uJ3QgZnJlZSBpdC4KICAgICAgICAgKi8KICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgaWYgKHBlX2V4cG9ydCkKICAgICAgICBTTk9PUF9SZWdpc3RlckRMTCggaE1vZHVsZSwgd20tPm1vZG5hbWUsIHBlX2V4cG9ydC0+TnVtYmVyT2ZGdW5jdGlvbnMgKTsKCiAgICAvKiBTZW5kIERMTCBsb2FkIGV2ZW50ICovCiAgICAvKiB3ZSBkb24ndCBuZWVkIHRvIHNlbmQgYSBkbGwgZXZlbnQgZm9yIHRoZSBtYWluIGV4ZSAqLwoKICAgIGlmIChudC0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9GSUxFX0RMTCkKICAgIHsKICAgICAgICBzdHJ1Y3QgbG9hZF9kbGxfcmVxdWVzdCAqcmVxID0gZ2V0X3JlcV9idWZmZXIoKTsKICAgICAgICByZXEtPmhhbmRsZSAgICAgPSBoRmlsZTsKICAgICAgICByZXEtPmJhc2UgICAgICAgPSAodm9pZCAqKWhNb2R1bGU7CiAgICAgICAgcmVxLT5kYmdfb2Zmc2V0ID0gbnQtPkZpbGVIZWFkZXIuUG9pbnRlclRvU3ltYm9sVGFibGU7CiAgICAgICAgcmVxLT5kYmdfc2l6ZSAgID0gbnQtPkZpbGVIZWFkZXIuTnVtYmVyT2ZTeW1ib2xzOwogICAgICAgIHJlcS0+bmFtZSAgICAgICA9ICZ3bS0+ZmlsZW5hbWU7CiAgICAgICAgc2VydmVyX2NhbGxfbm9lcnIoIFJFUV9MT0FEX0RMTCApOwogICAgfQoKICAgIHJldHVybiB3bTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBUaGUgUEUgTGlicmFyeSBMb2FkZXIgZnJvbnRlbmQuIAogKiBGSVhNRTogaGFuZGxlIHRoZSBmbGFncy4KICovCldJTkVfTU9EUkVGICpQRV9Mb2FkTGlicmFyeUV4QSAoTFBDU1RSIG5hbWUsIERXT1JEIGZsYWdzKQp7CglITU9EVUxFCQloTW9kdWxlMzI7CglXSU5FX01PRFJFRgkqd207CgljaGFyICAgICAgICAJZmlsZW5hbWVbMjU2XTsKCUhBTkRMRQkJaEZpbGU7CgoJLyogU2VhcmNoIGZvciBhbmQgb3BlbiBQRSBmaWxlICovCglpZiAoIFNlYXJjaFBhdGhBKCBOVUxMLCBuYW1lLCAiLkRMTCIsIAoJICAgICAgICAgICAgICAgICAgc2l6ZW9mKGZpbGVuYW1lKSwgZmlsZW5hbWUsIE5VTEwgKSA9PSAwICkgcmV0dXJuIE5VTEw7CiAgICAgICAKCWhGaWxlID0gQ3JlYXRlRmlsZUEoIGZpbGVuYW1lLCBHRU5FUklDX1JFQUQsIEZJTEVfU0hBUkVfUkVBRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCBPUEVOX0VYSVNUSU5HLCAwLCAtMSApOwoJaWYgKCBoRmlsZSA9PSBJTlZBTElEX0hBTkRMRV9WQUxVRSApIHJldHVybiBOVUxMOwoJCgkvKiBMb2FkIFBFIG1vZHVsZSAqLwoJaE1vZHVsZTMyID0gUEVfTG9hZEltYWdlKCBoRmlsZSwgZmlsZW5hbWUsIGZsYWdzICk7CglpZiAoIWhNb2R1bGUzMikKCXsKICAgICAgICAgICAgICAgIENsb3NlSGFuZGxlKCBoRmlsZSApOwoJCXJldHVybiBOVUxMOwoJfQoKCS8qIENyZWF0ZSAzMi1iaXQgTU9EUkVGICovCglpZiAoICEod20gPSBQRV9DcmVhdGVNb2R1bGUoIGhNb2R1bGUzMiwgZmlsZW5hbWUsIGZsYWdzLCAtMSwgRkFMU0UgKSkgKQoJewoJCUVSUiggImNhbid0IGxvYWQgJXNcbiIsIGZpbGVuYW1lICk7CiAgICAgICAgICAgICAgICBDbG9zZUhhbmRsZSggaEZpbGUgKTsKCQlTZXRMYXN0RXJyb3IoIEVSUk9SX09VVE9GTUVNT1JZICk7CgkJcmV0dXJuIE5VTEw7Cgl9CgogICAgICAgIENsb3NlSGFuZGxlKCBoRmlsZSApOwoJcmV0dXJuIHdtOwp9CgoKLyogQ2FsbGVkIGlmIHRoZSBsaWJyYXJ5IGlzIGxvYWRlZCBvciBmcmVlZC4KICogTk9URTogaWYgYSB0aHJlYWQgYXR0YWNoZXMgYSBETEwsIHRoZSBjdXJyZW50IHRocmVhZCB3aWxsIG9ubHkgZG8KICogRExMX1BST0NFU1NfQVRUQUNILiBPbmx5IG5ldyBjcmVhdGVkIHRocmVhZHMgZG8gRExMX1RIUkVBRF9BVFRBQ0gKICogKFNESykKICovCnR5cGVkZWYgRFdPUkQgQ0FMTEJBQ0soKkRMTEVOVFJZUFJPQykoSE1PRFVMRSxEV09SRCxMUFZPSUQpOwoKQk9PTCBQRV9Jbml0RExMKCBITU9EVUxFIG1vZHVsZSwgRFdPUkQgdHlwZSwgTFBWT0lEIGxwUmVzZXJ2ZWQgKQp7CiAgICBCT09MIHJldHYgPSBUUlVFOwogICAgSU1BR0VfTlRfSEVBREVSUyAqbnQgPSBQRV9IRUFERVIobW9kdWxlKTsKCiAgICAvKiBJcyB0aGlzIGEgbGlicmFyeT8gQW5kIGhhcyBpdCBnb3QgYW4gZW50cnlwb2ludD8gKi8KICAgIGlmICgobnQtPkZpbGVIZWFkZXIuQ2hhcmFjdGVyaXN0aWNzICYgSU1BR0VfRklMRV9ETEwpICYmCiAgICAgICAgKG50LT5PcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50KSkKICAgIHsKICAgICAgICBETExFTlRSWVBST0MgZW50cnkgPSAodm9pZCopKChjaGFyKiltb2R1bGUgKyBudC0+T3B0aW9uYWxIZWFkZXIuQWRkcmVzc09mRW50cnlQb2ludCk7CiAgICAgICAgVFJBQ0VfKHJlbGF5KSgiQ2FsbFRvMzIoZW50cnlwcm9jPSVwLG1vZHVsZT0lMDh4LHR5cGU9JWxkLHJlcz0lcClcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgZW50cnksIG1vZHVsZSwgdHlwZSwgbHBSZXNlcnZlZCApOwoKICAgICAgICByZXR2ID0gZW50cnkoIG1vZHVsZSwgdHlwZSwgbHBSZXNlcnZlZCApOwogICAgfQoKICAgIHJldHVybiByZXR2Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCVBFX0luaXRUbHMJCQkoaW50ZXJuYWwpCiAqCiAqIElmIGluY2x1ZGVkLCBpbml0aWFsaXNlcyB0aGUgdGhyZWFkIGxvY2FsIHN0b3JhZ2VzIG9mIG1vZHVsZXMuCiAqIFBvaW50ZXJzIGluIHRob3NlIHN0cnVjdHMgYXJlIG5vdCBSVkFzIGJ1dCByZWFsIHBvaW50ZXJzIHdoaWNoIGhhdmUgYmVlbgogKiByZWxvY2F0ZWQgYnkgZG9fcmVsb2NhdGlvbnMoKSBhbHJlYWR5LgogKi8Kc3RhdGljIExQVk9JRApfZml4dXBfYWRkcmVzcyhQSU1BR0VfT1BUSU9OQUxfSEVBREVSIG9wdCxpbnQgZGVsdGEsTFBWT0lEIGFkZHIpIHsKCWlmICgJKChEV09SRClhZGRyPm9wdC0+SW1hZ2VCYXNlKSAmJgoJCSgoRFdPUkQpYWRkcjxvcHQtPkltYWdlQmFzZStvcHQtPlNpemVPZkltYWdlKQoJKQoJCS8qIHRoZSBhZGRyZXNzIGhhcyBub3QgYmVlbiByZWxvY2F0ZWQhICovCgkJcmV0dXJuIChMUFZPSUQpKCgoRFdPUkQpYWRkcikrZGVsdGEpOwoJZWxzZQoJCS8qIHRoZSBhZGRyZXNzIGhhcyBiZWVuIHJlbG9jYXRlZCBhbHJlYWR5ICovCgkJcmV0dXJuIGFkZHI7Cn0Kdm9pZCBQRV9Jbml0VGxzKCB2b2lkICkKewoJV0lORV9NT0RSRUYJCSp3bTsKCUlNQUdFX05UX0hFQURFUlMJKnBlaDsKCURXT1JECQkJc2l6ZSxkYXRhc2l6ZTsKCUxQVk9JRAkJCW1lbTsKCVBJTUFHRV9UTFNfRElSRUNUT1JZCXBkaXI7CiAgICAgICAgaW50IGRlbHRhOwoJCglmb3IgKHdtID0gUFJPQ0VTU19DdXJyZW50KCktPm1vZHJlZl9saXN0O3dtO3dtPXdtLT5uZXh0KSB7CgkJcGVoID0gUEVfSEVBREVSKHdtLT5tb2R1bGUpOwoJCWRlbHRhID0gd20tPm1vZHVsZSAtIHBlaC0+T3B0aW9uYWxIZWFkZXIuSW1hZ2VCYXNlOwoJCWlmICghcGVoLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0ZJTEVfVEhSRUFEX0xPQ0FMX1NUT1JBR0VdLlZpcnR1YWxBZGRyZXNzKQoJCQljb250aW51ZTsKCQlwZGlyID0gKExQVk9JRCkod20tPm1vZHVsZSArIHBlaC0+T3B0aW9uYWxIZWFkZXIuCgkJCURhdGFEaXJlY3RvcnlbSU1BR0VfRklMRV9USFJFQURfTE9DQUxfU1RPUkFHRV0uVmlydHVhbEFkZHJlc3MpOwoJCQoJCQoJCWlmICggd20tPnRsc2luZGV4ID09IC0xICkgewoJCQlMUERXT1JEIHhhZGRyOwoJCQl3bS0+dGxzaW5kZXggPSBUbHNBbGxvYygpOwoJCQl4YWRkciA9IF9maXh1cF9hZGRyZXNzKCYocGVoLT5PcHRpb25hbEhlYWRlciksZGVsdGEsCgkJCQkJcGRpci0+QWRkcmVzc09mSW5kZXgKCQkJKTsKCQkJKnhhZGRyPXdtLT50bHNpbmRleDsKCQl9CgkJZGF0YXNpemU9IHBkaXItPkVuZEFkZHJlc3NPZlJhd0RhdGEtcGRpci0+U3RhcnRBZGRyZXNzT2ZSYXdEYXRhOwoJCXNpemUJPSBkYXRhc2l6ZSArIHBkaXItPlNpemVPZlplcm9GaWxsOwoJCW1lbT1WaXJ0dWFsQWxsb2MoMCxzaXplLE1FTV9SRVNFUlZFfE1FTV9DT01NSVQsUEFHRV9SRUFEV1JJVEUpOwoJCW1lbWNweShtZW0sX2ZpeHVwX2FkZHJlc3MoJihwZWgtPk9wdGlvbmFsSGVhZGVyKSxkZWx0YSwoTFBWT0lEKXBkaXItPlN0YXJ0QWRkcmVzc09mUmF3RGF0YSksZGF0YXNpemUpOwoJCWlmIChwZGlyLT5BZGRyZXNzT2ZDYWxsQmFja3MpIHsKCQkgICAgIFBJTUFHRV9UTFNfQ0FMTEJBQ0sgKmNiczsgCgoJCSAgICAgY2JzID0gX2ZpeHVwX2FkZHJlc3MoJihwZWgtPk9wdGlvbmFsSGVhZGVyKSxkZWx0YSxwZGlyLT5BZGRyZXNzT2ZDYWxsQmFja3MpOwoJCSAgICAgaWYgKCpjYnMpCgkJICAgICAgIEZJWE1FKCJUTFMgQ2FsbGJhY2tzIGFyZW4ndCBnb2luZyB0byBiZSBjYWxsZWRcbiIpOwoJCX0KCgkJVGxzU2V0VmFsdWUoIHdtLT50bHNpbmRleCwgbWVtICk7Cgl9Cn0KCg==