LyoKICogQ29weXJpZ2h0IDIwMDIgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgojaW5jbHVkZSA8YXNzZXJ0Lmg+CiNpbmNsdWRlIDxzdGRhcmcuaD4KCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmdkaS5oIgojaW5jbHVkZSAid2ludXNlci5oIgojaW5jbHVkZSAid2lubmxzLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAibW1zeXN0ZW0uaCIKI2luY2x1ZGUgInZmdy5oIgojaW5jbHVkZSAibXNhY20uaCIKCiNpbmNsdWRlICJhdmlmaWxlX3ByaXZhdGUuaCIKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChhdmlmaWxlKTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBBQ01TdHJlYW1fZm5RdWVyeUludGVyZmFjZShJQVZJU3RyZWFtKmlmYWNlLFJFRklJRCByZWZpaWQsTFBWT0lEICpvYmopOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgQUNNU3RyZWFtX2ZuQWRkUmVmKElBVklTdHJlYW0qaWZhY2UpOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgQUNNU3RyZWFtX2ZuUmVsZWFzZShJQVZJU3RyZWFtKiBpZmFjZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBBQ01TdHJlYW1fZm5DcmVhdGUoSUFWSVN0cmVhbSppZmFjZSxMUEFSQU0gbFBhcmFtMSxMUEFSQU0gbFBhcmFtMik7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBBQ01TdHJlYW1fZm5JbmZvKElBVklTdHJlYW0qaWZhY2UsQVZJU1RSRUFNSU5GT1cgKnBzaSxMT05HIHNpemUpOwpzdGF0aWMgTE9ORyAgICBXSU5BUEkgQUNNU3RyZWFtX2ZuRmluZFNhbXBsZShJQVZJU3RyZWFtKmlmYWNlLExPTkcgcG9zLExPTkcgZmxhZ3MpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQUNNU3RyZWFtX2ZuUmVhZEZvcm1hdChJQVZJU3RyZWFtKmlmYWNlLExPTkcgcG9zLExQVk9JRCBmb3JtYXQsTE9ORyAqZm9ybWF0c2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBBQ01TdHJlYW1fZm5TZXRGb3JtYXQoSUFWSVN0cmVhbSppZmFjZSxMT05HIHBvcyxMUFZPSUQgZm9ybWF0LExPTkcgZm9ybWF0c2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBBQ01TdHJlYW1fZm5SZWFkKElBVklTdHJlYW0qaWZhY2UsTE9ORyBzdGFydCxMT05HIHNhbXBsZXMsTFBWT0lEIGJ1ZmZlcixMT05HIGJ1ZmZlcnNpemUsTE9ORyAqYnl0ZXNyZWFkLExPTkcgKnNhbXBsZXNyZWFkKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIEFDTVN0cmVhbV9mbldyaXRlKElBVklTdHJlYW0qaWZhY2UsTE9ORyBzdGFydCxMT05HIHNhbXBsZXMsTFBWT0lEIGJ1ZmZlcixMT05HIGJ1ZmZlcnNpemUsRFdPUkQgZmxhZ3MsTE9ORyAqc2FtcHdyaXR0ZW4sTE9ORyAqYnl0ZXN3cml0dGVuKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIEFDTVN0cmVhbV9mbkRlbGV0ZShJQVZJU3RyZWFtKmlmYWNlLExPTkcgc3RhcnQsTE9ORyBzYW1wbGVzKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIEFDTVN0cmVhbV9mblJlYWREYXRhKElBVklTdHJlYW0qaWZhY2UsRFdPUkQgZmNjLExQVk9JRCBscCxMT05HICpscHJlYWQpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQUNNU3RyZWFtX2ZuV3JpdGVEYXRhKElBVklTdHJlYW0qaWZhY2UsRFdPUkQgZmNjLExQVk9JRCBscCxMT05HIHNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQUNNU3RyZWFtX2ZuU2V0SW5mbyhJQVZJU3RyZWFtKmlmYWNlLEFWSVNUUkVBTUlORk9XKmluZm8sTE9ORyBpbmZvbGVuKTsKCnN0YXRpYyBjb25zdCBzdHJ1Y3QgSUFWSVN0cmVhbVZ0YmwgaWFjbXN0ID0gewogIEFDTVN0cmVhbV9mblF1ZXJ5SW50ZXJmYWNlLAogIEFDTVN0cmVhbV9mbkFkZFJlZiwKICBBQ01TdHJlYW1fZm5SZWxlYXNlLAogIEFDTVN0cmVhbV9mbkNyZWF0ZSwKICBBQ01TdHJlYW1fZm5JbmZvLAogIEFDTVN0cmVhbV9mbkZpbmRTYW1wbGUsCiAgQUNNU3RyZWFtX2ZuUmVhZEZvcm1hdCwKICBBQ01TdHJlYW1fZm5TZXRGb3JtYXQsCiAgQUNNU3RyZWFtX2ZuUmVhZCwKICBBQ01TdHJlYW1fZm5Xcml0ZSwKICBBQ01TdHJlYW1fZm5EZWxldGUsCiAgQUNNU3RyZWFtX2ZuUmVhZERhdGEsCiAgQUNNU3RyZWFtX2ZuV3JpdGVEYXRhLAogIEFDTVN0cmVhbV9mblNldEluZm8KfTsKCnR5cGVkZWYgc3RydWN0IF9JQVZJU3RyZWFtSW1wbCB7CiAgLyogSVVua25vd24gc3R1ZmYgKi8KICBjb25zdCBJQVZJU3RyZWFtVnRibCAqbHBWdGJsOwogIExPTkcJCSAgcmVmOwoKICAvKiBJQVZJU3RyZWFtIHN0dWZmICovCiAgUEFWSVNUUkVBTSAgICAgIHBTdHJlYW07CiAgQVZJU1RSRUFNSU5GT1cgIHNJbmZvOwoKICBIQUNNU1RSRUFNICAgICAgaGFzOwoKICBMUFdBVkVGT1JNQVRFWCAgbHBJbkZvcm1hdDsKICBMT05HICAgICAgICAgICAgY2JJbkZvcm1hdDsKCiAgTFBXQVZFRk9STUFURVggIGxwT3V0Rm9ybWF0OwogIExPTkcgICAgICAgICAgICBjYk91dEZvcm1hdDsKCiAgQUNNU1RSRUFNSEVBREVSIGFjbVN0cmVhbUhkcjsKfSBJQVZJU3RyZWFtSW1wbDsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiNkZWZpbmUgQ09OVkVSVF9TVFJFQU1fdG9fVEhJUyhhKSBkbyB7IFwKICAgICAgICAgICBEV09SRCBfX2J5dGVzOyBcCiAgICAgICAgICAgYWNtU3RyZWFtU2l6ZShUaGlzLT5oYXMsKihhKSAqIFRoaXMtPmxwSW5Gb3JtYXQtPm5CbG9ja0FsaWduLFwKICAgICAgICAgICAgICAgICAgICAgICAgICZfX2J5dGVzLCBBQ01fU1RSRUFNU0laRUZfU09VUkNFKTsgXAogICAgICAgICAgICooYSkgPSBfX2J5dGVzIC8gVGhpcy0+bHBPdXRGb3JtYXQtPm5CbG9ja0FsaWduOyB9IHdoaWxlKDApCgojZGVmaW5lIENPTlZFUlRfVEhJU190b19TVFJFQU0oYSkgZG8geyBcCiAgICAgICAgICAgRFdPUkQgX19ieXRlczsgXAogICAgICAgICAgIGFjbVN0cmVhbVNpemUoVGhpcy0+aGFzLCooYSkgKiBUaGlzLT5scE91dEZvcm1hdC0+bkJsb2NrQWxpZ24sXAogICAgICAgICAgICAgICAgICAgICAgICAgJl9fYnl0ZXMsIEFDTV9TVFJFQU1TSVpFRl9ERVNUSU5BVElPTik7IFwKICAgICAgICAgICAqKGEpID0gX19ieXRlcyAvIFRoaXMtPmxwSW5Gb3JtYXQtPm5CbG9ja0FsaWduOyB9IHdoaWxlKDApCgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX09wZW5Db21wcmVzc29yKElBVklTdHJlYW1JbXBsICpUaGlzKTsKCkhSRVNVTFQgQVZJRklMRV9DcmVhdGVBQ01TdHJlYW0oUkVGSUlEIHJpaWQsIExQVk9JRCAqcHB2KQp7CiAgSUFWSVN0cmVhbUltcGwgKnBzdHJlYW07CiAgSFJFU1VMVCAgICAgICAgIGhyOwoKICBhc3NlcnQocmlpZCAhPSBOVUxMICYmIHBwdiAhPSBOVUxMKTsKCiAgKnBwdiA9IE5VTEw7CgogIHBzdHJlYW0gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKElBVklTdHJlYW1JbXBsKSk7CiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICBwc3RyZWFtLT5scFZ0YmwgPSAmaWFjbXN0OwoKICBociA9IElBVklTdHJlYW1fUXVlcnlJbnRlcmZhY2UoKElBVklTdHJlYW0qKXBzdHJlYW0sIHJpaWQsIHBwdik7CiAgaWYgKEZBSUxFRChocikpCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwc3RyZWFtKTsKCiAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQUNNU3RyZWFtX2ZuUXVlcnlJbnRlcmZhY2UoSUFWSVN0cmVhbSAqaWZhY2UsCgkJCQkJCSAgUkVGSUlEIHJlZmlpZCwgTFBWT0lEICpvYmopCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVzLCVwKVxuIiwgaWZhY2UsIGRlYnVnc3RyX2d1aWQocmVmaWlkKSwgb2JqKTsKCiAgaWYgKElzRXF1YWxHVUlEKCZJSURfSVVua25vd24sIHJlZmlpZCkgfHwKICAgICAgSXNFcXVhbEdVSUQoJklJRF9JQVZJU3RyZWFtLCByZWZpaWQpKSB7CiAgICAqb2JqID0gVGhpczsKICAgIElBVklTdHJlYW1fQWRkUmVmKGlmYWNlKTsKCiAgICByZXR1cm4gU19PSzsKICB9CgogIHJldHVybiBPTEVfRV9FTlVNX05PTU9SRTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBBQ01TdHJlYW1fZm5BZGRSZWYoSUFWSVN0cmVhbSAqaWZhY2UpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwogIFVMT05HIHJlZiA9IEludGVybG9ja2VkSW5jcmVtZW50KCZUaGlzLT5yZWYpOwoKICBUUkFDRSgiKCVwKSAtPiAlZFxuIiwgaWZhY2UsIHJlZik7CgogIC8qIGFsc28gYWRkIHJlZmVyZW5jZSB0byB0aGUgbmVzdGVkIHN0cmVhbSAqLwogIGlmIChUaGlzLT5wU3RyZWFtICE9IE5VTEwpCiAgICBJQVZJU3RyZWFtX0FkZFJlZihUaGlzLT5wU3RyZWFtKTsKCiAgcmV0dXJuIHJlZjsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBBQ01TdHJlYW1fZm5SZWxlYXNlKElBVklTdHJlYW0qIGlmYWNlKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+cmVmKTsKCiAgVFJBQ0UoIiglcCkgLT4gJWRcbiIsIGlmYWNlLCByZWYpOwoKICBpZiAocmVmID09IDApIHsKICAgIC8qIGRlc3RydWN0ICovCiAgICBpZiAoVGhpcy0+aGFzICE9IE5VTEwpIHsKICAgICAgaWYgKFRoaXMtPmFjbVN0cmVhbUhkci5mZHdTdGF0dXMgJiBBQ01TVFJFQU1IRUFERVJfU1RBVFVTRl9QUkVQQVJFRCkKCWFjbVN0cmVhbVVucHJlcGFyZUhlYWRlcihUaGlzLT5oYXMsICZUaGlzLT5hY21TdHJlYW1IZHIsIDApOwogICAgICBhY21TdHJlYW1DbG9zZShUaGlzLT5oYXMsIDApOwogICAgICBUaGlzLT5oYXMgPSBOVUxMOwogICAgfQogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+YWNtU3RyZWFtSGRyLnBiU3JjKTsKICAgIFRoaXMtPmFjbVN0cmVhbUhkci5wYlNyYyA9IE5VTEw7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5hY21TdHJlYW1IZHIucGJEc3QpOwogICAgVGhpcy0+YWNtU3RyZWFtSGRyLnBiRHN0ID0gTlVMTDsKICAgIGlmIChUaGlzLT5scEluRm9ybWF0ICE9IE5VTEwpIHsKICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+bHBJbkZvcm1hdCk7CiAgICAgIFRoaXMtPmxwSW5Gb3JtYXQgPSBOVUxMOwogICAgICBUaGlzLT5jYkluRm9ybWF0ID0gMDsKICAgIH0KICAgIGlmIChUaGlzLT5scE91dEZvcm1hdCAhPSBOVUxMKSB7CiAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPmxwT3V0Rm9ybWF0KTsKICAgICAgVGhpcy0+bHBPdXRGb3JtYXQgPSBOVUxMOwogICAgICBUaGlzLT5jYk91dEZvcm1hdCA9IDA7CiAgICB9CiAgICBpZiAoVGhpcy0+cFN0cmVhbSAhPSBOVUxMKSB7CiAgICAgIElBVklTdHJlYW1fUmVsZWFzZShUaGlzLT5wU3RyZWFtKTsKICAgICAgVGhpcy0+cFN0cmVhbSA9IE5VTEw7CiAgICB9CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzKTsKCiAgICByZXR1cm4gMDsKICB9CgogIC8qIGFsc28gcmVsZWFzZSByZWZlcmVuY2UgdG8gdGhlIG5lc3RlZCBzdHJlYW0gKi8KICBpZiAoVGhpcy0+cFN0cmVhbSAhPSBOVUxMKQogICAgSUFWSVN0cmVhbV9SZWxlYXNlKFRoaXMtPnBTdHJlYW0pOwoKICByZXR1cm4gcmVmOwp9CgovKiBsUGFyYW0xOiBQQVZJU1RSRUFNCiAqIGxQYXJhbTI6IExQQVZJQ09NUFJFU1NPUFRJT05TIC0tIGV2ZW4gaWYgZG9jJ3Mgc2F5IExQV0FWRUZPUk1BVAogKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIEFDTVN0cmVhbV9mbkNyZWF0ZShJQVZJU3RyZWFtICppZmFjZSwgTFBBUkFNIGxQYXJhbTEsCgkJCQkJICBMUEFSQU0gbFBhcmFtMikKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsMHglMDhsWCwweCUwOGxYKVxuIiwgaWZhY2UsIGxQYXJhbTEsIGxQYXJhbTIpOwoKICAvKiBjaGVjayBmb3Igc3dhcHBlZCBwYXJhbWV0ZXJzICovCiAgaWYgKChMUFZPSUQpbFBhcmFtMSAhPSBOVUxMICYmCiAgICAgICgoTFBBVklDT01QUkVTU09QVElPTlMpbFBhcmFtMSktPmZjY1R5cGUgPT0gc3RyZWFtdHlwZUFVRElPKSB7CiAgICByZWdpc3RlciBMUEFSQU0gdG1wID0gbFBhcmFtMTsKCiAgICBsUGFyYW0xID0gbFBhcmFtMjsKICAgIGxQYXJhbTIgPSB0bXA7CiAgfQoKICBpZiAoKExQVk9JRClsUGFyYW0xID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICBJQVZJU3RyZWFtX0luZm8oKFBBVklTVFJFQU0pbFBhcmFtMSwgJlRoaXMtPnNJbmZvLCBzaXplb2YoVGhpcy0+c0luZm8pKTsKICBpZiAoVGhpcy0+c0luZm8uZmNjVHlwZSAhPSBzdHJlYW10eXBlQVVESU8pCiAgICByZXR1cm4gQVZJRVJSX0VSUk9SOyAvKiBlcnJvciBpbiByZWdpc3RyeSBvciBBVklNYWtlQ29tcHJlc3NlZFN0cmVhbSAqLwoKICBUaGlzLT5zSW5mby5mY2NIYW5kbGVyID0gMDsgLyogYmUgcGFyYW5vaWQgKi8KCiAgLyogRklYTUU6IGNoZWNrIEFDTSB2ZXJzaW9uPyBXaGljaCB2ZXJzaW9uIGRvZXMgd2UgbmVlZD8gKi8KCiAgaWYgKChMUFZPSUQpbFBhcmFtMiAhPSBOVUxMKSB7CiAgICAvKiBXZSBvbmx5IG5lZWQgdGhlIGZvcm1hdCBmcm9tIHRoZSBjb21wcmVzcy1vcHRpb25zICovCiAgICBpZiAoKChMUEFWSUNPTVBSRVNTT1BUSU9OUylsUGFyYW0yKS0+ZmNjVHlwZSA9PSBzdHJlYW10eXBlQVVESU8pCiAgICAgIGxQYXJhbTIgPSAoTFBBUkFNKSgoTFBBVklDT01QUkVTU09QVElPTlMpbFBhcmFtMiktPmxwRm9ybWF0OwoKICAgIGlmICgoKExQV0FWRUZPUk1BVEVYKWxQYXJhbTIpLT53Rm9ybWF0VGFnICE9IFdBVkVfRk9STUFUX1BDTSkKICAgICAgVGhpcy0+Y2JPdXRGb3JtYXQgPSBzaXplb2YoV0FWRUZPUk1BVEVYKSArICgoTFBXQVZFRk9STUFURVgpbFBhcmFtMiktPmNiU2l6ZTsKICAgIGVsc2UKICAgICAgVGhpcy0+Y2JPdXRGb3JtYXQgPSBzaXplb2YoUENNV0FWRUZPUk1BVCk7CgogICAgVGhpcy0+bHBPdXRGb3JtYXQgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+Y2JPdXRGb3JtYXQpOwogICAgaWYgKFRoaXMtPmxwT3V0Rm9ybWF0ID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICAgIG1lbWNweShUaGlzLT5scE91dEZvcm1hdCwgKExQVk9JRClsUGFyYW0yLCBUaGlzLT5jYk91dEZvcm1hdCk7CiAgfSBlbHNlIHsKICAgIFRoaXMtPmxwT3V0Rm9ybWF0ID0gTlVMTDsKICAgIFRoaXMtPmNiT3V0Rm9ybWF0ID0gMDsKICB9CgogIFRoaXMtPnBTdHJlYW0gPSAoUEFWSVNUUkVBTSlsUGFyYW0xOwogIElBVklTdHJlYW1fQWRkUmVmKFRoaXMtPnBTdHJlYW0pOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQUNNU3RyZWFtX2ZuSW5mbyhJQVZJU3RyZWFtICppZmFjZSxMUEFWSVNUUkVBTUlORk9XIHBzaSwKCQkJCQlMT05HIHNpemUpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVwLCVkKVxuIiwgaWZhY2UsIHBzaSwgc2l6ZSk7CgogIGlmIChwc2kgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgaWYgKHNpemUgPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURTSVpFOwoKICAvKiBOZWVkIGNvZGVjIHRvIGNvcnJlY3Qgc29tZSB2YWx1ZXMgaW4gc3RydWN0dXJlICovCiAgaWYgKFRoaXMtPmhhcyA9PSBOVUxMKSB7CiAgICBIUkVTVUxUIGhyID0gQVZJRklMRV9PcGVuQ29tcHJlc3NvcihUaGlzKTsKCiAgICBpZiAoRkFJTEVEKGhyKSkKICAgICAgcmV0dXJuIGhyOwogIH0KCiAgbWVtY3B5KHBzaSwgJlRoaXMtPnNJbmZvLCBtaW4oc2l6ZSwgKExPTkcpc2l6ZW9mKFRoaXMtPnNJbmZvKSkpOwoKICBpZiAoc2l6ZSA8IChMT05HKXNpemVvZihUaGlzLT5zSW5mbykpCiAgICByZXR1cm4gQVZJRVJSX0JVRkZFUlRPT1NNQUxMOwogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBMT05HIFdJTkFQSSBBQ01TdHJlYW1fZm5GaW5kU2FtcGxlKElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHBvcywKCQkJCQkgICBMT05HIGZsYWdzKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlZCwweCUwOFgpXG4iLGlmYWNlLHBvcyxmbGFncyk7CgogIGlmIChmbGFncyAmIEZJTkRfRlJPTV9TVEFSVCkgewogICAgcG9zID0gVGhpcy0+c0luZm8uZHdTdGFydDsKICAgIGZsYWdzICY9IH4oRklORF9GUk9NX1NUQVJUfEZJTkRfUFJFVik7CiAgICBmbGFncyB8PSBGSU5EX05FWFQ7CiAgfQoKICAvKiBjb252ZXJ0IHBvcyBmcm9tIG91ciAnc3BhY2UnIHRvIFRoaXMtPnBTdHJlYW0ncyBvbmUgKi8KICBDT05WRVJUX1RISVNfdG9fU1RSRUFNKCZwb3MpOwoKICAvKiBhc2sgc3RyZWFtICovCiAgcG9zID0gSUFWSVN0cmVhbV9GaW5kU2FtcGxlKFRoaXMtPnBTdHJlYW0sIHBvcywgZmxhZ3MpOwoKICBpZiAocG9zICE9IC0xKSB7CiAgICAvKiBjb252ZXJ0IHBvcyBiYWNrIHRvIG91ciAnc3BhY2UnIGlmIGl0J3Mgbm8gc2l6ZSBvciBwaHlzaWNhbCBwb3MgKi8KICAgIGlmICgoZmxhZ3MgJiBGSU5EX1JFVCkgPT0gMCkKICAgICAgQ09OVkVSVF9TVFJFQU1fdG9fVEhJUygmcG9zKTsKICB9CgogIHJldHVybiBwb3M7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBBQ01TdHJlYW1fZm5SZWFkRm9ybWF0KElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHBvcywKCQkJCQkgICAgICBMUFZPSUQgZm9ybWF0LCBMT05HICpmb3JtYXRzaXplKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlZCwlcCwlcClcbiIsIGlmYWNlLCBwb3MsIGZvcm1hdCwgZm9ybWF0c2l6ZSk7CgogIGlmIChmb3JtYXRzaXplID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICBpZiAoVGhpcy0+aGFzID09IE5VTEwpIHsKICAgIEhSRVNVTFQgaHIgPSBBVklGSUxFX09wZW5Db21wcmVzc29yKFRoaXMpOwoKICAgIGlmIChGQUlMRUQoaHIpKQogICAgICByZXR1cm4gaHI7CiAgfQoKICAvKiBvbmx5IGludGVyZXN0ZWQgaW4gbmVlZGVkIGJ1ZmZlcnNpemU/ICovCiAgaWYgKGZvcm1hdCA9PSBOVUxMIHx8ICpmb3JtYXRzaXplIDw9IDApIHsKICAgICpmb3JtYXRzaXplID0gVGhpcy0+Y2JPdXRGb3JtYXQ7CgogICAgcmV0dXJuIEFWSUVSUl9PSzsKICB9CgogIC8qIGNvcHkgaW5pdGlhbCBmb3JtYXQgKG9ubHkgYXMgbXVjaCBhcyB3aWxsIGZpdCkgKi8KICBtZW1jcHkoZm9ybWF0LCBUaGlzLT5scE91dEZvcm1hdCwgbWluKCpmb3JtYXRzaXplLCBUaGlzLT5jYk91dEZvcm1hdCkpOwogIGlmICgqZm9ybWF0c2l6ZSA8IFRoaXMtPmNiT3V0Rm9ybWF0KSB7CiAgICAqZm9ybWF0c2l6ZSA9IFRoaXMtPmNiT3V0Rm9ybWF0OwogICAgcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKICB9CgogICpmb3JtYXRzaXplID0gVGhpcy0+Y2JPdXRGb3JtYXQ7CiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIEFDTVN0cmVhbV9mblNldEZvcm1hdChJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBwb3MsCgkJCQkJICAgICBMUFZPSUQgZm9ybWF0LCBMT05HIGZvcm1hdHNpemUpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBIUkVTVUxUIGhyOwoKICBUUkFDRSgiKCVwLCVkLCVwLCVkKVxuIiwgaWZhY2UsIHBvcywgZm9ybWF0LCBmb3JtYXRzaXplKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChmb3JtYXQgPT0gTlVMTCB8fCBmb3JtYXRzaXplIDw9IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBJbnB1dCBmb3JtYXQgYWxyZWFkeSBrbm93bj8KICAgKiBDaGFuZ2luZyBpcyB1bnN1cHBvcnRlZCwgYnV0IGJlIHF1aWV0IGlmIGl0J3MgdGhlIHNhbWUgKi8KICBpZiAoVGhpcy0+bHBJbkZvcm1hdCAhPSBOVUxMKSB7CiAgICBpZiAoVGhpcy0+Y2JJbkZvcm1hdCAhPSBmb3JtYXRzaXplIHx8CgltZW1jbXAoZm9ybWF0LCBUaGlzLT5scEluRm9ybWF0LCBmb3JtYXRzaXplKSAhPSAwKQogICAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICAgIHJldHVybiBBVklFUlJfT0s7CiAgfQoKICAvKiBEb2VzIHRoZSBuZXN0ZWQgc3RyZWFtIHN1cHBvcnQgd3JpdGluZz8gKi8KICBpZiAoKFRoaXMtPnNJbmZvLmR3Q2FwcyAmIEFWSUZJTEVDQVBTX0NBTldSSVRFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgVGhpcy0+bHBJbkZvcm1hdCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBmb3JtYXRzaXplKTsKICBpZiAoVGhpcy0+bHBJbkZvcm1hdCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgVGhpcy0+Y2JJbkZvcm1hdCA9IGZvcm1hdHNpemU7CiAgbWVtY3B5KFRoaXMtPmxwSW5Gb3JtYXQsIGZvcm1hdCwgZm9ybWF0c2l6ZSk7CgogIC8qIGluaXRpYWxpemUgZm9ybWF0cyBhbmQgZ2V0IGNvbXByZXNzb3IgKi8KICBociA9IEFWSUZJTEVfT3BlbkNvbXByZXNzb3IoVGhpcyk7CiAgaWYgKEZBSUxFRChocikpCiAgICByZXR1cm4gaHI7CgogIENPTlZFUlRfVEhJU190b19TVFJFQU0oJnBvcyk7CgogIC8qIHRlbGwgdGhlIG5lc3RlZCBzdHJlYW0gdGhlIG5ldyBmb3JtYXQgKi8KICByZXR1cm4gSUFWSVN0cmVhbV9TZXRGb3JtYXQoVGhpcy0+cFN0cmVhbSwgcG9zLCBUaGlzLT5scE91dEZvcm1hdCwKCQkJICAgICAgVGhpcy0+Y2JPdXRGb3JtYXQpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQUNNU3RyZWFtX2ZuUmVhZChJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBzdGFydCwKCQkJCQlMT05HIHNhbXBsZXMsIExQVk9JRCBidWZmZXIsCgkJCQkJTE9ORyBidWZmZXJzaXplLCBMUExPTkcgYnl0ZXNyZWFkLAoJCQkJCUxQTE9ORyBzYW1wbGVzcmVhZCkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIEhSRVNVTFQgaHI7CiAgRFdPUkQgICBzaXplOwoKICBUUkFDRSgiKCVwLCVkLCVkLCVwLCVkLCVwLCVwKVxuIiwgaWZhY2UsIHN0YXJ0LCBzYW1wbGVzLCBidWZmZXIsCiAJYnVmZmVyc2l6ZSwgYnl0ZXNyZWFkLCBzYW1wbGVzcmVhZCk7CgogIC8qIGNsZWFyIHJldHVybiBwYXJhbWV0ZXJzIGlmIGdpdmVuICovCiAgaWYgKGJ5dGVzcmVhZCAhPSBOVUxMKQogICAgKmJ5dGVzcmVhZCA9IDA7CiAgaWYgKHNhbXBsZXNyZWFkICE9IE5VTEwpCiAgICAqc2FtcGxlc3JlYWQgPSAwOwoKICAvKiBEbyB3ZSBoYXZlIG91ciBjb21wcmVzc29yPyAqLwogIGlmIChUaGlzLT5oYXMgPT0gTlVMTCkgewogICAgaHIgPSBBVklGSUxFX09wZW5Db21wcmVzc29yKFRoaXMpOwoKICAgIGlmIChGQUlMRUQoaHIpKQogICAgICByZXR1cm4gaHI7CiAgfQoKICAvKiBvbmx5IG5lZWQgdG8gcGFzcyB0aHJvdWdoPyAqLwogIGlmIChUaGlzLT5jYkluRm9ybWF0ID09IFRoaXMtPmNiT3V0Rm9ybWF0ICYmCiAgICAgIG1lbWNtcChUaGlzLT5scEluRm9ybWF0LCBUaGlzLT5scE91dEZvcm1hdCwgVGhpcy0+Y2JJbkZvcm1hdCkgPT0gMCkgewogICAgcmV0dXJuIElBVklTdHJlYW1fUmVhZChUaGlzLT5wU3RyZWFtLCBzdGFydCwgc2FtcGxlcywgYnVmZmVyLCBidWZmZXJzaXplLAoJCQkgICBieXRlc3JlYWQsIHNhbXBsZXNyZWFkKTsKICB9CgogIC8qIHJlYWQgYXMgbXVjaCBhcyBmaXQ/ICovCiAgaWYgKHNhbXBsZXMgPT0gLTEpCiAgICBzYW1wbGVzID0gYnVmZmVyc2l6ZSAvIFRoaXMtPmxwT3V0Rm9ybWF0LT5uQmxvY2tBbGlnbjsKICAvKiBsaW1pdCB0byBidWZmZXJzaXplICovCiAgaWYgKHNhbXBsZXMgKiBUaGlzLT5scE91dEZvcm1hdC0+bkJsb2NrQWxpZ24gPiBidWZmZXJzaXplKQogICAgc2FtcGxlcyA9IGJ1ZmZlcnNpemUgLyBUaGlzLT5scE91dEZvcm1hdC0+bkJsb2NrQWxpZ247CgogIC8qIG9ubHkgcmV0dXJuIG5lZWRlZCBzaXplPyAqLwogIGlmIChidWZmZXIgPT0gTlVMTCB8fCBidWZmZXJzaXplIDw9IDAgfHwgc2FtcGxlcyA9PSAwKSB7CiAgICBpZiAoYnl0ZXNyZWFkID09IE5VTEwgJiYgc2FtcGxlc3JlYWQgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgICBpZiAoYnl0ZXNyZWFkICE9IE5VTEwpCiAgICAgICpieXRlc3JlYWQgPSBzYW1wbGVzICogVGhpcy0+bHBPdXRGb3JtYXQtPm5CbG9ja0FsaWduOwogICAgaWYgKHNhbXBsZXNyZWFkICE9IE5VTEwpCiAgICAgICpzYW1wbGVzcmVhZCA9IHNhbXBsZXM7CgogICAgcmV0dXJuIEFWSUVSUl9PSzsKICB9CgogIC8qIG1hcCBvdXIgcG9zaXRpb25zIHRvIHBTdHJlYW0gcG9zaXRpb25zICovCiAgQ09OVkVSVF9USElTX3RvX1NUUkVBTSgmc3RhcnQpOwoKICAvKiBvdXIgbmVlZGVkIGludGVybmFsIGJ1ZmZlcnNpemUgKi8KICBzaXplID0gc2FtcGxlcyAqIFRoaXMtPmxwSW5Gb3JtYXQtPm5CbG9ja0FsaWduOwoKICAvKiBOZWVkIHRvIGZyZWUgZGVzdGluYXRpb24gYnVmZmVyIHVzZWQgZm9yIHdyaXRpbmc/ICovCiAgaWYgKFRoaXMtPmFjbVN0cmVhbUhkci5wYkRzdCAhPSBOVUxMKSB7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5hY21TdHJlYW1IZHIucGJEc3QpOwogICAgVGhpcy0+YWNtU3RyZWFtSGRyLnBiRHN0ICAgICA9IE5VTEw7CiAgICBUaGlzLT5hY21TdHJlYW1IZHIuZHdEc3RVc2VyID0gMDsKICB9CgogIC8qIG5lZWQgYmlnZ2VyIHNvdXJjZSBidWZmZXI/ICovCiAgaWYgKFRoaXMtPmFjbVN0cmVhbUhkci5wYlNyYyA9PSBOVUxMIHx8CiAgICAgIFRoaXMtPmFjbVN0cmVhbUhkci5kd1NyY1VzZXIgPCBzaXplKSB7CiAgICBpZiAoVGhpcy0+YWNtU3RyZWFtSGRyLnBiU3JjID09IE5VTEwpCiAgICAgIFRoaXMtPmFjbVN0cmVhbUhkci5wYlNyYyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplKTsKICAgIGVsc2UKICAgICAgVGhpcy0+YWNtU3RyZWFtSGRyLnBiRHN0ID0gSGVhcFJlQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+YWNtU3RyZWFtSGRyLnBiU3JjLCBzaXplKTsKICAgIGlmIChUaGlzLT5hY21TdHJlYW1IZHIucGJTcmMgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgICBUaGlzLT5hY21TdHJlYW1IZHIuZHdTcmNVc2VyID0gc2l6ZTsKICB9CgogIFRoaXMtPmFjbVN0cmVhbUhkci5jYlN0cnVjdCA9IHNpemVvZihUaGlzLT5hY21TdHJlYW1IZHIpOwogIFRoaXMtPmFjbVN0cmVhbUhkci5jYlNyY0xlbmd0aFVzZWQgPSAwOwogIFRoaXMtPmFjbVN0cmVhbUhkci5jYkRzdExlbmd0aFVzZWQgPSAwOwogIFRoaXMtPmFjbVN0cmVhbUhkci5jYlNyY0xlbmd0aCAgICAgPSBzaXplOwoKICAvKiByZWFkIHNvdXJjZSBkYXRhICovCiAgaHIgPSBJQVZJU3RyZWFtX1JlYWQoVGhpcy0+cFN0cmVhbSwgc3RhcnQsIC0xLCBUaGlzLT5hY21TdHJlYW1IZHIucGJTcmMsCgkJICAgICAgIFRoaXMtPmFjbVN0cmVhbUhkci5jYlNyY0xlbmd0aCwKCQkgICAgICAgKExPTkcgKikmVGhpcy0+YWNtU3RyZWFtSGRyLmNiU3JjTGVuZ3RoLCBOVUxMKTsKICBpZiAoRkFJTEVEKGhyKSB8fCBUaGlzLT5hY21TdHJlYW1IZHIuY2JTcmNMZW5ndGggPT0gMCkKICAgIHJldHVybiBocjsKCiAgLyogbmVlZCB0byBwcmVwYXJlIHN0cmVhbT8gKi8KICBUaGlzLT5hY21TdHJlYW1IZHIucGJEc3QgICAgICAgPSBidWZmZXI7CiAgVGhpcy0+YWNtU3RyZWFtSGRyLmNiRHN0TGVuZ3RoID0gYnVmZmVyc2l6ZTsKICBpZiAoKFRoaXMtPmFjbVN0cmVhbUhkci5mZHdTdGF0dXMgJiBBQ01TVFJFQU1IRUFERVJfU1RBVFVTRl9QUkVQQVJFRCkgPT0gMCkgewogICAgaWYgKGFjbVN0cmVhbVByZXBhcmVIZWFkZXIoVGhpcy0+aGFzLCAmVGhpcy0+YWNtU3RyZWFtSGRyLCAwKSAhPSBTX09LKSB7CiAgICAgIFRoaXMtPmFjbVN0cmVhbUhkci5wYkRzdCAgICAgICA9IE5VTEw7CiAgICAgIFRoaXMtPmFjbVN0cmVhbUhkci5jYkRzdExlbmd0aCA9IDA7CiAgICAgIHJldHVybiBBVklFUlJfQ09NUFJFU1NPUjsKICAgIH0KICB9CgogIC8qIG5vdyBkbyB0aGUgY29udmVyc2lvbiAqLwogIC8qIEZJWE1FOiB1c2UgQUNNX0NPTlZFUlRGXyogZmxhZ3MgKi8KICBpZiAoYWNtU3RyZWFtQ29udmVydChUaGlzLT5oYXMsICZUaGlzLT5hY21TdHJlYW1IZHIsIDApICE9IFNfT0spCiAgICBociA9IEFWSUVSUl9DT01QUkVTU09SOwoKICBUaGlzLT5hY21TdHJlYW1IZHIucGJEc3QgICAgICAgPSBOVUxMOwogIFRoaXMtPmFjbVN0cmVhbUhkci5jYkRzdExlbmd0aCA9IDA7CgogIC8qIGZpbGwgb3V0IHJldHVybiBwYXJhbWV0ZXJzIGlmIGdpdmVuICovCiAgaWYgKGJ5dGVzcmVhZCAhPSBOVUxMKQogICAgKmJ5dGVzcmVhZCA9IFRoaXMtPmFjbVN0cmVhbUhkci5jYkRzdExlbmd0aFVzZWQ7CiAgaWYgKHNhbXBsZXNyZWFkICE9IE5VTEwpCiAgICAqc2FtcGxlc3JlYWQgPQogICAgICBUaGlzLT5hY21TdHJlYW1IZHIuY2JEc3RMZW5ndGhVc2VkIC8gVGhpcy0+bHBPdXRGb3JtYXQtPm5CbG9ja0FsaWduOwoKICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBBQ01TdHJlYW1fZm5Xcml0ZShJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBzdGFydCwKCQkJCQkgTE9ORyBzYW1wbGVzLCBMUFZPSUQgYnVmZmVyLAoJCQkJCSBMT05HIGJ1ZmZlcnNpemUsIERXT1JEIGZsYWdzLAoJCQkJCSBMUExPTkcgc2FtcHdyaXR0ZW4sCgkJCQkJIExQTE9ORyBieXRlc3dyaXR0ZW4pCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBIUkVTVUxUIGhyOwogIFVMT05HICAgc2l6ZTsKCiAgVFJBQ0UoIiglcCwlZCwlZCwlcCwlZCwweCUwOFgsJXAsJXApXG4iLCBpZmFjZSwgc3RhcnQsIHNhbXBsZXMsCglidWZmZXIsIGJ1ZmZlcnNpemUsIGZsYWdzLCBzYW1wd3JpdHRlbiwgYnl0ZXN3cml0dGVuKTsKCiAgLyogY2xlYXIgcmV0dXJuIHBhcmFtZXRlcnMgaWYgZ2l2ZW4gKi8KICBpZiAoc2FtcHdyaXR0ZW4gIT0gTlVMTCkKICAgICpzYW1wd3JpdHRlbiA9IDA7CiAgaWYgKGJ5dGVzd3JpdHRlbiAhPSBOVUxMKQogICAgKmJ5dGVzd3JpdHRlbiA9IDA7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoYnVmZmVyID09IE5VTEwgJiYgKGJ1ZmZlcnNpemUgPiAwIHx8IHNhbXBsZXMgPiAwKSkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIC8qIEhhdmUgd2Ugd3JpdGUgY2FwYWJpbGl0eT8gKi8KICBpZiAoKFRoaXMtPnNJbmZvLmR3Q2FwcyAmIEFWSUZJTEVDQVBTX0NBTldSSVRFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgLyogYWxzbyBuZWVkIGEgY29tcHJlc3NvciAqLwogIGlmIChUaGlzLT5oYXMgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTk9DT01QUkVTU09SOwoKICAvKiBtYXAgb3VyIHNpemVzIHRvIHBTdHJlYW0gc2l6ZXMgKi8KICBzaXplID0gYnVmZmVyc2l6ZTsKICBDT05WRVJUX1RISVNfdG9fU1RSRUFNKCZzaXplKTsKICBDT05WRVJUX1RISVNfdG9fU1RSRUFNKCZzdGFydCk7CgogIC8qIG5vIGJ5dGVzIHRvIHdyaXRlPyAtLSBzaG9ydCBjaXJjdWl0ICovCiAgaWYgKHNpemUgPT0gMCkgewogICAgcmV0dXJuIElBVklTdHJlYW1fV3JpdGUoVGhpcy0+cFN0cmVhbSwgLTEsIHNhbXBsZXMsIGJ1ZmZlciwgc2l6ZSwKCQkJICAgIGZsYWdzLCBzYW1wd3JpdHRlbiwgYnl0ZXN3cml0dGVuKTsKICB9CgogIC8qIE5lZWQgdG8gZnJlZSBzb3VyY2UgYnVmZmVyIHVzZWQgZm9yIHJlYWRpbmc/ICovCiAgaWYgKFRoaXMtPmFjbVN0cmVhbUhkci5wYlNyYyAhPSBOVUxMKSB7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5hY21TdHJlYW1IZHIucGJTcmMpOwogICAgVGhpcy0+YWNtU3RyZWFtSGRyLnBiU3JjICAgICA9IE5VTEw7CiAgICBUaGlzLT5hY21TdHJlYW1IZHIuZHdTcmNVc2VyID0gMDsKICB9CgogIC8qIE5lZWQgYmlnZ2VyIGRlc3RpbmF0aW9uIGJ1ZmZlcj8gKi8KICBpZiAoVGhpcy0+YWNtU3RyZWFtSGRyLnBiRHN0ID09IE5VTEwgfHwKICAgICAgVGhpcy0+YWNtU3RyZWFtSGRyLmR3RHN0VXNlciA8IHNpemUpIHsKICAgIGlmIChUaGlzLT5hY21TdHJlYW1IZHIucGJEc3QgPT0gTlVMTCkKICAgICAgVGhpcy0+YWNtU3RyZWFtSGRyLnBiRHN0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemUpOwogICAgZWxzZQogICAgICBUaGlzLT5hY21TdHJlYW1IZHIucGJEc3QgPSBIZWFwUmVBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5hY21TdHJlYW1IZHIucGJEc3QsIHNpemUpOwogICAgaWYgKFRoaXMtPmFjbVN0cmVhbUhkci5wYkRzdCA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKICAgIFRoaXMtPmFjbVN0cmVhbUhkci5kd0RzdFVzZXIgPSBzaXplOwogIH0KICBUaGlzLT5hY21TdHJlYW1IZHIuY2JTdHJ1Y3QgICAgICAgID0gc2l6ZW9mKFRoaXMtPmFjbVN0cmVhbUhkcik7CiAgVGhpcy0+YWNtU3RyZWFtSGRyLmNiU3JjTGVuZ3RoVXNlZCA9IDA7CiAgVGhpcy0+YWNtU3RyZWFtSGRyLmNiRHN0TGVuZ3RoVXNlZCA9IDA7CiAgVGhpcy0+YWNtU3RyZWFtSGRyLmNiRHN0TGVuZ3RoICAgICA9IFRoaXMtPmFjbVN0cmVhbUhkci5kd0RzdFVzZXI7CgogIC8qIG5lZWQgdG8gcHJlcGFyZSBzdHJlYW0/ICovCiAgVGhpcy0+YWNtU3RyZWFtSGRyLnBiU3JjICAgICAgID0gYnVmZmVyOwogIFRoaXMtPmFjbVN0cmVhbUhkci5jYlNyY0xlbmd0aCA9IGJ1ZmZlcnNpemU7CiAgaWYgKChUaGlzLT5hY21TdHJlYW1IZHIuZmR3U3RhdHVzICYgQUNNU1RSRUFNSEVBREVSX1NUQVRVU0ZfUFJFUEFSRUQpID09IDApIHsKICAgIGlmIChhY21TdHJlYW1QcmVwYXJlSGVhZGVyKFRoaXMtPmhhcywgJlRoaXMtPmFjbVN0cmVhbUhkciwgMCkgIT0gU19PSykgewogICAgICBUaGlzLT5hY21TdHJlYW1IZHIucGJTcmMgICAgICAgPSBOVUxMOwogICAgICBUaGlzLT5hY21TdHJlYW1IZHIuY2JTcmNMZW5ndGggPSAwOwogICAgICByZXR1cm4gQVZJRVJSX0NPTVBSRVNTT1I7CiAgICB9CiAgfQoKICAvKiBub3cgZG8gdGhlIGNvbnZlcnNpb24gKi8KICAvKiBGSVhNRTogdXNlIEFDTV9DT05WRVJURl8qIGZsYWdzICovCiAgaWYgKGFjbVN0cmVhbUNvbnZlcnQoVGhpcy0+aGFzLCAmVGhpcy0+YWNtU3RyZWFtSGRyLCAwKSAhPSBTX09LKQogICAgaHIgPSBBVklFUlJfQ09NUFJFU1NPUjsKICBlbHNlCiAgICBociA9IEFWSUVSUl9PSzsKCiAgVGhpcy0+YWNtU3RyZWFtSGRyLnBiU3JjICAgICAgID0gTlVMTDsKICBUaGlzLT5hY21TdHJlYW1IZHIuY2JTcmNMZW5ndGggPSAwOwoKICBpZiAoRkFJTEVEKGhyKSkKICAgIHJldHVybiBocjsKCiAgcmV0dXJuIElBVklTdHJlYW1fV3JpdGUoVGhpcy0+cFN0cmVhbSwtMSxUaGlzLT5hY21TdHJlYW1IZHIuY2JEc3RMZW5ndGhVc2VkIC8KCQkJICBUaGlzLT5scE91dEZvcm1hdC0+bkJsb2NrQWxpZ24sVGhpcy0+YWNtU3RyZWFtSGRyLnBiRHN0LAoJCQkgIFRoaXMtPmFjbVN0cmVhbUhkci5jYkRzdExlbmd0aFVzZWQsZmxhZ3Msc2FtcHdyaXR0ZW4sCgkJCSAgYnl0ZXN3cml0dGVuKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIEFDTVN0cmVhbV9mbkRlbGV0ZShJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBzdGFydCwKCQkJCQkgIExPTkcgc2FtcGxlcykKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJWQsJWQpXG4iLCBpZmFjZSwgc3RhcnQsIHNhbXBsZXMpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKHN0YXJ0IDwgMCB8fCBzYW1wbGVzIDwgMCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIC8qIERlbGV0ZSBiZWZvcmUgc3RhcnQgb2Ygc3RyZWFtPyAqLwogIGlmICgoRFdPUkQpKHN0YXJ0ICsgc2FtcGxlcykgPCBUaGlzLT5zSW5mby5kd1N0YXJ0KQogICAgcmV0dXJuIEFWSUVSUl9PSzsKCiAgLyogRGVsZXRlIGFmdGVyIGVuZCBvZiBzdHJlYW0/ICovCiAgaWYgKChEV09SRClzdGFydCA+IFRoaXMtPnNJbmZvLmR3TGVuZ3RoKQogICAgcmV0dXJuIEFWSUVSUl9PSzsKCiAgLyogRm9yIHRoZSByZXN0IHdlIG5lZWQgd3JpdGUgY2FwYWJpbGl0eSAqLwogIGlmICgoVGhpcy0+c0luZm8uZHdDYXBzICYgQVZJRklMRUNBUFNfQ0FOV1JJVEUpID09IDApCiAgICByZXR1cm4gQVZJRVJSX1JFQURPTkxZOwoKICAvKiBBIGNvbXByZXNzb3IgaXMgYWxzbyBuZWNlc3NhcnkgKi8KICBpZiAoVGhpcy0+aGFzID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX05PQ09NUFJFU1NPUjsKCiAgLyogbWFwIG91ciBwb3NpdGlvbnMgdG8gcFN0cmVhbSBwb3NpdGlvbnMgKi8KICBDT05WRVJUX1RISVNfdG9fU1RSRUFNKCZzdGFydCk7CiAgQ09OVkVSVF9USElTX3RvX1NUUkVBTSgmc2FtcGxlcyk7CgogIHJldHVybiBJQVZJU3RyZWFtX0RlbGV0ZShUaGlzLT5wU3RyZWFtLCBzdGFydCwgc2FtcGxlcyk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBBQ01TdHJlYW1fZm5SZWFkRGF0YShJQVZJU3RyZWFtICppZmFjZSwgRFdPUkQgZmNjLAoJCQkJCSAgICBMUFZPSUQgbHAsIExQTE9ORyBscHJlYWQpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLDB4JTA4WCwlcCwlcClcbiIsIGlmYWNlLCBmY2MsIGxwLCBscHJlYWQpOwoKICBhc3NlcnQoVGhpcy0+cFN0cmVhbSAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklTdHJlYW1fUmVhZERhdGEoVGhpcy0+cFN0cmVhbSwgZmNjLCBscCwgbHByZWFkKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIEFDTVN0cmVhbV9mbldyaXRlRGF0YShJQVZJU3RyZWFtICppZmFjZSwgRFdPUkQgZmNjLAoJCQkJCSAgICAgTFBWT0lEIGxwLCBMT05HIHNpemUpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLDB4JTA4eCwlcCwlZClcbiIsIGlmYWNlLCBmY2MsIGxwLCBzaXplKTsKCiAgYXNzZXJ0KFRoaXMtPnBTdHJlYW0gIT0gTlVMTCk7CgogIHJldHVybiBJQVZJU3RyZWFtX1dyaXRlRGF0YShUaGlzLT5wU3RyZWFtLCBmY2MsIGxwLCBzaXplKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIEFDTVN0cmVhbV9mblNldEluZm8oSUFWSVN0cmVhbSAqaWZhY2UsCgkJCQkJICAgTFBBVklTVFJFQU1JTkZPVyBpbmZvLCBMT05HIGluZm9sZW4pCnsKICBGSVhNRSgiKCVwLCVwLCVkKTogc3R1YlxuIiwgaWZhY2UsIGluZm8sIGluZm9sZW4pOwoKICByZXR1cm4gRV9GQUlMOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX09wZW5Db21wcmVzc29yKElBVklTdHJlYW1JbXBsICpUaGlzKQp7CiAgSFJFU1VMVCBocjsKCiAgLyogcHJlLWNvbmRpdGlvbnMgKi8KICBhc3NlcnQoVGhpcyAhPSBOVUxMKTsKICBhc3NlcnQoVGhpcy0+cFN0cmVhbSAhPSBOVUxMKTsKCiAgaWYgKFRoaXMtPmhhcyAhPSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9PSzsKCiAgaWYgKFRoaXMtPmxwSW5Gb3JtYXQgPT0gTlVMTCkgewogICAgLyogZGVjb2RlIG9yIGVuY29kZSB0aGUgZGF0YSBmcm9tIHBTdHJlYW0gKi8KICAgIGhyID0gQVZJU3RyZWFtRm9ybWF0U2l6ZShUaGlzLT5wU3RyZWFtLCBUaGlzLT5zSW5mby5kd1N0YXJ0LCAmVGhpcy0+Y2JJbkZvcm1hdCk7CiAgICBpZiAoRkFJTEVEKGhyKSkKICAgICAgcmV0dXJuIGhyOwogICAgVGhpcy0+bHBJbkZvcm1hdCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5jYkluRm9ybWF0KTsKICAgIGlmIChUaGlzLT5scEluRm9ybWF0ID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICAgIGhyID0gSUFWSVN0cmVhbV9SZWFkRm9ybWF0KFRoaXMtPnBTdHJlYW0sIFRoaXMtPnNJbmZvLmR3U3RhcnQsCgkJCSAgICAgICBUaGlzLT5scEluRm9ybWF0LCAmVGhpcy0+Y2JJbkZvcm1hdCk7CiAgICBpZiAoRkFJTEVEKGhyKSkKICAgICAgcmV0dXJuIGhyOwoKICAgIGlmIChUaGlzLT5scE91dEZvcm1hdCA9PSBOVUxMKSB7CiAgICAgIC8qIHdlIG11c3QgZGVjb2RlIHRvIGRlZmF1bHQgZm9ybWF0ICovCiAgICAgIFRoaXMtPmNiT3V0Rm9ybWF0ID0gc2l6ZW9mKFBDTVdBVkVGT1JNQVQpOwogICAgICBUaGlzLT5scE91dEZvcm1hdCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5jYk91dEZvcm1hdCk7CiAgICAgIGlmIChUaGlzLT5scE91dEZvcm1hdCA9PSBOVUxMKQoJcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogICAgICBUaGlzLT5scE91dEZvcm1hdC0+d0Zvcm1hdFRhZyA9IFdBVkVfRk9STUFUX1BDTTsKICAgICAgaWYgKGFjbUZvcm1hdFN1Z2dlc3QoTlVMTCwgVGhpcy0+bHBJbkZvcm1hdCwgVGhpcy0+bHBPdXRGb3JtYXQsCgkJCSAgIFRoaXMtPmNiT3V0Rm9ybWF0LCBBQ01fRk9STUFUU1VHR0VTVEZfV0ZPUk1BVFRBRykgIT0gU19PSykKCXJldHVybiBBVklFUlJfTk9DT01QUkVTU09SOwogICAgfQogIH0gZWxzZSBpZiAoVGhpcy0+bHBPdXRGb3JtYXQgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfRVJST1I7IC8qIFRvIHdoYXQgc2hvdWxkIEkgZW5jb2RlPyAqLwoKICBpZiAoYWNtU3RyZWFtT3BlbigmVGhpcy0+aGFzLCBOVUxMLCBUaGlzLT5scEluRm9ybWF0LCBUaGlzLT5scE91dEZvcm1hdCwKCQkgICAgTlVMTCwgMCwgMCwgQUNNX1NUUkVBTU9QRU5GX05PTlJFQUxUSU1FKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9OT0NPTVBSRVNTT1I7CgogIC8qIHVwZGF0ZSBBVklTVFJFQU1JTkZPIHN0cnVjdHVyZSAqLwogIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSA9IFRoaXMtPmxwT3V0Rm9ybWF0LT5uQmxvY2tBbGlnbjsKICBUaGlzLT5zSW5mby5kd1NjYWxlICAgICAgPSBUaGlzLT5scE91dEZvcm1hdC0+bkJsb2NrQWxpZ247CiAgVGhpcy0+c0luZm8uZHdSYXRlICAgICAgID0gVGhpcy0+bHBPdXRGb3JtYXQtPm5BdmdCeXRlc1BlclNlYzsKICBUaGlzLT5zSW5mby5kd1F1YWxpdHkgICAgPSAoRFdPUkQpSUNRVUFMSVRZX0RFRkFVTFQ7CiAgU2V0UmVjdEVtcHR5KCZUaGlzLT5zSW5mby5yY0ZyYW1lKTsKCiAgLyogY29udmVydCBwb3NpdGlvbnMgYW5zZCBzaXplcyB0byBvdXRwdXQgZm9ybWF0ICovCiAgQ09OVkVSVF9TVFJFQU1fdG9fVEhJUygmVGhpcy0+c0luZm8uZHdTdGFydCk7CiAgQ09OVkVSVF9TVFJFQU1fdG9fVEhJUygmVGhpcy0+c0luZm8uZHdMZW5ndGgpOwogIENPTlZFUlRfU1RSRUFNX3RvX1RISVMoJlRoaXMtPnNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSk7CgogIHJldHVybiBBVklFUlJfT0s7Cn0K