LyoKICogQ29weXJpZ2h0IDE5OTkgTWFyY3VzIE1laXNzbmVyCiAqIENvcHlyaWdodCAyMDAyLTIwMDMgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgovKiBUT0RPOgogKiAgLSBJQVZJU3RyZWFtaW5nIGludGVyZmFjZSBpcyBtaXNzaW5nIGZvciB0aGUgSUFWSVN0cmVhbUltcGwKICogIC0gSUFWSVN0cmVhbV9mbkZpbmRTYW1wbGU6IEZJTkRfSU5ERVggaXNuJ3Qgc3VwcG9ydGVkLgogKiAgLSBJQVZJU3RyZWFtX2ZuUmVhZEZvcm1hdDogZm9ybWF0Y2hhbmdlcyBhcmVuJ3QgcmVhZCBpbi4KICogIC0gSUFWSVN0cmVhbV9mbkRlbGV0ZTogYSBzdHViLgogKiAgLSBJQVZJU3RyZWFtX2ZuU2V0SW5mbzogYSBzdHViLgogKiAgLSBtYWtlIHRocmVhZCBzYWZlCiAqCiAqIEtOT1dOIEJ1Z3M6CiAqICAtIG5hdGl2ZSB2ZXJzaW9uIGNhbiBoYW5ndXAgd2hlbiByZWFkaW5nIGEgZmlsZSBnZW5lcmF0ZWQgd2l0aCB0aGlzIERMTC4KICogICAgV2hlbiBpbmRleCBpcyBtaXNzaW5nIGl0IHdvcmtzLCBidXQgaW5kZXggc2VlbXMgdG8gYmUgb2theS4KICovCgojZGVmaW5lIENPTV9OT19XSU5ET1dTX0gKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbmRvd3N4LmgiCiNpbmNsdWRlICJtbXN5c3RlbS5oIgojaW5jbHVkZSAidmZ3LmgiCgojaW5jbHVkZSAiYXZpZmlsZV9wcml2YXRlLmgiCiNpbmNsdWRlICJleHRyYWNodW5rLmgiCgojaW5jbHVkZSAid2luZS91bmljb2RlLmgiCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChhdmlmaWxlKTsKCiNpZm5kZWYgSURYX1BFUl9CTE9DSwojZGVmaW5lIElEWF9QRVJfQkxPQ0sgMjczMAojZW5kaWYKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mblF1ZXJ5SW50ZXJmYWNlKElBVklGaWxlKiBpZmFjZSxSRUZJSUQgcmVmaWlkLExQVk9JRCAqb2JqKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElBVklGaWxlX2ZuQWRkUmVmKElBVklGaWxlKiBpZmFjZSk7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJQVZJRmlsZV9mblJlbGVhc2UoSUFWSUZpbGUqIGlmYWNlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuSW5mbyhJQVZJRmlsZSppZmFjZSxBVklGSUxFSU5GT1cqYWZpLExPTkcgc2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkdldFN0cmVhbShJQVZJRmlsZSppZmFjZSxQQVZJU1RSRUFNKmF2aXMsRFdPUkQgZmNjVHlwZSxMT05HIGxQYXJhbSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkNyZWF0ZVN0cmVhbShJQVZJRmlsZSppZmFjZSxQQVZJU1RSRUFNKmF2aXMsQVZJU1RSRUFNSU5GT1cqYXNpKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuV3JpdGVEYXRhKElBVklGaWxlKmlmYWNlLERXT1JEIGNraWQsTFBWT0lEIGxwRGF0YSxMT05HIHNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5SZWFkRGF0YShJQVZJRmlsZSppZmFjZSxEV09SRCBja2lkLExQVk9JRCBscERhdGEsTE9ORyAqc2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkVuZFJlY29yZChJQVZJRmlsZSppZmFjZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkRlbGV0ZVN0cmVhbShJQVZJRmlsZSppZmFjZSxEV09SRCBmY2NUeXBlLExPTkcgbFBhcmFtKTsKCnN0cnVjdCBJQ09NX1ZUQUJMRShJQVZJRmlsZSkgaWF2aWZ0ID0gewogIElDT01fTVNWVEFCTEVfQ09NUEFUX0R1bW15UlRUSVZBTFVFCiAgSUFWSUZpbGVfZm5RdWVyeUludGVyZmFjZSwKICBJQVZJRmlsZV9mbkFkZFJlZiwKICBJQVZJRmlsZV9mblJlbGVhc2UsCiAgSUFWSUZpbGVfZm5JbmZvLAogIElBVklGaWxlX2ZuR2V0U3RyZWFtLAogIElBVklGaWxlX2ZuQ3JlYXRlU3RyZWFtLAogIElBVklGaWxlX2ZuV3JpdGVEYXRhLAogIElBVklGaWxlX2ZuUmVhZERhdGEsCiAgSUFWSUZpbGVfZm5FbmRSZWNvcmQsCiAgSUFWSUZpbGVfZm5EZWxldGVTdHJlYW0KfTsKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5RdWVyeUludGVyZmFjZShJUGVyc2lzdEZpbGUqaWZhY2UsUkVGSUlEIHJlZmlpZCxMUFZPSUQqb2JqKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkFkZFJlZihJUGVyc2lzdEZpbGUqaWZhY2UpOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuUmVsZWFzZShJUGVyc2lzdEZpbGUqaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuR2V0Q2xhc3NJRChJUGVyc2lzdEZpbGUqaWZhY2UsQ0xTSUQqcENsYXNzSUQpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuSXNEaXJ0eShJUGVyc2lzdEZpbGUqaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuTG9hZChJUGVyc2lzdEZpbGUqaWZhY2UsTFBDT0xFU1RSIHBzekZpbGVOYW1lLERXT1JEIGR3TW9kZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5TYXZlKElQZXJzaXN0RmlsZSppZmFjZSxMUENPTEVTVFIgcHN6RmlsZU5hbWUsQk9PTCBmUmVtZW1iZXIpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuU2F2ZUNvbXBsZXRlZChJUGVyc2lzdEZpbGUqaWZhY2UsTFBDT0xFU1RSIHBzekZpbGVOYW1lKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkdldEN1ckZpbGUoSVBlcnNpc3RGaWxlKmlmYWNlLExQT0xFU1RSKnBwc3pGaWxlTmFtZSk7CgpzdHJ1Y3QgSUNPTV9WVEFCTEUoSVBlcnNpc3RGaWxlKSBpcGVyc2lzdGZ0ID0gewogIElDT01fTVNWVEFCTEVfQ09NUEFUX0R1bW15UlRUSVZBTFVFCiAgSVBlcnNpc3RGaWxlX2ZuUXVlcnlJbnRlcmZhY2UsCiAgSVBlcnNpc3RGaWxlX2ZuQWRkUmVmLAogIElQZXJzaXN0RmlsZV9mblJlbGVhc2UsCiAgSVBlcnNpc3RGaWxlX2ZuR2V0Q2xhc3NJRCwKICBJUGVyc2lzdEZpbGVfZm5Jc0RpcnR5LAogIElQZXJzaXN0RmlsZV9mbkxvYWQsCiAgSVBlcnNpc3RGaWxlX2ZuU2F2ZSwKICBJUGVyc2lzdEZpbGVfZm5TYXZlQ29tcGxldGVkLAogIElQZXJzaXN0RmlsZV9mbkdldEN1ckZpbGUKfTsKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUXVlcnlJbnRlcmZhY2UoSUFWSVN0cmVhbSppZmFjZSxSRUZJSUQgcmVmaWlkLExQVk9JRCAqb2JqKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElBVklTdHJlYW1fZm5BZGRSZWYoSUFWSVN0cmVhbSppZmFjZSk7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUmVsZWFzZShJQVZJU3RyZWFtKiBpZmFjZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuQ3JlYXRlKElBVklTdHJlYW0qaWZhY2UsTFBBUkFNIGxQYXJhbTEsTFBBUkFNIGxQYXJhbTIpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbkluZm8oSUFWSVN0cmVhbSppZmFjZSxBVklTVFJFQU1JTkZPVyAqcHNpLExPTkcgc2l6ZSk7CnN0YXRpYyBMT05HICAgIFdJTkFQSSBJQVZJU3RyZWFtX2ZuRmluZFNhbXBsZShJQVZJU3RyZWFtKmlmYWNlLExPTkcgcG9zLExPTkcgZmxhZ3MpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblJlYWRGb3JtYXQoSUFWSVN0cmVhbSppZmFjZSxMT05HIHBvcyxMUFZPSUQgZm9ybWF0LExPTkcgKmZvcm1hdHNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblNldEZvcm1hdChJQVZJU3RyZWFtKmlmYWNlLExPTkcgcG9zLExQVk9JRCBmb3JtYXQsTE9ORyBmb3JtYXRzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5SZWFkKElBVklTdHJlYW0qaWZhY2UsTE9ORyBzdGFydCxMT05HIHNhbXBsZXMsTFBWT0lEIGJ1ZmZlcixMT05HIGJ1ZmZlcnNpemUsTE9ORyAqYnl0ZXNyZWFkLExPTkcgKnNhbXBsZXNyZWFkKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5Xcml0ZShJQVZJU3RyZWFtKmlmYWNlLExPTkcgc3RhcnQsTE9ORyBzYW1wbGVzLExQVk9JRCBidWZmZXIsTE9ORyBidWZmZXJzaXplLERXT1JEIGZsYWdzLExPTkcgKnNhbXB3cml0dGVuLExPTkcgKmJ5dGVzd3JpdHRlbik7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuRGVsZXRlKElBVklTdHJlYW0qaWZhY2UsTE9ORyBzdGFydCxMT05HIHNhbXBsZXMpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblJlYWREYXRhKElBVklTdHJlYW0qaWZhY2UsRFdPUkQgZmNjLExQVk9JRCBscCxMT05HICpscHJlYWQpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbldyaXRlRGF0YShJQVZJU3RyZWFtKmlmYWNlLERXT1JEIGZjYyxMUFZPSUQgbHAsTE9ORyBzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5TZXRJbmZvKElBVklTdHJlYW0qaWZhY2UsQVZJU1RSRUFNSU5GT1cqaW5mbyxMT05HIGluZm9sZW4pOwoKc3RydWN0IElDT01fVlRBQkxFKElBVklTdHJlYW0pIGlhdmlzdCA9IHsKICBJQ09NX01TVlRBQkxFX0NPTVBBVF9EdW1teVJUVElWQUxVRQogIElBVklTdHJlYW1fZm5RdWVyeUludGVyZmFjZSwKICBJQVZJU3RyZWFtX2ZuQWRkUmVmLAogIElBVklTdHJlYW1fZm5SZWxlYXNlLAogIElBVklTdHJlYW1fZm5DcmVhdGUsCiAgSUFWSVN0cmVhbV9mbkluZm8sCiAgSUFWSVN0cmVhbV9mbkZpbmRTYW1wbGUsCiAgSUFWSVN0cmVhbV9mblJlYWRGb3JtYXQsCiAgSUFWSVN0cmVhbV9mblNldEZvcm1hdCwKICBJQVZJU3RyZWFtX2ZuUmVhZCwKICBJQVZJU3RyZWFtX2ZuV3JpdGUsCiAgSUFWSVN0cmVhbV9mbkRlbGV0ZSwKICBJQVZJU3RyZWFtX2ZuUmVhZERhdGEsCiAgSUFWSVN0cmVhbV9mbldyaXRlRGF0YSwKICBJQVZJU3RyZWFtX2ZuU2V0SW5mbwp9OwoKdHlwZWRlZiBzdHJ1Y3QgX0lBVklGaWxlSW1wbCBJQVZJRmlsZUltcGw7Cgp0eXBlZGVmIHN0cnVjdCBfSVBlcnNpc3RGaWxlSW1wbCB7CiAgLyogSVVua25vd24gc3R1ZmYgKi8KICBJQ09NX1ZGSUVMRChJUGVyc2lzdEZpbGUpOwoKICAvKiBJUGVyc2lzdEZpbGUgc3R1ZmYgKi8KICBJQVZJRmlsZUltcGwgICAgICpwYWY7Cn0gSVBlcnNpc3RGaWxlSW1wbDsKCnR5cGVkZWYgc3RydWN0IF9JQVZJU3RyZWFtSW1wbCB7CiAgLyogSVVua25vd24gc3R1ZmYgKi8KICBJQ09NX1ZGSUVMRChJQVZJU3RyZWFtKTsKICBEV09SRAkJICAgIHJlZjsKCiAgLyogSUFWSVN0cmVhbSBzdHVmZiAqLwogIElBVklGaWxlSW1wbCAgICAgKnBhZjsKICBEV09SRCAgICAgICAgICAgICBuU3RyZWFtOyAgICAgICAvKiB0aGUgbi10aCBzdHJlYW0gaW4gZmlsZSAqLwogIEFWSVNUUkVBTUlORk9XICAgIHNJbmZvOwoKICBMUFZPSUQgICAgICAgICAgICBscEZvcm1hdDsKICBEV09SRCAgICAgICAgICAgICBjYkZvcm1hdDsKCiAgTFBWT0lEICAgICAgICAgICAgbHBIYW5kbGVyRGF0YTsKICBEV09SRCAgICAgICAgICAgICBjYkhhbmRsZXJEYXRhOwoKICBFWFRSQUNIVU5LUyAgICAgICBleHRyYTsKCiAgTFBEV09SRCAgICAgICAgICAgbHBCdWZmZXI7CiAgRFdPUkQgICAgICAgICAgICAgY2JCdWZmZXI7ICAgICAgIC8qIHNpemUgb2YgbHBCdWZmZXIgKi8KICBEV09SRCAgICAgICAgICAgICBkd0N1cnJlbnRGcmFtZTsgLyogZnJhbWUvYmxvY2sgY3VycmVudGx5IGluIGxwQnVmZmVyICovCgogIExPTkcgICAgICAgICAgICAgIGxMYXN0RnJhbWU7ICAgIC8qIGxhc3QgY29ycmVjdCBpbmRleCBpbiBpZHhGcmFtZXMgKi8KICBBVklJTkRFWEVOVFJZICAgICppZHhGcmFtZXM7CiAgRFdPUkQgICAgICAgICAgICAgbklkeEZyYW1lczsgICAgIC8qIHVwcGVyIGluZGV4IGxpbWl0IG9mIGlkeEZyYW1lcyAqLwogIEFWSUlOREVYRU5UUlkgICAgKmlkeEZtdENoYW5nZXM7CiAgRFdPUkQgICAgICAgICAgICAgbklkeEZtdENoYW5nZXM7IC8qIHVwcGVyIGluZGV4IGxpbWl0IG9mIGlkeEZtdENoYW5nZXMgKi8KfSBJQVZJU3RyZWFtSW1wbDsKCnN0cnVjdCBfSUFWSUZpbGVJbXBsIHsKICAvKiBJVW5rbm93biBzdHVmZiAqLwogIElDT01fVkZJRUxEKElBVklGaWxlKTsKICBEV09SRAkJICAgIHJlZjsKCiAgLyogSUFWSUZpbGUgc3R1ZmYuLi4gKi8KICBJUGVyc2lzdEZpbGVJbXBsICBpUGVyc2lzdEZpbGU7CgogIEFWSUZJTEVJTkZPVyAgICAgIGZJbmZvOwogIElBVklTdHJlYW1JbXBsICAgKnBwU3RyZWFtc1tNQVhfQVZJU1RSRUFNU107CgogIEVYVFJBQ0hVTktTICAgICAgIGZpbGVleHRyYTsKCiAgRFdPUkQgICAgICAgICAgICAgZHdNb3ZpQ2h1bmtQb3M7ICAvKiBzb21lIHN0dWZmIGZvciBzYXZpbmcgLi4uICovCiAgRFdPUkQgICAgICAgICAgICAgZHdJZHhDaHVua1BvczsKICBEV09SRCAgICAgICAgICAgICBkd05leHRGcmFtZVBvczsKICBEV09SRCAgICAgICAgICAgICBkd0luaXRpYWxGcmFtZXM7CgogIE1NQ0tJTkZPICAgICAgICAgIGNrTGFzdFJlY29yZDsKICBBVklJTkRFWEVOVFJZICAgICppZHhSZWNvcmRzOyAgICAgIC8qIHdvbid0IGJlIHVwZGF0ZWQgd2hpbGUgbG9hZGluZyAqLwogIERXT1JEICAgICAgICAgICAgIG5JZHhSZWNvcmRzOyAgICAgLyogY3VycmVudCBmaWxsIGxldmVsICovCiAgRFdPUkQgICAgICAgICAgICAgY2JJZHhSZWNvcmRzOyAgICAvKiBzaXplIG9mIGlkeFJlY29yZHMgKi8KCiAgLyogSVBlcnNpc3RGaWxlIHN0dWZmIC4uLiAqLwogIEhNTUlPICAgICAgICAgICAgIGhtbWlvOwogIExQV1NUUiAgICAgICAgICAgIHN6RmlsZU5hbWU7CiAgVUlOVCAgICAgICAgICAgICAgdU1vZGU7CiAgQk9PTCAgICAgICAgICAgICAgZkRpcnR5Owp9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9BZGRGcmFtZShJQVZJU3RyZWFtSW1wbCAqVGhpcywgRFdPUkQgY2tpZCwgRFdPUkQgc2l6ZSwKCQkJCURXT1JEIG9mZnNldCwgRFdPUkQgZmxhZ3MpOwpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX0FkZFJlY29yZChJQVZJRmlsZUltcGwgKlRoaXMpOwpzdGF0aWMgRFdPUkQgICBBVklGSUxFX0NvbXB1dGVNb3ZpU3RhcnQoSUFWSUZpbGVJbXBsICpUaGlzKTsKc3RhdGljIHZvaWQgICAgQVZJRklMRV9Db25zdHJ1Y3RBVklTdHJlYW0oSUFWSUZpbGVJbXBsICpwYWYsIERXT1JEIG5yLAoJCQkJCSAgTFBBVklTVFJFQU1JTkZPVyBhc2kpOwpzdGF0aWMgdm9pZCAgICBBVklGSUxFX0Rlc3RydWN0QVZJU3RyZWFtKElBVklTdHJlYW1JbXBsICpUaGlzKTsKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9Mb2FkRmlsZShJQVZJRmlsZUltcGwgKlRoaXMpOwpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX0xvYWRJbmRleChJQVZJRmlsZUltcGwgKlRoaXMsIERXT1JEIHNpemUsIERXT1JEIG9mZnNldCk7CnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfUGFyc2VJbmRleChJQVZJRmlsZUltcGwgKlRoaXMsIEFWSUlOREVYRU5UUlkgKmxwLAoJCQkJICBMT05HIGNvdW50LCBEV09SRCBwb3MsIEJPT0wgKmJBYnNvbHV0ZSk7CnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfUmVhZEJsb2NrKElBVklTdHJlYW1JbXBsICpUaGlzLCBEV09SRCBzdGFydCwKCQkJCSBMUFZPSUQgYnVmZmVyLCBMT05HIHNpemUpOwpzdGF0aWMgdm9pZCAgICBBVklGSUxFX1NhbXBsZXNUb0Jsb2NrKElBVklTdHJlYW1JbXBsICpUaGlzLCBMUExPTkcgcG9zLAoJCQkJICAgICAgTFBMT05HIG9mZnNldCk7CnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfU2F2ZUZpbGUoSUFWSUZpbGVJbXBsICpUaGlzKTsKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9TYXZlSW5kZXgoSUFWSUZpbGVJbXBsICpUaGlzKTsKc3RhdGljIFVMT05HICAgQVZJRklMRV9TZWFyY2hTdHJlYW0oSUFWSUZpbGVJbXBsICpUaGlzLCBEV09SRCBmY2NUeXBlLAoJCQkJICAgIExPTkcgbFNraXApOwpzdGF0aWMgdm9pZCAgICBBVklGSUxFX1VwZGF0ZUluZm8oSUFWSUZpbGVJbXBsICpUaGlzKTsKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9Xcml0ZUJsb2NrKElBVklTdHJlYW1JbXBsICpUaGlzLCBEV09SRCBibG9jaywKCQkJCSAgRk9VUkNDIGNraWQsIERXT1JEIGZsYWdzLCBMUFZPSUQgYnVmZmVyLAoJCQkJICBMT05HIHNpemUpOwoKSFJFU1VMVCBBVklGSUxFX0NyZWF0ZUFWSUZpbGUoUkVGSUlEIHJpaWQsIExQVk9JRCAqcHB2KQp7CiAgSUFWSUZpbGVJbXBsICpwZmlsZTsKICBIUkVTVUxUICAgICAgIGhyOwoKICBhc3NlcnQocmlpZCAhPSBOVUxMICYmIHBwdiAhPSBOVUxMKTsKCiAgKnBwdiA9IE5VTEw7CgogIHBmaWxlID0gKElBVklGaWxlSW1wbCopTG9jYWxBbGxvYyhMUFRSLCBzaXplb2YoSUFWSUZpbGVJbXBsKSk7CiAgaWYgKHBmaWxlID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgcGZpbGUtPmxwVnRibCA9ICZpYXZpZnQ7CiAgcGZpbGUtPnJlZiA9IDA7CiAgcGZpbGUtPmlQZXJzaXN0RmlsZS5scFZ0YmwgPSAmaXBlcnNpc3RmdDsKICBwZmlsZS0+aVBlcnNpc3RGaWxlLnBhZiA9IHBmaWxlOwoKICBociA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKChJVW5rbm93biopcGZpbGUsIHJpaWQsIHBwdik7CiAgaWYgKEZBSUxFRChocikpCiAgICBMb2NhbEZyZWUoKEhMT0NBTClwZmlsZSk7CgogIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuUXVlcnlJbnRlcmZhY2UoSUFWSUZpbGUgKmlmYWNlLCBSRUZJSUQgcmVmaWlkLAoJCQkJCQlMUFZPSUQgKm9iaikKewogIElDT01fVEhJUyhJQVZJRmlsZUltcGwsaWZhY2UpOwoKICBUUkFDRSgiKCVwLCVzLCVwKVxuIiwgVGhpcywgZGVidWdzdHJfZ3VpZChyZWZpaWQpLCBvYmopOwoKICBpZiAoSXNFcXVhbEdVSUQoJklJRF9JVW5rbm93biwgcmVmaWlkKSB8fAogICAgICBJc0VxdWFsR1VJRCgmSUlEX0lBVklGaWxlLCByZWZpaWQpKSB7CiAgICAqb2JqID0gaWZhY2U7CiAgICBJQVZJRmlsZV9BZGRSZWYoaWZhY2UpOwoKICAgIHJldHVybiBTX09LOwogIH0gZWxzZSBpZiAoSXNFcXVhbEdVSUQoJklJRF9JUGVyc2lzdEZpbGUsIHJlZmlpZCkpIHsKICAgICpvYmogPSAmVGhpcy0+aVBlcnNpc3RGaWxlOwogICAgSUFWSUZpbGVfQWRkUmVmKGlmYWNlKTsKCiAgICByZXR1cm4gU19PSzsKICB9CgogIHJldHVybiBPTEVfRV9FTlVNX05PTU9SRTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBJQVZJRmlsZV9mbkFkZFJlZihJQVZJRmlsZSAqaWZhY2UpCnsKICBJQ09NX1RISVMoSUFWSUZpbGVJbXBsLGlmYWNlKTsKCiAgVFJBQ0UoIiglcCkgLT4gJWxkXG4iLCBpZmFjZSwgVGhpcy0+cmVmICsgMSk7CiAgcmV0dXJuICsrKFRoaXMtPnJlZik7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSUFWSUZpbGVfZm5SZWxlYXNlKElBVklGaWxlICppZmFjZSkKewogIElDT01fVEhJUyhJQVZJRmlsZUltcGwsaWZhY2UpOwogIFVJTlQgaTsKCiAgVFJBQ0UoIiglcCkgLT4gJWxkXG4iLCBpZmFjZSwgVGhpcy0+cmVmIC0gMSk7CgogIGlmICghLS0oVGhpcy0+cmVmKSkgewogICAgaWYgKFRoaXMtPmZEaXJ0eSkgewogICAgICAvKiBuZWVkIHRvIHdyaXRlIGhlYWRlcnMgdG8gZmlsZSAqLwogICAgICBBVklGSUxFX1NhdmVGaWxlKFRoaXMpOwogICAgfQoKICAgIGZvciAoaSA9IDA7IGkgPCBUaGlzLT5mSW5mby5kd1N0cmVhbXM7IGkrKykgewogICAgICBpZiAoVGhpcy0+cHBTdHJlYW1zW2ldICE9IE5VTEwpIHsKCWlmIChUaGlzLT5wcFN0cmVhbXNbaV0tPnJlZiAhPSAwKSB7CgkgIEVSUigiOiBzb21lb25lIGhhcyBzdGlsbCAlbHUgcmVmZXJlbmNlIHRvIHN0cmVhbSAldSAoJXApIVxuIiwKCSAgICAgICBUaGlzLT5wcFN0cmVhbXNbaV0tPnJlZiwgaSwgVGhpcy0+cHBTdHJlYW1zW2ldKTsKCX0KCUFWSUZJTEVfRGVzdHJ1Y3RBVklTdHJlYW0oVGhpcy0+cHBTdHJlYW1zW2ldKTsKCUxvY2FsRnJlZSgoSExPQ0FMKVRoaXMtPnBwU3RyZWFtc1tpXSk7CglUaGlzLT5wcFN0cmVhbXNbaV0gPSBOVUxMOwogICAgICB9CiAgICB9CgogICAgaWYgKFRoaXMtPmlkeFJlY29yZHMgIT0gTlVMTCkgewogICAgICBHbG9iYWxGcmVlUHRyKFRoaXMtPmlkeFJlY29yZHMpOwogICAgICBUaGlzLT5pZHhSZWNvcmRzICA9IE5VTEw7CiAgICAgIFRoaXMtPm5JZHhSZWNvcmRzID0gMDsKICAgIH0KCiAgICBpZiAoVGhpcy0+ZmlsZWV4dHJhLmxwICE9IE5VTEwpIHsKICAgICAgR2xvYmFsRnJlZVB0cihUaGlzLT5maWxlZXh0cmEubHApOwogICAgICBUaGlzLT5maWxlZXh0cmEubHAgPSBOVUxMOwogICAgICBUaGlzLT5maWxlZXh0cmEuY2IgPSAwOwogICAgfQoKICAgIGlmIChUaGlzLT5zekZpbGVOYW1lICE9IE5VTEwpIHsKICAgICAgTG9jYWxGcmVlKChITE9DQUwpVGhpcy0+c3pGaWxlTmFtZSk7CiAgICAgIFRoaXMtPnN6RmlsZU5hbWUgPSBOVUxMOwogICAgfQogICAgaWYgKFRoaXMtPmhtbWlvICE9IE5VTEwpIHsKICAgICAgbW1pb0Nsb3NlKFRoaXMtPmhtbWlvLCAwKTsKICAgICAgVGhpcy0+aG1taW8gPSBOVUxMOwogICAgfQoKICAgIExvY2FsRnJlZSgoSExPQ0FMKVRoaXMpOwogICAgcmV0dXJuIDA7CiAgfQogIHJldHVybiBUaGlzLT5yZWY7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkluZm8oSUFWSUZpbGUgKmlmYWNlLCBMUEFWSUZJTEVJTkZPVyBhZmksCgkJCQkgICAgICBMT05HIHNpemUpCnsKICBJQ09NX1RISVMoSUFWSUZpbGVJbXBsLGlmYWNlKTsKCiAgVFJBQ0UoIiglcCwlcCwlbGQpXG4iLGlmYWNlLGFmaSxzaXplKTsKCiAgaWYgKGFmaSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICBpZiAoc2l6ZSA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CgogIEFWSUZJTEVfVXBkYXRlSW5mbyhUaGlzKTsKCiAgbWVtY3B5KGFmaSwgJlRoaXMtPmZJbmZvLCBtaW4oKERXT1JEKXNpemUsIHNpemVvZihUaGlzLT5mSW5mbykpKTsKCiAgaWYgKChEV09SRClzaXplIDwgc2l6ZW9mKFRoaXMtPmZJbmZvKSkKICAgIHJldHVybiBBVklFUlJfQlVGRkVSVE9PU01BTEw7CiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuR2V0U3RyZWFtKElBVklGaWxlICppZmFjZSwgUEFWSVNUUkVBTSAqYXZpcywKCQkJCQkgICBEV09SRCBmY2NUeXBlLCBMT05HIGxQYXJhbSkKewogIElDT01fVEhJUyhJQVZJRmlsZUltcGwsaWZhY2UpOwoKICBVTE9ORyBuU3RyZWFtOwoKICBUUkFDRSgiKCVwLCVwLDB4JTA4bFgsJWxkKVxuIiwgaWZhY2UsIGF2aXMsIGZjY1R5cGUsIGxQYXJhbSk7CgogIGlmIChhdmlzID09IE5VTEwgfHwgbFBhcmFtIDwgMCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIG5TdHJlYW0gPSBBVklGSUxFX1NlYXJjaFN0cmVhbShUaGlzLCBmY2NUeXBlLCBsUGFyYW0pOwoKICAvKiBEb2VzIHRoZSByZXF1ZXN0ZWQgc3RyZWFtIGV4aXN0PyAqLwogIGlmIChuU3RyZWFtIDwgVGhpcy0+ZkluZm8uZHdTdHJlYW1zICYmCiAgICAgIFRoaXMtPnBwU3RyZWFtc1tuU3RyZWFtXSAhPSBOVUxMKSB7CiAgICAqYXZpcyA9IChQQVZJU1RSRUFNKVRoaXMtPnBwU3RyZWFtc1tuU3RyZWFtXTsKICAgIElBVklTdHJlYW1fQWRkUmVmKCphdmlzKTsKCiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0KCiAgLyogU29ycnksIGJ1dCB0aGUgc3BlY2lmaWVkIHN0cmVhbSBkb2Vzbid0IGV4aXN0ICovCiAgcmV0dXJuIEFWSUVSUl9OT0RBVEE7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkNyZWF0ZVN0cmVhbShJQVZJRmlsZSAqaWZhY2UsUEFWSVNUUkVBTSAqYXZpcywKCQkJCQkgICAgICBMUEFWSVNUUkVBTUlORk9XIGFzaSkKewogIElDT01fVEhJUyhJQVZJRmlsZUltcGwsaWZhY2UpOwoKICBEV09SRCBuOwoKICBUUkFDRSgiKCVwLCVwLCVwKVxuIiwgaWZhY2UsIGF2aXMsIGFzaSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoYXZpcyA9PSBOVUxMIHx8IGFzaSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgKmF2aXMgPSBOVUxMOwoKICAvKiBEb2VzIHRoZSB1c2VyIGhhdmUgd3JpdGUgcGVybWlzc2lvbj8gKi8KICBpZiAoKFRoaXMtPnVNb2RlICYgTU1JT19SV01PREUpID09IDApCiAgICByZXR1cm4gQVZJRVJSX1JFQURPTkxZOwoKICAvKiBDYW4gd2UgYWRkIGFub3RoZXIgc3RyZWFtPyAqLwogIG4gPSBUaGlzLT5mSW5mby5kd1N0cmVhbXM7CiAgaWYgKG4gPj0gTUFYX0FWSVNUUkVBTVMgfHwgVGhpcy0+ZHdNb3ZpQ2h1bmtQb3MgIT0gMCkgewogICAgLyogYWxyZWFkeSByZWFjaGVkIG1heCBuciBvZiBzdHJlYW1zCiAgICAgKiBvciBoYXZlIGFscmVhZHkgd3JpdHRlbiBmcmFtZXMgdG8gZGlzayAqLwogICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKICB9CgogIC8qIGNoZWNrIEFWSVNUUkVBTUlORk8gZm9yIHNvbWUgcmVhbGx5IG5lZWRlZCB0aGluZ3MgKi8KICBpZiAoYXNpLT5mY2NUeXBlID09IDAgfHwgYXNpLT5kd1NjYWxlID09IDAgfHwgYXNpLT5kd1JhdGUgPT0gMCkKICAgIHJldHVybiBBVklFUlJfQkFERk9STUFUOwoKICAvKiBub3cgaXQgc2VlbXMgdG8gYmUgc2F2ZSB0byBhZGQgdGhlIHN0cmVhbSAqLwogIGFzc2VydChUaGlzLT5wcFN0cmVhbXNbbl0gPT0gTlVMTCk7CiAgVGhpcy0+cHBTdHJlYW1zW25dID0gKElBVklTdHJlYW1JbXBsKilMb2NhbEFsbG9jKExQVFIsCgkJCQkJCSAgIHNpemVvZihJQVZJU3RyZWFtSW1wbCkpOwogIGlmIChUaGlzLT5wcFN0cmVhbXNbbl0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICAvKiBpbml0aWFsaXplIHRoZSBuZXcgYWxsb2NhdGVkIHN0cmVhbSAqLwogIEFWSUZJTEVfQ29uc3RydWN0QVZJU3RyZWFtKFRoaXMsIG4sIGFzaSk7CgogIFRoaXMtPmZJbmZvLmR3U3RyZWFtcysrOwogIFRoaXMtPmZEaXJ0eSA9IFRSVUU7CgogIC8qIHVwZGF0ZSBvdXIgQVZJRklMRUlORk8gc3RydWN0dXJlICovCiAgQVZJRklMRV9VcGRhdGVJbmZvKFRoaXMpOwoKICAvKiByZXR1cm4gaXQgKi8KICAqYXZpcyA9IChQQVZJU1RSRUFNKVRoaXMtPnBwU3RyZWFtc1tuXTsKICBJQVZJU3RyZWFtX0FkZFJlZigqYXZpcyk7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbldyaXRlRGF0YShJQVZJRmlsZSAqaWZhY2UsIERXT1JEIGNraWQsCgkJCQkJICAgTFBWT0lEIGxwRGF0YSwgTE9ORyBzaXplKQp7CiAgSUNPTV9USElTKElBVklGaWxlSW1wbCxpZmFjZSk7CgogIFRSQUNFKCIoJXAsMHglMDhsWCwlcCwlbGQpXG4iLCBpZmFjZSwgY2tpZCwgbHBEYXRhLCBzaXplKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChscERhdGEgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgaWYgKHNpemUgPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURTSVpFOwoKICAvKiBEbyB3ZSBoYXZlIHdyaXRlIHBlcm1pc3Npb24/ICovCiAgaWYgKChUaGlzLT51TW9kZSAmIE1NSU9fUldNT0RFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgVGhpcy0+ZkRpcnR5ID0gVFJVRTsKCiAgcmV0dXJuIFdyaXRlRXh0cmFDaHVuaygmVGhpcy0+ZmlsZWV4dHJhLCBja2lkLCBscERhdGEsIHNpemUpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5SZWFkRGF0YShJQVZJRmlsZSAqaWZhY2UsIERXT1JEIGNraWQsCgkJCQkJICBMUFZPSUQgbHBEYXRhLCBMT05HICpzaXplKQp7CiAgSUNPTV9USElTKElBVklGaWxlSW1wbCxpZmFjZSk7CgogIFRSQUNFKCIoJXAsMHglMDhsWCwlcCwlcClcbiIsIGlmYWNlLCBja2lkLCBscERhdGEsIHNpemUpOwoKICByZXR1cm4gUmVhZEV4dHJhQ2h1bmsoJlRoaXMtPmZpbGVleHRyYSwgY2tpZCwgbHBEYXRhLCBzaXplKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuRW5kUmVjb3JkKElBVklGaWxlICppZmFjZSkKewogIElDT01fVEhJUyhJQVZJRmlsZUltcGwsaWZhY2UpOwoKICBUUkFDRSgiKCVwKVxuIixpZmFjZSk7CgogIGlmICgoVGhpcy0+dU1vZGUgJiBNTUlPX1JXTU9ERSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIFRoaXMtPmZEaXJ0eSA9IFRSVUU7CgogIC8qIG5vIGZyYW1lcyB3cml0dGVuIHRvIGFueSBzdHJlYW0/IC0tIGNvbXB1dGUgc3RhcnQgb2YgJ21vdmknLWNodW5rICovCiAgaWYgKFRoaXMtPmR3TW92aUNodW5rUG9zID09IDApCiAgICBBVklGSUxFX0NvbXB1dGVNb3ZpU3RhcnQoVGhpcyk7CgogIFRoaXMtPmZJbmZvLmR3RmxhZ3MgIHw9IEFWSUZJTEVJTkZPX0lTSU5URVJMRUFWRUQ7CgogIC8qIGFscmVhZHkgd3JpdHRlbiBmcmFtZXMgdG8gYW55IHN0cmVhbSwgLi4uICovCiAgaWYgKFRoaXMtPmNrTGFzdFJlY29yZC5kd0ZsYWdzICYgTU1JT19ESVJUWSkgewogICAgLyogY2xvc2UgbGFzdCByZWNvcmQgKi8KICAgIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmVGhpcy0+Y2tMYXN0UmVjb3JkLCAwKSAhPSAwKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgICBBVklGSUxFX0FkZFJlY29yZChUaGlzKTsKCiAgICBpZiAoVGhpcy0+ZkluZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplIDwgVGhpcy0+Y2tMYXN0UmVjb3JkLmNrc2l6ZSArIDMgKiBzaXplb2YoRFdPUkQpKQogICAgICBUaGlzLT5mSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPSBUaGlzLT5ja0xhc3RSZWNvcmQuY2tzaXplICsgMyAqIHNpemVvZihEV09SRCk7CiAgfQoKICAvKiB3cml0ZSBvdXQgYSBuZXcgcmVjb3JkIGludG8gZmlsZSwgYnV0IGRvbid0IGNsb3NlIGl0ICovCiAgVGhpcy0+Y2tMYXN0UmVjb3JkLmNrc2l6ZSAgPSAwOwogIFRoaXMtPmNrTGFzdFJlY29yZC5mY2NUeXBlID0gbGlzdHR5cGVBVklSRUNPUkQ7CiAgaWYgKG1taW9TZWVrKFRoaXMtPmhtbWlvLCBUaGlzLT5kd05leHRGcmFtZVBvcywgU0VFS19TRVQpID09IC0xKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJlRoaXMtPmNrTGFzdFJlY29yZCwgTU1JT19DUkVBVEVMSVNUKSAhPSAwKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgVGhpcy0+ZHdOZXh0RnJhbWVQb3MgKz0gMyAqIHNpemVvZihEV09SRCk7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkRlbGV0ZVN0cmVhbShJQVZJRmlsZSAqaWZhY2UsIERXT1JEIGZjY1R5cGUsCgkJCQkJICAgICAgTE9ORyBsUGFyYW0pCnsKICBJQ09NX1RISVMoSUFWSUZpbGVJbXBsLGlmYWNlKTsKCiAgVUxPTkcgblN0cmVhbTsKCiAgVFJBQ0UoIiglcCwweCUwOGxYLCVsZClcbiIsIGlmYWNlLCBmY2NUeXBlLCBsUGFyYW0pOwoKICAvKiBjaGVjayBwYXJhbWV0ZXIgKi8KICBpZiAobFBhcmFtIDwgMCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIC8qIEhhdmUgdXNlciB3cml0ZSBwZXJtaXNzaW9ucz8gKi8KICBpZiAoKFRoaXMtPnVNb2RlICYgTU1JT19SV01PREUpID09IDApCiAgICByZXR1cm4gQVZJRVJSX1JFQURPTkxZOwoKICBuU3RyZWFtID0gQVZJRklMRV9TZWFyY2hTdHJlYW0oVGhpcywgZmNjVHlwZSwgbFBhcmFtKTsKCiAgLyogRG9lcyB0aGUgcmVxdWVzdGVkIHN0cmVhbSBleGlzdD8gKi8KICBpZiAoblN0cmVhbSA8IFRoaXMtPmZJbmZvLmR3U3RyZWFtcyAmJgogICAgICBUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV0gIT0gTlVMTCkgewogICAgLyogLi4uIHNvIGRlbGV0ZSBpdCBub3cgKi8KICAgIExvY2FsRnJlZSgoSExPQ0FMKVRoaXMtPnBwU3RyZWFtc1tuU3RyZWFtXSk7CgogICAgaWYgKFRoaXMtPmZJbmZvLmR3U3RyZWFtcyAtIG5TdHJlYW0gPiAwKQogICAgICBtZW1jcHkoVGhpcy0+cHBTdHJlYW1zICsgblN0cmVhbSwgVGhpcy0+cHBTdHJlYW1zICsgblN0cmVhbSArIDEsCgkgICAgIChUaGlzLT5mSW5mby5kd1N0cmVhbXMgLSBuU3RyZWFtKSAqIHNpemVvZihJQVZJU3RyZWFtSW1wbCopKTsKCiAgICBUaGlzLT5wcFN0cmVhbXNbVGhpcy0+ZkluZm8uZHdTdHJlYW1zXSA9IE5VTEw7CiAgICBUaGlzLT5mSW5mby5kd1N0cmVhbXMtLTsKICAgIFRoaXMtPmZEaXJ0eSA9IFRSVUU7CgogICAgLyogVGhpcy0+ZkluZm8gd2lsbCBiZSB1cGRhdGVkIGZ1cnRoZXIgd2hlbiBhc2tlZCBmb3IgKi8KICAgIHJldHVybiBBVklFUlJfT0s7CiAgfSBlbHNlCiAgICByZXR1cm4gQVZJRVJSX05PREFUQTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mblF1ZXJ5SW50ZXJmYWNlKElQZXJzaXN0RmlsZSAqaWZhY2UsCgkJCQkJCSAgICBSRUZJSUQgcmVmaWlkLCBMUFZPSUQgKm9iaikKewogIElDT01fVEhJUyhJUGVyc2lzdEZpbGVJbXBsLGlmYWNlKTsKCiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklGaWxlX1F1ZXJ5SW50ZXJmYWNlKChQQVZJRklMRSlUaGlzLT5wYWYsIHJlZmlpZCwgb2JqKTsKfQoKc3RhdGljIFVMT05HICAgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkFkZFJlZihJUGVyc2lzdEZpbGUgKmlmYWNlKQp7CiAgSUNPTV9USElTKElQZXJzaXN0RmlsZUltcGwsaWZhY2UpOwoKICBhc3NlcnQoVGhpcy0+cGFmICE9IE5VTEwpOwoKICByZXR1cm4gSUFWSUZpbGVfQWRkUmVmKChQQVZJRklMRSlUaGlzLT5wYWYpOwp9CgpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuUmVsZWFzZShJUGVyc2lzdEZpbGUgKmlmYWNlKQp7CiAgSUNPTV9USElTKElQZXJzaXN0RmlsZUltcGwsaWZhY2UpOwoKICBhc3NlcnQoVGhpcy0+cGFmICE9IE5VTEwpOwoKICByZXR1cm4gSUFWSUZpbGVfUmVsZWFzZSgoUEFWSUZJTEUpVGhpcy0+cGFmKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkdldENsYXNzSUQoSVBlcnNpc3RGaWxlICppZmFjZSwKCQkJCQkJTFBDTFNJRCBwQ2xhc3NJRCkKewogIFRSQUNFKCIoJXAsJXApXG4iLCBpZmFjZSwgcENsYXNzSUQpOwoKICBpZiAocENsYXNzSUQgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIG1lbWNweShwQ2xhc3NJRCwgJkNMU0lEX0FWSUZpbGUsIHNpemVvZihDTFNJRF9BVklGaWxlKSk7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5Jc0RpcnR5KElQZXJzaXN0RmlsZSAqaWZhY2UpCnsKICBJQ09NX1RISVMoSVBlcnNpc3RGaWxlSW1wbCxpZmFjZSk7CgogIFRSQUNFKCIoJXApXG4iLCBpZmFjZSk7CgogIGFzc2VydChUaGlzLT5wYWYgIT0gTlVMTCk7CgogIHJldHVybiAoVGhpcy0+cGFmLT5mRGlydHkgPyBTX09LIDogU19GQUxTRSk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5Mb2FkKElQZXJzaXN0RmlsZSAqaWZhY2UsCgkJCQkJICBMUENPTEVTVFIgcHN6RmlsZU5hbWUsIERXT1JEIGR3TW9kZSkKewogIElDT01fVEhJUyhJUGVyc2lzdEZpbGVJbXBsLGlmYWNlKTsKCiAgaW50IGxlbjsKCiAgVFJBQ0UoIiglcCwlcywweCUwOGxYKVxuIiwgaWZhY2UsIGRlYnVnc3RyX3cocHN6RmlsZU5hbWUpLCBkd01vZGUpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXIgKi8KICBpZiAocHN6RmlsZU5hbWUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIGFzc2VydChUaGlzLT5wYWYgIT0gTlVMTCk7CiAgaWYgKFRoaXMtPnBhZi0+aG1taW8gIT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfRVJST1I7IC8qIE5vIHJldXNlIG9mIHRoaXMgb2JqZWN0IGZvciBhbm90aGVyIGZpbGUhICovCgogIC8qIHJlbWViZXIgbW9kZSBhbmQgbmFtZSAqLwogIFRoaXMtPnBhZi0+dU1vZGUgPSBkd01vZGU7CgogIGxlbiA9IGxzdHJsZW5XKHBzekZpbGVOYW1lKSArIDE7CiAgVGhpcy0+cGFmLT5zekZpbGVOYW1lID0gKExQV1NUUilMb2NhbEFsbG9jKExQVFIsIGxlbiAqIHNpemVvZihXQ0hBUikpOwogIGlmIChUaGlzLT5wYWYtPnN6RmlsZU5hbWUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogIGxzdHJjcHlXKFRoaXMtPnBhZi0+c3pGaWxlTmFtZSwgcHN6RmlsZU5hbWUpOwoKICAvKiB0cnkgdG8gb3BlbiB0aGUgZmlsZSAqLwogIFRoaXMtPnBhZi0+aG1taW8gPSBtbWlvT3BlblcoVGhpcy0+cGFmLT5zekZpbGVOYW1lLCBOVUxMLAoJCQkgICAgICAgTU1JT19BTExPQ0JVRiB8IGR3TW9kZSk7CiAgaWYgKFRoaXMtPnBhZi0+aG1taW8gPT0gTlVMTCkgewogICAgLyogbW1pb09wZW5XIG5vdCBpbiBuYXRpdmUgRExMcyBvZiBXaW45eCAtLSB0cnkgbW1pb09wZW5BICovCiAgICBMUFNUUiBzekZpbGVOYW1lOwoKICAgIGxlbiA9IFdpZGVDaGFyVG9NdWx0aUJ5dGUoQ1BfQUNQLCAwLCBUaGlzLT5wYWYtPnN6RmlsZU5hbWUsIC0xLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgMCwgTlVMTCwgTlVMTCk7CiAgICBzekZpbGVOYW1lID0gTG9jYWxBbGxvYyhMUFRSLCBsZW4gKiBzaXplb2YoQ0hBUikpOwogICAgaWYgKHN6RmlsZU5hbWUgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogICAgV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIFRoaXMtPnBhZi0+c3pGaWxlTmFtZSwgLTEsIHN6RmlsZU5hbWUsCgkJCWxlbiwgTlVMTCwgTlVMTCk7CgogICAgVGhpcy0+cGFmLT5obW1pbyA9IG1taW9PcGVuQShzekZpbGVOYW1lLCBOVUxMLCBNTUlPX0FMTE9DQlVGIHwgZHdNb2RlKTsKICAgIExvY2FsRnJlZSgoSExPQ0FMKXN6RmlsZU5hbWUpOwogICAgaWYgKFRoaXMtPnBhZi0+aG1taW8gPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFT1BFTjsKICB9CgogIC8qIHNob3VsZCB3ZSBjcmVhdGUgYSBuZXcgZmlsZT8gKi8KICBpZiAoZHdNb2RlICYgT0ZfQ1JFQVRFKSB7CiAgICBtZW1zZXQoJiBUaGlzLT5wYWYtPmZJbmZvLCAwLCBzaXplb2YoVGhpcy0+cGFmLT5mSW5mbykpOwogICAgVGhpcy0+cGFmLT5mSW5mby5kd0ZsYWdzID0gQVZJRklMRUlORk9fSEFTSU5ERVggfCBBVklGSUxFSU5GT19UUlVTVENLVFlQRTsKCiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0gZWxzZQogICAgcmV0dXJuIEFWSUZJTEVfTG9hZEZpbGUoVGhpcy0+cGFmKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mblNhdmUoSVBlcnNpc3RGaWxlICppZmFjZSwKCQkJCQkgIExQQ09MRVNUUiBwc3pGaWxlTmFtZSxCT09MIGZSZW1lbWJlcikKewogIFRSQUNFKCIoJXAsJXMsJWQpXG4iLCBpZmFjZSwgZGVidWdzdHJfdyhwc3pGaWxlTmFtZSksIGZSZW1lbWJlcik7CgogIC8qIFdlIHdyaXRlIGRpcmVjdGx5IHRvIGRpc2ssIHNvIG5vdGhpbmcgdG8gZG8uICovCgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5TYXZlQ29tcGxldGVkKElQZXJzaXN0RmlsZSAqaWZhY2UsCgkJCQkJCSAgIExQQ09MRVNUUiBwc3pGaWxlTmFtZSkKewogIFRSQUNFKCIoJXAsJXMpXG4iLCBpZmFjZSwgZGVidWdzdHJfdyhwc3pGaWxlTmFtZSkpOwoKICAvKiBXZSB3cml0ZSBkaXJlY3RseSB0byBkaXNrLCBzbyBub3RoaW5nIHRvIGRvLiAqLwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuR2V0Q3VyRmlsZShJUGVyc2lzdEZpbGUgKmlmYWNlLAoJCQkJCQlMUE9MRVNUUiAqcHBzekZpbGVOYW1lKQp7CiAgSUNPTV9USElTKElQZXJzaXN0RmlsZUltcGwsaWZhY2UpOwoKICBUUkFDRSgiKCVwLCVwKVxuIiwgaWZhY2UsIHBwc3pGaWxlTmFtZSk7CgogIGlmIChwcHN6RmlsZU5hbWUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICpwcHN6RmlsZU5hbWUgPSBOVUxMOwoKICBhc3NlcnQoVGhpcy0+cGFmICE9IE5VTEwpOwoKICBpZiAoVGhpcy0+cGFmLT5zekZpbGVOYW1lICE9IE5VTEwpIHsKICAgIGludCBsZW4gPSBsc3RybGVuVyhUaGlzLT5wYWYtPnN6RmlsZU5hbWUpICsgMTsKCiAgICAqcHBzekZpbGVOYW1lID0gKExQT0xFU1RSKUdsb2JhbEFsbG9jUHRyKEdITkQsIGxlbiAqIHNpemVvZihXQ0hBUikpOwogICAgaWYgKCpwcHN6RmlsZU5hbWUgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogICAgc3RyY3B5VygqcHBzekZpbGVOYW1lLCBUaGlzLT5wYWYtPnN6RmlsZU5hbWUpOwogIH0KCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5RdWVyeUludGVyZmFjZShJQVZJU3RyZWFtICppZmFjZSwKCQkJCQkJICBSRUZJSUQgcmVmaWlkLCBMUFZPSUQgKm9iaikKewogIElDT01fVEhJUyhJQVZJU3RyZWFtSW1wbCxpZmFjZSk7CgogIFRSQUNFKCIoJXAsJXMsJXApXG4iLCBpZmFjZSwgZGVidWdzdHJfZ3VpZChyZWZpaWQpLCBvYmopOwoKICBpZiAoSXNFcXVhbEdVSUQoJklJRF9JVW5rbm93biwgcmVmaWlkKSB8fAogICAgICBJc0VxdWFsR1VJRCgmSUlEX0lBVklTdHJlYW0sIHJlZmlpZCkpIHsKICAgICpvYmogPSBUaGlzOwogICAgSUFWSVN0cmVhbV9BZGRSZWYoaWZhY2UpOwoKICAgIHJldHVybiBTX09LOwogIH0KICAvKiBGSVhNRTogSUFWSVN0cmVhbWluZyBpbnRlcmZhY2UgKi8KCiAgcmV0dXJuIE9MRV9FX0VOVU1fTk9NT1JFOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIElBVklTdHJlYW1fZm5BZGRSZWYoSUFWSVN0cmVhbSAqaWZhY2UpCnsKICBJQ09NX1RISVMoSUFWSVN0cmVhbUltcGwsaWZhY2UpOwoKICBUUkFDRSgiKCVwKSAtPiAlbGRcbiIsIGlmYWNlLCBUaGlzLT5yZWYgKyAxKTsKCiAgLyogYWxzbyBhZGQgcmVmIHRvIHBhcmVudCwgc28gdGhhdCBpdCBkb2Vzbid0IGtpbGwgdXMgKi8KICBpZiAoVGhpcy0+cGFmICE9IE5VTEwpCiAgICBJQVZJRmlsZV9BZGRSZWYoKFBBVklGSUxFKVRoaXMtPnBhZik7CgogIHJldHVybiArKyhUaGlzLT5yZWYpOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIElBVklTdHJlYW1fZm5SZWxlYXNlKElBVklTdHJlYW0qIGlmYWNlKQp7CiAgSUNPTV9USElTKElBVklTdHJlYW1JbXBsLGlmYWNlKTsKCiAgVFJBQ0UoIiglcCkgLT4gJWxkXG4iLCBpZmFjZSwgVGhpcy0+cmVmIC0gMSk7CgogIC8qIHdlIGJlbG9uZyB0byB0aGUgQVZJRmlsZSwgd2hpY2ggbXVzdCBmcmVlIHVzISAqLwogIGlmIChUaGlzLT5yZWYgPT0gMCkgewogICAgRVJSKCI6IGFscmVhZHkgcmVsZWFzZWQhXG4iKTsKICAgIHJldHVybiAwOwogIH0KCiAgVGhpcy0+cmVmLS07CgogIGlmIChUaGlzLT5wYWYgIT0gTlVMTCkKICAgIElBVklGaWxlX1JlbGVhc2UoKFBBVklGSUxFKVRoaXMtPnBhZik7CgogIHJldHVybiBUaGlzLT5yZWY7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuQ3JlYXRlKElBVklTdHJlYW0gKmlmYWNlLCBMUEFSQU0gbFBhcmFtMSwKCQkJCQkgIExQQVJBTSBsUGFyYW0yKQp7CiAgVFJBQ0UoIiglcCwweCUwOGxYLDB4JTA4bFgpXG4iLCBpZmFjZSwgbFBhcmFtMSwgbFBhcmFtMik7CgogIC8qIFRoaXMgSUFWSVN0cmVhbSBpbnRlcmZhY2UgbmVlZHMgYW4gQVZJRmlsZSAqLwogIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuSW5mbyhJQVZJU3RyZWFtICppZmFjZSxMUEFWSVNUUkVBTUlORk9XIHBzaSwKCQkJCQlMT05HIHNpemUpCnsKICBJQ09NX1RISVMoSUFWSVN0cmVhbUltcGwsaWZhY2UpOwoKICBUUkFDRSgiKCVwLCVwLCVsZClcbiIsIGlmYWNlLCBwc2ksIHNpemUpOwoKICBpZiAocHNpID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIGlmIChzaXplIDwgMCkKICAgIHJldHVybiBBVklFUlJfQkFEU0laRTsKCiAgbWVtY3B5KHBzaSwgJlRoaXMtPnNJbmZvLCBtaW4oKERXT1JEKXNpemUsIHNpemVvZihUaGlzLT5zSW5mbykpKTsKCiAgaWYgKChEV09SRClzaXplIDwgc2l6ZW9mKFRoaXMtPnNJbmZvKSkKICAgIHJldHVybiBBVklFUlJfQlVGRkVSVE9PU01BTEw7CiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIExPTkcgV0lOQVBJIElBVklTdHJlYW1fZm5GaW5kU2FtcGxlKElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHBvcywKCQkJCQkgICBMT05HIGZsYWdzKQp7CiAgSUNPTV9USElTKElBVklTdHJlYW1JbXBsLGlmYWNlKTsKCiAgTE9ORyBvZmZzZXQgPSAwOwoKICBUUkFDRSgiKCVwLCVsZCwweCUwOGxYKVxuIixpZmFjZSxwb3MsZmxhZ3MpOwoKICBpZiAoZmxhZ3MgJiBGSU5EX0ZST01fU1RBUlQpIHsKICAgIHBvcyA9IFRoaXMtPnNJbmZvLmR3U3RhcnQ7CiAgICBmbGFncyAmPSB+KEZJTkRfRlJPTV9TVEFSVHxGSU5EX1BSRVYpOwogICAgZmxhZ3MgfD0gRklORF9ORVhUOwogIH0KCiAgaWYgKFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSAhPSAwKSB7CiAgICAvKiBjb252ZXJ0IHNhbXBsZXMgaW50byBibG9jayBudW1iZXIgd2l0aCBvZmZzZXQgKi8KICAgIEFWSUZJTEVfU2FtcGxlc1RvQmxvY2soVGhpcywgJnBvcywgJm9mZnNldCk7CiAgfQoKICBpZiAoZmxhZ3MgJiBGSU5EX1RZUEUpIHsKICAgIGlmIChmbGFncyAmIEZJTkRfS0VZKSB7CiAgICAgIHdoaWxlICgwIDw9IHBvcyAmJiBwb3MgPD0gVGhpcy0+bExhc3RGcmFtZSkgewoJaWYgKFRoaXMtPmlkeEZyYW1lc1twb3NdLmR3RmxhZ3MgJiBBVklJRl9LRVlGUkFNRSkKCSAgZ290byBSRVRVUk5fRk9VTkQ7CgoJaWYgKGZsYWdzICYgRklORF9ORVhUKQoJICBwb3MrKzsKCWVsc2UKCSAgcG9zLS07CiAgICAgIH07CiAgICB9IGVsc2UgaWYgKGZsYWdzICYgRklORF9BTlkpIHsKICAgICAgd2hpbGUgKDAgPD0gcG9zICYmIHBvcyA8PSBUaGlzLT5sTGFzdEZyYW1lKSB7CglpZiAoVGhpcy0+aWR4RnJhbWVzW3Bvc10uZHdDaHVua0xlbmd0aCA+IDApCgkgIGdvdG8gUkVUVVJOX0ZPVU5EOwoKCWlmIChmbGFncyAmIEZJTkRfTkVYVCkKCSAgcG9zKys7CgllbHNlCgkgIHBvcy0tOwoKICAgICAgfTsKICAgIH0gZWxzZSBpZiAoKGZsYWdzICYgRklORF9GT1JNQVQpICYmIFRoaXMtPmlkeEZtdENoYW5nZXMgIT0gTlVMTCAmJgoJICAgICAgIFRoaXMtPnNJbmZvLmZjY1R5cGUgPT0gc3RyZWFtdHlwZVZJREVPKSB7CiAgICAgIGlmIChmbGFncyAmIEZJTkRfTkVYVCkgewoJVUxPTkcgbjsKCglmb3IgKG4gPSAwOyBuIDwgVGhpcy0+c0luZm8uZHdGb3JtYXRDaGFuZ2VDb3VudDsgbisrKQoJICBpZiAoVGhpcy0+aWR4Rm10Q2hhbmdlc1tuXS5ja2lkID49IHBvcykgewogICAgICAgICAgICBwb3MgPSBUaGlzLT5pZHhGbXRDaGFuZ2VzW25dLmNraWQ7CgkgICAgZ290byBSRVRVUk5fRk9VTkQ7CiAgICAgICAgICB9CiAgICAgIH0gZWxzZSB7CglMT05HIG47CgoJZm9yIChuID0gKExPTkcpVGhpcy0+c0luZm8uZHdGb3JtYXRDaGFuZ2VDb3VudDsgbiA+PSAwOyBuLS0pIHsKCSAgaWYgKFRoaXMtPmlkeEZtdENoYW5nZXNbbl0uY2tpZCA8PSBwb3MpIHsKICAgICAgICAgICAgcG9zID0gVGhpcy0+aWR4Rm10Q2hhbmdlc1tuXS5ja2lkOwoJICAgIGdvdG8gUkVUVVJOX0ZPVU5EOwogICAgICAgICAgfQoJfQoKCWlmIChwb3MgPiAoTE9ORylUaGlzLT5zSW5mby5kd1N0YXJ0KQoJICByZXR1cm4gMDsgLyogZm9ybWF0IGNoYW5nZXMgYWx3YXlzIGZvciBmaXJzdCBmcmFtZSAqLwogICAgICB9CiAgICB9CgogICAgcmV0dXJuIC0xOwogIH0KCiBSRVRVUk5fRk9VTkQ6CiAgaWYgKHBvcyA8IChMT05HKVRoaXMtPnNJbmZvLmR3U3RhcnQpCiAgICByZXR1cm4gLTE7CgogIHN3aXRjaCAoZmxhZ3MgJiBGSU5EX1JFVCkgewogIGNhc2UgRklORF9MRU5HVEg6CiAgICAvKiBwaHlzaWNhbCBzaXplICovCiAgICBwb3MgPSBUaGlzLT5pZHhGcmFtZXNbcG9zXS5kd0NodW5rTGVuZ3RoOwogICAgYnJlYWs7CiAgY2FzZSBGSU5EX09GRlNFVDoKICAgIC8qIHBoeXNpY2FsIHBvc2l0aW9uICovCiAgICBwb3MgPSBUaGlzLT5pZHhGcmFtZXNbcG9zXS5kd0NodW5rT2Zmc2V0ICsgMiAqIHNpemVvZihEV09SRCkKICAgICAgKyBvZmZzZXQgKiBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemU7CiAgICBicmVhazsKICBjYXNlIEZJTkRfU0laRToKICAgIC8qIGxvZ2ljYWwgc2l6ZSAqLwogICAgaWYgKFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSkKICAgICAgcG9zID0gVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplOwogICAgZWxzZQogICAgICBwb3MgPSAxOwogICAgYnJlYWs7CiAgY2FzZSBGSU5EX0lOREVYOgogICAgRklYTUUoIjogRklORF9JTkRFWCBmbGFnIGlzIG5vdCBzdXBwb3J0ZWQhXG4iKTsKICAgIC8qIFRoaXMgaXMgYW4gaW5kZXggaW4gdGhlIGluZGV4LXRhYmxlIG9uIGRpc2MuICovCiAgICBicmVhazsKICB9OyAvKiBlbHNlIGxvZ2ljYWwgcG9zaXRpb24gKi8KCiAgcmV0dXJuIHBvczsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5SZWFkRm9ybWF0KElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHBvcywKCQkJCQkgICAgICBMUFZPSUQgZm9ybWF0LCBMT05HICpmb3JtYXRzaXplKQp7CiAgSUNPTV9USElTKElBVklTdHJlYW1JbXBsLGlmYWNlKTsKCiAgVFJBQ0UoIiglcCwlbGQsJXAsJXApXG4iLCBpZmFjZSwgcG9zLCBmb3JtYXQsIGZvcm1hdHNpemUpOwoKICBpZiAoZm9ybWF0c2l6ZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogb25seSBpbnRlcmVzdGVkIGluIG5lZWRlZCBidWZmZXJzaXplPyAqLwogIGlmIChmb3JtYXQgPT0gTlVMTCB8fCAqZm9ybWF0c2l6ZSA8PSAwKSB7CiAgICAqZm9ybWF0c2l6ZSA9IFRoaXMtPmNiRm9ybWF0OwoKICAgIHJldHVybiBBVklFUlJfT0s7CiAgfQoKICAvKiBjb3B5IGluaXRpYWwgZm9ybWF0IChvbmx5IGFzIG11Y2ggYXMgd2lsbCBmaXQpICovCiAgbWVtY3B5KGZvcm1hdCwgVGhpcy0+bHBGb3JtYXQsIG1pbigqKERXT1JEKilmb3JtYXRzaXplLCBUaGlzLT5jYkZvcm1hdCkpOwogIGlmICgqKERXT1JEKilmb3JtYXRzaXplIDwgVGhpcy0+Y2JGb3JtYXQpIHsKICAgICpmb3JtYXRzaXplID0gVGhpcy0+Y2JGb3JtYXQ7CiAgICByZXR1cm4gQVZJRVJSX0JVRkZFUlRPT1NNQUxMOwogIH0KCiAgLyogQ291bGQgZm9ybWF0IGNoYW5nZT8gV2hlbiB5ZXMgd2lsbCBpdCBjaGFuZ2U/ICovCiAgaWYgKChUaGlzLT5zSW5mby5kd0ZsYWdzICYgQVZJU1RSRUFNSU5GT19GT1JNQVRDSEFOR0VTKSAmJgogICAgICBwb3MgPiBUaGlzLT5zSW5mby5kd1N0YXJ0KSB7CiAgICBMT05HIGxMYXN0Rm10OwoKICAgIGxMYXN0Rm10ID0gSUFWSVN0cmVhbV9mbkZpbmRTYW1wbGUoaWZhY2UsIHBvcywgRklORF9GT1JNQVR8RklORF9QUkVWKTsKICAgIGlmIChsTGFzdEZtdCA+IDApIHsKICAgICAgRklYTUUoIjogbmVlZCB0byByZWFkIGZvcm1hdGNoYW5nZSBmb3IgJWxkIC0tIHVuaW1wbGVtZW50ZWQhXG4iLGxMYXN0Rm10KTsKICAgIH0KICB9CgogICpmb3JtYXRzaXplID0gVGhpcy0+Y2JGb3JtYXQ7CiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5TZXRGb3JtYXQoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgcG9zLAoJCQkJCSAgICAgTFBWT0lEIGZvcm1hdCwgTE9ORyBmb3JtYXRzaXplKQp7CiAgSUNPTV9USElTKElBVklTdHJlYW1JbXBsLGlmYWNlKTsKCiAgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmlOZXcgPSAoTFBCSVRNQVBJTkZPSEVBREVSKWZvcm1hdDsKCiAgVFJBQ0UoIiglcCwlbGQsJXAsJWxkKVxuIiwgaWZhY2UsIHBvcywgZm9ybWF0LCBmb3JtYXRzaXplKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChmb3JtYXQgPT0gTlVMTCB8fCBmb3JtYXRzaXplIDw9IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBEbyB3ZSBoYXZlIHdyaXRlIHBlcm1pc3Npb24/ICovCiAgaWYgKChUaGlzLT5wYWYtPnVNb2RlICYgTU1JT19SV01PREUpID09IDApCiAgICByZXR1cm4gQVZJRVJSX1JFQURPTkxZOwoKICAvKiBjYW4gb25seSBzZXQgZm9ybWF0IGJlZm9yZSBmcmFtZSBpcyB3cml0dGVuISAqLwogIGlmIChUaGlzLT5sTGFzdEZyYW1lID4gcG9zKQogICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKCiAgLyogaW5pdGlhbCBmb3JtYXQgb3IgYSBmb3JtYXRjaGFuZ2U/ICovCiAgaWYgKFRoaXMtPmxwRm9ybWF0ID09IE5VTEwpIHsKICAgIC8qIGluaXRpYWwgZm9ybWF0ICovCiAgICBpZiAoVGhpcy0+cGFmLT5kd01vdmlDaHVua1BvcyAhPSAwKQogICAgICByZXR1cm4gQVZJRVJSX0VSUk9SOyAvKiB1c2VyIGhhcyB1c2VkIEFQSSBpbiB3cm9uZyBzZXF1bmVjZSEgKi8KCiAgICBUaGlzLT5scEZvcm1hdCA9IEdsb2JhbEFsbG9jUHRyKEdNRU1fTU9WRUFCTEUsIGZvcm1hdHNpemUpOwogICAgaWYgKFRoaXMtPmxwRm9ybWF0ID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogICAgVGhpcy0+Y2JGb3JtYXQgPSBmb3JtYXRzaXplOwoKICAgIG1lbWNweShUaGlzLT5scEZvcm1hdCwgZm9ybWF0LCBmb3JtYXRzaXplKTsKCiAgICAvKiB1cGRhdGUgc29tZSBpbmZvcyBhYm91dCBzdHJlYW0gKi8KICAgIGlmIChUaGlzLT5zSW5mby5mY2NUeXBlID09IHN0cmVhbXR5cGVWSURFTykgewogICAgICBMT05HIGxEaW07CgogICAgICBsRGltID0gVGhpcy0+c0luZm8ucmNGcmFtZS5yaWdodCAtIFRoaXMtPnNJbmZvLnJjRnJhbWUubGVmdDsKICAgICAgaWYgKGxEaW0gPCBscGJpTmV3LT5iaVdpZHRoKQoJVGhpcy0+c0luZm8ucmNGcmFtZS5yaWdodCA9IFRoaXMtPnNJbmZvLnJjRnJhbWUubGVmdCArIGxwYmlOZXctPmJpV2lkdGg7CiAgICAgIGxEaW0gPSBUaGlzLT5zSW5mby5yY0ZyYW1lLmJvdHRvbSAtIFRoaXMtPnNJbmZvLnJjRnJhbWUudG9wOwogICAgICBpZiAobERpbSA8IGxwYmlOZXctPmJpSGVpZ2h0KQoJVGhpcy0+c0luZm8ucmNGcmFtZS5ib3R0b20gPSBUaGlzLT5zSW5mby5yY0ZyYW1lLnRvcCArIGxwYmlOZXctPmJpSGVpZ2h0OwogICAgfSBlbHNlIGlmIChUaGlzLT5zSW5mby5mY2NUeXBlID09IHN0cmVhbXR5cGVBVURJTykKICAgICAgVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplID0gKChMUFdBVkVGT1JNQVRFWClUaGlzLT5scEZvcm1hdCktPm5CbG9ja0FsaWduOwoKICAgIHJldHVybiBBVklFUlJfT0s7CiAgfSBlbHNlIHsKICAgIE1NQ0tJTkZPICAgICAgICAgICBjazsKICAgIExQQklUTUFQSU5GT0hFQURFUiBscGJpT2xkID0gKExQQklUTUFQSU5GT0hFQURFUilUaGlzLT5scEZvcm1hdDsKICAgIFJHQlFVQUQgICAgICAgICAgICpyZ2JOZXcgID0gKFJHQlFVQUQqKSgoTFBCWVRFKWxwYmlOZXcgKyBscGJpTmV3LT5iaVNpemUpOwogICAgQVZJUEFMQ0hBTkdFICAgICAgKmxwcGMgPSBOVUxMOwogICAgSU5UICAgICAgICAgICAgICAgIG47CgogICAgLyogcGhlcmhhcHMgZm9ybWF0Y2hhbmdlLCBjaGVjayBpdCAuLi4gKi8KICAgIGlmIChUaGlzLT5jYkZvcm1hdCAhPSBmb3JtYXRzaXplKQogICAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICAgIC8qIG5vIGZvcm1hdGNoYW5nZSwgb25seSB0aGUgaW5pdGlhbCBvbmUgKi8KICAgIGlmIChtZW1jbXAoVGhpcy0+bHBGb3JtYXQsIGZvcm1hdCwgZm9ybWF0c2l6ZSkgPT0gMCkKICAgICAgcmV0dXJuIEFWSUVSUl9PSzsKCiAgICAvKiBjaGVjayB0aGF0J3Mgb25seSB0aGUgcGFsZXR0ZSwgd2hpY2ggY2hhbmdlcyAqLwogICAgaWYgKGxwYmlPbGQtPmJpU2l6ZSAgICAgICAgIT0gbHBiaU5ldy0+YmlTaXplIHx8CglscGJpT2xkLT5iaVdpZHRoICAgICAgICE9IGxwYmlOZXctPmJpV2lkdGggfHwKCWxwYmlPbGQtPmJpSGVpZ2h0ICAgICAgIT0gbHBiaU5ldy0+YmlIZWlnaHQgfHwKCWxwYmlPbGQtPmJpUGxhbmVzICAgICAgIT0gbHBiaU5ldy0+YmlQbGFuZXMgfHwKCWxwYmlPbGQtPmJpQml0Q291bnQgICAgIT0gbHBiaU5ldy0+YmlCaXRDb3VudCB8fAoJbHBiaU9sZC0+YmlDb21wcmVzc2lvbiAhPSBscGJpTmV3LT5iaUNvbXByZXNzaW9uIHx8CglscGJpT2xkLT5iaUNsclVzZWQgICAgICE9IGxwYmlOZXctPmJpQ2xyVXNlZCkKICAgICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKCiAgICBUaGlzLT5zSW5mby5kd0ZsYWdzIHw9IEFWSVNUUkVBTUlORk9fRk9STUFUQ0hBTkdFUzsKCiAgICAvKiBzaW1wbHkgc2F5IGFsbCBjb2xvcnMgaGF2ZSBjaGFuZ2VkICovCiAgICBjay5ja2lkICAgPSBNQUtFQVZJQ0tJRChja3R5cGVQQUxjaGFuZ2UsIFRoaXMtPm5TdHJlYW0pOwogICAgY2suY2tzaXplID0gMiAqIHNpemVvZihXT1JEKSArIGxwYmlPbGQtPmJpQ2xyVXNlZCAqIHNpemVvZihQQUxFVFRFRU5UUlkpOwogICAgbHBwYyA9IChBVklQQUxDSEFOR0UqKUdsb2JhbEFsbG9jUHRyKEdNRU1fTU9WRUFCTEUsIGNrLmNrc2l6ZSk7CiAgICBpZiAobHBwYyA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgICBscHBjLT5iRmlyc3RFbnRyeSA9IDA7CiAgICBscHBjLT5iTnVtRW50cmllcyA9IChscGJpT2xkLT5iaUNsclVzZWQgPCAyNTYgPyBscGJpT2xkLT5iaUNsclVzZWQgOiAwKTsKICAgIGxwcGMtPndGbGFncyAgICAgID0gMDsKICAgIGZvciAobiA9IDA7IG4gPCBscGJpT2xkLT5iaUNsclVzZWQ7IG4rKykgewogICAgICBscHBjLT5wZU5ld1tuXS5wZVJlZCAgID0gcmdiTmV3W25dLnJnYlJlZDsKICAgICAgbHBwYy0+cGVOZXdbbl0ucGVHcmVlbiA9IHJnYk5ld1tuXS5yZ2JHcmVlbjsKICAgICAgbHBwYy0+cGVOZXdbbl0ucGVCbHVlICA9IHJnYk5ld1tuXS5yZ2JCbHVlOwogICAgICBscHBjLT5wZU5ld1tuXS5wZUZsYWdzID0gMDsKICAgIH0KCiAgICBpZiAobW1pb1NlZWsoVGhpcy0+cGFmLT5obW1pbywgVGhpcy0+cGFmLT5kd05leHRGcmFtZVBvcywgU0VFS19TRVQpID09IC0xKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgIGlmIChtbWlvQ3JlYXRlQ2h1bmsoVGhpcy0+cGFmLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgIGlmIChtbWlvV3JpdGUoVGhpcy0+cGFmLT5obW1pbywgKEhQU1RSKWxwcGMsIGNrLmNrc2l6ZSkgIT0gY2suY2tzaXplKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgIGlmIChtbWlvQXNjZW5kKFRoaXMtPnBhZi0+aG1taW8sICZjaywgMCkgIT0gU19PSykKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICBUaGlzLT5wYWYtPmR3TmV4dEZyYW1lUG9zICs9IGNrLmNrc2l6ZSArIDIgKiBzaXplb2YoRFdPUkQpOwoKICAgIEdsb2JhbEZyZWVQdHIobHBwYyk7CgogICAgcmV0dXJuIEFWSUZJTEVfQWRkRnJhbWUoVGhpcywgY2t0eXBlUEFMY2hhbmdlLCBuLCBjay5kd0RhdGFPZmZzZXQsIDApOwogIH0KfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5SZWFkKElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHN0YXJ0LAoJCQkJCUxPTkcgc2FtcGxlcywgTFBWT0lEIGJ1ZmZlciwKCQkJCQlMT05HIGJ1ZmZlcnNpemUsIExQTE9ORyBieXRlc3JlYWQsCgkJCQkJTFBMT05HIHNhbXBsZXNyZWFkKQp7CiAgSUNPTV9USElTKElBVklTdHJlYW1JbXBsLGlmYWNlKTsKCiAgRFdPUkQgICAgc2l6ZTsKICBIUkVTVUxUICBocjsKCiAgVFJBQ0UoIiglcCwlbGQsJWxkLCVwLCVsZCwlcCwlcClcbiIsIGlmYWNlLCBzdGFydCwgc2FtcGxlcywgYnVmZmVyLAogCWJ1ZmZlcnNpemUsIGJ5dGVzcmVhZCwgc2FtcGxlc3JlYWQpOwoKICAvKiBjbGVhciByZXR1cm4gcGFyYW1ldGVycyBpZiBnaXZlbiAqLwogIGlmIChieXRlc3JlYWQgIT0gTlVMTCkKICAgICpieXRlc3JlYWQgPSAwOwogIGlmIChzYW1wbGVzcmVhZCAhPSBOVUxMKQogICAgKnNhbXBsZXNyZWFkID0gMDsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmICgoTE9ORylUaGlzLT5zSW5mby5kd1N0YXJ0ID4gc3RhcnQpCiAgICByZXR1cm4gQVZJRVJSX05PREFUQTsgLyogY291bGRuJ3QgcmVhZCBiZWZvcmUgc3RhcnQgb2Ygc3RyZWFtICovCiAgaWYgKFRoaXMtPnNJbmZvLmR3U3RhcnQgKyBUaGlzLT5zSW5mby5kd0xlbmd0aCA8IChEV09SRClzdGFydCkKICAgIHJldHVybiBBVklFUlJfTk9EQVRBOyAvKiBzdGFydCBpcyBwYXN0IGVuZCBvZiBzdHJlYW0gKi8KCiAgLyogc2hvdWxkIHdlIHJlYWQgYXMgbXVjaCBhcyBwb3NzaWJsZT8gKi8KICBpZiAoc2FtcGxlcyA9PSAtMSkgewogICAgLyogVXNlciBzaG91bGQga25vdyBob3cgbXVjaCB3ZSBoYXZlIHJlYWQgKi8KICAgIGlmIChieXRlc3JlYWQgPT0gTlVMTCAmJiBzYW1wbGVzcmVhZCA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAgIGlmIChUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUgIT0gMCkKICAgICAgc2FtcGxlcyA9IGJ1ZmZlcnNpemUgLyBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemU7CiAgICBlbHNlCiAgICAgIHNhbXBsZXMgPSAxOwogIH0KCiAgLyogbGltaXQgdG8gZW5kIG9mIHN0cmVhbSAqLwogIGlmICgoTE9ORylUaGlzLT5zSW5mby5kd0xlbmd0aCA8IHNhbXBsZXMpCiAgICBzYW1wbGVzID0gVGhpcy0+c0luZm8uZHdMZW5ndGg7CiAgaWYgKChzdGFydCAtIFRoaXMtPnNJbmZvLmR3U3RhcnQpID4gKFRoaXMtPnNJbmZvLmR3TGVuZ3RoIC0gc2FtcGxlcykpCiAgICBzYW1wbGVzID0gVGhpcy0+c0luZm8uZHdMZW5ndGggLSAoc3RhcnQgLSBUaGlzLT5zSW5mby5kd1N0YXJ0KTsKCiAgLyogbm90aGluZyB0byByZWFkPyBUaGVuIGxlYXZlIC4uLiAqLwogIGlmIChzYW1wbGVzID09IDApCiAgICByZXR1cm4gQVZJRVJSX09LOwoKICBpZiAoVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplICE9IDApIHsKICAgIC8qIGZpeGVkIHNhbXBsZXNpemUgLS0gd2UgY2FuIHJlYWQgb3ZlciBmcmFtZS9ibG9jayBib3VuZGFyaWVzICovCiAgICBMT05HIGJsb2NrICA9IHN0YXJ0OwogICAgTE9ORyBvZmZzZXQgPSAwOwoKICAgIC8qIGNvbnZlcnQgc3RhcnQgc2FtcGxlIHRvIGJsb2NrLG9mZnNldCBwYWlyICovCiAgICBBVklGSUxFX1NhbXBsZXNUb0Jsb2NrKFRoaXMsICZibG9jaywgJm9mZnNldCk7CgogICAgLyogY29udmVydCBzYW1wbGVzIHRvIGJ5dGVzICovCiAgICBzYW1wbGVzICo9IFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZTsKCiAgICB3aGlsZSAoc2FtcGxlcyA+IDAgJiYgYnVmZmVyc2l6ZSA+IDApIHsKICAgICAgaWYgKGJsb2NrICE9IFRoaXMtPmR3Q3VycmVudEZyYW1lKSB7CglociA9IEFWSUZJTEVfUmVhZEJsb2NrKFRoaXMsIGJsb2NrLCBOVUxMLCAwKTsKCWlmIChGQUlMRUQoaHIpKQoJICByZXR1cm4gaHI7CiAgICAgIH0KCiAgICAgIHNpemUgPSBtaW4oKERXT1JEKXNhbXBsZXMsIChEV09SRClidWZmZXJzaXplKTsKICAgICAgc2l6ZSA9IG1pbihzaXplLCBUaGlzLT5jYkJ1ZmZlciAtIG9mZnNldCk7CiAgICAgIG1lbWNweShidWZmZXIsICgoQllURSopJlRoaXMtPmxwQnVmZmVyWzJdKSArIG9mZnNldCwgc2l6ZSk7CgogICAgICBibG9jaysrOwogICAgICBvZmZzZXQgPSAwOwogICAgICBidWZmZXIgPSAoKExQQllURSlidWZmZXIpK3NpemU7CiAgICAgIHNhbXBsZXMgICAgLT0gc2l6ZTsKICAgICAgYnVmZmVyc2l6ZSAtPSBzaXplOwoKICAgICAgLyogZmlsbCBvdXQgcmV0dXJuIHBhcmFtZXRlcnMgaWYgZ2l2ZW4gKi8KICAgICAgaWYgKGJ5dGVzcmVhZCAhPSBOVUxMKQoJKmJ5dGVzcmVhZCAgICs9IHNpemU7CiAgICAgIGlmIChzYW1wbGVzcmVhZCAhPSBOVUxMKQoJKnNhbXBsZXNyZWFkICs9IHNpemUgLyBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemU7CiAgICB9CgogICAgaWYgKHNhbXBsZXMgPT0gMCkKICAgICAgcmV0dXJuIEFWSUVSUl9PSzsKICAgIGVsc2UKICAgICAgcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKICB9IGVsc2UgewogICAgLyogdmFyaWFibGUgc2FtcGxlc2l6ZSAtLSB3ZSBjYW4gb25seSByZWFkIG9uZSBmdWxsIGZyYW1lL2Jsb2NrICovCiAgICBpZiAoc2FtcGxlcyA+IDEpCiAgICAgIHNhbXBsZXMgPSAxOwoKICAgIGFzc2VydChzdGFydCA8PSBUaGlzLT5sTGFzdEZyYW1lKTsKICAgIHNpemUgPSBUaGlzLT5pZHhGcmFtZXNbc3RhcnRdLmR3Q2h1bmtMZW5ndGg7CiAgICBpZiAoYnVmZmVyICE9IE5VTEwgJiYgYnVmZmVyc2l6ZSA+PSBzaXplKSB7CiAgICAgIGhyID0gQVZJRklMRV9SZWFkQmxvY2soVGhpcywgc3RhcnQsIGJ1ZmZlciwgc2l6ZSk7CiAgICAgIGlmIChGQUlMRUQoaHIpKQoJcmV0dXJuIGhyOwogICAgfSBlbHNlIGlmIChidWZmZXIgIT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKCiAgICAvKiBmaWxsIG91dCByZXR1cm4gcGFyYW1ldGVycyBpZiBnaXZlbiAqLwogICAgaWYgKGJ5dGVzcmVhZCAhPSBOVUxMKQogICAgICAqYnl0ZXNyZWFkID0gc2l6ZTsKICAgIGlmIChzYW1wbGVzcmVhZCAhPSBOVUxMKQogICAgICAqc2FtcGxlc3JlYWQgPSBzYW1wbGVzOwoKICAgIHJldHVybiBBVklFUlJfT0s7CiAgfQp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbldyaXRlKElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHN0YXJ0LAoJCQkJCSBMT05HIHNhbXBsZXMsIExQVk9JRCBidWZmZXIsCgkJCQkJIExPTkcgYnVmZmVyc2l6ZSwgRFdPUkQgZmxhZ3MsCgkJCQkJIExQTE9ORyBzYW1wd3JpdHRlbiwKCQkJCQkgTFBMT05HIGJ5dGVzd3JpdHRlbikKewogIElDT01fVEhJUyhJQVZJU3RyZWFtSW1wbCxpZmFjZSk7CgogIEZPVVJDQyAgY2tpZDsKICBIUkVTVUxUIGhyOwoKICBUUkFDRSgiKCVwLCVsZCwlbGQsJXAsJWxkLDB4JTA4bFgsJXAsJXApXG4iLCBpZmFjZSwgc3RhcnQsIHNhbXBsZXMsCglidWZmZXIsIGJ1ZmZlcnNpemUsIGZsYWdzLCBzYW1wd3JpdHRlbiwgYnl0ZXN3cml0dGVuKTsKCiAgLyogY2xlYXIgcmV0dXJuIHBhcmFtZXRlcnMgaWYgZ2l2ZW4gKi8KICBpZiAoc2FtcHdyaXR0ZW4gIT0gTlVMTCkKICAgICpzYW1wd3JpdHRlbiA9IDA7CiAgaWYgKGJ5dGVzd3JpdHRlbiAhPSBOVUxMKQogICAgKmJ5dGVzd3JpdHRlbiA9IDA7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoYnVmZmVyID09IE5VTEwgJiYgKGJ1ZmZlcnNpemUgPiAwIHx8IHNhbXBsZXMgPiAwKSkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIC8qIEhhdmUgd2Ugd3JpdGUgcGVybWlzc2lvbj8gKi8KICBpZiAoKFRoaXMtPnBhZi0+dU1vZGUgJiBNTUlPX1JXTU9ERSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIHN3aXRjaCAoVGhpcy0+c0luZm8uZmNjVHlwZSkgewogIGNhc2Ugc3RyZWFtdHlwZUFVRElPOgogICAgY2tpZCA9IE1BS0VBVklDS0lEKGNrdHlwZVdBVkVieXRlcywgVGhpcy0+blN0cmVhbSk7CiAgICBicmVhazsKICBkZWZhdWx0OgogICAgaWYgKChmbGFncyAmIEFWSUlGX0tFWUZSQU1FKSAmJiBidWZmZXJzaXplICE9IDApCiAgICAgIGNraWQgPSBNQUtFQVZJQ0tJRChja3R5cGVESUJiaXRzLCBUaGlzLT5uU3RyZWFtKTsKICAgIGVsc2UKICAgICAgY2tpZCA9IE1BS0VBVklDS0lEKGNrdHlwZURJQmNvbXByZXNzZWQsIFRoaXMtPm5TdHJlYW0pOwogICAgYnJlYWs7CiAgfTsKCiAgLyogYXBwZW5kIHRvIGVuZCBvZiBzdHJlYW0/ICovCiAgaWYgKHN0YXJ0ID09IC0xKSB7CiAgICBpZiAoVGhpcy0+bExhc3RGcmFtZSA9PSAtMSkKICAgICAgc3RhcnQgPSBUaGlzLT5zSW5mby5kd1N0YXJ0OwogICAgZWxzZQogICAgICBzdGFydCA9IFRoaXMtPnNJbmZvLmR3TGVuZ3RoOwogIH0gZWxzZSBpZiAoVGhpcy0+bExhc3RGcmFtZSA9PSAtMSkKICAgIFRoaXMtPnNJbmZvLmR3U3RhcnQgPSBzdGFydDsKCiAgaWYgKFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSAhPSAwKSB7CiAgICAvKiBmaXhlZCBzYW1wbGUgc2l6ZSAtLSBhdWRpbyBsaWtlICovCiAgICBpZiAoc2FtcGxlcyAqIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSAhPSBidWZmZXJzaXplKQogICAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAgIC8qIENvdWxkbid0IHNraXAgYXVkaW8tbGlrZSBkYXRhIC0tIFVzZXIgbXVzdCBzdXBwbHkgYXBwcm9wcmlhdGUgc2lsZW5jZSAqLwogICAgaWYgKFRoaXMtPnNJbmZvLmR3TGVuZ3RoICE9IHN0YXJ0KQogICAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICAgIC8qIENvbnZlcnQgcG9zaXRpb24gdG8gZnJhbWUvYmxvY2sgKi8KICAgIHN0YXJ0ID0gVGhpcy0+bExhc3RGcmFtZSArIDE7CgogICAgaWYgKChUaGlzLT5wYWYtPmZJbmZvLmR3RmxhZ3MgJiBBVklGSUxFSU5GT19JU0lOVEVSTEVBVkVEKSA9PSAwKSB7CiAgICAgIEZJWE1FKCI6IG5vdCBpbnRlcmxlYXZlZCwgY291bGQgY29sbGVjdCBhdWRpbyBkYXRhIVxuIik7CiAgICB9CiAgfSBlbHNlIHsKICAgIC8qIHZhcmlhYmxlIHNhbXBsZSBzaXplIC0tIHZpZGVvIGxpa2UgKi8KICAgIGlmIChzYW1wbGVzID4gMSkKICAgICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKCiAgICAvKiBtdXN0IHdlIGZpbGwgdXAgd2l0aCBlbXB0eSBmcmFtZXM/ICovCiAgICBpZiAoVGhpcy0+bExhc3RGcmFtZSAhPSAtMSkgewogICAgICBGT1VSQ0MgY2tpZDIgPSBNQUtFQVZJQ0tJRChja3R5cGVESUJjb21wcmVzc2VkLCBUaGlzLT5uU3RyZWFtKTsKCiAgICAgIHdoaWxlIChzdGFydCA+IFRoaXMtPmxMYXN0RnJhbWUgKyAxKSB7CglociA9IEFWSUZJTEVfV3JpdGVCbG9jayhUaGlzLCBUaGlzLT5sTGFzdEZyYW1lICsgMSwgY2tpZDIsIDAsIE5VTEwsIDApOwoJaWYgKEZBSUxFRChocikpCgkgIHJldHVybiBocjsKICAgICAgfQogICAgfQogIH0KCiAgLyogd3JpdGUgdGhlIGJsb2NrIG5vdyAqLwogIGhyID0gQVZJRklMRV9Xcml0ZUJsb2NrKFRoaXMsIHN0YXJ0LCBja2lkLCBmbGFncywgYnVmZmVyLCBidWZmZXJzaXplKTsKICBpZiAoU1VDQ0VFREVEKGhyKSkgewogICAgLyogZmlsbCBvdXQgcmV0dXJuIHBhcmFtZXRlcnMgaWYgZ2l2ZW4gKi8KICAgIGlmIChzYW1wd3JpdHRlbiAhPSBOVUxMKQogICAgICAqc2FtcHdyaXR0ZW4gPSBzYW1wbGVzOwogICAgaWYgKGJ5dGVzd3JpdHRlbiAhPSBOVUxMKQogICAgICAqYnl0ZXN3cml0dGVuID0gYnVmZmVyc2l6ZTsKICB9CgogIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5EZWxldGUoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgc3RhcnQsCgkJCQkJICBMT05HIHNhbXBsZXMpCnsKICBJQ09NX1RISVMoSUFWSVN0cmVhbUltcGwsaWZhY2UpOwoKICBGSVhNRSgiKCVwLCVsZCwlbGQpOiBzdHViXG4iLCBpZmFjZSwgc3RhcnQsIHNhbXBsZXMpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKHN0YXJ0IDwgMCB8fCBzYW1wbGVzIDwgMCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIC8qIERlbGV0ZSBiZWZvcmUgc3RhcnQgb2Ygc3RyZWFtPyAqLwogIGlmIChzdGFydCArIHNhbXBsZXMgPCBUaGlzLT5zSW5mby5kd1N0YXJ0KQogICAgcmV0dXJuIEFWSUVSUl9PSzsKCiAgLyogRGVsZXRlIGFmdGVyIGVuZCBvZiBzdHJlYW0/ICovCiAgaWYgKHN0YXJ0ID4gVGhpcy0+c0luZm8uZHdMZW5ndGgpCiAgICByZXR1cm4gQVZJRVJSX09LOwoKICAvKiBGb3IgdGhlIHJlc3Qgd2UgbmVlZCB3cml0ZSBwZXJtaXNzaW9ucyAqLwogIGlmICgoVGhpcy0+cGFmLT51TW9kZSAmIE1NSU9fUldNT0RFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgLyogMS4gb3ZlcndyaXRlIHRoZSBkYXRhIHdpdGggSlVOSwogICAqCiAgICogaWYgSVNJTlRFUkxFQVZFRCB7CiAgICogICAyLiBjb25jYXQgYWxsIG5laWdoYm91cmVkIEpVTkstYmxvY2tzIGluIHRoaXMgcmVjb3JkIHRvIG9uZQogICAqICAgMy4gaWYgdGhpcyByZWNvcmQgb25seSBjb250YWlucyBKVU5LIGFuZCBpcyBhdCBlbmQgc2V0IGR3TmV4dEZyYW1lUG9zCiAgICogICAgICB0byBzdGFydCBvZiB0aGlzIHJlY29yZCwgcmVwZWF0IHRoaXMuCiAgICogfSBlbHNlIHsKICAgKiAgIDIuIGNvbmNhdCBhbGwgbmVpZ2hib3VyZWQgSlVOSy1ibG9ja3MuCiAgICogICAzLiBpZiB0aGUgSlVOSyBibG9jayBpcyBhdCB0aGUgZW5kLCB0aGVuIHNldCBkd05leHRGcmFtZVBvcyB0bwogICAqICAgICAgc3RhcnQgb2YgdGhpcyBibG9jay4KICAgKiB9CiAgICovCgogIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUmVhZERhdGEoSUFWSVN0cmVhbSAqaWZhY2UsIERXT1JEIGZjYywKCQkJCQkgICAgTFBWT0lEIGxwLCBMUExPTkcgbHByZWFkKQp7CiAgSUNPTV9USElTKElBVklTdHJlYW1JbXBsLGlmYWNlKTsKCiAgVFJBQ0UoIiglcCwweCUwOGxYLCVwLCVwKVxuIiwgaWZhY2UsIGZjYywgbHAsIGxwcmVhZCk7CgogIGlmIChmY2MgPT0gY2tpZFNUUkVBTUhBTkRMRVJEQVRBKSB7CiAgICBpZiAoVGhpcy0+bHBIYW5kbGVyRGF0YSAhPSBOVUxMICYmIFRoaXMtPmNiSGFuZGxlckRhdGEgPiAwKSB7CiAgICAgIGlmIChscCA9PSBOVUxMIHx8ICpscHJlYWQgPD0gMCkgewoJKmxwcmVhZCA9IFRoaXMtPmNiSGFuZGxlckRhdGE7CglyZXR1cm4gQVZJRVJSX09LOwogICAgICB9CgogICAgICBtZW1jcHkobHAsIFRoaXMtPmxwSGFuZGxlckRhdGEsIG1pbihUaGlzLT5jYkhhbmRsZXJEYXRhLCAqbHByZWFkKSk7CiAgICAgIGlmICgqbHByZWFkIDwgVGhpcy0+Y2JIYW5kbGVyRGF0YSkKCXJldHVybiBBVklFUlJfQlVGRkVSVE9PU01BTEw7CiAgICAgIHJldHVybiBBVklFUlJfT0s7CiAgICB9IGVsc2UKICAgICAgcmV0dXJuIEFWSUVSUl9OT0RBVEE7CiAgfSBlbHNlCiAgICByZXR1cm4gUmVhZEV4dHJhQ2h1bmsoJlRoaXMtPmV4dHJhLCBmY2MsIGxwLCBscHJlYWQpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbldyaXRlRGF0YShJQVZJU3RyZWFtICppZmFjZSwgRFdPUkQgZmNjLAoJCQkJCSAgICAgTFBWT0lEIGxwLCBMT05HIHNpemUpCnsKICBJQ09NX1RISVMoSUFWSVN0cmVhbUltcGwsaWZhY2UpOwoKICBUUkFDRSgiKCVwLDB4JTA4bHgsJXAsJWxkKVxuIiwgaWZhY2UsIGZjYywgbHAsIHNpemUpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKGxwID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIGlmIChzaXplIDw9IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CgogIC8qIG5lZWQgd3JpdGUgcGVybWlzc2lvbiAqLwogIGlmICgoVGhpcy0+cGFmLT51TW9kZSAmIE1NSU9fUldNT0RFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgLyogYWxyZWFkeSB3cml0dGVuIHNvbWV0aGluZyB0byB0aGlzIGZpbGU/ICovCiAgaWYgKFRoaXMtPnBhZi0+ZHdNb3ZpQ2h1bmtQb3MgIT0gMCkgewogICAgLyogdGhlIGRhdGEgd2lsbCBiZSBpbnNlcnRlZCBiZWZvcmUgdGhlICdtb3ZpJyBjaHVuaywgc28gY2hlY2sgZm9yCiAgICAgKiBlbm91Z2ggc3BhY2UgKi8KICAgIERXT1JEIGR3UG9zID0gQVZJRklMRV9Db21wdXRlTW92aVN0YXJ0KFRoaXMtPnBhZik7CgogICAgLyogY2tpZCxzaXplID0+IDIgKiBzaXplb2YoRFdPUkQpICovCiAgICBkd1BvcyArPSAyICogc2l6ZW9mKERXT1JEKSArIHNpemU7CiAgICBpZiAoc2l6ZSA+PSBUaGlzLT5wYWYtPmR3TW92aUNodW5rUG9zIC0gMiAqIHNpemVvZihEV09SRCkpCiAgICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7IC8qIG5vdCBlbm91Z2ggc3BhY2UgbGVmdCAqLwogIH0KCiAgVGhpcy0+cGFmLT5mRGlydHkgPSBUUlVFOwoKICBpZiAoZmNjID09IGNraWRTVFJFQU1IQU5ETEVSREFUQSkgewogICAgaWYgKFRoaXMtPmxwSGFuZGxlckRhdGEgIT0gTlVMTCkgewogICAgICBGSVhNRSgiOiBoYW5kbGVyIGRhdGEgYWxyZWFkeSBzZXQgLS0gb3ZlcndpcnRlP1xuIik7CiAgICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CiAgICB9CgogICAgVGhpcy0+bHBIYW5kbGVyRGF0YSA9IEdsb2JhbEFsbG9jUHRyKEdNRU1fTU9WRUFCTEUsIHNpemUpOwogICAgaWYgKFRoaXMtPmxwSGFuZGxlckRhdGEgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgICBUaGlzLT5jYkhhbmRsZXJEYXRhID0gc2l6ZTsKICAgIG1lbWNweShUaGlzLT5scEhhbmRsZXJEYXRhLCBscCwgc2l6ZSk7CgogICAgcmV0dXJuIEFWSUVSUl9PSzsKICB9IGVsc2UKICAgIHJldHVybiBXcml0ZUV4dHJhQ2h1bmsoJlRoaXMtPmV4dHJhLCBmY2MsIGxwLCBzaXplKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5TZXRJbmZvKElBVklTdHJlYW0gKmlmYWNlLAoJCQkJCSAgIExQQVZJU1RSRUFNSU5GT1cgaW5mbywgTE9ORyBpbmZvbGVuKQp7CiAgRklYTUUoIiglcCwlcCwlbGQpOiBzdHViXG4iLCBpZmFjZSwgaW5mbywgaW5mb2xlbik7CgogIHJldHVybiBFX0ZBSUw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfQWRkRnJhbWUoSUFWSVN0cmVhbUltcGwgKlRoaXMsIERXT1JEIGNraWQsIERXT1JEIHNpemUsIERXT1JEIG9mZnNldCwgRFdPUkQgZmxhZ3MpCnsKICAvKiBwcmUtY29uZGl0aW9ucyAqLwogIGFzc2VydChUaGlzICE9IE5VTEwpOwoKICBzd2l0Y2ggKFRXT0NDRnJvbUZPVVJDQyhja2lkKSkgewogIGNhc2UgY2t0eXBlRElCYml0czoKICAgIGlmIChUaGlzLT5wYWYtPmZJbmZvLmR3RmxhZ3MgJiBBVklGSUxFSU5GT19UUlVTVENLVFlQRSkKICAgICAgZmxhZ3MgfD0gQVZJSUZfS0VZRlJBTUU7CiAgICBicmVhazsKICBjYXNlIGNrdHlwZURJQmNvbXByZXNzZWQ6CiAgICBpZiAoVGhpcy0+cGFmLT5mSW5mby5kd0ZsYWdzICYgQVZJRklMRUlORk9fVFJVU1RDS1RZUEUpCiAgICAgIGZsYWdzICY9IH5BVklJRl9LRVlGUkFNRTsKICAgIGJyZWFrOwogIGNhc2UgY2t0eXBlUEFMY2hhbmdlOgogICAgaWYgKFRoaXMtPnNJbmZvLmZjY1R5cGUgIT0gc3RyZWFtdHlwZVZJREVPKSB7CiAgICAgIEVSUigiOiBmb3VuZCBwYWxldHRlIGNoYW5nZSBpbiBub24tdmlkZW8gc3RyZWFtIVxuIik7CiAgICAgIHJldHVybiBBVklFUlJfQkFERk9STUFUOwogICAgfQogICAgVGhpcy0+c0luZm8uZHdGbGFncyB8PSBBVklTVFJFQU1JTkZPX0ZPUk1BVENIQU5HRVM7CiAgICBUaGlzLT5zSW5mby5kd0Zvcm1hdENoYW5nZUNvdW50Kys7CgogICAgaWYgKFRoaXMtPmlkeEZtdENoYW5nZXMgPT0gTlVMTCB8fCBUaGlzLT5zSW5mby5kd0Zvcm1hdENoYW5nZUNvdW50IDwgVGhpcy0+bklkeEZtdENoYW5nZXMpIHsKICAgICAgVUlOVCBuID0gVGhpcy0+c0luZm8uZHdGb3JtYXRDaGFuZ2VDb3VudDsKCiAgICAgIFRoaXMtPm5JZHhGbXRDaGFuZ2VzICs9IDE2OwogICAgICBpZiAoVGhpcy0+aWR4Rm10Q2hhbmdlcyA9PSBOVUxMKQoJVGhpcy0+aWR4Rm10Q2hhbmdlcyA9CgkgIEdsb2JhbEFsbG9jUHRyKEdITkQsIFRoaXMtPm5JZHhGbXRDaGFuZ2VzICogc2l6ZW9mKEFWSUlOREVYRU5UUlkpKTsKICAgICAgZWxzZQoJVGhpcy0+aWR4Rm10Q2hhbmdlcyA9CgkgIEdsb2JhbFJlQWxsb2NQdHIoVGhpcy0+aWR4Rm10Q2hhbmdlcywKCQkJICAgVGhpcy0+bklkeEZtdENoYW5nZXMgKiBzaXplb2YoQVZJSU5ERVhFTlRSWSksIEdITkQpOwogICAgICBpZiAoVGhpcy0+aWR4Rm10Q2hhbmdlcyA9PSBOVUxMKQoJcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogICAgICBUaGlzLT5pZHhGbXRDaGFuZ2VzW25dLmNraWQgICAgICAgICAgPSBUaGlzLT5sTGFzdEZyYW1lOwogICAgICBUaGlzLT5pZHhGbXRDaGFuZ2VzW25dLmR3RmxhZ3MgICAgICAgPSAwOwogICAgICBUaGlzLT5pZHhGbXRDaGFuZ2VzW25dLmR3Q2h1bmtPZmZzZXQgPSBvZmZzZXQ7CiAgICAgIFRoaXMtPmlkeEZtdENoYW5nZXNbbl0uZHdDaHVua0xlbmd0aCA9IHNpemU7CgogICAgICByZXR1cm4gQVZJRVJSX09LOwogICAgfQogICAgYnJlYWs7CiAgY2FzZSBja3R5cGVXQVZFYnl0ZXM6CiAgICBpZiAoVGhpcy0+cGFmLT5mSW5mby5kd0ZsYWdzICYgQVZJRklMRUlORk9fVFJVU1RDS1RZUEUpCiAgICAgIGZsYWdzIHw9IEFWSUlGX0tFWUZSQU1FOwogICAgYnJlYWs7CiAgZGVmYXVsdDoKICAgIFdBUk4oIjogdW5rbm93biBUV09DQyAweCUwNFggZm91bmRcbiIsIFRXT0NDRnJvbUZPVVJDQyhja2lkKSk7CiAgICBicmVhazsKICB9OwoKICAvKiBmaXJzdCBmcmFtZSBpcyBhbHdhc3kgYSBrZXlmcmFtZSAqLwogIGlmIChUaGlzLT5sTGFzdEZyYW1lID09IC0xKQogICAgZmxhZ3MgfD0gQVZJSUZfS0VZRlJBTUU7CgogIGlmIChUaGlzLT5zSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPCBzaXplKQogICAgVGhpcy0+c0luZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplID0gc2l6ZTsKCiAgLyogZ2V0IG1lbW9yeSBmb3IgaW5kZXggKi8KICBpZiAoVGhpcy0+aWR4RnJhbWVzID09IE5VTEwgfHwgVGhpcy0+bExhc3RGcmFtZSArIDEgPj0gVGhpcy0+bklkeEZyYW1lcykgewogICAgVGhpcy0+bklkeEZyYW1lcyArPSA1MTI7CiAgICBpZiAoVGhpcy0+aWR4RnJhbWVzID09IE5VTEwpCiAgICAgIFRoaXMtPmlkeEZyYW1lcyA9CglHbG9iYWxBbGxvY1B0cihHSE5ELCBUaGlzLT5uSWR4RnJhbWVzICogc2l6ZW9mKEFWSUlOREVYRU5UUlkpKTsKICAgICAgZWxzZQoJVGhpcy0+aWR4RnJhbWVzID0KCSAgR2xvYmFsUmVBbGxvY1B0cihUaGlzLT5pZHhGcmFtZXMsCgkJCSAgIFRoaXMtPm5JZHhGcmFtZXMgKiBzaXplb2YoQVZJSU5ERVhFTlRSWSksIEdITkQpOwogICAgaWYgKFRoaXMtPmlkeEZyYW1lcyA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKICB9CgogIFRoaXMtPmxMYXN0RnJhbWUrKzsKICBUaGlzLT5pZHhGcmFtZXNbVGhpcy0+bExhc3RGcmFtZV0uY2tpZCAgICAgICAgICA9IGNraWQ7CiAgVGhpcy0+aWR4RnJhbWVzW1RoaXMtPmxMYXN0RnJhbWVdLmR3RmxhZ3MgICAgICAgPSBmbGFnczsKICBUaGlzLT5pZHhGcmFtZXNbVGhpcy0+bExhc3RGcmFtZV0uZHdDaHVua09mZnNldCA9IG9mZnNldDsKICBUaGlzLT5pZHhGcmFtZXNbVGhpcy0+bExhc3RGcmFtZV0uZHdDaHVua0xlbmd0aCA9IHNpemU7CgogIC8qIHVwZGF0ZSBBVklTVFJFQU1JTkZPIHN0cnVjdHVyZSBpZiBuZWNlc3NhcnkgKi8KICBpZiAoVGhpcy0+c0luZm8uZHdMZW5ndGggPD0gVGhpcy0+bExhc3RGcmFtZSkKICAgIFRoaXMtPnNJbmZvLmR3TGVuZ3RoID0gVGhpcy0+bExhc3RGcmFtZSArIDE7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfQWRkUmVjb3JkKElBVklGaWxlSW1wbCAqVGhpcykKewogIC8qIHByZS1jb25kaXRpb25zICovCiAgYXNzZXJ0KFRoaXMgIT0gTlVMTCAmJiBUaGlzLT5wcFN0cmVhbXNbMF0gIT0gTlVMTCk7CgogIGlmIChUaGlzLT5pZHhSZWNvcmRzID09IE5VTEwgfHwgVGhpcy0+Y2JJZHhSZWNvcmRzID09IDApIHsKICAgIFRoaXMtPmNiSWR4UmVjb3JkcyArPSAxMDI0ICogc2l6ZW9mKEFWSUlOREVYRU5UUlkpOwogICAgVGhpcy0+aWR4UmVjb3JkcyA9IEdsb2JhbEFsbG9jUHRyKEdITkQsIFRoaXMtPmNiSWR4UmVjb3Jkcyk7CiAgICBpZiAoVGhpcy0+aWR4UmVjb3JkcyA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKICB9CgogIGFzc2VydChUaGlzLT5uSWR4UmVjb3JkcyA8IFRoaXMtPmNiSWR4UmVjb3Jkcy9zaXplb2YoQVZJSU5ERVhFTlRSWSkpOwoKICBUaGlzLT5pZHhSZWNvcmRzW1RoaXMtPm5JZHhSZWNvcmRzXS5ja2lkICAgICAgICAgID0gbGlzdHR5cGVBVklSRUNPUkQ7CiAgVGhpcy0+aWR4UmVjb3Jkc1tUaGlzLT5uSWR4UmVjb3Jkc10uZHdGbGFncyAgICAgICA9IEFWSUlGX0xJU1Q7CiAgVGhpcy0+aWR4UmVjb3Jkc1tUaGlzLT5uSWR4UmVjb3Jkc10uZHdDaHVua09mZnNldCA9CiAgICBUaGlzLT5ja0xhc3RSZWNvcmQuZHdEYXRhT2Zmc2V0IC0gMiAqIHNpemVvZihEV09SRCk7CiAgVGhpcy0+aWR4UmVjb3Jkc1tUaGlzLT5uSWR4UmVjb3Jkc10uZHdDaHVua0xlbmd0aCA9CiAgICBUaGlzLT5ja0xhc3RSZWNvcmQuY2tzaXplOwogIFRoaXMtPm5JZHhSZWNvcmRzKys7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBEV09SRCAgIEFWSUZJTEVfQ29tcHV0ZU1vdmlTdGFydChJQVZJRmlsZUltcGwgKlRoaXMpCnsKICBEV09SRCBkd1BvczsKICBEV09SRCBuU3RyZWFtOwoKICAvKiBSSUZGLGhkcmwsbW92aSxhdmloID0+ICgzICogMyArIDIpICogc2l6ZW9mKERXT1JEKSA9IDExICogc2l6ZW9mKERXT1JEKSAqLwogIGR3UG9zID0gMTEgKiBzaXplb2YoRFdPUkQpICsgc2l6ZW9mKE1haW5BVklIZWFkZXIpOwoKICBmb3IgKG5TdHJlYW0gPSAwOyBuU3RyZWFtIDwgVGhpcy0+ZkluZm8uZHdTdHJlYW1zOyBuU3RyZWFtKyspIHsKICAgIElBVklTdHJlYW1JbXBsICpwU3RyZWFtID0gVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dOwoKICAgIC8qIHN0cmwsc3RyaCxzdHJmID0+ICgzICsgMiAqIDIpICogc2l6ZW9mKERXT1JEKSA9IDcgKiBzaXplb2YoRFdPUkQpICovCiAgICBkd1BvcyArPSA3ICogc2l6ZW9mKERXT1JEKSArIHNpemVvZihBVklTdHJlYW1IZWFkZXIpOwogICAgZHdQb3MgKz0gKChwU3RyZWFtLT5jYkZvcm1hdCArIDEpICYgfjFVKTsKICAgIGlmIChwU3RyZWFtLT5scEhhbmRsZXJEYXRhICE9IE5VTEwgJiYgcFN0cmVhbS0+Y2JIYW5kbGVyRGF0YSA+IDApCiAgICAgIGR3UG9zICs9IDIgKiBzaXplb2YoRFdPUkQpICsgKChwU3RyZWFtLT5jYkhhbmRsZXJEYXRhICsgMSkgJiB+MVUpOwogICAgaWYgKGxzdHJsZW5XKHBTdHJlYW0tPnNJbmZvLnN6TmFtZSkgPiAwKQogICAgICBkd1BvcyArPSAyICogc2l6ZW9mKERXT1JEKSArICgobHN0cmxlblcocFN0cmVhbS0+c0luZm8uc3pOYW1lKSArIDEpICYgfjFVKTsKICB9CgogIGlmIChUaGlzLT5kd01vdmlDaHVua1BvcyA9PSAwKSB7CiAgICBUaGlzLT5kd05leHRGcmFtZVBvcyA9IGR3UG9zOwoKICAgIC8qIHBhZCB0byBtdWx0aXBsZSBvZiBBVklfSEVBREVSU0laRSBvbmx5IGlmIHdlIGFyZSBtb3JlIHRoYW4gOCBieXRlcyBhd2F5IGZyb20gaXQgKi8KICAgIGlmICgoKGR3UG9zICsgQVZJX0hFQURFUlNJWkUpICYgfihBVklfSEVBREVSU0laRSAtIDEpKSAtIGR3UG9zID4gMiAqIHNpemVvZihEV09SRCkpCiAgICAgIFRoaXMtPmR3TmV4dEZyYW1lUG9zID0gKGR3UG9zICsgQVZJX0hFQURFUlNJWkUpICYgfihBVklfSEVBREVSU0laRSAtIDEpOwoKICAgIFRoaXMtPmR3TW92aUNodW5rUG9zID0gVGhpcy0+ZHdOZXh0RnJhbWVQb3MgLSBzaXplb2YoRFdPUkQpOwogIH0KCiAgcmV0dXJuIGR3UG9zOwp9CgpzdGF0aWMgdm9pZCAgICBBVklGSUxFX0NvbnN0cnVjdEFWSVN0cmVhbShJQVZJRmlsZUltcGwgKnBhZiwgRFdPUkQgbnIsIExQQVZJU1RSRUFNSU5GT1cgYXNpKQp7CiAgSUFWSVN0cmVhbUltcGwgKnBzdHJlYW07CgogIC8qIHByZS1jb25kaXRpb25zICovCiAgYXNzZXJ0KHBhZiAhPSBOVUxMKTsKICBhc3NlcnQobnIgPCBNQVhfQVZJU1RSRUFNUyk7CiAgYXNzZXJ0KHBhZi0+cHBTdHJlYW1zW25yXSAhPSBOVUxMKTsKCiAgcHN0cmVhbSA9IHBhZi0+cHBTdHJlYW1zW25yXTsKCiAgcHN0cmVhbS0+bHBWdGJsICAgICAgICAgPSAmaWF2aXN0OwogIHBzdHJlYW0tPnJlZiAgICAgICAgICAgID0gMDsKICBwc3RyZWFtLT5wYWYgICAgICAgICAgICA9IHBhZjsKICBwc3RyZWFtLT5uU3RyZWFtICAgICAgICA9IG5yOwogIHBzdHJlYW0tPmR3Q3VycmVudEZyYW1lID0gKERXT1JEKS0xOwogIHBzdHJlYW0tPmxMYXN0RnJhbWUgICAgPSAtMTsKCiAgaWYgKGFzaSAhPSBOVUxMKSB7CiAgICBtZW1jcHkoJnBzdHJlYW0tPnNJbmZvLCBhc2ksIHNpemVvZihwc3RyZWFtLT5zSW5mbykpOwoKICAgIGlmIChhc2ktPmR3TGVuZ3RoID4gMCkgewogICAgICAvKiBwcmUtYWxsb2NhdGUgbWVtIGZvciBmcmFtZS1pbmRleCBzdHJ1Y3R1cmUgKi8KICAgICAgcHN0cmVhbS0+aWR4RnJhbWVzID0KCShBVklJTkRFWEVOVFJZKilHbG9iYWxBbGxvY1B0cihHSE5ELCBhc2ktPmR3TGVuZ3RoICogc2l6ZW9mKEFWSUlOREVYRU5UUlkpKTsKICAgICAgaWYgKHBzdHJlYW0tPmlkeEZyYW1lcyAhPSBOVUxMKQoJcHN0cmVhbS0+bklkeEZyYW1lcyA9IGFzaS0+ZHdMZW5ndGg7CiAgICB9CiAgICBpZiAoYXNpLT5kd0Zvcm1hdENoYW5nZUNvdW50ID4gMCkgewogICAgICAvKiBwcmUtYWxsb2NhdGUgbWVtIGZvciBmb3JtYXRjaGFuZ2UtaW5kZXggc3RydWN0dXJlICovCiAgICAgIHBzdHJlYW0tPmlkeEZtdENoYW5nZXMgPQoJKEFWSUlOREVYRU5UUlkqKUdsb2JhbEFsbG9jUHRyKEdITkQsIGFzaS0+ZHdGb3JtYXRDaGFuZ2VDb3VudCAqIHNpemVvZihBVklJTkRFWEVOVFJZKSk7CiAgICAgIGlmIChwc3RyZWFtLT5pZHhGbXRDaGFuZ2VzICE9IE5VTEwpCglwc3RyZWFtLT5uSWR4Rm10Q2hhbmdlcyA9IGFzaS0+ZHdGb3JtYXRDaGFuZ2VDb3VudDsKICAgIH0KCiAgICAvKiBUaGVzZSB2YWx1ZXMgd2lsbCBiZSBjb21wdXRlZCAqLwogICAgcHN0cmVhbS0+c0luZm8uZHdMZW5ndGggICAgICAgICAgICAgID0gMDsKICAgIHBzdHJlYW0tPnNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA9IDA7CiAgICBwc3RyZWFtLT5zSW5mby5kd0Zvcm1hdENoYW5nZUNvdW50ICAgPSAwOwogICAgcHN0cmVhbS0+c0luZm8uZHdFZGl0Q291bnQgICAgICAgICAgID0gMTsKICAgIGlmIChwc3RyZWFtLT5zSW5mby5kd1NhbXBsZVNpemUgPiAwKQogICAgICBTZXRSZWN0RW1wdHkoJnBzdHJlYW0tPnNJbmZvLnJjRnJhbWUpOwogIH0KCiAgcHN0cmVhbS0+c0luZm8uZHdDYXBzID0gQVZJRklMRUNBUFNfQ0FOUkVBRHxBVklGSUxFQ0FQU19DQU5XUklURTsKfQoKc3RhdGljIHZvaWQgICAgQVZJRklMRV9EZXN0cnVjdEFWSVN0cmVhbShJQVZJU3RyZWFtSW1wbCAqVGhpcykKewogIC8qIHByZS1jb25kaXRpb25zICovCiAgYXNzZXJ0KFRoaXMgIT0gTlVMTCk7CgogIFRoaXMtPmR3Q3VycmVudEZyYW1lID0gKERXT1JEKS0xOwogIFRoaXMtPmxMYXN0RnJhbWUgICAgPSAtMTsKICBUaGlzLT5wYWYgPSBOVUxMOwogIGlmIChUaGlzLT5pZHhGcmFtZXMgIT0gTlVMTCkgewogICAgR2xvYmFsRnJlZVB0cihUaGlzLT5pZHhGcmFtZXMpOwogICAgVGhpcy0+aWR4RnJhbWVzICA9IE5VTEw7CiAgICBUaGlzLT5uSWR4RnJhbWVzID0gMDsKICB9CiAgaWYgKFRoaXMtPmlkeEZtdENoYW5nZXMgIT0gTlVMTCkgewogICAgR2xvYmFsRnJlZVB0cihUaGlzLT5pZHhGbXRDaGFuZ2VzKTsKICAgIFRoaXMtPmlkeEZtdENoYW5nZXMgPSBOVUxMOwogIH0KICBpZiAoVGhpcy0+bHBCdWZmZXIgIT0gTlVMTCkgewogICAgR2xvYmFsRnJlZVB0cihUaGlzLT5scEJ1ZmZlcik7CiAgICBUaGlzLT5scEJ1ZmZlciA9IE5VTEw7CiAgICBUaGlzLT5jYkJ1ZmZlciA9IDA7CiAgfQogIGlmIChUaGlzLT5scEhhbmRsZXJEYXRhICE9IE5VTEwpIHsKICAgIEdsb2JhbEZyZWVQdHIoVGhpcy0+bHBIYW5kbGVyRGF0YSk7CiAgICBUaGlzLT5scEhhbmRsZXJEYXRhID0gTlVMTDsKICAgIFRoaXMtPmNiSGFuZGxlckRhdGEgPSAwOwogIH0KICBpZiAoVGhpcy0+ZXh0cmEubHAgIT0gTlVMTCkgewogICAgR2xvYmFsRnJlZVB0cihUaGlzLT5leHRyYS5scCk7CiAgICBUaGlzLT5leHRyYS5scCA9IE5VTEw7CiAgICBUaGlzLT5leHRyYS5jYiA9IDA7CiAgfQogIGlmIChUaGlzLT5scEZvcm1hdCAhPSBOVUxMKSB7CiAgICBHbG9iYWxGcmVlUHRyKFRoaXMtPmxwRm9ybWF0KTsKICAgIFRoaXMtPmxwRm9ybWF0ID0gTlVMTDsKICAgIFRoaXMtPmNiRm9ybWF0ID0gMDsKICB9Cn0KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfTG9hZEZpbGUoSUFWSUZpbGVJbXBsICpUaGlzKQp7CiAgTWFpbkFWSUhlYWRlciAgIE1haW5BVklIZHI7CiAgTU1DS0lORk8gICAgICAgIGNrUklGRjsKICBNTUNLSU5GTyAgICAgICAgY2tMSVNUMTsKICBNTUNLSU5GTyAgICAgICAgY2tMSVNUMjsKICBNTUNLSU5GTyAgICAgICAgY2s7CiAgSUFWSVN0cmVhbUltcGwgKnBTdHJlYW07CiAgRFdPUkQgICAgICAgICAgIG5TdHJlYW07CiAgSFJFU1VMVCAgICAgICAgIGhyOwoKICBpZiAoVGhpcy0+aG1taW8gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfRklMRU9QRU47CgogIC8qIGluaXRpYWxpemUgc3RyZWFtIHB0cidzICovCiAgbWVtc2V0KFRoaXMtPnBwU3RyZWFtcywgMCwgc2l6ZW9mKFRoaXMtPnBwU3RyZWFtcykpOwoKICAvKiB0cnkgdG8gZ2V0ICJSSUZGIiBjaHVuayAtLSBtdXN0IG5vdCBiZSBhdCBiZWdpbm5pbmcgb2YgZmlsZSEgKi8KICBja1JJRkYuZmNjVHlwZSA9IGZvcm10eXBlQVZJOwogIGlmIChtbWlvRGVzY2VuZChUaGlzLT5obW1pbywgJmNrUklGRiwgTlVMTCwgTU1JT19GSU5EUklGRikgIT0gU19PSykgewogICAgRVJSKCI6IG5vdCBhbiBBVkkhXG4iKTsKICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CiAgfQoKICAvKiBnZXQgIkxJU1QiICJoZHJsIiAqLwogIGNrTElTVDEuZmNjVHlwZSA9IGxpc3R0eXBlQVZJSEVBREVSOwogIGhyID0gRmluZENodW5rQW5kS2VlcEV4dHJhcygmVGhpcy0+ZmlsZWV4dHJhLCBUaGlzLT5obW1pbywgJmNrTElTVDEsICZja1JJRkYsIE1NSU9fRklORExJU1QpOwogIGlmIChGQUlMRUQoaHIpKQogICAgcmV0dXJuIGhyOwoKICAvKiBnZXQgImF2aWgiIGNodW5rICovCiAgY2suY2tpZCA9IGNraWRBVklNQUlOSERSOwogIGhyID0gRmluZENodW5rQW5kS2VlcEV4dHJhcygmVGhpcy0+ZmlsZWV4dHJhLCBUaGlzLT5obW1pbywgJmNrLCAmY2tMSVNUMSwgTU1JT19GSU5EQ0hVTkspOwogIGlmIChGQUlMRUQoaHIpKQogICAgcmV0dXJuIGhyOwoKICBpZiAoY2suY2tzaXplICE9IHNpemVvZihNYWluQVZJSGRyKSkgewogICAgRVJSKCI6IGludmFsaWQgc2l6ZSBvZiAlbGQgZm9yIE1haW5BVklIZWFkZXIhXG4iLCBjay5ja3NpemUpOwogICAgcmV0dXJuIEFWSUVSUl9CQURGT1JNQVQ7CiAgfQogIGlmIChtbWlvUmVhZChUaGlzLT5obW1pbywgKEhQU1RSKSZNYWluQVZJSGRyLCBjay5ja3NpemUpICE9IGNrLmNrc2l6ZSkKICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CgogIC8qIGNoZWNrIGZvciBNQVhfQVZJU1RSRUFNUyBsaW1pdCAqLwogIGlmIChNYWluQVZJSGRyLmR3U3RyZWFtcyA+IE1BWF9BVklTVFJFQU1TKSB7CiAgICBXQVJOKCJmaWxlIGNvbnRhaW5zICVsdSBzdHJlYW1zLCBidXQgb25seSBzdXBwb3J0cyAlZCAtLSBjaGFuZ2UgTUFYX0FWSVNUUkVBTVMhXG4iLCBNYWluQVZJSGRyLmR3U3RyZWFtcywgTUFYX0FWSVNUUkVBTVMpOwogICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKICB9CgogIC8qIGFkanVzdCBwZXJtaXNzaW9ucyBpZiBjb3B5cmlnaHRlZCBtYXRlcmlhbCBpbiBmaWxlICovCiAgaWYgKE1haW5BVklIZHIuZHdGbGFncyAmIEFWSUZJTEVJTkZPX0NPUFlSSUdIVEVEKSB7CiAgICBUaGlzLT51TW9kZSAmPSB+TU1JT19SV01PREU7CiAgICBUaGlzLT51TW9kZSB8PSBNTUlPX1JFQUQ7CiAgfQoKICAvKiBjb252ZXJ0IE1haW5BVklIZWFkZXIgaW50byBBVklGSUxJTkZPVyAqLwogIG1lbXNldCgmVGhpcy0+ZkluZm8sIDAsIHNpemVvZihUaGlzLT5mSW5mbykpOwogIFRoaXMtPmZJbmZvLmR3UmF0ZSAgICAgICAgICAgICAgICA9IE1haW5BVklIZHIuZHdNaWNyb1NlY1BlckZyYW1lOwogIFRoaXMtPmZJbmZvLmR3U2NhbGUgICAgICAgICAgICAgICA9IDEwMDAwMDA7CiAgVGhpcy0+ZkluZm8uZHdNYXhCeXRlc1BlclNlYyAgICAgID0gTWFpbkFWSUhkci5kd01heEJ5dGVzUGVyU2VjOwogIFRoaXMtPmZJbmZvLmR3RmxhZ3MgICAgICAgICAgICAgICA9IE1haW5BVklIZHIuZHdGbGFnczsKICBUaGlzLT5mSW5mby5kd0NhcHMgICAgICAgICAgICAgICAgPSBBVklGSUxFQ0FQU19DQU5SRUFEfEFWSUZJTEVDQVBTX0NBTldSSVRFOwogIFRoaXMtPmZJbmZvLmR3TGVuZ3RoICAgICAgICAgICAgICA9IE1haW5BVklIZHIuZHdUb3RhbEZyYW1lczsKICBUaGlzLT5mSW5mby5kd1N0cmVhbXMgICAgICAgICAgICAgPSBNYWluQVZJSGRyLmR3U3RyZWFtczsKICBUaGlzLT5mSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPSBNYWluQVZJSGRyLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZTsKICBUaGlzLT5mSW5mby5kd1dpZHRoICAgICAgICAgICAgICAgPSBNYWluQVZJSGRyLmR3V2lkdGg7CiAgVGhpcy0+ZkluZm8uZHdIZWlnaHQgICAgICAgICAgICAgID0gTWFpbkFWSUhkci5kd0hlaWdodDsKICBMb2FkU3RyaW5nVyhBVklGSUxFX2hNb2R1bGUsIElEU19BVklGSUxFVFlQRSwgVGhpcy0+ZkluZm8uc3pGaWxlVHlwZSwKCSAgICAgIHNpemVvZihUaGlzLT5mSW5mby5zekZpbGVUeXBlKSk7CgogIC8qIGdvIGJhY2sgdG8gaW50byBoZWFkZXIgbGlzdCAqLwogIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwoKICAvKiBmb3JlYWNoIHN0cmVhbSBleGlzdHMgYSAiTElTVCIsInN0cmwiIGNodW5rICovCiAgZm9yIChuU3RyZWFtID0gMDsgblN0cmVhbSA8IFRoaXMtPmZJbmZvLmR3U3RyZWFtczsgblN0cmVhbSsrKSB7CiAgICAvKiBnZXQgbmV4dCBuZXN0ZWQgY2h1bmsgaW4gdGhpcyAiTElTVCIsInN0cmwiICovCiAgICBpZiAobW1pb0Rlc2NlbmQoVGhpcy0+aG1taW8sICZja0xJU1QyLCAmY2tMSVNUMSwgMCkgIT0gU19PSykKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCiAgICAvKiBuZXN0ZWQgY2h1bmsgbXVzdCBiZSBvZiB0eXBlICJMSVNUIiwic3RybCIgLS0gd2hlbiBub3Qgbm9ybWFsbHkgSlVOSyAqLwogICAgaWYgKGNrTElTVDIuY2tpZCA9PSBGT1VSQ0NfTElTVCAmJgoJY2tMSVNUMi5mY2NUeXBlID09IGxpc3R0eXBlU1RSRUFNSEVBREVSKSB7CiAgICAgIHBTdHJlYW0gPSBUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV0gPQoJKElBVklTdHJlYW1JbXBsKilMb2NhbEFsbG9jKExQVFIsIHNpemVvZihJQVZJU3RyZWFtSW1wbCkpOwogICAgICBpZiAocFN0cmVhbSA9PSBOVUxMKQoJcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgICAgIEFWSUZJTEVfQ29uc3RydWN0QVZJU3RyZWFtKFRoaXMsIG5TdHJlYW0sIE5VTEwpOwoKICAgICAgY2suY2tpZCA9IDA7CiAgICAgIHdoaWxlIChtbWlvRGVzY2VuZChUaGlzLT5obW1pbywgJmNrLCAmY2tMSVNUMiwgMCkgPT0gU19PSykgewoJc3dpdGNoIChjay5ja2lkKSB7CgljYXNlIGNraWRTVFJFQU1IQU5ETEVSREFUQToKCSAgaWYgKHBTdHJlYW0tPmxwSGFuZGxlckRhdGEgIT0gTlVMTCkKCSAgICByZXR1cm4gQVZJRVJSX0JBREZPUk1BVDsKCSAgcFN0cmVhbS0+bHBIYW5kbGVyRGF0YSA9IEdsb2JhbEFsbG9jUHRyKEdNRU1fRERFU0hBUkV8R01FTV9NT1ZFQUJMRSwKCQkJCQkJICBjay5ja3NpemUpOwoJICBpZiAocFN0cmVhbS0+bHBIYW5kbGVyRGF0YSA9PSBOVUxMKQoJICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoJICBwU3RyZWFtLT5jYkhhbmRsZXJEYXRhID0gY2suY2tzaXplOwoKCSAgaWYgKG1taW9SZWFkKFRoaXMtPmhtbWlvLCAoSFBTVFIpcFN0cmVhbS0+bHBIYW5kbGVyRGF0YSwgY2suY2tzaXplKSAhPSBjay5ja3NpemUpCgkgICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCSAgYnJlYWs7CgljYXNlIGNraWRTVFJFQU1GT1JNQVQ6CgkgIGlmIChwU3RyZWFtLT5scEZvcm1hdCAhPSBOVUxMKQoJICAgIHJldHVybiBBVklFUlJfQkFERk9STUFUOwogICAgICAgICAgaWYgKGNrLmNrc2l6ZSA9PSAwKQogICAgICAgICAgICBicmVhazsKCgkgIHBTdHJlYW0tPmxwRm9ybWF0ID0gR2xvYmFsQWxsb2NQdHIoR01FTV9EREVTSEFSRXxHTUVNX01PVkVBQkxFLAoJCQkJCSAgICAgY2suY2tzaXplKTsKCSAgaWYgKHBTdHJlYW0tPmxwRm9ybWF0ID09IE5VTEwpCgkgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgkgIHBTdHJlYW0tPmNiRm9ybWF0ID0gY2suY2tzaXplOwoKCSAgaWYgKG1taW9SZWFkKFRoaXMtPmhtbWlvLCAoSFBTVFIpcFN0cmVhbS0+bHBGb3JtYXQsIGNrLmNrc2l6ZSkgIT0gY2suY2tzaXplKQoJICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CgoJICBpZiAocFN0cmVhbS0+c0luZm8uZmNjVHlwZSA9PSBzdHJlYW10eXBlVklERU8pIHsKCSAgICBMUEJJVE1BUElORk9IRUFERVIgbHBiaSA9IChMUEJJVE1BUElORk9IRUFERVIpcFN0cmVhbS0+bHBGb3JtYXQ7CgoJICAgIC8qIHNvbWUgY29ycmVjdGlvbnMgdG8gdGhlIHZpZGVvIGZvcm1hdCAqLwoJICAgIGlmIChscGJpLT5iaUNsclVzZWQgPT0gMCAmJiBscGJpLT5iaUJpdENvdW50IDw9IDgpCgkgICAgICBscGJpLT5iaUNsclVzZWQgPSAxdSA8PCBscGJpLT5iaUJpdENvdW50OwoJICAgIGlmIChscGJpLT5iaUNvbXByZXNzaW9uID09IEJJX1JHQiAmJiBscGJpLT5iaVNpemVJbWFnZSA9PSAwKQoJICAgICAgbHBiaS0+YmlTaXplSW1hZ2UgPSBESUJXSURUSEJZVEVTKCpscGJpKSAqIGxwYmktPmJpSGVpZ2h0OwoJICAgIGlmIChscGJpLT5iaUNvbXByZXNzaW9uICE9IEJJX1JHQiAmJiBscGJpLT5iaUJpdENvdW50ID09IDgpIHsKCSAgICAgIGlmIChwU3RyZWFtLT5zSW5mby5mY2NIYW5kbGVyID09IG1taW9GT1VSQ0MoJ1InLCdMJywnRScsJzAnKSB8fAoJCSAgcFN0cmVhbS0+c0luZm8uZmNjSGFuZGxlciA9PSBtbWlvRk9VUkNDKCdSJywnTCcsJ0UnLCcgJykpCgkJbHBiaS0+YmlDb21wcmVzc2lvbiA9IEJJX1JMRTg7CgkgICAgfQoJICAgIGlmIChscGJpLT5iaUNvbXByZXNzaW9uID09IEJJX1JHQiAmJgoJCShwU3RyZWFtLT5zSW5mby5mY2NIYW5kbGVyID09IDAgfHwKCQkgcFN0cmVhbS0+c0luZm8uZmNjSGFuZGxlciA9PSBtbWlvRk9VUkNDKCdOJywnTycsJ04nLCdFJykpKQoJICAgICAgcFN0cmVhbS0+c0luZm8uZmNjSGFuZGxlciA9IGNvbXB0eXBlRElCOwoKCSAgICAvKiBpbml0IHJjRnJhbWUgaWYgaXQncyBlbXB0eSAqLwoJICAgIGlmIChJc1JlY3RFbXB0eSgmcFN0cmVhbS0+c0luZm8ucmNGcmFtZSkpCgkgICAgICBTZXRSZWN0KCZwU3RyZWFtLT5zSW5mby5yY0ZyYW1lLCAwLCAwLCBscGJpLT5iaVdpZHRoLCBscGJpLT5iaUhlaWdodCk7CgkgIH0KCSAgYnJlYWs7CgljYXNlIGNraWRTVFJFQU1IRUFERVI6CgkgIHsKCSAgICBzdGF0aWMgY29uc3QgV0NIQVIgc3RyZWFtVHlwZUZtdFtdID0geyclJywnNCcsJy4nLCc0JywnaCcsJ3MnLDB9OwoKCSAgICBBVklTdHJlYW1IZWFkZXIgc3RyZWFtSGRyOwoJICAgIFdDSEFSICAgICAgICAgICBzelR5cGVbMjVdOwoJICAgIFdDSEFSICAgICAgICAgICBzdHJlYW1OYW1lRm10WzI1XTsKCSAgICBVSU5UICAgICAgICAgICAgY291bnQ7CgkgICAgTE9ORyAgICAgICAgICAgIG4gPSBjay5ja3NpemU7CgoJICAgIGlmIChjay5ja3NpemUgPiBzaXplb2Yoc3RyZWFtSGRyKSkKCSAgICAgIG4gPSBzaXplb2Yoc3RyZWFtSGRyKTsKCgkgICAgaWYgKG1taW9SZWFkKFRoaXMtPmhtbWlvLCAoSFBTVFIpJnN0cmVhbUhkciwgbikgIT0gbikKCSAgICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CgoJICAgIHBTdHJlYW0tPnNJbmZvLmZjY1R5cGUgICAgICAgICAgICAgICA9IHN0cmVhbUhkci5mY2NUeXBlOwoJICAgIHBTdHJlYW0tPnNJbmZvLmZjY0hhbmRsZXIgICAgICAgICAgICA9IHN0cmVhbUhkci5mY2NIYW5kbGVyOwoJICAgIHBTdHJlYW0tPnNJbmZvLmR3RmxhZ3MgICAgICAgICAgICAgICA9IHN0cmVhbUhkci5kd0ZsYWdzOwoJICAgIHBTdHJlYW0tPnNJbmZvLndQcmlvcml0eSAgICAgICAgICAgICA9IHN0cmVhbUhkci53UHJpb3JpdHk7CgkgICAgcFN0cmVhbS0+c0luZm8ud0xhbmd1YWdlICAgICAgICAgICAgID0gc3RyZWFtSGRyLndMYW5ndWFnZTsKCSAgICBwU3RyZWFtLT5zSW5mby5kd0luaXRpYWxGcmFtZXMgICAgICAgPSBzdHJlYW1IZHIuZHdJbml0aWFsRnJhbWVzOwoJICAgIHBTdHJlYW0tPnNJbmZvLmR3U2NhbGUgICAgICAgICAgICAgICA9IHN0cmVhbUhkci5kd1NjYWxlOwoJICAgIHBTdHJlYW0tPnNJbmZvLmR3UmF0ZSAgICAgICAgICAgICAgICA9IHN0cmVhbUhkci5kd1JhdGU7CgkgICAgcFN0cmVhbS0+c0luZm8uZHdTdGFydCAgICAgICAgICAgICAgID0gc3RyZWFtSGRyLmR3U3RhcnQ7CgkgICAgcFN0cmVhbS0+c0luZm8uZHdMZW5ndGggICAgICAgICAgICAgID0gc3RyZWFtSGRyLmR3TGVuZ3RoOwoJICAgIHBTdHJlYW0tPnNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA9CgkgICAgICBzdHJlYW1IZHIuZHdTdWdnZXN0ZWRCdWZmZXJTaXplOwoJICAgIHBTdHJlYW0tPnNJbmZvLmR3UXVhbGl0eSAgICAgICAgICAgICA9IHN0cmVhbUhkci5kd1F1YWxpdHk7CgkgICAgcFN0cmVhbS0+c0luZm8uZHdTYW1wbGVTaXplICAgICAgICAgID0gc3RyZWFtSGRyLmR3U2FtcGxlU2l6ZTsKCSAgICBwU3RyZWFtLT5zSW5mby5yY0ZyYW1lLmxlZnQgICAgICAgICAgPSBzdHJlYW1IZHIucmNGcmFtZS5sZWZ0OwoJICAgIHBTdHJlYW0tPnNJbmZvLnJjRnJhbWUudG9wICAgICAgICAgICA9IHN0cmVhbUhkci5yY0ZyYW1lLnRvcDsKCSAgICBwU3RyZWFtLT5zSW5mby5yY0ZyYW1lLnJpZ2h0ICAgICAgICAgPSBzdHJlYW1IZHIucmNGcmFtZS5yaWdodDsKCSAgICBwU3RyZWFtLT5zSW5mby5yY0ZyYW1lLmJvdHRvbSAgICAgICAgPSBzdHJlYW1IZHIucmNGcmFtZS5ib3R0b207CgkgICAgcFN0cmVhbS0+c0luZm8uZHdFZGl0Q291bnQgICAgICAgICAgID0gMDsKCSAgICBwU3RyZWFtLT5zSW5mby5kd0Zvcm1hdENoYW5nZUNvdW50ICAgPSAwOwoKCSAgICAvKiBnZW5lcmF0ZSBkZXNjcmlwdGlvbiBmb3Igc3RyZWFtIGxpa2UgImZpbGVuYW1lLmF2aSBUeXBlICNuIiAqLwoJICAgIGlmIChzdHJlYW1IZHIuZmNjVHlwZSA9PSBzdHJlYW10eXBlVklERU8pCgkgICAgICBMb2FkU3RyaW5nVyhBVklGSUxFX2hNb2R1bGUsIElEU19WSURFTywgc3pUeXBlLCBzaXplb2Yoc3pUeXBlKSk7CgkgICAgZWxzZSBpZiAoc3RyZWFtSGRyLmZjY1R5cGUgPT0gc3RyZWFtdHlwZUFVRElPKQoJICAgICAgTG9hZFN0cmluZ1coQVZJRklMRV9oTW9kdWxlLCBJRFNfQVVESU8sIHN6VHlwZSwgc2l6ZW9mKHN6VHlwZSkpOwoJICAgIGVsc2UKCSAgICAgIHdzcHJpbnRmVyhzelR5cGUsIHN0cmVhbVR5cGVGbXQsIChjaGFyKikmc3RyZWFtSGRyLmZjY1R5cGUpOwoKCSAgICAvKiBnZXQgY291bnQgb2YgdGhpcyBzdHJlYW10eXBlIHVwIHRvIHRoaXMgc3RyZWFtICovCgkgICAgY291bnQgPSAwOwoJICAgIGZvciAobiA9IG5TdHJlYW07IDAgPD0gbjsgbi0tKSB7CgkgICAgICBpZiAoVGhpcy0+cHBTdHJlYW1zW25dLT5zSW5mby5mY2NIYW5kbGVyID09IHN0cmVhbUhkci5mY2NUeXBlKQoJCWNvdW50Kys7CgkgICAgfQoKCSAgICBtZW1zZXQocFN0cmVhbS0+c0luZm8uc3pOYW1lLCAwLCBzaXplb2YocFN0cmVhbS0+c0luZm8uc3pOYW1lKSk7CgoJICAgIExvYWRTdHJpbmdXKEFWSUZJTEVfaE1vZHVsZSwgSURTX0FWSVNUUkVBTUZPUk1BVCwgc3RyZWFtTmFtZUZtdCwgc2l6ZW9mKHN0cmVhbU5hbWVGbXQpKTsKCgkgICAgLyogRklYTUU6IGF2b2lkIG92ZXJmbG93IC0tIGJldHRlciB1c2Ugd3NucHJpbnRmVywgd2hpY2ggZG9lc24ndCBleGlzdHMgISAqLwoJICAgIHdzcHJpbnRmVyhwU3RyZWFtLT5zSW5mby5zek5hbWUsIHN0cmVhbU5hbWVGbXQsCgkJICAgICAgQVZJRklMRV9CYXNlbmFtZVcoVGhpcy0+c3pGaWxlTmFtZSksIHN6VHlwZSwgY291bnQpOwoJICB9CgkgIGJyZWFrOwoJY2FzZSBja2lkU1RSRUFNTkFNRToKCSAgeyAvKiBzdHJlYW1uYW1lIHdpbGwgYmUgc2F2ZWQgYXMgQVNDSUkgc3RyaW5nICovCgkgICAgTFBTVFIgc3RyID0gKExQU1RSKUxvY2FsQWxsb2MoTE1FTV9GSVhFRCwgY2suY2tzaXplKTsKCSAgICBpZiAoc3RyID09IE5VTEwpCgkgICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCgkgICAgaWYgKG1taW9SZWFkKFRoaXMtPmhtbWlvLCAoSFBTVFIpc3RyLCBjay5ja3NpemUpICE9IGNrLmNrc2l6ZSkKCSAgICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CgoJICAgIE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBzdHIsIC0xLCBwU3RyZWFtLT5zSW5mby5zek5hbWUsCgkJCQlzaXplb2YocFN0cmVhbS0+c0luZm8uc3pOYW1lKS9zaXplb2YocFN0cmVhbS0+c0luZm8uc3pOYW1lWzBdKSk7CgoJICAgIExvY2FsRnJlZSgoSExPQ0FMKXN0cik7CgkgIH0KCSAgYnJlYWs7CgljYXNlIGNraWRBVklQQURESU5HOgoJY2FzZSBtbWlvRk9VUkNDKCdwJywnYScsJ2QnLCdkJyk6CgkgIGJyZWFrOwoJZGVmYXVsdDoKCSAgV0FSTigiOiBmb3VuZCBleHRyYSBjaHVuayAweCUwOGxYXG4iLCBjay5ja2lkKTsKCSAgaHIgPSBSZWFkQ2h1bmtJbnRvRXh0cmEoJnBTdHJlYW0tPmV4dHJhLCBUaGlzLT5obW1pbywgJmNrKTsKCSAgaWYgKEZBSUxFRChocikpCgkgICAgcmV0dXJuIGhyOwoJfTsKCglpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQoJICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICAvKiBuZXN0ZWQgY2h1bmtzIGluICJMSVNUIiwiaGRybCIgd2hpY2ggYXJlIG5vdCBvZiB0eXBlICJMSVNUIiwic3RybCIgKi8KICAgICAgaHIgPSBSZWFkQ2h1bmtJbnRvRXh0cmEoJlRoaXMtPmZpbGVleHRyYSwgVGhpcy0+aG1taW8sICZja0xJU1QyKTsKICAgICAgaWYgKEZBSUxFRChocikpCglyZXR1cm4gaHI7CiAgICB9CiAgICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrTElTVDIsIDApICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CiAgfQoKICAvKiByZWFkIGFueSBleHRyYSBoZWFkZXJzIGluICJMSVNUIiwiaGRybCIgKi8KICBGaW5kQ2h1bmtBbmRLZWVwRXh0cmFzKCZUaGlzLT5maWxlZXh0cmEsIFRoaXMtPmhtbWlvLCAmY2ssICZja0xJU1QxLCAwKTsKICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrTElTVDEsIDApICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwoKICAvKiBzZWFyY2ggIkxJU1QiLCJtb3ZpIiBjaHVuayBpbiAiUklGRiIsIkFWSSAiICovCiAgY2tMSVNUMS5mY2NUeXBlID0gbGlzdHR5cGVBVklNT1ZJRTsKICBociA9IEZpbmRDaHVua0FuZEtlZXBFeHRyYXMoJlRoaXMtPmZpbGVleHRyYSwgVGhpcy0+aG1taW8sICZja0xJU1QxLCAmY2tSSUZGLAoJCQkgICAgICBNTUlPX0ZJTkRMSVNUKTsKICBpZiAoRkFJTEVEKGhyKSkKICAgIHJldHVybiBocjsKCiAgVGhpcy0+ZHdNb3ZpQ2h1bmtQb3MgPSBja0xJU1QxLmR3RGF0YU9mZnNldDsKICBUaGlzLT5kd0lkeENodW5rUG9zICA9IGNrTElTVDEuY2tzaXplICsgY2tMSVNUMS5kd0RhdGFPZmZzZXQ7CiAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZja0xJU1QxLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCiAgLyogdHJ5IHRvIGZpbmQgYW4gaW5kZXggKi8KICBjay5ja2lkID0gY2tpZEFWSU5FV0lOREVYOwogIGhyID0gRmluZENodW5rQW5kS2VlcEV4dHJhcygmVGhpcy0+ZmlsZWV4dHJhLCBUaGlzLT5obW1pbywKCQkJICAgICAgJmNrLCAmY2tSSUZGLCBNTUlPX0ZJTkRDSFVOSyk7CiAgaWYgKFNVQ0NFRURFRChocikgJiYgY2suY2tzaXplID4gMCkgewogICAgaWYgKEZBSUxFRChBVklGSUxFX0xvYWRJbmRleChUaGlzLCBjay5ja3NpemUsIGNrTElTVDEuZHdEYXRhT2Zmc2V0KSkpCiAgICAgIFRoaXMtPmZJbmZvLmR3RmxhZ3MgJj0gfkFWSUZJTEVJTkZPX0hBU0lOREVYOwogIH0KCiAgLyogd2hlbiB3ZSBoYXZlbid0IGZvdW5kIGFuIGluZGV4IG9yIGl0J3MgYmFkLCB0aGVuIGJ1aWxkIG9uZQogICAqIGJ5IHBhcnNpbmcgJ21vdmknIGNodW5rICovCiAgaWYgKChUaGlzLT5mSW5mby5kd0ZsYWdzICYgQVZJRklMRUlORk9fSEFTSU5ERVgpID09IDApIHsKICAgIGZvciAoblN0cmVhbSA9IDA7IG5TdHJlYW0gPCBUaGlzLT5mSW5mby5kd1N0cmVhbXM7IG5TdHJlYW0rKykKICAgICAgVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dLT5sTGFzdEZyYW1lID0gLTE7CgogICAgaWYgKG1taW9TZWVrKFRoaXMtPmhtbWlvLCBja0xJU1QxLmR3RGF0YU9mZnNldCArIHNpemVvZihEV09SRCksIFNFRUtfU0VUKSA9PSAtMSkgewogICAgICBFUlIoIjogT29wcywgY2FuJ3Qgc2VlayBiYWNrIHRvICdtb3ZpJyBjaHVuayFcbiIpOwogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwogICAgfQoKICAgIC8qIHNlZWsgdGhyb3VnaCB0aGUgJ21vdmknIGxpc3QgdW50aWwgZW5kICovCiAgICB3aGlsZSAobW1pb0Rlc2NlbmQoVGhpcy0+aG1taW8sICZjaywgJmNrTElTVDEsIDApID09IFNfT0spIHsKICAgICAgaWYgKGNrLmNraWQgIT0gRk9VUkNDX0xJU1QpIHsKCWlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2ssIDApID09IFNfT0spIHsKCSAgblN0cmVhbSA9IFN0cmVhbUZyb21GT1VSQ0MoY2suY2tpZCk7CgoJICBpZiAoblN0cmVhbSA+IFRoaXMtPmZJbmZvLmR3U3RyZWFtcykKCSAgICByZXR1cm4gQVZJRVJSX0JBREZPUk1BVDsKCgkgIEFWSUZJTEVfQWRkRnJhbWUoVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dLCBjay5ja2lkLCBjay5ja3NpemUsCgkJCSAgIGNrLmR3RGF0YU9mZnNldCAtIDIgKiBzaXplb2YoRFdPUkQpLCAwKTsKCX0gZWxzZSB7CgkgIG5TdHJlYW0gPSBTdHJlYW1Gcm9tRk9VUkNDKGNrLmNraWQpOwoJICBXQVJOKCI6IGZpbGUgc2VlbXMgdG8gYmUgdHJ1bmNhdGVkIVxuIik7CgkgIGlmIChuU3RyZWFtIDw9IFRoaXMtPmZJbmZvLmR3U3RyZWFtcyAmJgoJICAgICAgVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dLT5zSW5mby5kd1NhbXBsZVNpemUgPiAwKSB7CgkgICAgY2suY2tzaXplID0gbW1pb1NlZWsoVGhpcy0+aG1taW8sIDAsIFNFRUtfRU5EKTsKCSAgICBpZiAoY2suY2tzaXplICE9IC0xKSB7CgkgICAgICBjay5ja3NpemUgLT0gY2suZHdEYXRhT2Zmc2V0OwoJICAgICAgY2suY2tzaXplICY9IH4oVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dLT5zSW5mby5kd1NhbXBsZVNpemUgLSAxKTsKCgkgICAgICBBVklGSUxFX0FkZEZyYW1lKFRoaXMtPnBwU3RyZWFtc1tuU3RyZWFtXSwgY2suY2tpZCwgY2suY2tzaXplLAoJCQkgICAgICAgY2suZHdEYXRhT2Zmc2V0IC0gMiAqIHNpemVvZihEV09SRCksIDApOwoJICAgIH0KCSAgfQoJfQogICAgICB9CiAgICB9CiAgfQoKICAvKiBmaW5kIG90aGVyIGNodW5rcyAqLwogIEZpbmRDaHVua0FuZEtlZXBFeHRyYXMoJlRoaXMtPmZpbGVleHRyYSwgVGhpcy0+aG1taW8sICZjaywgJmNrUklGRiwgMCk7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfTG9hZEluZGV4KElBVklGaWxlSW1wbCAqVGhpcywgRFdPUkQgc2l6ZSwgRFdPUkQgb2Zmc2V0KQp7CiAgQVZJSU5ERVhFTlRSWSAqbHA7CiAgRFdPUkQgICAgICAgICAgcG9zLCBuOwogIEhSRVNVTFQgICAgICAgIGhyID0gQVZJRVJSX09LOwogIEJPT0wgICAgICAgICAgIGJBYnNvbHV0ZSA9IFRSVUU7CgogIGxwID0gKEFWSUlOREVYRU5UUlkqKUdsb2JhbEFsbG9jUHRyKEdNRU1fTU9WRUFCTEUsCgkJCQkgICAgICBJRFhfUEVSX0JMT0NLICogc2l6ZW9mKEFWSUlOREVYRU5UUlkpKTsKICBpZiAobHAgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICAvKiBhZGp1c3QgbGltaXRzIGZvciBpbmRleCB0YWJsZXMsIHNvIHRoYXQgaW5zZXJ0aW5nIHdpbGwgYmUgZmFzdGVyICovCiAgZm9yIChuID0gMDsgbiA8IFRoaXMtPmZJbmZvLmR3U3RyZWFtczsgbisrKSB7CiAgICBJQVZJU3RyZWFtSW1wbCAqcFN0cmVhbSA9IFRoaXMtPnBwU3RyZWFtc1tuXTsKCiAgICBwU3RyZWFtLT5sTGFzdEZyYW1lID0gLTE7CgogICAgaWYgKHBTdHJlYW0tPmlkeEZyYW1lcyAhPSBOVUxMKSB7CiAgICAgIEdsb2JhbEZyZWVQdHIocFN0cmVhbS0+aWR4RnJhbWVzKTsKICAgICAgcFN0cmVhbS0+aWR4RnJhbWVzICA9IE5VTEw7CiAgICAgIHBTdHJlYW0tPm5JZHhGcmFtZXMgPSAwOwogICAgfQoKICAgIGlmIChwU3RyZWFtLT5zSW5mby5kd1NhbXBsZVNpemUgIT0gMCkgewogICAgICBpZiAobiA+IDAgJiYgVGhpcy0+ZkluZm8uZHdGbGFncyAmIEFWSUZJTEVJTkZPX0lTSU5URVJMRUFWRUQpIHsKCXBTdHJlYW0tPm5JZHhGcmFtZXMgPSBUaGlzLT5wcFN0cmVhbXNbMF0tPm5JZHhGcmFtZXM7CiAgICAgIH0gZWxzZSBpZiAocFN0cmVhbS0+c0luZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplKSB7CglwU3RyZWFtLT5uSWR4RnJhbWVzID0KCSAgcFN0cmVhbS0+c0luZm8uZHdMZW5ndGggLyBwU3RyZWFtLT5zSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemU7CiAgICAgIH0KICAgIH0gZWxzZQogICAgICBwU3RyZWFtLT5uSWR4RnJhbWVzID0gcFN0cmVhbS0+c0luZm8uZHdMZW5ndGg7CgogICAgcFN0cmVhbS0+aWR4RnJhbWVzID0KICAgICAgKEFWSUlOREVYRU5UUlkqKUdsb2JhbEFsbG9jUHRyKEdITkQsIHBTdHJlYW0tPm5JZHhGcmFtZXMgKiBzaXplb2YoQVZJSU5ERVhFTlRSWSkpOwogICAgaWYgKHBTdHJlYW0tPmlkeEZyYW1lcyA9PSBOVUxMICYmIHBTdHJlYW0tPm5JZHhGcmFtZXMgPiAwKSB7CiAgICAgIHBTdHJlYW0tPm5JZHhGcmFtZXMgPSAwOwogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKICAgIH0KICB9CgogIHBvcyA9IChEV09SRCktMTsKICB3aGlsZSAoc2l6ZSAhPSAwKSB7CiAgICBMT05HIHJlYWQgPSBtaW4oSURYX1BFUl9CTE9DSyAqIHNpemVvZihBVklJTkRFWEVOVFJZKSwgc2l6ZSk7CgogICAgaWYgKG1taW9SZWFkKFRoaXMtPmhtbWlvLCAoSFBTVFIpbHAsIHJlYWQpICE9IHJlYWQpIHsKICAgICAgaHIgPSBBVklFUlJfRklMRVJFQUQ7CiAgICAgIGJyZWFrOwogICAgfQogICAgc2l6ZSAtPSByZWFkOwoKICAgIGlmIChwb3MgPT0gKERXT1JEKS0xKQogICAgICBwb3MgPSBvZmZzZXQgLSBscC0+ZHdDaHVua09mZnNldCArIHNpemVvZihEV09SRCk7CgogICAgQVZJRklMRV9QYXJzZUluZGV4KFRoaXMsIGxwLCByZWFkIC8gc2l6ZW9mKEFWSUlOREVYRU5UUlkpLAoJCSAgICAgICBwb3MsICZiQWJzb2x1dGUpOwogIH0KCiAgaWYgKGxwICE9IE5VTEwpCiAgICBHbG9iYWxGcmVlUHRyKGxwKTsKCiAgLyogY2hlY2tpbmcgLi4uICovCiAgZm9yIChuID0gMDsgbiA8IFRoaXMtPmZJbmZvLmR3U3RyZWFtczsgbisrKSB7CiAgICBJQVZJU3RyZWFtSW1wbCAqcFN0cmVhbSA9IFRoaXMtPnBwU3RyZWFtc1tuXTsKCiAgICBpZiAocFN0cmVhbS0+c0luZm8uZHdTYW1wbGVTaXplID09IDAgJiYKCXBTdHJlYW0tPnNJbmZvLmR3TGVuZ3RoICE9IHBTdHJlYW0tPmxMYXN0RnJhbWUrMSkKICAgICAgRVJSKCJzdHJlYW0gJWx1IGxlbmd0aCBtaXNtYXRjaDogZHdMZW5ndGg9JWx1IGZvdW5kPSVsZFxuIiwKCSAgIG4sIHBTdHJlYW0tPnNJbmZvLmR3TGVuZ3RoLCBwU3RyZWFtLT5sTGFzdEZyYW1lKTsKICB9CgogIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9QYXJzZUluZGV4KElBVklGaWxlSW1wbCAqVGhpcywgQVZJSU5ERVhFTlRSWSAqbHAsCgkJCQkgIExPTkcgY291bnQsIERXT1JEIHBvcywgQk9PTCAqYkFic29sdXRlKQp7CiAgaWYgKGxwID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICBmb3IgKDsgY291bnQgPiAwOyBjb3VudC0tLCBscCsrKSB7CiAgICBXT1JEIG5TdHJlYW0gPSBTdHJlYW1Gcm9tRk9VUkNDKGxwLT5ja2lkKTsKCiAgICBpZiAobHAtPmNraWQgPT0gbGlzdHR5cGVBVklSRUNPUkQgfHwgblN0cmVhbSA9PSAweDdGKQogICAgICBjb250aW51ZTsgLyogc2tpcCB0aGVzZSAqLwoKICAgIGlmIChuU3RyZWFtID4gVGhpcy0+ZkluZm8uZHdTdHJlYW1zKQogICAgICByZXR1cm4gQVZJRVJSX0JBREZPUk1BVDsKCiAgICBpZiAoKmJBYnNvbHV0ZSA9PSBUUlVFICYmIGxwLT5kd0NodW5rT2Zmc2V0IDwgVGhpcy0+ZHdNb3ZpQ2h1bmtQb3MpCiAgICAgICpiQWJzb2x1dGUgPSBGQUxTRTsKCiAgICBpZiAoKmJBYnNvbHV0ZSkKICAgICAgbHAtPmR3Q2h1bmtPZmZzZXQgKz0gc2l6ZW9mKERXT1JEKTsKICAgIGVsc2UKICAgICAgbHAtPmR3Q2h1bmtPZmZzZXQgKz0gcG9zOwoKICAgIGlmIChGQUlMRUQoQVZJRklMRV9BZGRGcmFtZShUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV0sIGxwLT5ja2lkLCBscC0+ZHdDaHVua0xlbmd0aCwgbHAtPmR3Q2h1bmtPZmZzZXQsIGxwLT5kd0ZsYWdzKSkpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogIH0KCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9SZWFkQmxvY2soSUFWSVN0cmVhbUltcGwgKlRoaXMsIERXT1JEIHBvcywKCQkJCSBMUFZPSUQgYnVmZmVyLCBMT05HIHNpemUpCnsKICAvKiBwcmUtY29uZGl0aW9ucyAqLwogIGFzc2VydChUaGlzICE9IE5VTEwpOwogIGFzc2VydChUaGlzLT5wYWYgIT0gTlVMTCk7CiAgYXNzZXJ0KFRoaXMtPnBhZi0+aG1taW8gIT0gTlVMTCk7CiAgYXNzZXJ0KFRoaXMtPnNJbmZvLmR3U3RhcnQgPD0gcG9zICYmIHBvcyA8IFRoaXMtPnNJbmZvLmR3TGVuZ3RoKTsKICBhc3NlcnQocG9zIDw9IFRoaXMtPmxMYXN0RnJhbWUpOwoKICAvKiBzaG91bGQgd2UgcmVhZCBhcyBtdWNoIGFzIGJsb2NrIGdpdmVzIHVzPyAqLwogIGlmIChzaXplID09IDAgfHwgc2l6ZSA+IFRoaXMtPmlkeEZyYW1lc1twb3NdLmR3Q2h1bmtMZW5ndGgpCiAgICBzaXplID0gVGhpcy0+aWR4RnJhbWVzW3Bvc10uZHdDaHVua0xlbmd0aDsKCiAgLyogcmVhZCBpbnRvIG91dCBvd24gYnVmZmVyIG9yIGdpdmVuIG9uZT8gKi8KICBpZiAoYnVmZmVyID09IE5VTEwpIHsKICAgIC8qIHdlIGFsc28gcmVhZCB0aGUgY2h1bmsgKi8KICAgIHNpemUgKz0gMiAqIHNpemVvZihEV09SRCk7CgogICAgLyogY2hlY2sgdGhhdCBidWZmZXIgaXMgYmlnIGVub3VnaCAtLSBkb24ndCB0cnVzdCBkd1N1Z2dlc3RlZEJ1ZmZlclNpemUgKi8KICAgIGlmIChUaGlzLT5scEJ1ZmZlciA9PSBOVUxMIHx8IHNpemUgPCBUaGlzLT5jYkJ1ZmZlcikgewogICAgICBEV09SRCBtYXhTaXplID0gbWF4KHNpemUsIFRoaXMtPnNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSk7CgogICAgICBpZiAoVGhpcy0+bHBCdWZmZXIgPT0gTlVMTCkKCVRoaXMtPmxwQnVmZmVyID0gKExQRFdPUkQpR2xvYmFsQWxsb2NQdHIoR01FTV9NT1ZFQUJMRSwgbWF4U2l6ZSk7CiAgICAgIGVsc2UKCVRoaXMtPmxwQnVmZmVyID0KCSAgKExQRFdPUkQpR2xvYmFsUmVBbGxvY1B0cihUaGlzLT5scEJ1ZmZlciwgbWF4U2l6ZSwgR01FTV9NT1ZFQUJMRSk7CiAgICAgIGlmIChUaGlzLT5scEJ1ZmZlciA9PSBOVUxMKQoJcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgICAgIFRoaXMtPmNiQnVmZmVyID0gbWF4KHNpemUsIFRoaXMtPnNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSk7CiAgICB9CgogICAgLyogbm93IHJlYWQgdGhlIGNvbXBsZXRlIGNodW5rIGludG8gb3VyIGJ1ZmZlciAqLwogICAgaWYgKG1taW9TZWVrKFRoaXMtPnBhZi0+aG1taW8sIFRoaXMtPmlkeEZyYW1lc1twb3NdLmR3Q2h1bmtPZmZzZXQsIFNFRUtfU0VUKSA9PSAtMSkKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKICAgIGlmIChtbWlvUmVhZChUaGlzLT5wYWYtPmhtbWlvLCAoSFBTVFIpVGhpcy0+bHBCdWZmZXIsIHNpemUpICE9IHNpemUpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CgogICAgLyogY2hlY2sgaWYgaXQgd2FzIHRoZSBjb3JyZWN0IGJsb2NrIHdoaWNoIHdlIGhhdmUgcmVhZCAqLwogICAgaWYgKFRoaXMtPmxwQnVmZmVyWzBdICE9IFRoaXMtPmlkeEZyYW1lc1twb3NdLmNraWQgfHwKCVRoaXMtPmxwQnVmZmVyWzFdICE9IFRoaXMtPmlkeEZyYW1lc1twb3NdLmR3Q2h1bmtMZW5ndGgpIHsKICAgICAgRVJSKCI6IGJsb2NrICVsZCBub3QgZm91bmQgYXQgMHglMDhsWFxuIiwgcG9zLCBUaGlzLT5pZHhGcmFtZXNbcG9zXS5kd0NodW5rT2Zmc2V0KTsKICAgICAgRVJSKCI6IEluZGV4IHNheXM6ICclNC40cycoMHglMDhsWCkgc2l6ZSAweCUwOGxYXG4iLAoJICAoY2hhciopJlRoaXMtPmlkeEZyYW1lc1twb3NdLmNraWQsIFRoaXMtPmlkeEZyYW1lc1twb3NdLmNraWQsCgkgIFRoaXMtPmlkeEZyYW1lc1twb3NdLmR3Q2h1bmtMZW5ndGgpOwogICAgICBFUlIoIjogRGF0YSAgc2F5czogJyU0LjRzJygweCUwOGxYKSBzaXplIDB4JTA4bFhcbiIsCgkgIChjaGFyKikmVGhpcy0+bHBCdWZmZXJbMF0sIFRoaXMtPmxwQnVmZmVyWzBdLCBUaGlzLT5scEJ1ZmZlclsxXSk7CiAgICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CiAgICB9CiAgfSBlbHNlIHsKICAgIGlmIChtbWlvU2VlayhUaGlzLT5wYWYtPmhtbWlvLCBUaGlzLT5pZHhGcmFtZXNbcG9zXS5kd0NodW5rT2Zmc2V0ICsgMiAqIHNpemVvZihEV09SRCksIFNFRUtfU0VUKSA9PSAtMSkKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKICAgIGlmIChtbWlvUmVhZChUaGlzLT5wYWYtPmhtbWlvLCAoSFBTVFIpYnVmZmVyLCBzaXplKSAhPSBzaXplKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwogIH0KCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIHZvaWQgICAgQVZJRklMRV9TYW1wbGVzVG9CbG9jayhJQVZJU3RyZWFtSW1wbCAqVGhpcywgTFBMT05HIHBvcywKCQkJCSAgICAgIExQTE9ORyBvZmZzZXQpCnsKICBEV09SRCBibG9jazsKCiAgLyogcHJlLWNvbmRpdGlvbnMgKi8KICBhc3NlcnQoVGhpcyAhPSBOVUxMKTsKICBhc3NlcnQocG9zICE9IE5VTEwpOwogIGFzc2VydChvZmZzZXQgIT0gTlVMTCk7CiAgYXNzZXJ0KFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSAhPSAwKTsKICBhc3NlcnQoKnBvcyA+PSBUaGlzLT5zSW5mby5kd1N0YXJ0KTsKCiAgLyogY29udmVydCBzdGFydCBzYW1wbGUgdG8gc3RhcnQgYnl0ZXMgKi8KICAoKm9mZnNldCkgID0gKCpwb3MpIC0gVGhpcy0+c0luZm8uZHdTdGFydDsKICAoKm9mZnNldCkgKj0gVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplOwoKICAvKiBjb252ZXJ0IGJ5dGVzIHRvIGJsb2NrIG51bWJlciAqLwogIGZvciAoYmxvY2sgPSAwOyBibG9jayA8PSBUaGlzLT5sTGFzdEZyYW1lOyBibG9jaysrKSB7CiAgICBpZiAoVGhpcy0+aWR4RnJhbWVzW2Jsb2NrXS5kd0NodW5rTGVuZ3RoIDw9ICpvZmZzZXQpCiAgICAgICgqb2Zmc2V0KSAtPSBUaGlzLT5pZHhGcmFtZXNbYmxvY2tdLmR3Q2h1bmtMZW5ndGg7CiAgICBlbHNlCiAgICAgIGJyZWFrOwogIH0KCiAgKnBvcyA9IGJsb2NrOwp9CgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX1NhdmVGaWxlKElBVklGaWxlSW1wbCAqVGhpcykKewogIE1haW5BVklIZWFkZXIgICBNYWluQVZJSGRyOwogIElBVklTdHJlYW1JbXBsKiBwU3RyZWFtOwogIE1NQ0tJTkZPICAgICAgICBja1JJRkY7CiAgTU1DS0lORk8gICAgICAgIGNrTElTVDE7CiAgTU1DS0lORk8gICAgICAgIGNrTElTVDI7CiAgTU1DS0lORk8gICAgICAgIGNrOwogIERXT1JEICAgICAgICAgICBuU3RyZWFtOwogIERXT1JEICAgICAgICAgICBkd1BvczsKICBIUkVTVUxUICAgICAgICAgaHI7CgogIC8qIGluaXRpYWxpemUgc29tZSB0aGluZ3MgKi8KICBpZiAoVGhpcy0+ZHdNb3ZpQ2h1bmtQb3MgPT0gMCkKICAgIEFWSUZJTEVfQ29tcHV0ZU1vdmlTdGFydChUaGlzKTsKCiAgLyogd3JpdHRlbiBvbmUgcmVjb3JkIHRvIG11Y2g/ICovCiAgaWYgKFRoaXMtPmNrTGFzdFJlY29yZC5kd0ZsYWdzICYgTU1JT19ESVJUWSkgewogICAgVGhpcy0+ZHdOZXh0RnJhbWVQb3MgLT0gMyAqIHNpemVvZihEV09SRCk7CiAgICBpZiAoVGhpcy0+bklkeFJlY29yZHMgPiAwKQogICAgICBUaGlzLT5uSWR4UmVjb3Jkcy0tOwogIH0KCiAgQVZJRklMRV9VcGRhdGVJbmZvKFRoaXMpOwoKICBhc3NlcnQoVGhpcy0+ZkluZm8uZHdTY2FsZSAhPSAwKTsKCiAgbWVtc2V0KCZNYWluQVZJSGRyLCAwLCBzaXplb2YoTWFpbkFWSUhkcikpOwogIE1haW5BVklIZHIuZHdNaWNyb1NlY1BlckZyYW1lICAgID0gTXVsRGl2KFRoaXMtPmZJbmZvLmR3UmF0ZSwgMTAwMDAwMCwKCQkJCQkgICAgVGhpcy0+ZkluZm8uZHdTY2FsZSk7CiAgTWFpbkFWSUhkci5kd01heEJ5dGVzUGVyU2VjICAgICAgPSBUaGlzLT5mSW5mby5kd01heEJ5dGVzUGVyU2VjOwogIE1haW5BVklIZHIuZHdQYWRkaW5nR3JhbnVsYXJpdHkgID0gQVZJX0hFQURFUlNJWkU7CiAgTWFpbkFWSUhkci5kd0ZsYWdzICAgICAgICAgICAgICAgPSBUaGlzLT5mSW5mby5kd0ZsYWdzOwogIE1haW5BVklIZHIuZHdUb3RhbEZyYW1lcyAgICAgICAgID0gVGhpcy0+ZkluZm8uZHdMZW5ndGg7CiAgTWFpbkFWSUhkci5kd0luaXRpYWxGcmFtZXMgICAgICAgPSAwOwogIE1haW5BVklIZHIuZHdTdHJlYW1zICAgICAgICAgICAgID0gVGhpcy0+ZkluZm8uZHdTdHJlYW1zOwogIE1haW5BVklIZHIuZHdTdWdnZXN0ZWRCdWZmZXJTaXplID0gVGhpcy0+ZkluZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplOwogIE1haW5BVklIZHIuZHdXaWR0aCAgICAgICAgICAgICAgID0gVGhpcy0+ZkluZm8uZHdXaWR0aDsKICBNYWluQVZJSGRyLmR3SGVpZ2h0ICAgICAgICAgICAgICA9IFRoaXMtPmZJbmZvLmR3SGVpZ2h0OwogIE1haW5BVklIZHIuZHdJbml0aWFsRnJhbWVzICAgICAgID0gVGhpcy0+ZHdJbml0aWFsRnJhbWVzOwoKICAvKiBub3cgYmVnaW4gd3JpdGluZyAuLi4gKi8KICBtbWlvU2VlayhUaGlzLT5obW1pbywgMCwgU0VFS19TRVQpOwoKICAvKiBSSUZGIGNodW5rICovCiAgY2tSSUZGLmNrc2l6ZSAgPSAwOwogIGNrUklGRi5mY2NUeXBlID0gZm9ybXR5cGVBVkk7CiAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJmNrUklGRiwgTU1JT19DUkVBVEVSSUZGKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogIC8qIEFWSSBoZWFkZXJsaXN0ICovCiAgY2tMSVNUMS5ja3NpemUgID0gMDsKICBja0xJU1QxLmZjY1R5cGUgPSBsaXN0dHlwZUFWSUhFQURFUjsKICBpZiAobW1pb0NyZWF0ZUNodW5rKFRoaXMtPmhtbWlvLCAmY2tMSVNUMSwgTU1JT19DUkVBVEVMSVNUKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogIC8qIE1haW5BVklIZWFkZXIgKi8KICBjay5ja2lkICAgID0gY2tpZEFWSU1BSU5IRFI7CiAgY2suY2tzaXplICA9IHNpemVvZihNYWluQVZJSGRyKTsKICBjay5mY2NUeXBlID0gMDsKICBpZiAobW1pb0NyZWF0ZUNodW5rKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICBpZiAobW1pb1dyaXRlKFRoaXMtPmhtbWlvLCAoSFBTVFIpJk1haW5BVklIZHIsIGNrLmNrc2l6ZSkgIT0gY2suY2tzaXplKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAvKiB3cml0ZSB0aGUgaGVhZGVycyBvZiBlYWNoIHN0cmVhbSBpbnRvIGEgc2VwYXJhdGUgc3RyZWFtaGVhZGVyIGxpc3QgKi8KICBmb3IgKG5TdHJlYW0gPSAwOyBuU3RyZWFtIDwgVGhpcy0+ZkluZm8uZHdTdHJlYW1zOyBuU3RyZWFtKyspIHsKICAgIEFWSVN0cmVhbUhlYWRlciBzdHJIZHI7CgogICAgcFN0cmVhbSA9IFRoaXMtPnBwU3RyZWFtc1tuU3RyZWFtXTsKCiAgICAvKiBiZWdpbiB0aGUgbmV3IHN0cmVhbWhlYWRlciBsaXN0ICovCiAgICBja0xJU1QyLmNrc2l6ZSAgPSAwOwogICAgY2tMSVNUMi5mY2NUeXBlID0gbGlzdHR5cGVTVFJFQU1IRUFERVI7CiAgICBpZiAobW1pb0NyZWF0ZUNodW5rKFRoaXMtPmhtbWlvLCAmY2tMSVNUMiwgTU1JT19DUkVBVEVMSVNUKSAhPSBTX09LKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgICAvKiBjcmVhdGUgYW4gQVZJU3RyZWFtSGVhZGVyIGZyb20gdGhlIEFWU1RSRUFNSU5GTyAqLwogICAgc3RySGRyLmZjY1R5cGUgICAgICAgICAgICAgICA9IHBTdHJlYW0tPnNJbmZvLmZjY1R5cGU7CiAgICBzdHJIZHIuZmNjSGFuZGxlciAgICAgICAgICAgID0gcFN0cmVhbS0+c0luZm8uZmNjSGFuZGxlcjsKICAgIHN0ckhkci5kd0ZsYWdzICAgICAgICAgICAgICAgPSBwU3RyZWFtLT5zSW5mby5kd0ZsYWdzOwogICAgc3RySGRyLndQcmlvcml0eSAgICAgICAgICAgICA9IHBTdHJlYW0tPnNJbmZvLndQcmlvcml0eTsKICAgIHN0ckhkci53TGFuZ3VhZ2UgICAgICAgICAgICAgPSBwU3RyZWFtLT5zSW5mby53TGFuZ3VhZ2U7CiAgICBzdHJIZHIuZHdJbml0aWFsRnJhbWVzICAgICAgID0gcFN0cmVhbS0+c0luZm8uZHdJbml0aWFsRnJhbWVzOwogICAgc3RySGRyLmR3U2NhbGUgICAgICAgICAgICAgICA9IHBTdHJlYW0tPnNJbmZvLmR3U2NhbGU7CiAgICBzdHJIZHIuZHdSYXRlICAgICAgICAgICAgICAgID0gcFN0cmVhbS0+c0luZm8uZHdSYXRlOwogICAgc3RySGRyLmR3U3RhcnQgICAgICAgICAgICAgICA9IHBTdHJlYW0tPnNJbmZvLmR3U3RhcnQ7CiAgICBzdHJIZHIuZHdMZW5ndGggICAgICAgICAgICAgID0gcFN0cmVhbS0+c0luZm8uZHdMZW5ndGg7CiAgICBzdHJIZHIuZHdTdWdnZXN0ZWRCdWZmZXJTaXplID0gcFN0cmVhbS0+c0luZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplOwogICAgc3RySGRyLmR3UXVhbGl0eSAgICAgICAgICAgICA9IHBTdHJlYW0tPnNJbmZvLmR3UXVhbGl0eTsKICAgIHN0ckhkci5kd1NhbXBsZVNpemUgICAgICAgICAgPSBwU3RyZWFtLT5zSW5mby5kd1NhbXBsZVNpemU7CiAgICBzdHJIZHIucmNGcmFtZS5sZWZ0ICAgICAgICAgID0gcFN0cmVhbS0+c0luZm8ucmNGcmFtZS5sZWZ0OwogICAgc3RySGRyLnJjRnJhbWUudG9wICAgICAgICAgICA9IHBTdHJlYW0tPnNJbmZvLnJjRnJhbWUudG9wOwogICAgc3RySGRyLnJjRnJhbWUucmlnaHQgICAgICAgICA9IHBTdHJlYW0tPnNJbmZvLnJjRnJhbWUucmlnaHQ7CiAgICBzdHJIZHIucmNGcmFtZS5ib3R0b20gICAgICAgID0gcFN0cmVhbS0+c0luZm8ucmNGcmFtZS5ib3R0b207CgogICAgLyogbm93IHdyaXRlIHRoZSBBVklTdHJlYW1IZWFkZXIgKi8KICAgIGNrLmNraWQgICA9IGNraWRTVFJFQU1IRUFERVI7CiAgICBjay5ja3NpemUgPSBzaXplb2Yoc3RySGRyKTsKICAgIGlmIChtbWlvQ3JlYXRlQ2h1bmsoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICBpZiAobW1pb1dyaXRlKFRoaXMtPmhtbWlvLCAoSFBTVFIpJnN0ckhkciwgY2suY2tzaXplKSAhPSBjay5ja3NpemUpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogICAgLyogLi4uIHRoZSBob3BlZnVsbHkgZXZlciBwcmVzZW50IHN0cmVhbWZvcm1hdCAuLi4gKi8KICAgIGNrLmNraWQgICA9IGNraWRTVFJFQU1GT1JNQVQ7CiAgICBjay5ja3NpemUgPSBwU3RyZWFtLT5jYkZvcm1hdDsKICAgIGlmIChtbWlvQ3JlYXRlQ2h1bmsoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICBpZiAocFN0cmVhbS0+bHBGb3JtYXQgIT0gTlVMTCAmJiBjay5ja3NpemUgPiAwKSB7CiAgICAgIGlmIChtbWlvV3JpdGUoVGhpcy0+aG1taW8sIChIUFNUUilwU3RyZWFtLT5scEZvcm1hdCwgY2suY2tzaXplKSAhPSBjay5ja3NpemUpCglyZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgIH0KICAgIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAgIC8qIC4uLiBzb21lIG9wdGlvbmFsIGV4aXN0aW5nIGhhbmRsZXIgZGF0YSAuLi4gKi8KICAgIGlmIChwU3RyZWFtLT5scEhhbmRsZXJEYXRhICE9IE5VTEwgJiYgcFN0cmVhbS0+Y2JIYW5kbGVyRGF0YSA+IDApIHsKICAgICAgY2suY2tpZCAgID0gY2tpZFNUUkVBTUhBTkRMRVJEQVRBOwogICAgICBjay5ja3NpemUgPSBwU3RyZWFtLT5jYkhhbmRsZXJEYXRhOwogICAgICBpZiAobW1pb0NyZWF0ZUNodW5rKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCglyZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgICAgaWYgKG1taW9Xcml0ZShUaGlzLT5obW1pbywgKEhQU1RSKXBTdHJlYW0tPmxwSGFuZGxlckRhdGEsIGNrLmNrc2l6ZSkgIT0gY2suY2tzaXplKQoJcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICAgIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCglyZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgIH0KCiAgICAvKiAuLi4gc29tZSBvcHRpb25hbCBhZGRpdGlvbmFsIGV4dHJhIGNodW5rIGZvciB0aGlzIHN0cmVhbSAuLi4gKi8KICAgIGlmIChwU3RyZWFtLT5leHRyYS5scCAhPSBOVUxMICYmIHBTdHJlYW0tPmV4dHJhLmNiID4gMCkgewogICAgICAvKiB0aGUgY2h1bmsgaGVhZGVyKHMpIGFyZSBhbHJlYWR5IGluIHRoZSBzdHJ1Y3V0dXJlICovCiAgICAgIGlmIChtbWlvV3JpdGUoVGhpcy0+aG1taW8sIChIUFNUUilwU3RyZWFtLT5leHRyYS5scCwgcFN0cmVhbS0+ZXh0cmEuY2IpICE9IHBTdHJlYW0tPmV4dHJhLmNiKQoJcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICB9CgogICAgLyogLi4uIGFuIG9wdGlvbmFsIG5hbWUgZm9yIHRoaXMgc3RyZWFtIC4uLiAqLwogICAgaWYgKGxzdHJsZW5XKHBTdHJlYW0tPnNJbmZvLnN6TmFtZSkgPiAwKSB7CiAgICAgIExQU1RSIHN0cjsKCiAgICAgIGNrLmNraWQgICA9IGNraWRTVFJFQU1OQU1FOwogICAgICBjay5ja3NpemUgPSBsc3RybGVuVyhwU3RyZWFtLT5zSW5mby5zek5hbWUpICsgMTsKICAgICAgaWYgKGNrLmNrc2l6ZSAmIDEpIC8qIGFsaWduICovCgljay5ja3NpemUrKzsKICAgICAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQoJcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogICAgICAvKiB0aGUgc3RyZWFtbmFtZSBtdXN0IGJlIHNhdmVkIGluIEFTQ0lJIG5vdCBVbmljb2RlICovCiAgICAgIHN0ciA9IChMUFNUUilMb2NhbEFsbG9jKExQVFIsIGNrLmNrc2l6ZSk7CiAgICAgIGlmIChzdHIgPT0gTlVMTCkKCXJldHVybiBBVklFUlJfTUVNT1JZOwogICAgICBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgcFN0cmVhbS0+c0luZm8uc3pOYW1lLCAtMSwgc3RyLAoJCQkgIGNrLmNrc2l6ZSwgTlVMTCwgTlVMTCk7CgogICAgICBpZiAobW1pb1dyaXRlKFRoaXMtPmhtbWlvLCAoSFBTVFIpc3RyLCBjay5ja3NpemUpICE9IGNrLmNrc2l6ZSkgewoJTG9jYWxGcmVlKChITE9DQUwpc3RyKTsJCglyZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgICAgfQoKICAgICAgTG9jYWxGcmVlKChITE9DQUwpc3RyKTsKICAgICAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKCXJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgfQoKICAgIC8qIGNsb3NlIHN0cmVhbWhlYWRlciBsaXN0IGZvciB0aGlzIHN0cmVhbSAqLwogICAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZja0xJU1QyLCAwKSAhPSBTX09LKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICB9IC8qIGZvciAoMCA8PSBuU3RyZWFtIDwgTWFpbkFWSUhkci5kd1N0cmVhbXMpICovCgogIC8qIGNsb3NlIHRoZSBhdmloZWFkZXIgbGlzdCAqLwogIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2tMSVNUMSwgMCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAvKiBjaGVjayBmb3IgcGFkZGluZyB0byBwcmUtZ3Vlc3NlZCAnbW92aSctY2h1bmsgcG9zaXRpb24gKi8KICBkd1BvcyA9IGNrTElTVDEuZHdEYXRhT2Zmc2V0ICsgY2tMSVNUMS5ja3NpemU7CiAgaWYgKFRoaXMtPmR3TW92aUNodW5rUG9zIC0gMiAqIHNpemVvZihEV09SRCkgPiBkd1BvcykgewogICAgY2suY2tpZCAgID0gY2tpZEFWSVBBRERJTkc7CiAgICBjay5ja3NpemUgPSBUaGlzLT5kd01vdmlDaHVua1BvcyAtIGR3UG9zIC0gNCAqIHNpemVvZihEV09SRCk7CiAgICBhc3NlcnQoKExPTkcpY2suY2tzaXplID49IDApOwoKICAgIGlmIChtbWlvQ3JlYXRlQ2h1bmsoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICBpZiAobW1pb1NlZWsoVGhpcy0+aG1taW8sIGNrLmNrc2l6ZSwgU0VFS19DVVIpID09IC0xKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogIH0KCiAgLyogbm93IHdyaXRlIHRoZSAnbW92aScgY2h1bmsgKi8KICBtbWlvU2VlayhUaGlzLT5obW1pbywgVGhpcy0+ZHdNb3ZpQ2h1bmtQb3MgLSAyICogc2l6ZW9mKERXT1JEKSwgU0VFS19TRVQpOwogIGNrTElTVDEuY2tzaXplICA9IDA7CiAgY2tMSVNUMS5mY2NUeXBlID0gbGlzdHR5cGVBVklNT1ZJRTsKICBpZiAobW1pb0NyZWF0ZUNodW5rKFRoaXMtPmhtbWlvLCAmY2tMSVNUMSwgTU1JT19DUkVBVEVMSVNUKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgaWYgKG1taW9TZWVrKFRoaXMtPmhtbWlvLCBUaGlzLT5kd05leHRGcmFtZVBvcywgU0VFS19TRVQpID09IC0xKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZja0xJU1QxLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogIC8qIHdyaXRlICdpZHgxJyBjaHVuayAqLwogIGhyID0gQVZJRklMRV9TYXZlSW5kZXgoVGhpcyk7CiAgaWYgKEZBSUxFRChocikpCiAgICByZXR1cm4gaHI7CgogIC8qIHdyaXRlIG9wdGlvbmFsIGV4dHJhIGZpbGUgY2h1bmtzICovCiAgaWYgKFRoaXMtPmZpbGVleHRyYS5scCAhPSBOVUxMICYmIFRoaXMtPmZpbGVleHRyYS5jYiA+IDApIHsKICAgIC8qIGFzIGZvciB0aGUgc3RyZWFtcywgYXJlIHRoZSBjaHVuayBoZWFkZXIocykgaW4gdGhlIHN0cnVjdHVyZSAqLwogICAgaWYgKG1taW9Xcml0ZShUaGlzLT5obW1pbywgKEhQU1RSKVRoaXMtPmZpbGVleHRyYS5scCwgVGhpcy0+ZmlsZWV4dHJhLmNiKSAhPSBUaGlzLT5maWxlZXh0cmEuY2IpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogIH0KCiAgLyogY2xvc2UgUklGRiBjaHVuayAqLwogIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2tSSUZGLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogIC8qIGFkZCBzb21lIEpVTksgYXQgZW5kIGZvciBiYWQgcGFyc2VycyAqLwogIG1lbXNldCgmY2tSSUZGLCAwLCBzaXplb2YoY2tSSUZGKSk7CiAgbW1pb1dyaXRlKFRoaXMtPmhtbWlvLCAoSFBTVFIpJmNrUklGRiwgc2l6ZW9mKGNrUklGRikpOwogIG1taW9GbHVzaChUaGlzLT5obW1pbywgMCk7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfU2F2ZUluZGV4KElBVklGaWxlSW1wbCAqVGhpcykKewogIElBVklTdHJlYW1JbXBsICpwU3RyZWFtOwogIEFWSUlOREVYRU5UUlkgICBpZHg7CiAgTU1DS0lORk8gICAgICAgIGNrOwogIERXT1JEICAgICAgICAgICBuU3RyZWFtOwogIExPTkcgICAgICAgICAgICBuOwoKICBjay5ja2lkICAgPSBja2lkQVZJTkVXSU5ERVg7CiAgY2suY2tzaXplID0gMDsKICBpZiAobW1pb0NyZWF0ZUNodW5rKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgaWYgKFRoaXMtPmZJbmZvLmR3RmxhZ3MgJiBBVklGSUxFSU5GT19JU0lOVEVSTEVBVkVEKSB7CiAgICAvKiBpcyBpbnRlcmxlYXZlZCAtLSB3cml0ZSBibG9jayBvZiBjb3Jlc3BvbmRpbmcgZnJhbWVzICovCiAgICBMT05HIGxJbml0aWFsRnJhbWVzID0gMDsKICAgIExPTkcgc3RlcHNpemU7CiAgICBMT05HIGk7CgogICAgaWYgKFRoaXMtPnBwU3RyZWFtc1swXS0+c0luZm8uZHdTYW1wbGVTaXplID09IDApCiAgICAgIHN0ZXBzaXplID0gMTsKICAgIGVsc2UKICAgICAgc3RlcHNpemUgPSBBVklTdHJlYW1UaW1lVG9TYW1wbGUoKFBBVklTVFJFQU0pVGhpcy0+cHBTdHJlYW1zWzBdLCAxMDAwMDAwKTsKCiAgICBhc3NlcnQoc3RlcHNpemUgPiAwKTsKCiAgICBmb3IgKG5TdHJlYW0gPSAwOyBuU3RyZWFtIDwgVGhpcy0+ZkluZm8uZHdTdHJlYW1zOyBuU3RyZWFtKyspIHsKICAgICAgaWYgKGxJbml0aWFsRnJhbWVzIDwgVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dLT5zSW5mby5kd0luaXRpYWxGcmFtZXMpCglsSW5pdGlhbEZyYW1lcyA9IFRoaXMtPnBwU3RyZWFtc1tuU3RyZWFtXS0+c0luZm8uZHdJbml0aWFsRnJhbWVzOwogICAgfQoKICAgIGZvciAoaSA9IC1sSW5pdGlhbEZyYW1lczsgaSA8IChMT05HKVRoaXMtPmZJbmZvLmR3TGVuZ3RoIC0gbEluaXRpYWxGcmFtZXM7CgkgaSArPSBzdGVwc2l6ZSkgewogICAgICBEV09SRCBuRnJhbWUgPSBsSW5pdGlhbEZyYW1lcyArIGk7CgogICAgICBhc3NlcnQobkZyYW1lIDwgVGhpcy0+bklkeFJlY29yZHMpOwoKICAgICAgaWR4LmNraWQgICAgICAgICAgPSBsaXN0dHlwZUFWSVJFQ09SRDsKICAgICAgaWR4LmR3RmxhZ3MgICAgICAgPSBBVklJRl9MSVNUOwogICAgICBpZHguZHdDaHVua0xlbmd0aCA9IFRoaXMtPmlkeFJlY29yZHNbbkZyYW1lXS5kd0NodW5rTGVuZ3RoOwogICAgICBpZHguZHdDaHVua09mZnNldCA9IFRoaXMtPmlkeFJlY29yZHNbbkZyYW1lXS5kd0NodW5rT2Zmc2V0CgktIFRoaXMtPmR3TW92aUNodW5rUG9zOwogICAgICBpZiAobW1pb1dyaXRlKFRoaXMtPmhtbWlvLCAoSFBTVFIpJmlkeCwgc2l6ZW9mKGlkeCkpICE9IHNpemVvZihpZHgpKQoJcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogICAgICBmb3IgKG5TdHJlYW0gPSAwOyBuU3RyZWFtIDwgVGhpcy0+ZkluZm8uZHdTdHJlYW1zOyBuU3RyZWFtKyspIHsKCXBTdHJlYW0gPSBUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV07CgoJLyogaGVhdmUgd2UgcmVhY2hlZCBzdGFydCBvZiB0aGlzIHN0cmVhbT8gKi8KCWlmICgtKExPTkcpcFN0cmVhbS0+c0luZm8uZHdJbml0aWFsRnJhbWVzID4gaSkKCSAgY29udGludWU7CgoJaWYgKHBTdHJlYW0tPnNJbmZvLmR3SW5pdGlhbEZyYW1lcyA8IGxJbml0aWFsRnJhbWVzKQoJICBuRnJhbWUgLT0gKGxJbml0aWFsRnJhbWVzIC0gcFN0cmVhbS0+c0luZm8uZHdJbml0aWFsRnJhbWVzKTsKCgkvKiByZWFjaGVkIGVuZCBvZiB0aGlzIHN0cmVhbT8gKi8KCWlmIChwU3RyZWFtLT5sTGFzdEZyYW1lIDw9IG5GcmFtZSkKCSAgY29udGludWU7CgoJaWYgKChwU3RyZWFtLT5zSW5mby5kd0ZsYWdzICYgQVZJU1RSRUFNSU5GT19GT1JNQVRDSEFOR0VTKSAmJgoJICAgIHBTdHJlYW0tPnNJbmZvLmR3Rm9ybWF0Q2hhbmdlQ291bnQgIT0gMCAmJgoJICAgIHBTdHJlYW0tPmlkeEZtdENoYW5nZXMgIT0gTlVMTCkgewoJICBEV09SRCBwb3M7CgoJICBmb3IgKHBvcyA9IDA7IHBvcyA8IHBTdHJlYW0tPnNJbmZvLmR3Rm9ybWF0Q2hhbmdlQ291bnQ7IHBvcysrKSB7CgkgICAgaWYgKHBTdHJlYW0tPmlkeEZtdENoYW5nZXNbcG9zXS5ja2lkID09IG5GcmFtZSkgewoJICAgICAgaWR4LmR3RmxhZ3MgPSBBVklJRl9OT1RJTUU7CgkgICAgICBpZHguY2tpZCAgICA9IE1BS0VBVklDS0lEKGNrdHlwZVBBTGNoYW5nZSwgcFN0cmVhbS0+blN0cmVhbSk7CgkgICAgICBpZHguZHdDaHVua0xlbmd0aCA9IHBTdHJlYW0tPmlkeEZtdENoYW5nZXNbcG9zXS5kd0NodW5rTGVuZ3RoOwoJICAgICAgaWR4LmR3Q2h1bmtPZmZzZXQgPSBwU3RyZWFtLT5pZHhGbXRDaGFuZ2VzW3Bvc10uZHdDaHVua09mZnNldAoJCS0gVGhpcy0+ZHdNb3ZpQ2h1bmtQb3M7CgoJICAgICAgaWYgKG1taW9Xcml0ZShUaGlzLT5obW1pbywgKEhQU1RSKSZpZHgsIHNpemVvZihpZHgpKSAhPSBzaXplb2YoaWR4KSkKCQlyZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCSAgICAgIGJyZWFrOwoJICAgIH0KCSAgfQoJfSAvKiBpZiBoYXZlIGZvcm1hdGNoYW5nZXMgKi8KCglpZHguY2tpZCAgICAgICAgICA9IHBTdHJlYW0tPmlkeEZyYW1lc1tuRnJhbWVdLmNraWQ7CglpZHguZHdGbGFncyAgICAgICA9IHBTdHJlYW0tPmlkeEZyYW1lc1tuRnJhbWVdLmR3RmxhZ3M7CglpZHguZHdDaHVua0xlbmd0aCA9IHBTdHJlYW0tPmlkeEZyYW1lc1tuRnJhbWVdLmR3Q2h1bmtMZW5ndGg7CglpZHguZHdDaHVua09mZnNldCA9IHBTdHJlYW0tPmlkeEZyYW1lc1tuRnJhbWVdLmR3Q2h1bmtPZmZzZXQKCSAgLSBUaGlzLT5kd01vdmlDaHVua1BvczsKCWlmIChtbWlvV3JpdGUoVGhpcy0+aG1taW8sIChIUFNUUikmaWR4LCBzaXplb2YoaWR4KSkgIT0gc2l6ZW9mKGlkeCkpCgkgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgICB9CiAgICB9CiAgfSBlbHNlIHsKICAgIC8qIG5vdCBpbnRlcmxlYXZlZCAtLSB3cml0ZSBpbmRleCBmb3IgZWFjaCBzdHJlYW0gYXQgb25jZSAqLwogICAgZm9yIChuU3RyZWFtID0gMDsgblN0cmVhbSA8IFRoaXMtPmZJbmZvLmR3U3RyZWFtczsgblN0cmVhbSsrKSB7CiAgICAgIHBTdHJlYW0gPSBUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV07CgogICAgICBmb3IgKG4gPSAwOyBuIDw9IHBTdHJlYW0tPmxMYXN0RnJhbWU7IG4rKykgewoJaWYgKChwU3RyZWFtLT5zSW5mby5kd0ZsYWdzICYgQVZJU1RSRUFNSU5GT19GT1JNQVRDSEFOR0VTKSAmJgoJICAgIChwU3RyZWFtLT5zSW5mby5kd0Zvcm1hdENoYW5nZUNvdW50ICE9IDApKSB7CgkgIERXT1JEIHBvczsKCgkgIGZvciAocG9zID0gMDsgcG9zIDwgcFN0cmVhbS0+c0luZm8uZHdGb3JtYXRDaGFuZ2VDb3VudDsgcG9zKyspIHsKCSAgICBpZiAocFN0cmVhbS0+aWR4Rm10Q2hhbmdlc1twb3NdLmNraWQgPT0gbikgewoJICAgICAgaWR4LmR3RmxhZ3MgPSBBVklJRl9OT1RJTUU7CgkgICAgICBpZHguY2tpZCAgICA9IE1BS0VBVklDS0lEKGNrdHlwZVBBTGNoYW5nZSwgcFN0cmVhbS0+blN0cmVhbSk7CgkgICAgICBpZHguZHdDaHVua0xlbmd0aCA9IHBTdHJlYW0tPmlkeEZtdENoYW5nZXNbcG9zXS5kd0NodW5rTGVuZ3RoOwoJICAgICAgaWR4LmR3Q2h1bmtPZmZzZXQgPQoJCXBTdHJlYW0tPmlkeEZtdENoYW5nZXNbcG9zXS5kd0NodW5rT2Zmc2V0IC0gVGhpcy0+ZHdNb3ZpQ2h1bmtQb3M7CgkgICAgICBpZiAobW1pb1dyaXRlKFRoaXMtPmhtbWlvLCAoSFBTVFIpJmlkeCwgc2l6ZW9mKGlkeCkpICE9IHNpemVvZihpZHgpKQoJCXJldHVybiBBVklFUlJfRklMRVdSSVRFOwoJICAgICAgYnJlYWs7CgkgICAgfQoJICB9Cgl9IC8qIGlmIGhhdmUgZm9ybWF0Y2hhbmdlcyAqLwoKCWlkeC5ja2lkICAgICAgICAgID0gcFN0cmVhbS0+aWR4RnJhbWVzW25dLmNraWQ7CglpZHguZHdGbGFncyAgICAgICA9IHBTdHJlYW0tPmlkeEZyYW1lc1tuXS5kd0ZsYWdzOwoJaWR4LmR3Q2h1bmtMZW5ndGggPSBwU3RyZWFtLT5pZHhGcmFtZXNbbl0uZHdDaHVua0xlbmd0aDsKCWlkeC5kd0NodW5rT2Zmc2V0ID0gcFN0cmVhbS0+aWR4RnJhbWVzW25dLmR3Q2h1bmtPZmZzZXQKCSAgLSBUaGlzLT5kd01vdmlDaHVua1BvczsKCglpZiAobW1pb1dyaXRlKFRoaXMtPmhtbWlvLCAoSFBTVFIpJmlkeCwgc2l6ZW9mKGlkeCkpICE9IHNpemVvZihpZHgpKQoJICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgICAgfQogICAgfQogIH0gLyogaWYgbm90IGludGVybGVhdmVkICovCgogIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIFVMT05HICBBVklGSUxFX1NlYXJjaFN0cmVhbShJQVZJRmlsZUltcGwgKlRoaXMsIERXT1JEIGZjYywgTE9ORyBsU2tpcCkKewogIFVJTlQgaTsKICBVSU5UIG5TdHJlYW07CgogIC8qIHByZS1jb25kaXRpb24gKi8KICBhc3NlcnQobFNraXAgPj0gMCk7CgogIGlmIChmY2MgIT0gMCkgewogICAgLyogc2VhcmNoIHRoZSBudW1iZXIgb2YgdGhlIHNwZWNpZmllZCBzdHJlYW0gKi8KICAgIG5TdHJlYW0gPSAoVUxPTkcpLTE7CiAgICBmb3IgKGkgPSAwOyBpIDwgVGhpcy0+ZkluZm8uZHdTdHJlYW1zOyBpKyspIHsKICAgICAgYXNzZXJ0KFRoaXMtPnBwU3RyZWFtc1tpXSAhPSBOVUxMKTsKCiAgICAgIGlmIChUaGlzLT5wcFN0cmVhbXNbaV0tPnNJbmZvLmZjY1R5cGUgPT0gZmNjKSB7CglpZiAobFNraXAgPT0gMCkgewoJICBuU3RyZWFtID0gaTsKCSAgYnJlYWs7Cgl9IGVsc2UKCSAgbFNraXAtLTsKICAgICAgfQogICAgfQogIH0gZWxzZQogICAgblN0cmVhbSA9IGxTa2lwOwoKICByZXR1cm4gblN0cmVhbTsKfQoKc3RhdGljIHZvaWQgICAgQVZJRklMRV9VcGRhdGVJbmZvKElBVklGaWxlSW1wbCAqVGhpcykKewogIFVJTlQgaTsKCiAgLyogcHJlLWNvbmRpdGlvbnMgKi8KICBhc3NlcnQoVGhpcyAhPSBOVUxMKTsKCiAgVGhpcy0+ZkluZm8uZHdNYXhCeXRlc1BlclNlYyAgICAgID0gMDsKICBUaGlzLT5mSW5mby5kd0NhcHMgICAgICAgICAgICAgICAgPSBBVklGSUxFQ0FQU19DQU5SRUFEfEFWSUZJTEVDQVBTX0NBTldSSVRFOwogIFRoaXMtPmZJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA9IDA7CiAgVGhpcy0+ZkluZm8uZHdXaWR0aCAgICAgICAgICAgICAgID0gMDsKICBUaGlzLT5mSW5mby5kd0hlaWdodCAgICAgICAgICAgICAgPSAwOwogIFRoaXMtPmZJbmZvLmR3U2NhbGUgICAgICAgICAgICAgICA9IDA7CiAgVGhpcy0+ZkluZm8uZHdSYXRlICAgICAgICAgICAgICAgID0gMDsKICBUaGlzLT5mSW5mby5kd0xlbmd0aCAgICAgICAgICAgICAgPSAwOwogIFRoaXMtPmR3SW5pdGlhbEZyYW1lcyAgICAgICAgICAgICA9IDA7CgogIGZvciAoaSA9IDA7IGkgPCBUaGlzLT5mSW5mby5kd1N0cmVhbXM7IGkrKykgewogICAgQVZJU1RSRUFNSU5GT1cgKnBzaTsKICAgIERXT1JEICAgICAgICAgICBuOwoKICAgIC8qIHByZS1jb25kaXRpb25zICovCiAgICBhc3NlcnQoVGhpcy0+cHBTdHJlYW1zW2ldICE9IE5VTEwpOwoKICAgIHBzaSA9ICZUaGlzLT5wcFN0cmVhbXNbaV0tPnNJbmZvOwogICAgYXNzZXJ0KHBzaS0+ZHdTY2FsZSAhPSAwKTsKICAgIGFzc2VydChwc2ktPmR3UmF0ZSAhPSAwKTsKCiAgICBpZiAoaSA9PSAwKSB7CiAgICAgIC8qIHVzZSBmaXJzdCBzdHJlYW0gdGltaW5ncyBhcyBiYXNlICovCiAgICAgIFRoaXMtPmZJbmZvLmR3U2NhbGUgID0gcHNpLT5kd1NjYWxlOwogICAgICBUaGlzLT5mSW5mby5kd1JhdGUgICA9IHBzaS0+ZHdSYXRlOwogICAgICBUaGlzLT5mSW5mby5kd0xlbmd0aCA9IHBzaS0+ZHdMZW5ndGg7CiAgICB9IGVsc2UgewogICAgICBuID0gQVZJU3RyZWFtU2FtcGxlVG9TYW1wbGUoKFBBVklTVFJFQU0pVGhpcy0+cHBTdHJlYW1zWzBdLAoJCQkJICAoUEFWSVNUUkVBTSlUaGlzLT5wcFN0cmVhbXNbaV0scHNpLT5kd0xlbmd0aCk7CiAgICAgIGlmIChUaGlzLT5mSW5mby5kd0xlbmd0aCA8IG4pCglUaGlzLT5mSW5mby5kd0xlbmd0aCA9IG47CiAgICB9CgogICAgaWYgKFRoaXMtPmR3SW5pdGlhbEZyYW1lcyA8IHBzaS0+ZHdJbml0aWFsRnJhbWVzKQogICAgICBUaGlzLT5kd0luaXRpYWxGcmFtZXMgPSBwc2ktPmR3SW5pdGlhbEZyYW1lczsKCiAgICBpZiAoVGhpcy0+ZkluZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplIDwgcHNpLT5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUpCiAgICAgIFRoaXMtPmZJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA9IHBzaS0+ZHdTdWdnZXN0ZWRCdWZmZXJTaXplOwoKICAgIGlmIChwc2ktPmR3U2FtcGxlU2l6ZSAhPSAwKSB7CiAgICAgIC8qIGZpeGVkIHNhbXBsZSBzaXplIC0tIGV4YWN0IGNvbXB1dGF0aW9uICovCiAgICAgIFRoaXMtPmZJbmZvLmR3TWF4Qnl0ZXNQZXJTZWMgKz0gTXVsRGl2KHBzaS0+ZHdTYW1wbGVTaXplLCBwc2ktPmR3UmF0ZSwKCQkJCQkgICAgIHBzaS0+ZHdTY2FsZSk7CiAgICB9IGVsc2UgewogICAgICAvKiB2YXJpYWJsZSBzYW1wbGUgc2l6ZSAtLSBvbmx5IHVwcGVyIGxpbWl0ICovCiAgICAgIFRoaXMtPmZJbmZvLmR3TWF4Qnl0ZXNQZXJTZWMgKz0gTXVsRGl2KHBzaS0+ZHdTdWdnZXN0ZWRCdWZmZXJTaXplLAoJCQkJCSAgICAgcHNpLT5kd1JhdGUsIHBzaS0+ZHdTY2FsZSk7CgogICAgICAvKiB1cGRhdGUgZGltZW5zaW9ucyAqLwogICAgICBuID0gcHNpLT5yY0ZyYW1lLnJpZ2h0IC0gcHNpLT5yY0ZyYW1lLmxlZnQ7CiAgICAgIGlmIChUaGlzLT5mSW5mby5kd1dpZHRoIDwgbikKCVRoaXMtPmZJbmZvLmR3V2lkdGggPSBuOwogICAgICBuID0gcHNpLT5yY0ZyYW1lLmJvdHRvbSAtIHBzaS0+cmNGcmFtZS50b3A7CiAgICAgIGlmIChUaGlzLT5mSW5mby5kd0hlaWdodCA8IG4pCglUaGlzLT5mSW5mby5kd0hlaWdodCA9IG47CiAgICB9CiAgfQp9CgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX1dyaXRlQmxvY2soSUFWSVN0cmVhbUltcGwgKlRoaXMsIERXT1JEIGJsb2NrLAoJCQkJICBGT1VSQ0MgY2tpZCwgRFdPUkQgZmxhZ3MsIExQVk9JRCBidWZmZXIsCgkJCQkgIExPTkcgc2l6ZSkKewogIE1NQ0tJTkZPIGNrOwoKICBjay5ja2lkICAgID0gY2tpZDsKICBjay5ja3NpemUgID0gc2l6ZTsKICBjay5mY2NUeXBlID0gMDsKCiAgLyogaWYgbm8gZnJhbWUvYmxvY2sgaXMgYWxyZWFkeSB3cml0dGVuLCB3ZSBtdXN0IGNvbXB1dGUgc3RhcnQgb2YgbW92aSBjaHVuayAqLwogIGlmIChUaGlzLT5wYWYtPmR3TW92aUNodW5rUG9zID09IDApCiAgICBBVklGSUxFX0NvbXB1dGVNb3ZpU3RhcnQoVGhpcy0+cGFmKTsKCiAgaWYgKG1taW9TZWVrKFRoaXMtPnBhZi0+aG1taW8sIFRoaXMtPnBhZi0+ZHdOZXh0RnJhbWVQb3MsIFNFRUtfU0VUKSA9PSAtMSkKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICBpZiAobW1pb0NyZWF0ZUNodW5rKFRoaXMtPnBhZi0+aG1taW8sICZjaywgMCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogIGlmIChidWZmZXIgIT0gTlVMTCAmJiBzaXplID4gMCkgewogICAgaWYgKG1taW9Xcml0ZShUaGlzLT5wYWYtPmhtbWlvLCAoSFBTVFIpYnVmZmVyLCBzaXplKSAhPSBzaXplKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICB9CiAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+cGFmLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogIFRoaXMtPnBhZi0+ZkRpcnR5ICAgICAgICAgPSBUUlVFOwogIFRoaXMtPnBhZi0+ZHdOZXh0RnJhbWVQb3MgPSBtbWlvU2VlayhUaGlzLT5wYWYtPmhtbWlvLCAwLCBTRUVLX0NVUik7CgogIHJldHVybiBBVklGSUxFX0FkZEZyYW1lKFRoaXMsIGNraWQsIHNpemUsCgkJCSAgY2suZHdEYXRhT2Zmc2V0IC0gMiAqIHNpemVvZihEV09SRCksIGZsYWdzKTsKfQo=