LyoKICogQ29weXJpZ2h0IDIwMDIgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgojaW5jbHVkZSA8YXNzZXJ0Lmg+CiNpbmNsdWRlIDxzdGRhcmcuaD4KCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmdkaS5oIgojaW5jbHVkZSAid2ludXNlci5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIm1tc3lzdGVtLmgiCiNpbmNsdWRlICJ2ZncuaCIKCiNpbmNsdWRlICJhdmlmaWxlX3ByaXZhdGUuaCIKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChhdmlmaWxlKTsKCiNkZWZpbmUgTUFYX0ZSQU1FU0laRSAgICAgICAoMTYgKiAxMDI0ICogMTAyNCkKI2RlZmluZSBNQVhfRlJBTUVTSVpFX0RJRkYgIDUxMgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElDTVN0cmVhbV9mblF1ZXJ5SW50ZXJmYWNlKElBVklTdHJlYW0qaWZhY2UsUkVGSUlEIHJlZmlpZCxMUFZPSUQgKm9iaik7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJQ01TdHJlYW1fZm5BZGRSZWYoSUFWSVN0cmVhbSppZmFjZSk7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJQ01TdHJlYW1fZm5SZWxlYXNlKElBVklTdHJlYW0qIGlmYWNlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElDTVN0cmVhbV9mbkNyZWF0ZShJQVZJU3RyZWFtKmlmYWNlLExQQVJBTSBsUGFyYW0xLExQQVJBTSBsUGFyYW0yKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElDTVN0cmVhbV9mbkluZm8oSUFWSVN0cmVhbSppZmFjZSxBVklTVFJFQU1JTkZPVyAqcHNpLExPTkcgc2l6ZSk7CnN0YXRpYyBMT05HICAgIFdJTkFQSSBJQ01TdHJlYW1fZm5GaW5kU2FtcGxlKElBVklTdHJlYW0qaWZhY2UsTE9ORyBwb3MsTE9ORyBmbGFncyk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQ01TdHJlYW1fZm5SZWFkRm9ybWF0KElBVklTdHJlYW0qaWZhY2UsTE9ORyBwb3MsTFBWT0lEIGZvcm1hdCxMT05HICpmb3JtYXRzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElDTVN0cmVhbV9mblNldEZvcm1hdChJQVZJU3RyZWFtKmlmYWNlLExPTkcgcG9zLExQVk9JRCBmb3JtYXQsTE9ORyBmb3JtYXRzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElDTVN0cmVhbV9mblJlYWQoSUFWSVN0cmVhbSppZmFjZSxMT05HIHN0YXJ0LExPTkcgc2FtcGxlcyxMUFZPSUQgYnVmZmVyLExPTkcgYnVmZmVyc2l6ZSxMT05HICpieXRlc3JlYWQsTE9ORyAqc2FtcGxlc3JlYWQpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUNNU3RyZWFtX2ZuV3JpdGUoSUFWSVN0cmVhbSppZmFjZSxMT05HIHN0YXJ0LExPTkcgc2FtcGxlcyxMUFZPSUQgYnVmZmVyLExPTkcgYnVmZmVyc2l6ZSxEV09SRCBmbGFncyxMT05HICpzYW1wd3JpdHRlbixMT05HICpieXRlc3dyaXR0ZW4pOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUNNU3RyZWFtX2ZuRGVsZXRlKElBVklTdHJlYW0qaWZhY2UsTE9ORyBzdGFydCxMT05HIHNhbXBsZXMpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUNNU3RyZWFtX2ZuUmVhZERhdGEoSUFWSVN0cmVhbSppZmFjZSxEV09SRCBmY2MsTFBWT0lEIGxwLExPTkcgKmxwcmVhZCk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQ01TdHJlYW1fZm5Xcml0ZURhdGEoSUFWSVN0cmVhbSppZmFjZSxEV09SRCBmY2MsTFBWT0lEIGxwLExPTkcgc2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQ01TdHJlYW1fZm5TZXRJbmZvKElBVklTdHJlYW0qaWZhY2UsQVZJU1RSRUFNSU5GT1cqaW5mbyxMT05HIGluZm9sZW4pOwoKc3RhdGljIGNvbnN0IHN0cnVjdCBJQVZJU3RyZWFtVnRibCBpaWNtc3QgPSB7CiAgSUNNU3RyZWFtX2ZuUXVlcnlJbnRlcmZhY2UsCiAgSUNNU3RyZWFtX2ZuQWRkUmVmLAogIElDTVN0cmVhbV9mblJlbGVhc2UsCiAgSUNNU3RyZWFtX2ZuQ3JlYXRlLAogIElDTVN0cmVhbV9mbkluZm8sCiAgSUNNU3RyZWFtX2ZuRmluZFNhbXBsZSwKICBJQ01TdHJlYW1fZm5SZWFkRm9ybWF0LAogIElDTVN0cmVhbV9mblNldEZvcm1hdCwKICBJQ01TdHJlYW1fZm5SZWFkLAogIElDTVN0cmVhbV9mbldyaXRlLAogIElDTVN0cmVhbV9mbkRlbGV0ZSwKICBJQ01TdHJlYW1fZm5SZWFkRGF0YSwKICBJQ01TdHJlYW1fZm5Xcml0ZURhdGEsCiAgSUNNU3RyZWFtX2ZuU2V0SW5mbwp9OwoKdHlwZWRlZiBzdHJ1Y3QgX0lBVklTdHJlYW1JbXBsIHsKICAvKiBJVW5rbm93biBzdHVmZiAqLwogIGNvbnN0IElBVklTdHJlYW1WdGJsICpscFZ0Ymw7CiAgTE9ORwkJICAgICByZWY7CgogIC8qIElBVklTdHJlYW0gc3R1ZmYgKi8KICBQQVZJU1RSRUFNICAgICAgICAgcFN0cmVhbTsKICBBVklTVFJFQU1JTkZPVyAgICAgc0luZm87CgogIFBHRVRGUkFNRSAgICAgICAgICBwZzsKICBISUMgICAgICAgICAgICAgICAgaGljOwogIERXT1JEICAgICAgICAgICAgICBkd0lDTUZsYWdzOwoKICBMT05HICAgICAgICAgICAgICAgbEN1cnJlbnQ7CiAgTE9ORyAgICAgICAgICAgICAgIGxMYXN0S2V5OwogIExPTkcgICAgICAgICAgICAgICBsS2V5RnJhbWVFdmVyeTsKICBEV09SRCAgICAgICAgICAgICAgZHdMYXN0UXVhbGl0eTsKICBEV09SRCAgICAgICAgICAgICAgZHdCeXRlc1BlckZyYW1lOwogIERXT1JEICAgICAgICAgICAgICBkd1VudXNlZEJ5dGVzOwoKICBMUEJJVE1BUElORk9IRUFERVIgbHBiaUN1cjsgIC8qIGN1cnJlbnQgZnJhbWUgKi8KICBMUFZPSUQgICAgICAgICAgICAgbHBDdXI7CiAgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmlQcmV2OyAvKiBwcmV2aW91cyBmcmFtZSAqLwogIExQVk9JRCAgICAgICAgICAgICBscFByZXY7CgogIExQQklUTUFQSU5GT0hFQURFUiBscGJpT3V0cHV0OyAvKiBvdXRwdXQgZm9ybWF0IG9mIGNvZGVjICovCiAgTE9ORyAgICAgICAgICAgICAgIGNiT3V0cHV0OwogIExQQklUTUFQSU5GT0hFQURFUiBscGJpSW5wdXQ7ICAvKiBpbnB1dCBmb3JtYXQgZm9yIGNvZGVjICovCiAgTE9ORyAgICAgICAgICAgICAgIGNiSW5wdXQ7Cn0gSUFWSVN0cmVhbUltcGw7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX0VuY29kZUZyYW1lKElBVklTdHJlYW1JbXBsICpUaGlzLAoJCQkJICAgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmksIExQVk9JRCBscEJpdHMpOwpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX09wZW5HZXRGcmFtZShJQVZJU3RyZWFtSW1wbCAqVGhpcyk7CgpzdGF0aWMgaW5saW5lIHZvaWQgQVZJRklMRV9SZXNldChJQVZJU3RyZWFtSW1wbCAqVGhpcykKewogIFRoaXMtPmxDdXJyZW50ICAgICAgPSAtMTsKICBUaGlzLT5sTGFzdEtleSAgICAgID0gMDsKICBUaGlzLT5kd0xhc3RRdWFsaXR5ID0gSUNRVUFMSVRZX0hJR0g7CiAgVGhpcy0+ZHdVbnVzZWRCeXRlcyA9IDA7Cn0KCkhSRVNVTFQgQVZJRklMRV9DcmVhdGVJQ01TdHJlYW0oUkVGSUlEIHJpaWQsIExQVk9JRCAqcHB2KQp7CiAgSUFWSVN0cmVhbUltcGwgKnBzdHJlYW07CiAgSFJFU1VMVCAgICAgICAgIGhyOwoKICBhc3NlcnQocmlpZCAhPSBOVUxMICYmIHBwdiAhPSBOVUxMKTsKCiAgKnBwdiA9IE5VTEw7CgogIHBzdHJlYW0gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKElBVklTdHJlYW1JbXBsKSk7CiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICBwc3RyZWFtLT5scFZ0YmwgID0gJmlpY21zdDsKICBBVklGSUxFX1Jlc2V0KHBzdHJlYW0pOwoKICBociA9IElBVklTdHJlYW1fUXVlcnlJbnRlcmZhY2UoKElBVklTdHJlYW0qKXBzdHJlYW0sIHJpaWQsIHBwdik7CiAgaWYgKEZBSUxFRChocikpCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwc3RyZWFtKTsKCiAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUNNU3RyZWFtX2ZuUXVlcnlJbnRlcmZhY2UoSUFWSVN0cmVhbSAqaWZhY2UsCgkJCQkJCSAgUkVGSUlEIHJlZmlpZCwgTFBWT0lEICpvYmopCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVzLCVwKVxuIiwgaWZhY2UsIGRlYnVnc3RyX2d1aWQocmVmaWlkKSwgb2JqKTsKCiAgaWYgKElzRXF1YWxHVUlEKCZJSURfSVVua25vd24sIHJlZmlpZCkgfHwKICAgICAgSXNFcXVhbEdVSUQoJklJRF9JQVZJU3RyZWFtLCByZWZpaWQpKSB7CiAgICAqb2JqID0gVGhpczsKICAgIElBVklTdHJlYW1fQWRkUmVmKGlmYWNlKTsKCiAgICByZXR1cm4gU19PSzsKICB9CgogIHJldHVybiBPTEVfRV9FTlVNX05PTU9SRTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBJQ01TdHJlYW1fZm5BZGRSZWYoSUFWSVN0cmVhbSAqaWZhY2UpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwogIFVMT05HIHJlZiA9IEludGVybG9ja2VkSW5jcmVtZW50KCZUaGlzLT5yZWYpOwoKICBUUkFDRSgiKCVwKSAtPiAlZFxuIiwgaWZhY2UsIHJlZik7CgogIC8qIGFsc28gYWRkIHJlZmVyZW5jZSB0byB0aGUgbmVzdGVkIHN0cmVhbSAqLwogIGlmIChUaGlzLT5wU3RyZWFtICE9IE5VTEwpCiAgICBJQVZJU3RyZWFtX0FkZFJlZihUaGlzLT5wU3RyZWFtKTsKCiAgcmV0dXJuIHJlZjsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBJQ01TdHJlYW1fZm5SZWxlYXNlKElBVklTdHJlYW0qIGlmYWNlKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+cmVmKTsKCiAgVFJBQ0UoIiglcCkgLT4gJWRcbiIsIGlmYWNlLCByZWYpOwoKICBpZiAocmVmID09IDApIHsKICAgIC8qIGRlc3RydWN0ICovCiAgICBpZiAoVGhpcy0+cGcgIT0gTlVMTCkgewogICAgICBBVklTdHJlYW1HZXRGcmFtZUNsb3NlKFRoaXMtPnBnKTsKICAgICAgVGhpcy0+cGcgPSBOVUxMOwogICAgfQogICAgaWYgKFRoaXMtPnBTdHJlYW0gIT0gTlVMTCkgewogICAgICBJQVZJU3RyZWFtX1JlbGVhc2UoVGhpcy0+cFN0cmVhbSk7CiAgICAgIFRoaXMtPnBTdHJlYW0gPSBOVUxMOwogICAgfQogICAgaWYgKFRoaXMtPmhpYyAhPSBOVUxMKSB7CiAgICAgIGlmIChUaGlzLT5scGJpUHJldiAhPSBOVUxMKSB7CglJQ0RlY29tcHJlc3NFbmQoVGhpcy0+aGljKTsKCUhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPmxwYmlQcmV2KTsKCVRoaXMtPmxwYmlQcmV2ID0gTlVMTDsKCVRoaXMtPmxwUHJldiAgID0gTlVMTDsKICAgICAgfQogICAgICBJQ0NvbXByZXNzRW5kKFRoaXMtPmhpYyk7CiAgICAgIFRoaXMtPmhpYyA9IE5VTEw7CiAgICB9CiAgICBpZiAoVGhpcy0+bHBiaUN1ciAhPSBOVUxMKSB7CiAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPmxwYmlDdXIpOwogICAgICBUaGlzLT5scGJpQ3VyID0gTlVMTDsKICAgICAgVGhpcy0+bHBDdXIgICA9IE5VTEw7CiAgICB9CiAgICBpZiAoVGhpcy0+bHBiaU91dHB1dCAhPSBOVUxMKSB7CiAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPmxwYmlPdXRwdXQpOwogICAgICBUaGlzLT5scGJpT3V0cHV0ID0gTlVMTDsKICAgICAgVGhpcy0+Y2JPdXRwdXQgICA9IDA7CiAgICB9CiAgICBpZiAoVGhpcy0+bHBiaUlucHV0ICE9IE5VTEwpIHsKICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+bHBiaUlucHV0KTsKICAgICAgVGhpcy0+bHBiaUlucHV0ID0gTlVMTDsKICAgICAgVGhpcy0+Y2JJbnB1dCAgID0gMDsKICAgIH0KCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzKTsKCiAgICByZXR1cm4gMDsKICB9CgogIC8qIGFsc28gcmVsZWFzZSByZWZlcmVuY2UgdG8gdGhlIG5lc3RlZCBzdHJlYW0gKi8KICBpZiAoVGhpcy0+cFN0cmVhbSAhPSBOVUxMKQogICAgSUFWSVN0cmVhbV9SZWxlYXNlKFRoaXMtPnBTdHJlYW0pOwoKICByZXR1cm4gcmVmOwp9CgovKiBsUGFyYW0xOiBQQVZJU1RSRUFNCiAqIGxQYXJhbTI6IExQQVZJQ09NUFJFU1NPUFRJT05TCiAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUNNU3RyZWFtX2ZuQ3JlYXRlKElBVklTdHJlYW0gKmlmYWNlLCBMUEFSQU0gbFBhcmFtMSwKCQkJCQkgIExQQVJBTSBsUGFyYW0yKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgSUNJTkZPICAgICAgICAgICAgICAgaWNpbmZvOwogIElDQ09NUFJFU1NGUkFNRVMgICAgIGljRnJhbWVzOwogIExQQVZJQ09NUFJFU1NPUFRJT05TIHBjbyA9IChMUEFWSUNPTVBSRVNTT1BUSU9OUylsUGFyYW0yOwoKICBUUkFDRSgiKCVwLDB4JTA4bFgsMHglMDhsWClcbiIsIGlmYWNlLCBsUGFyYW0xLCBsUGFyYW0yKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVyICovCiAgaWYgKChMUFZPSUQpbFBhcmFtMSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogZ2V0IGluZm9zIGZyb20gc3RyZWFtICovCiAgSUFWSVN0cmVhbV9JbmZvKChQQVZJU1RSRUFNKWxQYXJhbTEsICZUaGlzLT5zSW5mbywgc2l6ZW9mKFRoaXMtPnNJbmZvKSk7CiAgaWYgKFRoaXMtPnNJbmZvLmZjY1R5cGUgIT0gc3RyZWFtdHlwZVZJREVPKQogICAgcmV0dXJuIEFWSUVSUl9FUlJPUjsgLyogZXJyb3IgaW4gcmVnaXN0cnkgb3IgQVZJTWFrZUNvbXByZXNzZWRTdHJlYW0gKi8KCiAgLyogYWRkIHJlZmVyZW5jZSB0byB0aGUgc3RyZWFtICovCiAgVGhpcy0+cFN0cmVhbSA9IChQQVZJU1RSRUFNKWxQYXJhbTE7CiAgSUFWSVN0cmVhbV9BZGRSZWYoVGhpcy0+cFN0cmVhbSk7CgogIEFWSUZJTEVfUmVzZXQoVGhpcyk7CgogIGlmIChwY28gIT0gTlVMTCAmJiBwY28tPmZjY0hhbmRsZXIgIT0gY29tcHR5cGVESUIpIHsKICAgIC8qIHdlIHNob3VsZCBjb21wcmVzcyAqLwogICAgVGhpcy0+c0luZm8uZmNjSGFuZGxlciA9IHBjby0+ZmNjSGFuZGxlcjsKCiAgICBUaGlzLT5oaWMgPSBJQ09wZW4oSUNUWVBFX1ZJREVPLCBwY28tPmZjY0hhbmRsZXIsIElDTU9ERV9DT01QUkVTUyk7CiAgICBpZiAoVGhpcy0+aGljID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTk9DT01QUkVTU09SOwoKICAgIC8qIHJlc3RvcmUgc2F2ZWQgc3RhdGUgb2YgY29kZWMgKi8KICAgIGlmIChwY28tPmNiUGFybXMgPiAwICYmIHBjby0+bHBQYXJtcyAhPSBOVUxMKSB7CiAgICAgIElDU2V0U3RhdGUoVGhpcy0+aGljLCBwY28tPmxwUGFybXMsIHBjby0+Y2JQYXJtcyk7CiAgICB9CgogICAgLyogc2V0IHF1YWxpdHkgLS0gcmVzb2x2ZSBkZWZhdWx0IHF1YWxpdHkgKi8KICAgIFRoaXMtPnNJbmZvLmR3UXVhbGl0eSA9IHBjby0+ZHdRdWFsaXR5OwogICAgaWYgKHBjby0+ZHdRdWFsaXR5ID09IElDUVVBTElUWV9ERUZBVUxUKQogICAgICBUaGlzLT5zSW5mby5kd1F1YWxpdHkgPSBJQ0dldERlZmF1bHRRdWFsaXR5KFRoaXMtPmhpYyk7CgogICAgLyogZ2V0IGNhcGFiaWxpdGllcyBvZiBjb2RlYyAqLwogICAgSUNHZXRJbmZvKFRoaXMtPmhpYywgJmljaW5mbywgc2l6ZW9mKGljaW5mbykpOwogICAgVGhpcy0+ZHdJQ01GbGFncyA9IGljaW5mby5kd0ZsYWdzOwoKICAgIC8qIHVzZSBrZXlmcmFtZXM/ICovCiAgICBpZiAoKHBjby0+ZHdGbGFncyAmIEFWSUNPTVBSRVNTRl9LRVlGUkFNRVMpICYmCgkoaWNpbmZvLmR3RmxhZ3MgJiAoVklEQ0ZfVEVNUE9SQUx8VklEQ0ZfRkFTVFRFTVBPUkFMQykpKSB7CiAgICAgIFRoaXMtPmxLZXlGcmFtZUV2ZXJ5ID0gcGNvLT5kd0tleUZyYW1lRXZlcnk7CiAgICB9IGVsc2UKICAgICAgVGhpcy0+bEtleUZyYW1lRXZlcnkgPSAxOwoKICAgIC8qIHVzZSBkYXRhcmF0ZT8gKi8KICAgIGlmICgocGNvLT5kd0ZsYWdzICYgQVZJQ09NUFJFU1NGX0RBVEFSQVRFKSkgewogICAgICAvKiBEbyB3ZSBoYXZlIGEgY2hhbmNlIHRvIHJlZHVjZSBzaXplIHRvIGRlc2lyZWQgb25lPyAqLwogICAgICBpZiAoKGljaW5mby5kd0ZsYWdzICYgKFZJRENGX0NSVU5DSHxWSURDRl9RVUFMSVRZKSkgPT0gMCkKCXJldHVybiBBVklFUlJfTk9DT01QUkVTU09SOwoKICAgICAgYXNzZXJ0KFRoaXMtPnNJbmZvLmR3UmF0ZSAhPSAwKTsKCiAgICAgIFRoaXMtPmR3Qnl0ZXNQZXJGcmFtZSA9IE11bERpdihwY28tPmR3Qnl0ZXNQZXJTZWNvbmQsCgkJCQkgICAgIFRoaXMtPnNJbmZvLmR3U2NhbGUsIFRoaXMtPnNJbmZvLmR3UmF0ZSk7CiAgICB9IGVsc2UgewogICAgICBwY28tPmR3Qnl0ZXNQZXJTZWNvbmQgPSAwOwogICAgICBUaGlzLT5kd0J5dGVzUGVyRnJhbWUgPSAwOwogICAgfQoKICAgIGlmIChpY2luZm8uZHdGbGFncyAmIFZJRENGX0NPTVBSRVNTRlJBTUVTKSB7CiAgICAgIG1lbXNldCgmaWNGcmFtZXMsIDAsIHNpemVvZihpY0ZyYW1lcykpOwogICAgICBpY0ZyYW1lcy5scGJpT3V0cHV0ICA9IFRoaXMtPmxwYmlPdXRwdXQ7CiAgICAgIGljRnJhbWVzLmxwYmlJbnB1dCAgID0gVGhpcy0+bHBiaUlucHV0OwogICAgICBpY0ZyYW1lcy5sRnJhbWVDb3VudCA9IFRoaXMtPnNJbmZvLmR3TGVuZ3RoOwogICAgICBpY0ZyYW1lcy5sUXVhbGl0eSAgICA9IFRoaXMtPnNJbmZvLmR3UXVhbGl0eTsKICAgICAgaWNGcmFtZXMubERhdGFSYXRlICAgPSBwY28tPmR3Qnl0ZXNQZXJTZWNvbmQ7CiAgICAgIGljRnJhbWVzLmxLZXlSYXRlICAgID0gVGhpcy0+bEtleUZyYW1lRXZlcnk7CiAgICAgIGljRnJhbWVzLmR3UmF0ZSAgICAgID0gVGhpcy0+c0luZm8uZHdSYXRlOwogICAgICBpY0ZyYW1lcy5kd1NjYWxlICAgICA9IFRoaXMtPnNJbmZvLmR3U2NhbGU7CiAgICAgIElDU2VuZE1lc3NhZ2UoVGhpcy0+aGljLCBJQ01fQ09NUFJFU1NfRlJBTUVTX0lORk8sCgkJICAgIChMUEFSQU0pJmljRnJhbWVzLCAoTFBBUkFNKXNpemVvZihpY0ZyYW1lcykpOwogICAgfQogIH0gZWxzZQogICAgVGhpcy0+c0luZm8uZmNjSGFuZGxlciA9IGNvbXB0eXBlRElCOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUNNU3RyZWFtX2ZuSW5mbyhJQVZJU3RyZWFtICppZmFjZSxMUEFWSVNUUkVBTUlORk9XIHBzaSwKCQkJCQlMT05HIHNpemUpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVwLCVkKVxuIiwgaWZhY2UsIHBzaSwgc2l6ZSk7CgogIGlmIChwc2kgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgaWYgKHNpemUgPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURTSVpFOwoKICBtZW1jcHkocHNpLCAmVGhpcy0+c0luZm8sIG1pbigoRFdPUkQpc2l6ZSwgc2l6ZW9mKFRoaXMtPnNJbmZvKSkpOwoKICBpZiAoKERXT1JEKXNpemUgPCBzaXplb2YoVGhpcy0+c0luZm8pKQogICAgcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgTE9ORyBXSU5BUEkgSUNNU3RyZWFtX2ZuRmluZFNhbXBsZShJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBwb3MsCgkJCQkJICAgTE9ORyBmbGFncykKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJWQsMHglMDhYKVxuIixpZmFjZSxwb3MsZmxhZ3MpOwoKICBpZiAoZmxhZ3MgJiBGSU5EX0ZST01fU1RBUlQpIHsKICAgIHBvcyA9IFRoaXMtPnNJbmZvLmR3U3RhcnQ7CiAgICBmbGFncyAmPSB+KEZJTkRfRlJPTV9TVEFSVHxGSU5EX1BSRVYpOwogICAgZmxhZ3MgfD0gRklORF9ORVhUOwogIH0KCiAgaWYgKGZsYWdzICYgRklORF9SRVQpCiAgICBXQVJOKCI6IEZJTkRfUkVUIGZsYWdzIHdpbGwgYmUgaWdub3JlZCFcbiIpOwoKICBpZiAoZmxhZ3MgJiBGSU5EX0tFWSkgewogICAgaWYgKFRoaXMtPmhpYyA9PSBOVUxMKQogICAgICByZXR1cm4gcG9zOyAvKiB3ZSBkZWNvbXByZXNzIHNvIGV2ZXJ5IGZyYW1lIGlzIGEga2V5ZnJhbWUgKi8KCiAgICBpZiAoZmxhZ3MgJiBGSU5EX1BSRVYpIHsKICAgICAgLyogbmVlZCB0byByZWFkIG9sZCBvciBuZXcgZnJhbWVzPyAqLwogICAgICBpZiAoVGhpcy0+bExhc3RLZXkgPD0gcG9zIHx8IHBvcyA8IFRoaXMtPmxDdXJyZW50KQoJSUFWSVN0cmVhbV9SZWFkKGlmYWNlLCBwb3MsIDEsIE5VTEwsIDAsIE5VTEwsIE5VTEwpOwoKICAgICAgcmV0dXJuIFRoaXMtPmxMYXN0S2V5OwogICAgfQogIH0gZWxzZSBpZiAoZmxhZ3MgJiBGSU5EX0FOWSkgewogICAgcmV0dXJuIHBvczsgLyogV2UgcmVhbGx5IGRvbid0IGtub3csIHJlcmVhZCBpcyB0byBleHBlbnNpdmUsIHNvIGd1ZXNzLiAqLwogIH0gZWxzZSBpZiAoZmxhZ3MgJiBGSU5EX0ZPUk1BVCkgewogICAgaWYgKGZsYWdzICYgRklORF9QUkVWKQogICAgICByZXR1cm4gMDsKICB9CgogIHJldHVybiAtMTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElDTVN0cmVhbV9mblJlYWRGb3JtYXQoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgcG9zLAoJCQkJCSAgICAgIExQVk9JRCBmb3JtYXQsIExPTkcgKmZvcm1hdHNpemUpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBMUEJJVE1BUElORk9IRUFERVIgbHBiaTsKICBIUkVTVUxUICAgICAgICAgICAgaHI7CgogIFRSQUNFKCIoJXAsJWQsJXAsJXApXG4iLCBpZmFjZSwgcG9zLCBmb3JtYXQsIGZvcm1hdHNpemUpOwoKICBpZiAoZm9ybWF0c2l6ZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgaWYgKFRoaXMtPnBnID09IE5VTEwpIHsKICAgIGhyID0gQVZJRklMRV9PcGVuR2V0RnJhbWUoVGhpcyk7CgogICAgaWYgKEZBSUxFRChocikpCiAgICAgIHJldHVybiBocjsKICB9CgogIGxwYmkgPSAoTFBCSVRNQVBJTkZPSEVBREVSKUFWSVN0cmVhbUdldEZyYW1lKFRoaXMtPnBnLCBwb3MpOwogIGlmIChscGJpID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgaWYgKFRoaXMtPmhpYyA9PSBOVUxMKSB7CiAgICBMT05HIHNpemUgPSBscGJpLT5iaVNpemUgKyBscGJpLT5iaUNsclVzZWQgKiBzaXplb2YoUkdCUVVBRCk7CgogICAgaWYgKHNpemUgPiAwKSB7CiAgICAgIGlmIChUaGlzLT5zSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPCBscGJpLT5iaVNpemVJbWFnZSkKCVRoaXMtPnNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA9IGxwYmktPmJpU2l6ZUltYWdlOwoKICAgICAgVGhpcy0+Y2JPdXRwdXQgPSBzaXplOwogICAgICBpZiAoZm9ybWF0ICE9IE5VTEwpIHsKCWlmIChUaGlzLT5scGJpT3V0cHV0ICE9IE5VTEwpCgkgIG1lbWNweShmb3JtYXQsIFRoaXMtPmxwYmlPdXRwdXQsIG1pbigqZm9ybWF0c2l6ZSwgVGhpcy0+Y2JPdXRwdXQpKTsKCWVsc2UKCSAgbWVtY3B5KGZvcm1hdCwgbHBiaSwgbWluKCpmb3JtYXRzaXplLCBzaXplKSk7CiAgICAgIH0KICAgIH0KICB9IGVsc2UgaWYgKGZvcm1hdCAhPSBOVUxMKQogICAgbWVtY3B5KGZvcm1hdCwgVGhpcy0+bHBiaU91dHB1dCwgbWluKCpmb3JtYXRzaXplLCBUaGlzLT5jYk91dHB1dCkpOwoKICBpZiAoKmZvcm1hdHNpemUgPCBUaGlzLT5jYk91dHB1dCkKICAgIGhyID0gQVZJRVJSX0JVRkZFUlRPT1NNQUxMOwogIGVsc2UKICAgIGhyID0gQVZJRVJSX09LOwoKICAqZm9ybWF0c2l6ZSA9IFRoaXMtPmNiT3V0cHV0OwogIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElDTVN0cmVhbV9mblNldEZvcm1hdChJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBwb3MsCgkJCQkJICAgICBMUFZPSUQgZm9ybWF0LCBMT05HIGZvcm1hdHNpemUpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVkLCVwLCVkKVxuIiwgaWZhY2UsIHBvcywgZm9ybWF0LCBmb3JtYXRzaXplKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChmb3JtYXQgPT0gTlVMTCB8fCBmb3JtYXRzaXplIDw9IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBXZSBjYW4gb25seSBhY2NlcHQgUkdCIGRhdGEgZm9yIHdyaXRpbmcgKi8KICBpZiAoKChMUEJJVE1BUElORk9IRUFERVIpZm9ybWF0KS0+YmlDb21wcmVzc2lvbiAhPSBCSV9SR0IpIHsKICAgIFdBUk4oIjogbmVlZCBSR0IgZGF0YSBhcyBpbnB1dFxuIik7CiAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwogIH0KCiAgLyogSW5wdXQgZm9ybWF0IGFscmVhZHkga25vd24/CiAgICogQ2hhbmdpbmcgb2YgcGFsZXR0ZSBpcyBzdXBwb3J0ZWQsIGJ1dCBiZSBxdWlldCBpZiBpdCdzIHRoZSBzYW1lICovCiAgaWYgKFRoaXMtPmxwYmlJbnB1dCAhPSBOVUxMKSB7CiAgICBpZiAoVGhpcy0+Y2JJbnB1dCAhPSBmb3JtYXRzaXplKQogICAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICAgIGlmIChtZW1jbXAoZm9ybWF0LCBUaGlzLT5scGJpSW5wdXQsIGZvcm1hdHNpemUpID09IDApCiAgICAgIHJldHVybiBBVklFUlJfT0s7CiAgfQoKICAvKiBEb2VzIHRoZSBuZXN0ZWQgc3RyZWFtIHN1cHBvcnQgd3JpdGluZz8gKi8KICBpZiAoKFRoaXMtPnNJbmZvLmR3Q2FwcyAmIEFWSUZJTEVDQVBTX0NBTldSSVRFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgLyogY2hlY2sgaWYgZnJhbWUgaXMgYWxyZWFkeSB3cml0dGVuICovCiAgaWYgKFRoaXMtPnNJbmZvLmR3TGVuZ3RoICsgVGhpcy0+c0luZm8uZHdTdGFydCA+IHBvcykKICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CgogIC8qIGNoZWNrIGlmIHdlIHNob3VsZCBjb21wcmVzcyAqLwogIGlmIChUaGlzLT5zSW5mby5mY2NIYW5kbGVyID09IDAgfHwKICAgICAgVGhpcy0+c0luZm8uZmNjSGFuZGxlciA9PSBtbWlvRk9VUkNDKCdOJywnTycsJ04nLCdFJykpCiAgICBUaGlzLT5zSW5mby5mY2NIYW5kbGVyID0gY29tcHR5cGVESUI7CgogIC8qIG9ubHkgcGFzcyB0aHJvdWdoPyAqLwogIGlmIChUaGlzLT5zSW5mby5mY2NIYW5kbGVyID09IGNvbXB0eXBlRElCKQogICAgcmV0dXJuIElBVklTdHJlYW1fU2V0Rm9ybWF0KFRoaXMtPnBTdHJlYW0sIHBvcywgZm9ybWF0LCBmb3JtYXRzaXplKTsKCiAgLyogaW5pdGlhbCBmb3JtYXQgc2V0dGluZz8gKi8KICBpZiAoVGhpcy0+bHBiaUlucHV0ID09IE5VTEwpIHsKICAgIFVMT05HIHNpemU7CgogICAgYXNzZXJ0KFRoaXMtPmhpYyAhPSBOVUxMKTsKCiAgICAvKiBnZXQgbWVtb3J5IGZvciBpbnB1dCBmb3JtYXQgKi8KICAgIFRoaXMtPmxwYmlJbnB1dCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBmb3JtYXRzaXplKTsKICAgIGlmIChUaGlzLT5scGJpSW5wdXQgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgICBUaGlzLT5jYklucHV0ID0gZm9ybWF0c2l6ZTsKICAgIG1lbWNweShUaGlzLT5scGJpSW5wdXQsIGZvcm1hdCwgZm9ybWF0c2l6ZSk7CgogICAgLyogZ2V0IG91dHB1dCBmb3JtYXQgKi8KICAgIHNpemUgPSBJQ0NvbXByZXNzR2V0Rm9ybWF0U2l6ZShUaGlzLT5oaWMsIFRoaXMtPmxwYmlJbnB1dCk7CiAgICBpZiAoc2l6ZSA8IHNpemVvZihCSVRNQVBJTkZPSEVBREVSKSkKICAgICAgcmV0dXJuIEFWSUVSUl9DT01QUkVTU09SOwogICAgVGhpcy0+bHBiaU91dHB1dCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplKTsKICAgIGlmIChUaGlzLT5scGJpT3V0cHV0ID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogICAgVGhpcy0+Y2JPdXRwdXQgPSBzaXplOwogICAgaWYgKElDQ29tcHJlc3NHZXRGb3JtYXQoVGhpcy0+aGljLFRoaXMtPmxwYmlJbnB1dCxUaGlzLT5scGJpT3V0cHV0KSA8IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfQ09NUFJFU1NPUjsKCiAgICAvKiB1cGRhdGUgQVZJU1RSRUFNSU5GTyBzdHJ1Y3R1cmUgKi8KICAgIFRoaXMtPnNJbmZvLnJjRnJhbWUucmlnaHQgID0KICAgICAgVGhpcy0+c0luZm8ucmNGcmFtZS5sZWZ0ICsgVGhpcy0+bHBiaU91dHB1dC0+YmlXaWR0aDsKICAgIFRoaXMtPnNJbmZvLnJjRnJhbWUuYm90dG9tID0KICAgICAgVGhpcy0+c0luZm8ucmNGcmFtZS50b3AgICsgVGhpcy0+bHBiaU91dHB1dC0+YmlIZWlnaHQ7CgogICAgLyogcHJlcGFyZSBjb2RlYyBmb3IgY29tcHJlc3Npb24gKi8KICAgIGlmIChJQ0NvbXByZXNzQmVnaW4oVGhpcy0+aGljLCBUaGlzLT5scGJpSW5wdXQsIFRoaXMtPmxwYmlPdXRwdXQpICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfQ09NUFJFU1NPUjsKCiAgICAvKiBhbGxvY2F0ZSBtZW1vcnkgZm9yIGNvbXByZXNzZWQgZnJhbWUgKi8KICAgIHNpemUgPSBJQ0NvbXByZXNzR2V0U2l6ZShUaGlzLT5oaWMsIFRoaXMtPmxwYmlJbnB1dCwgVGhpcy0+bHBiaU91dHB1dCk7CiAgICBUaGlzLT5scGJpQ3VyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPmNiT3V0cHV0ICsgc2l6ZSk7CiAgICBpZiAoVGhpcy0+bHBiaUN1ciA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKICAgIG1lbWNweShUaGlzLT5scGJpQ3VyLCBUaGlzLT5scGJpT3V0cHV0LCBUaGlzLT5jYk91dHB1dCk7CiAgICBUaGlzLT5scEN1ciA9IERJQlBUUihUaGlzLT5scGJpQ3VyKTsKCiAgICAvKiBhbGxvY2F0ZSBtZW1vcnkgZm9yIGxhc3QgZnJhbWUgaWYgbmVlZGVkICovCiAgICBpZiAoVGhpcy0+bEtleUZyYW1lRXZlcnkgIT0gMSAmJgoJKFRoaXMtPmR3SUNNRmxhZ3MgJiBWSURDRl9GQVNUVEVNUE9SQUxDKSA9PSAwKSB7CiAgICAgIHNpemUgPSBJQ0RlY29tcHJlc3NHZXRGb3JtYXRTaXplKFRoaXMtPmhpYywgVGhpcy0+bHBiaU91dHB1dCk7CiAgICAgIFRoaXMtPmxwYmlQcmV2ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemUpOwogICAgICBpZiAoVGhpcy0+bHBiaVByZXYgPT0gTlVMTCkKCXJldHVybiBBVklFUlJfTUVNT1JZOwogICAgICBpZiAoSUNEZWNvbXByZXNzR2V0Rm9ybWF0KFRoaXMtPmhpYywgVGhpcy0+bHBiaU91dHB1dCwgVGhpcy0+bHBiaVByZXYpIDwgU19PSykKCXJldHVybiBBVklFUlJfQ09NUFJFU1NPUjsKCiAgICAgIGlmIChUaGlzLT5scGJpUHJldi0+YmlTaXplSW1hZ2UgPT0gMCkgewoJVGhpcy0+bHBiaVByZXYtPmJpU2l6ZUltYWdlID0KCSAgRElCV0lEVEhCWVRFUygqVGhpcy0+bHBiaVByZXYpICogVGhpcy0+bHBiaVByZXYtPmJpSGVpZ2h0OwogICAgICB9CgogICAgICAvKiBnZXQgbWVtb3J5IGZvciBmb3JtYXQgYW5kIHBpY3R1cmUgKi8KICAgICAgc2l6ZSArPSBUaGlzLT5scGJpUHJldi0+YmlTaXplSW1hZ2U7CiAgICAgIFRoaXMtPmxwYmlQcmV2ID0gSGVhcFJlQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+bHBiaVByZXYsIHNpemUpOwogICAgICBpZiAoVGhpcy0+bHBiaVByZXYgPT0gTlVMTCkKCXJldHVybiBBVklFUlJfTUVNT1JZOwogICAgICBUaGlzLT5scFByZXYgPSBESUJQVFIoVGhpcy0+bHBiaVByZXYpOwoKICAgICAgLyogcHJlcGFyZSBjb2RlYyBhbHNvIGZvciBkZWNvbXByZXNzaW9uICovCiAgICAgIGlmIChJQ0RlY29tcHJlc3NCZWdpbihUaGlzLT5oaWMsVGhpcy0+bHBiaU91dHB1dCxUaGlzLT5scGJpUHJldikgIT0gU19PSykKCXJldHVybiBBVklFUlJfQ09NUFJFU1NPUjsKICAgIH0KICB9IGVsc2UgewogICAgLyogZm9ybWF0IGNoYW5nZSAtLSBjaGVjayB0aGF0J3Mgb25seSB0aGUgcGFsZXR0ZSAqLwogICAgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmkgPSAoTFBCSVRNQVBJTkZPSEVBREVSKWZvcm1hdDsKCiAgICBpZiAobHBiaS0+YmlTaXplICE9IFRoaXMtPmxwYmlJbnB1dC0+YmlTaXplIHx8CglscGJpLT5iaVdpZHRoICE9IFRoaXMtPmxwYmlJbnB1dC0+YmlXaWR0aCB8fAoJbHBiaS0+YmlIZWlnaHQgIT0gVGhpcy0+bHBiaUlucHV0LT5iaUhlaWdodCB8fAoJbHBiaS0+YmlCaXRDb3VudCAhPSBUaGlzLT5scGJpSW5wdXQtPmJpQml0Q291bnQgfHwKCWxwYmktPmJpUGxhbmVzICE9IFRoaXMtPmxwYmlJbnB1dC0+YmlQbGFuZXMgfHwKCWxwYmktPmJpQ29tcHJlc3Npb24gIT0gVGhpcy0+bHBiaUlucHV0LT5iaUNvbXByZXNzaW9uIHx8CglscGJpLT5iaUNsclVzZWQgIT0gVGhpcy0+bHBiaUlucHV0LT5iaUNsclVzZWQpCiAgICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CgogICAgLyogZ2V0IG5ldyBvdXRwdXQgZm9ybWF0ICovCiAgICBpZiAoSUNDb21wcmVzc0dldEZvcm1hdChUaGlzLT5oaWMsIGxwYmksIFRoaXMtPmxwYmlPdXRwdXQpIDwgU19PSykKICAgICAgcmV0dXJuIEFWSUVSUl9CQURGT1JNQVQ7CgogICAgLyogcmVzdGFydCBjb21wcmVzc2lvbiAqLwogICAgSUNDb21wcmVzc0VuZChUaGlzLT5oaWMpOwogICAgaWYgKElDQ29tcHJlc3NCZWdpbihUaGlzLT5oaWMsIGxwYmksIFRoaXMtPmxwYmlPdXRwdXQpICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfQ09NUFJFU1NPUjsKCiAgICAvKiBjaGVjayBpZiB3ZSBuZWVkIHRvIHJlc3RhcnQgZGVjb21wcmVzaW9uIGFsc28gKi8KICAgIGlmIChUaGlzLT5sS2V5RnJhbWVFdmVyeSAhPSAxICYmCgkoVGhpcy0+ZHdJQ01GbGFncyAmIFZJRENGX0ZBU1RURU1QT1JBTEMpID09IDApIHsKICAgICAgSUNEZWNvbXByZXNzRW5kKFRoaXMtPmhpYyk7CiAgICAgIGlmIChJQ0RlY29tcHJlc3NHZXRGb3JtYXQoVGhpcy0+aGljLFRoaXMtPmxwYmlPdXRwdXQsVGhpcy0+bHBiaVByZXYpIDwgU19PSykKCXJldHVybiBBVklFUlJfQ09NUFJFU1NPUjsKICAgICAgaWYgKElDRGVjb21wcmVzc0JlZ2luKFRoaXMtPmhpYyxUaGlzLT5scGJpT3V0cHV0LFRoaXMtPmxwYmlQcmV2KSAhPSBTX09LKQoJcmV0dXJuIEFWSUVSUl9DT01QUkVTU09SOwogICAgfQogIH0KCiAgLyogdGVsbCBuZXN0ZWQgc3RyZWFtIHRoZSBuZXcgZm9ybWF0ICovCiAgcmV0dXJuIElBVklTdHJlYW1fU2V0Rm9ybWF0KFRoaXMtPnBTdHJlYW0sIHBvcywKCQkJICAgICAgVGhpcy0+bHBiaU91dHB1dCwgVGhpcy0+Y2JPdXRwdXQpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUNNU3RyZWFtX2ZuUmVhZChJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBzdGFydCwKCQkJCQlMT05HIHNhbXBsZXMsIExQVk9JRCBidWZmZXIsCgkJCQkJTE9ORyBidWZmZXJzaXplLCBMUExPTkcgYnl0ZXNyZWFkLAoJCQkJCUxQTE9ORyBzYW1wbGVzcmVhZCkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIExQQklUTUFQSU5GT0hFQURFUiBscGJpOwoKICBUUkFDRSgiKCVwLCVkLCVkLCVwLCVkLCVwLCVwKVxuIiwgaWZhY2UsIHN0YXJ0LCBzYW1wbGVzLCBidWZmZXIsCiAJYnVmZmVyc2l6ZSwgYnl0ZXNyZWFkLCBzYW1wbGVzcmVhZCk7CgogIC8qIGNsZWFyIHJldHVybiBwYXJhbWV0ZXJzIGlmIGdpdmVuICovCiAgaWYgKGJ5dGVzcmVhZCAhPSBOVUxMKQogICAgKmJ5dGVzcmVhZCA9IDA7CiAgaWYgKHNhbXBsZXNyZWFkICE9IE5VTEwpCiAgICAqc2FtcGxlc3JlYWQgPSAwOwoKICBpZiAoc2FtcGxlcyA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9PSzsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChzYW1wbGVzICE9IDEgJiYgKGJ5dGVzcmVhZCA9PSBOVUxMICYmIHNhbXBsZXNyZWFkID09IE5VTEwpKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICBpZiAoc2FtcGxlcyA9PSAtMSkgLyogcmVhZCBhcyBtdWNoIGFzIHdlIGNvdWxkICovCiAgICBzYW1wbGVzID0gMTsKCiAgaWYgKFRoaXMtPnBnID09IE5VTEwpIHsKICAgIEhSRVNVTFQgaHIgPSBBVklGSUxFX09wZW5HZXRGcmFtZShUaGlzKTsKCiAgICBpZiAoRkFJTEVEKGhyKSkKICAgICAgcmV0dXJuIGhyOwogIH0KCiAgLyogY29tcHJlc3Mgb3IgZGVjb21wcmVzcz8gKi8KICBpZiAoVGhpcy0+aGljID09IE5VTEwpIHsKICAgIC8qIGRlY29tcHJlc3MgKi8KICAgIGxwYmkgPSAoTFBCSVRNQVBJTkZPSEVBREVSKUFWSVN0cmVhbUdldEZyYW1lKFRoaXMtPnBnLCBzdGFydCk7CiAgICBpZiAobHBiaSA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgICBpZiAoYnVmZmVyICE9IE5VTEwgJiYgYnVmZmVyc2l6ZSA+IDApIHsKICAgICAgLyogY2hlY2sgYnVmZmVyc2l6ZSAqLwogICAgICBpZiAoYnVmZmVyc2l6ZSA8IGxwYmktPmJpU2l6ZUltYWdlKQoJcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKCiAgICAgIG1lbWNweShidWZmZXIsIERJQlBUUihscGJpKSwgbHBiaS0+YmlTaXplSW1hZ2UpOwogICAgfQoKICAgIC8qIGZpbGwgb3V0IHJldHVybiBwYXJhbWV0ZXJzIGlmIGdpdmVuICovCiAgICBpZiAoYnl0ZXNyZWFkICE9IE5VTEwpCiAgICAgICpieXRlc3JlYWQgPSBscGJpLT5iaVNpemVJbWFnZTsKICB9IGVsc2UgewogICAgLyogY29tcHJlc3MgKi8KICAgIGlmIChUaGlzLT5sQ3VycmVudCA+IHN0YXJ0KQogICAgICBBVklGSUxFX1Jlc2V0KFRoaXMpOwoKICAgIHdoaWxlIChzdGFydCA+IFRoaXMtPmxDdXJyZW50KSB7CiAgICAgIEhSRVNVTFQgaHI7CgogICAgICBscGJpID0gKExQQklUTUFQSU5GT0hFQURFUilBVklTdHJlYW1HZXRGcmFtZShUaGlzLT5wZywgKytUaGlzLT5sQ3VycmVudCk7CiAgICAgIGlmIChscGJpID09IE5VTEwpIHsKCUFWSUZJTEVfUmVzZXQoVGhpcyk7CglyZXR1cm4gQVZJRVJSX01FTU9SWTsKICAgICAgfQoKICAgICAgaHIgPSBBVklGSUxFX0VuY29kZUZyYW1lKFRoaXMsIGxwYmksIERJQlBUUihscGJpKSk7CiAgICAgIGlmIChGQUlMRUQoaHIpKSB7CglBVklGSUxFX1Jlc2V0KFRoaXMpOwoJcmV0dXJuIGhyOwogICAgICB9CiAgICB9CgogICAgaWYgKGJ1ZmZlciAhPSBOVUxMICYmIGJ1ZmZlcnNpemUgPiAwKSB7CiAgICAgIC8qIGNoZWNrIGJ1ZmZlcnNpemUgKi8KICAgICAgaWYgKFRoaXMtPmxwYmlDdXItPmJpU2l6ZUltYWdlID4gYnVmZmVyc2l6ZSkKCXJldHVybiBBVklFUlJfQlVGRkVSVE9PU01BTEw7CgogICAgICBtZW1jcHkoYnVmZmVyLCBUaGlzLT5scEN1ciwgVGhpcy0+bHBiaUN1ci0+YmlTaXplSW1hZ2UpOwogICAgfQoKICAgIC8qIGZpbGwgb3V0IHJldHVybiBwYXJhbWV0ZXJzIGlmIGdpdmVuICovCiAgICBpZiAoYnl0ZXNyZWFkICE9IE5VTEwpCiAgICAgICpieXRlc3JlYWQgPSBUaGlzLT5scGJpQ3VyLT5iaVNpemVJbWFnZTsKICB9CgogIC8qIGZpbGwgb3V0IHJldHVybiBwYXJhbWV0ZXJzIGlmIGdpdmVuICovCiAgaWYgKHNhbXBsZXNyZWFkICE9IE5VTEwpCiAgICAqc2FtcGxlc3JlYWQgPSAxOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUNNU3RyZWFtX2ZuV3JpdGUoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgc3RhcnQsCgkJCQkJIExPTkcgc2FtcGxlcywgTFBWT0lEIGJ1ZmZlciwKCQkJCQkgTE9ORyBidWZmZXJzaXplLCBEV09SRCBmbGFncywKCQkJCQkgTFBMT05HIHNhbXB3cml0dGVuLAoJCQkJCSBMUExPTkcgYnl0ZXN3cml0dGVuKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgSFJFU1VMVCBocjsKCiAgVFJBQ0UoIiglcCwlZCwlZCwlcCwlZCwweCUwOFgsJXAsJXApXG4iLCBpZmFjZSwgc3RhcnQsIHNhbXBsZXMsCglidWZmZXIsIGJ1ZmZlcnNpemUsIGZsYWdzLCBzYW1wd3JpdHRlbiwgYnl0ZXN3cml0dGVuKTsKCiAgLyogY2xlYXIgcmV0dXJuIHBhcmFtZXRlcnMgaWYgZ2l2ZW4gKi8KICBpZiAoc2FtcHdyaXR0ZW4gIT0gTlVMTCkKICAgICpzYW1wd3JpdHRlbiA9IDA7CiAgaWYgKGJ5dGVzd3JpdHRlbiAhPSBOVUxMKQogICAgKmJ5dGVzd3JpdHRlbiA9IDA7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoYnVmZmVyID09IE5VTEwgJiYgKGJ1ZmZlcnNpemUgPiAwIHx8IHNhbXBsZXMgPiAwKSkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIGlmIChUaGlzLT5zSW5mby5mY2NIYW5kbGVyID09IGNvbXB0eXBlRElCKSB7CiAgICAvKiBvbmx5IHBhc3MgdGhyb3VnaCAqLwogICAgZmxhZ3MgfD0gQVZJSUZfS0VZRlJBTUU7CgogICAgcmV0dXJuIElBVklTdHJlYW1fV3JpdGUoVGhpcy0+cFN0cmVhbSwgc3RhcnQsIHNhbXBsZXMsIGJ1ZmZlciwgYnVmZmVyc2l6ZSwKCQkJICAgIGZsYWdzLCBzYW1wd3JpdHRlbiwgYnl0ZXN3cml0dGVuKTsKICB9IGVsc2UgewogICAgLyogY29tcHJlc3MgZGF0YSBiZWZvcmUgd3JpdGluZyB0byBwU3RyZWFtICovCiAgICBpZiAoc2FtcGxlcyAhPSAxICYmIChzYW1wd3JpdHRlbiA9PSBOVUxMICYmIGJ5dGVzd3JpdHRlbiA9PSBOVUxMKSkKICAgICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKCiAgICBUaGlzLT5sQ3VycmVudCA9IHN0YXJ0OwogICAgaHIgPSBBVklGSUxFX0VuY29kZUZyYW1lKFRoaXMsIFRoaXMtPmxwYmlJbnB1dCwgYnVmZmVyKTsKICAgIGlmIChGQUlMRUQoaHIpKQogICAgICByZXR1cm4gaHI7CgogICAgaWYgKFRoaXMtPmxMYXN0S2V5ID09IHN0YXJ0KQogICAgICBmbGFncyB8PSBBVklJRl9LRVlGUkFNRTsKCiAgICByZXR1cm4gSUFWSVN0cmVhbV9Xcml0ZShUaGlzLT5wU3RyZWFtLCBzdGFydCwgc2FtcGxlcywgVGhpcy0+bHBDdXIsCgkJCSAgICBUaGlzLT5scGJpQ3VyLT5iaVNpemVJbWFnZSwgZmxhZ3MsIGJ5dGVzd3JpdHRlbiwKCQkJICAgIHNhbXB3cml0dGVuKTsKICB9Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQ01TdHJlYW1fZm5EZWxldGUoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgc3RhcnQsCgkJCQkJICBMT05HIHNhbXBsZXMpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVkLCVkKVxuIiwgaWZhY2UsIHN0YXJ0LCBzYW1wbGVzKTsKCiAgcmV0dXJuIElBVklTdHJlYW1fRGVsZXRlKFRoaXMtPnBTdHJlYW0sIHN0YXJ0LCBzYW1wbGVzKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElDTVN0cmVhbV9mblJlYWREYXRhKElBVklTdHJlYW0gKmlmYWNlLCBEV09SRCBmY2MsCgkJCQkJICAgIExQVk9JRCBscCwgTFBMT05HIGxwcmVhZCkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsMHglMDhYLCVwLCVwKVxuIiwgaWZhY2UsIGZjYywgbHAsIGxwcmVhZCk7CgogIGFzc2VydChUaGlzLT5wU3RyZWFtICE9IE5VTEwpOwoKICByZXR1cm4gSUFWSVN0cmVhbV9SZWFkRGF0YShUaGlzLT5wU3RyZWFtLCBmY2MsIGxwLCBscHJlYWQpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUNNU3RyZWFtX2ZuV3JpdGVEYXRhKElBVklTdHJlYW0gKmlmYWNlLCBEV09SRCBmY2MsCgkJCQkJICAgICBMUFZPSUQgbHAsIExPTkcgc2l6ZSkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsMHglMDh4LCVwLCVkKVxuIiwgaWZhY2UsIGZjYywgbHAsIHNpemUpOwoKICBhc3NlcnQoVGhpcy0+cFN0cmVhbSAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklTdHJlYW1fV3JpdGVEYXRhKFRoaXMtPnBTdHJlYW0sIGZjYywgbHAsIHNpemUpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUNNU3RyZWFtX2ZuU2V0SW5mbyhJQVZJU3RyZWFtICppZmFjZSwKCQkJCQkgICBMUEFWSVNUUkVBTUlORk9XIGluZm8sIExPTkcgaW5mb2xlbikKewogIEZJWE1FKCIoJXAsJXAsJWQpOiBzdHViXG4iLCBpZmFjZSwgaW5mbywgaW5mb2xlbik7CgogIHJldHVybiBFX0ZBSUw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfRW5jb2RlRnJhbWUoSUFWSVN0cmVhbUltcGwgKlRoaXMsCgkJCQkgICBMUEJJVE1BUElORk9IRUFERVIgbHBiaSwgTFBWT0lEIGxwQml0cykKewogIERXT1JEIGR3TWluUXVhbCwgZHdNYXhRdWFsLCBkd0N1clF1YWw7CiAgRFdPUkQgZHdSZXF1ZXN0OwogIERXT1JEIGljbUZsYWdzID0gMDsKICBEV09SRCBpZHhGbGFncyA9IDA7CiAgQk9PTCAgYkRlY3JlYXNlZFF1YWwgPSBGQUxTRTsKICBCT09MICBkb1NpemVDaGVjazsKICBCT09MICBub1ByZXY7CgogIC8qIG1ha2UgbEtleUZyYW1lRXZlcnkgYW5kIGF0IHN0YXJ0IGEga2V5ZnJhbWUgKi8KICBpZiAoKFRoaXMtPmxLZXlGcmFtZUV2ZXJ5ICE9IDAgJiYKICAgICAgIChUaGlzLT5sQ3VycmVudCAtIFRoaXMtPmxMYXN0S2V5KSA+PSBUaGlzLT5sS2V5RnJhbWVFdmVyeSkgfHwKICAgICAgVGhpcy0+bEN1cnJlbnQgPT0gVGhpcy0+c0luZm8uZHdTdGFydCkgewogICAgaWR4RmxhZ3MgPSBBVklJRl9LRVlGUkFNRTsKICAgIGljbUZsYWdzID0gSUNDT01QUkVTU19LRVlGUkFNRTsKICB9CgogIGlmIChUaGlzLT5sS2V5RnJhbWVFdmVyeSAhPSAwKSB7CiAgICBpZiAoVGhpcy0+bEN1cnJlbnQgPT0gVGhpcy0+c0luZm8uZHdTdGFydCkgewogICAgICBpZiAoaWR4RmxhZ3MgJiBBVklJRl9LRVlGUkFNRSkgewoJLyogZm9yIGtleWZyYW1lcyBhbGxvdyB0byBjb25zdW1lIGFsbCB1bnVzZWQgYnl0ZXMgKi8KCWR3UmVxdWVzdCA9IFRoaXMtPmR3Qnl0ZXNQZXJGcmFtZSArIFRoaXMtPmR3VW51c2VkQnl0ZXM7CglUaGlzLT5kd1VudXNlZEJ5dGVzID0gMDsKICAgICAgfSBlbHNlIHsKCS8qIGZvciBub24ta2V5ZnJhbWVzIG9ubHkgYWxsb3cgc29tZXRoaW5nIG9mIHRoZSB1bnVzZWQgYnl0ZXMgdG8gYmUgY29uc3VtZWQgKi8KCURXT1JEIHRtcDEgPSAwOwoJRFdPUkQgdG1wMjsKCglpZiAoVGhpcy0+ZHdCeXRlc1BlckZyYW1lID49IFRoaXMtPmR3VW51c2VkQnl0ZXMpCgkgIHRtcDEgPSBUaGlzLT5kd0J5dGVzUGVyRnJhbWUgLyBUaGlzLT5sS2V5RnJhbWVFdmVyeTsKCXRtcDIgPSAoVGhpcy0+ZHdVbnVzZWRCeXRlcyArIHRtcDEpIC8gVGhpcy0+bEtleUZyYW1lRXZlcnk7CgoJZHdSZXF1ZXN0ID0gVGhpcy0+ZHdCeXRlc1BlckZyYW1lIC0gdG1wMSArIHRtcDI7CglUaGlzLT5kd1VudXNlZEJ5dGVzIC09IHRtcDI7CiAgICAgIH0KICAgIH0gZWxzZQogICAgICBkd1JlcXVlc3QgPSBNQVhfRlJBTUVTSVpFOwogIH0gZWxzZSB7CiAgICAvKiBvbmx5IG9uZSBrZXlmcmFtZSBhdCBzdGFydCBkZXNpcmVkICovCiAgICBpZiAoVGhpcy0+bEN1cnJlbnQgPT0gVGhpcy0+c0luZm8uZHdTdGFydCkgewogICAgICBkd1JlcXVlc3QgPSBUaGlzLT5kd0J5dGVzUGVyRnJhbWUgKyBUaGlzLT5kd1VudXNlZEJ5dGVzOwogICAgICBUaGlzLT5kd1VudXNlZEJ5dGVzID0gMDsKICAgIH0gZWxzZQogICAgICBkd1JlcXVlc3QgPSBNQVhfRlJBTUVTSVpFOwogIH0KCiAgLyogbXVzdCB3ZSBjaGVjayBmb3IgZnJhbWVzaXplIHRvIGdhaW4gcmVxdWVzdGVkCiAgICogZGF0YXJhdGUgb3IgY291bGQgd2UgdHJ1c3QgY29kZWM/ICovCiAgZG9TaXplQ2hlY2sgPSAoZHdSZXF1ZXN0ICE9IDAgJiYgKChUaGlzLT5kd0lDTUZsYWdzICYgKFZJRENGX0NSVU5DSHxWSURDRl9RVUFMSVRZKSkgPT0gMCkpOwoKICBkd01heFF1YWwgPSBkd0N1clF1YWwgPSBUaGlzLT5zSW5mby5kd1F1YWxpdHk7CiAgZHdNaW5RdWFsID0gSUNRVUFMSVRZX0xPVzsKCiAgbm9QcmV2ID0gVFJVRTsKICBpZiAoKGljbUZsYWdzICYgSUNDT01QUkVTU19LRVlGUkFNRSkgPT0gMCAmJiAKICAgICAgKFRoaXMtPmR3SUNNRmxhZ3MgJiBWSURDRl9GQVNUVEVNUE9SQUxDKSA9PSAwKQogICAgbm9QcmV2ID0gRkFMU0U7CgogIGRvIHsKICAgIERXT1JEICAgaWR4Q2tpZCA9IDA7CiAgICBIUkVTVUxUIGhyOwoKICAgIGhyID0gSUNDb21wcmVzcyhUaGlzLT5oaWMsaWNtRmxhZ3MsVGhpcy0+bHBiaUN1cixUaGlzLT5scEN1cixscGJpLGxwQml0cywKCQkgICAgJmlkeENraWQsICZpZHhGbGFncywgVGhpcy0+bEN1cnJlbnQsIGR3UmVxdWVzdCwgZHdDdXJRdWFsLAoJCSAgICBub1ByZXYgPyBOVUxMOlRoaXMtPmxwYmlQcmV2LCBub1ByZXYgPyBOVUxMOlRoaXMtPmxwUHJldik7CiAgICBpZiAoaHIgPT0gSUNFUlJfTkVXUEFMRVRURSkgewogICAgICBGSVhNRSgiOiBjb2RlYyBoYXMgY2hhbmdlZCBwYWxldHRlIC0tIHVuaGFuZGxlZCFcbiIpOwogICAgfSBlbHNlIGlmIChociAhPSBJQ0VSUl9PSykKICAgICAgcmV0dXJuIEFWSUVSUl9DT01QUkVTU09SOwoKICAgIC8qIG5lZWQgdG8gY2hlY2sgZm9yIGZyYW1lc2l6ZSAqLwogICAgaWYgKCEgZG9TaXplQ2hlY2spCiAgICAgIGJyZWFrOwoKICAgIGlmIChkd1JlcXVlc3QgPj0gVGhpcy0+bHBiaUN1ci0+YmlTaXplSW1hZ2UpIHsKICAgICAgLyogZnJhbWUgaXMgc21hbGxlciAtLSB0cnkgdG8gbWF4aW1pemUgcXVhbGl0eSAqLwogICAgICBpZiAoZHdNYXhRdWFsIC0gZHdDdXJRdWFsID4gMTApIHsKCURXT1JEIHRtcCA9IGR3UmVxdWVzdCAvIDg7CgoJaWYgKHRtcCA8IE1BWF9GUkFNRVNJWkVfRElGRikKCSAgdG1wID0gTUFYX0ZSQU1FU0laRV9ESUZGOwoKCWlmICh0bXAgPCBkd1JlcXVlc3QgLSBUaGlzLT5scGJpQ3VyLT5iaVNpemVJbWFnZSAmJiBiRGVjcmVhc2VkUXVhbCkgewoJICB0bXAgPSBkd0N1clF1YWw7CgkgIGR3Q3VyUXVhbCA9IChkd01pblF1YWwgKyBkd01heFF1YWwpIC8gMjsKCSAgZHdNaW5RdWFsID0gdG1wOwoJICBjb250aW51ZTsKCX0KICAgICAgfSBlbHNlCglicmVhazsKICAgIH0gZWxzZSBpZiAoZHdNYXhRdWFsIC0gZHdNaW5RdWFsIDw9IDEpIHsKICAgICAgYnJlYWs7CiAgICB9IGVsc2UgewogICAgICBkd01heFF1YWwgPSBkd0N1clF1YWw7CgogICAgICBpZiAoYkRlY3JlYXNlZFF1YWwgfHwgZHdDdXJRdWFsID09IFRoaXMtPmR3TGFzdFF1YWxpdHkpCglkd0N1clF1YWwgPSAoZHdNaW5RdWFsICsgZHdNYXhRdWFsKSAvIDI7CiAgICAgIGVsc2UKCUZJWE1FKCI6IG5vIG5ldyBxdWFsaXR5IGNvbXB1dGVkIG1pbj0ldSBjdXI9JXUgbWF4PSV1IGxhc3Q9JXVcbiIsCgkgICAgICBkd01pblF1YWwsIGR3Q3VyUXVhbCwgZHdNYXhRdWFsLCBUaGlzLT5kd0xhc3RRdWFsaXR5KTsKCiAgICAgIGJEZWNyZWFzZWRRdWFsID0gVFJVRTsKICAgIH0KICB9IHdoaWxlIChUUlVFKTsKCiAgLyogcmVtZW1iZXIgc29tZSB2YWx1ZXMgKi8KICBUaGlzLT5kd0xhc3RRdWFsaXR5ID0gZHdDdXJRdWFsOwogIFRoaXMtPmR3VW51c2VkQnl0ZXMgPSBkd1JlcXVlc3QgLSBUaGlzLT5scGJpQ3VyLT5iaVNpemVJbWFnZTsKICBpZiAoaWNtRmxhZ3MgJiBJQ0NPTVBSRVNTX0tFWUZSQU1FKQogICAgVGhpcy0+bExhc3RLZXkgPSBUaGlzLT5sQ3VycmVudDsKCiAgLyogRG9lcyB3ZSBtYW5hZ2UgcHJldmlvdXMgZnJhbWU/ICovCiAgaWYgKFRoaXMtPmxwUHJldiAhPSBOVUxMICYmIFRoaXMtPmxLZXlGcmFtZUV2ZXJ5ICE9IDEpCiAgICBJQ0RlY29tcHJlc3MoVGhpcy0+aGljLCAwLCBUaGlzLT5scGJpQ3VyLCBUaGlzLT5scEN1ciwKCQkgVGhpcy0+bHBiaVByZXYsIFRoaXMtPmxwUHJldik7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfT3BlbkdldEZyYW1lKElBVklTdHJlYW1JbXBsICpUaGlzKQp7CiAgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmk7CiAgRFdPUkQgICAgICAgICAgICAgIHNpemU7CgogIC8qIHByZS1jb25kaXRpb25zICovCiAgYXNzZXJ0KFRoaXMgIT0gTlVMTCk7CiAgYXNzZXJ0KFRoaXMtPnBTdHJlYW0gIT0gTlVMTCk7CiAgYXNzZXJ0KFRoaXMtPnBnID09IE5VTEwpOwoKICBUaGlzLT5wZyA9IEFWSVN0cmVhbUdldEZyYW1lT3BlbihUaGlzLT5wU3RyZWFtLCBOVUxMKTsKICBpZiAoVGhpcy0+cGcgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfRVJST1I7CgogIC8qIFdoZW4gd2Ugb25seSBkZWNvbXByZXNzIHRoaXMgaXMgZW5vdWdoICovCiAgaWYgKFRoaXMtPnNJbmZvLmZjY0hhbmRsZXIgPT0gY29tcHR5cGVESUIpCiAgICByZXR1cm4gQVZJRVJSX09LOwoKICBhc3NlcnQoVGhpcy0+aGljICE9IE5VTEwpOwogIGFzc2VydChUaGlzLT5scGJpT3V0cHV0ID09IE5VTEwpOwoKICAvKiBnZXQgaW5wdXQgZm9ybWF0ICovCiAgbHBiaSA9IChMUEJJVE1BUElORk9IRUFERVIpQVZJU3RyZWFtR2V0RnJhbWUoVGhpcy0+cGcsIFRoaXMtPnNJbmZvLmR3U3RhcnQpOwogIGlmIChscGJpID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgLyogZ2V0IG1lbW9yeSBmb3Igb3V0cHV0IGZvcm1hdCAqLwogIHNpemUgPSBJQ0NvbXByZXNzR2V0Rm9ybWF0U2l6ZShUaGlzLT5oaWMsIGxwYmkpOwogIGlmICgoTE9ORylzaXplIDwgKExPTkcpc2l6ZW9mKEJJVE1BUElORk9IRUFERVIpKQogICAgcmV0dXJuIEFWSUVSUl9DT01QUkVTU09SOwogIFRoaXMtPmxwYmlPdXRwdXQgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZSk7CiAgaWYgKFRoaXMtPmxwYmlPdXRwdXQgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogIFRoaXMtPmNiT3V0cHV0ID0gc2l6ZTsKCiAgaWYgKElDQ29tcHJlc3NHZXRGb3JtYXQoVGhpcy0+aGljLCBscGJpLCBUaGlzLT5scGJpT3V0cHV0KSA8IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0JBREZPUk1BVDsKCiAgLyogdXBkYXRlIEFWSVNUUkVBTUlORk8gc3RydWN0dXJlICovCiAgVGhpcy0+c0luZm8ucmNGcmFtZS5yaWdodCAgPQogICAgVGhpcy0+c0luZm8ucmNGcmFtZS5sZWZ0ICsgVGhpcy0+bHBiaU91dHB1dC0+YmlXaWR0aDsKICBUaGlzLT5zSW5mby5yY0ZyYW1lLmJvdHRvbSA9CiAgICBUaGlzLT5zSW5mby5yY0ZyYW1lLnRvcCAgKyBUaGlzLT5scGJpT3V0cHV0LT5iaUhlaWdodDsKICBUaGlzLT5zSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPQogICAgSUNDb21wcmVzc0dldFNpemUoVGhpcy0+aGljLCBscGJpLCBUaGlzLT5scGJpT3V0cHV0KTsKCiAgLyogcHJlcGFyZSBjb2RlYyBmb3IgY29tcHJlc3Npb24gKi8KICBpZiAoSUNDb21wcmVzc0JlZ2luKFRoaXMtPmhpYywgbHBiaSwgVGhpcy0+bHBiaU91dHB1dCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfQ09NUFJFU1NPUjsKCiAgLyogYWxsb2NhdGUgbWVtb3J5IGZvciBjdXJyZW50IGZyYW1lICovCiAgc2l6ZSArPSBUaGlzLT5zSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemU7CiAgVGhpcy0+bHBiaUN1ciA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplKTsKICBpZiAoVGhpcy0+bHBiaUN1ciA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgbWVtY3B5KFRoaXMtPmxwYmlDdXIsIFRoaXMtPmxwYmlPdXRwdXQsIFRoaXMtPmNiT3V0cHV0KTsKICBUaGlzLT5scEN1ciA9IERJQlBUUihUaGlzLT5scGJpQ3VyKTsKCiAgLyogYWxsb2NhdGUgbWVtb3J5IGZvciBsYXN0IGZyYW1lIGlmIG5lZWRlZCAqLwogIGlmIChUaGlzLT5sS2V5RnJhbWVFdmVyeSAhPSAxICYmCiAgICAgIChUaGlzLT5kd0lDTUZsYWdzICYgVklEQ0ZfRkFTVFRFTVBPUkFMQykgPT0gMCkgewogICAgc2l6ZSA9IElDRGVjb21wcmVzc0dldEZvcm1hdFNpemUoVGhpcy0+aGljLCBUaGlzLT5scGJpT3V0cHV0KTsKICAgIFRoaXMtPmxwYmlQcmV2ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemUpOwogICAgaWYgKFRoaXMtPmxwYmlQcmV2ID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogICAgaWYgKElDRGVjb21wcmVzc0dldEZvcm1hdChUaGlzLT5oaWMsIFRoaXMtPmxwYmlPdXRwdXQsIFRoaXMtPmxwYmlQcmV2KSA8IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfQ09NUFJFU1NPUjsKCiAgICBpZiAoVGhpcy0+bHBiaVByZXYtPmJpU2l6ZUltYWdlID09IDApIHsKICAgICAgVGhpcy0+bHBiaVByZXYtPmJpU2l6ZUltYWdlID0KCURJQldJRFRIQllURVMoKlRoaXMtPmxwYmlQcmV2KSAqIFRoaXMtPmxwYmlQcmV2LT5iaUhlaWdodDsKICAgIH0KCiAgICAvKiBnZXQgbWVtb3J5IGZvciBmb3JtYXQgYW5kIHBpY3R1cmUgKi8KICAgIHNpemUgKz0gVGhpcy0+bHBiaVByZXYtPmJpU2l6ZUltYWdlOwogICAgVGhpcy0+bHBiaVByZXYgPSBIZWFwUmVBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5scGJpUHJldiwgc2l6ZSApOwogICAgaWYgKFRoaXMtPmxwYmlQcmV2ID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogICAgVGhpcy0+bHBQcmV2ID0gRElCUFRSKFRoaXMtPmxwYmlQcmV2KTsKCiAgICAvKiBwcmVwYXJlIGNvZGVjIGFsc28gZm9yIGRlY29tcHJlc3Npb24gKi8KICAgIGlmIChJQ0RlY29tcHJlc3NCZWdpbihUaGlzLT5oaWMsVGhpcy0+bHBiaU91dHB1dCxUaGlzLT5scGJpUHJldikgIT0gU19PSykKICAgICAgcmV0dXJuIEFWSUVSUl9DT01QUkVTU09SOwogIH0KCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQo=