LyoKICogQ29weXJpZ2h0IDE5OTkgTWFyY3VzIE1laXNzbmVyCiAqIENvcHlyaWdodCAyMDAyLTIwMDMgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgovKiBUT0RPOgogKiAgLSBJQVZJU3RyZWFtaW5nIGludGVyZmFjZSBpcyBtaXNzaW5nIGZvciB0aGUgSUFWSVN0cmVhbUltcGwKICogIC0gSUFWSVN0cmVhbV9mbkZpbmRTYW1wbGU6IEZJTkRfSU5ERVggaXNuJ3Qgc3VwcG9ydGVkLgogKiAgLSBJQVZJU3RyZWFtX2ZuUmVhZEZvcm1hdDogZm9ybWF0Y2hhbmdlcyBhcmVuJ3QgcmVhZCBpbi4KICogIC0gSUFWSVN0cmVhbV9mbkRlbGV0ZTogYSBzdHViLgogKiAgLSBJQVZJU3RyZWFtX2ZuU2V0SW5mbzogYSBzdHViLgogKiAgLSBtYWtlIHRocmVhZCBzYWZlCiAqCiAqIEtOT1dOIEJ1Z3M6CiAqICAtIG5hdGl2ZSB2ZXJzaW9uIGNhbiBoYW5ndXAgd2hlbiByZWFkaW5nIGEgZmlsZSBnZW5lcmF0ZWQgd2l0aCB0aGlzIERMTC4KICogICAgV2hlbiBpbmRleCBpcyBtaXNzaW5nIGl0IHdvcmtzLCBidXQgaW5kZXggc2VlbXMgdG8gYmUgb2theS4KICovCgojZGVmaW5lIENPTV9OT19XSU5ET1dTX0gKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbmRvd3N4LmgiCiNpbmNsdWRlICJtbXN5c3RlbS5oIgojaW5jbHVkZSAidmZ3LmgiCgojaW5jbHVkZSAiYXZpZmlsZV9wcml2YXRlLmgiCiNpbmNsdWRlICJleHRyYWNodW5rLmgiCgojaW5jbHVkZSAid2luZS91bmljb2RlLmgiCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChhdmlmaWxlKTsKCiNpZm5kZWYgSURYX1BFUl9CTE9DSwojZGVmaW5lIElEWF9QRVJfQkxPQ0sgMjczMAojZW5kaWYKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mblF1ZXJ5SW50ZXJmYWNlKElBVklGaWxlKiBpZmFjZSxSRUZJSUQgcmVmaWlkLExQVk9JRCAqb2JqKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElBVklGaWxlX2ZuQWRkUmVmKElBVklGaWxlKiBpZmFjZSk7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJQVZJRmlsZV9mblJlbGVhc2UoSUFWSUZpbGUqIGlmYWNlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuSW5mbyhJQVZJRmlsZSppZmFjZSxBVklGSUxFSU5GT1cqYWZpLExPTkcgc2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkdldFN0cmVhbShJQVZJRmlsZSppZmFjZSxQQVZJU1RSRUFNKmF2aXMsRFdPUkQgZmNjVHlwZSxMT05HIGxQYXJhbSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkNyZWF0ZVN0cmVhbShJQVZJRmlsZSppZmFjZSxQQVZJU1RSRUFNKmF2aXMsQVZJU1RSRUFNSU5GT1cqYXNpKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuV3JpdGVEYXRhKElBVklGaWxlKmlmYWNlLERXT1JEIGNraWQsTFBWT0lEIGxwRGF0YSxMT05HIHNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5SZWFkRGF0YShJQVZJRmlsZSppZmFjZSxEV09SRCBja2lkLExQVk9JRCBscERhdGEsTE9ORyAqc2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkVuZFJlY29yZChJQVZJRmlsZSppZmFjZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkRlbGV0ZVN0cmVhbShJQVZJRmlsZSppZmFjZSxEV09SRCBmY2NUeXBlLExPTkcgbFBhcmFtKTsKCnN0cnVjdCBJQVZJRmlsZVZ0YmwgaWF2aWZ0ID0gewogIElBVklGaWxlX2ZuUXVlcnlJbnRlcmZhY2UsCiAgSUFWSUZpbGVfZm5BZGRSZWYsCiAgSUFWSUZpbGVfZm5SZWxlYXNlLAogIElBVklGaWxlX2ZuSW5mbywKICBJQVZJRmlsZV9mbkdldFN0cmVhbSwKICBJQVZJRmlsZV9mbkNyZWF0ZVN0cmVhbSwKICBJQVZJRmlsZV9mbldyaXRlRGF0YSwKICBJQVZJRmlsZV9mblJlYWREYXRhLAogIElBVklGaWxlX2ZuRW5kUmVjb3JkLAogIElBVklGaWxlX2ZuRGVsZXRlU3RyZWFtCn07CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuUXVlcnlJbnRlcmZhY2UoSVBlcnNpc3RGaWxlKmlmYWNlLFJFRklJRCByZWZpaWQsTFBWT0lEKm9iaik7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5BZGRSZWYoSVBlcnNpc3RGaWxlKmlmYWNlKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElQZXJzaXN0RmlsZV9mblJlbGVhc2UoSVBlcnNpc3RGaWxlKmlmYWNlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkdldENsYXNzSUQoSVBlcnNpc3RGaWxlKmlmYWNlLENMU0lEKnBDbGFzc0lEKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mbklzRGlydHkoSVBlcnNpc3RGaWxlKmlmYWNlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkxvYWQoSVBlcnNpc3RGaWxlKmlmYWNlLExQQ09MRVNUUiBwc3pGaWxlTmFtZSxEV09SRCBkd01vZGUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuU2F2ZShJUGVyc2lzdEZpbGUqaWZhY2UsTFBDT0xFU1RSIHBzekZpbGVOYW1lLEJPT0wgZlJlbWVtYmVyKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mblNhdmVDb21wbGV0ZWQoSVBlcnNpc3RGaWxlKmlmYWNlLExQQ09MRVNUUiBwc3pGaWxlTmFtZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5HZXRDdXJGaWxlKElQZXJzaXN0RmlsZSppZmFjZSxMUE9MRVNUUipwcHN6RmlsZU5hbWUpOwoKc3RydWN0IElQZXJzaXN0RmlsZVZ0YmwgaXBlcnNpc3RmdCA9IHsKICBJUGVyc2lzdEZpbGVfZm5RdWVyeUludGVyZmFjZSwKICBJUGVyc2lzdEZpbGVfZm5BZGRSZWYsCiAgSVBlcnNpc3RGaWxlX2ZuUmVsZWFzZSwKICBJUGVyc2lzdEZpbGVfZm5HZXRDbGFzc0lELAogIElQZXJzaXN0RmlsZV9mbklzRGlydHksCiAgSVBlcnNpc3RGaWxlX2ZuTG9hZCwKICBJUGVyc2lzdEZpbGVfZm5TYXZlLAogIElQZXJzaXN0RmlsZV9mblNhdmVDb21wbGV0ZWQsCiAgSVBlcnNpc3RGaWxlX2ZuR2V0Q3VyRmlsZQp9OwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5RdWVyeUludGVyZmFjZShJQVZJU3RyZWFtKmlmYWNlLFJFRklJRCByZWZpaWQsTFBWT0lEICpvYmopOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUFWSVN0cmVhbV9mbkFkZFJlZihJQVZJU3RyZWFtKmlmYWNlKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElBVklTdHJlYW1fZm5SZWxlYXNlKElBVklTdHJlYW0qIGlmYWNlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5DcmVhdGUoSUFWSVN0cmVhbSppZmFjZSxMUEFSQU0gbFBhcmFtMSxMUEFSQU0gbFBhcmFtMik7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuSW5mbyhJQVZJU3RyZWFtKmlmYWNlLEFWSVNUUkVBTUlORk9XICpwc2ksTE9ORyBzaXplKTsKc3RhdGljIExPTkcgICAgV0lOQVBJIElBVklTdHJlYW1fZm5GaW5kU2FtcGxlKElBVklTdHJlYW0qaWZhY2UsTE9ORyBwb3MsTE9ORyBmbGFncyk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUmVhZEZvcm1hdChJQVZJU3RyZWFtKmlmYWNlLExPTkcgcG9zLExQVk9JRCBmb3JtYXQsTE9ORyAqZm9ybWF0c2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuU2V0Rm9ybWF0KElBVklTdHJlYW0qaWZhY2UsTE9ORyBwb3MsTFBWT0lEIGZvcm1hdCxMT05HIGZvcm1hdHNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblJlYWQoSUFWSVN0cmVhbSppZmFjZSxMT05HIHN0YXJ0LExPTkcgc2FtcGxlcyxMUFZPSUQgYnVmZmVyLExPTkcgYnVmZmVyc2l6ZSxMT05HICpieXRlc3JlYWQsTE9ORyAqc2FtcGxlc3JlYWQpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbldyaXRlKElBVklTdHJlYW0qaWZhY2UsTE9ORyBzdGFydCxMT05HIHNhbXBsZXMsTFBWT0lEIGJ1ZmZlcixMT05HIGJ1ZmZlcnNpemUsRFdPUkQgZmxhZ3MsTE9ORyAqc2FtcHdyaXR0ZW4sTE9ORyAqYnl0ZXN3cml0dGVuKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5EZWxldGUoSUFWSVN0cmVhbSppZmFjZSxMT05HIHN0YXJ0LExPTkcgc2FtcGxlcyk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUmVhZERhdGEoSUFWSVN0cmVhbSppZmFjZSxEV09SRCBmY2MsTFBWT0lEIGxwLExPTkcgKmxwcmVhZCk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuV3JpdGVEYXRhKElBVklTdHJlYW0qaWZhY2UsRFdPUkQgZmNjLExQVk9JRCBscCxMT05HIHNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblNldEluZm8oSUFWSVN0cmVhbSppZmFjZSxBVklTVFJFQU1JTkZPVyppbmZvLExPTkcgaW5mb2xlbik7CgpzdHJ1Y3QgSUFWSVN0cmVhbVZ0YmwgaWF2aXN0ID0gewogIElBVklTdHJlYW1fZm5RdWVyeUludGVyZmFjZSwKICBJQVZJU3RyZWFtX2ZuQWRkUmVmLAogIElBVklTdHJlYW1fZm5SZWxlYXNlLAogIElBVklTdHJlYW1fZm5DcmVhdGUsCiAgSUFWSVN0cmVhbV9mbkluZm8sCiAgSUFWSVN0cmVhbV9mbkZpbmRTYW1wbGUsCiAgSUFWSVN0cmVhbV9mblJlYWRGb3JtYXQsCiAgSUFWSVN0cmVhbV9mblNldEZvcm1hdCwKICBJQVZJU3RyZWFtX2ZuUmVhZCwKICBJQVZJU3RyZWFtX2ZuV3JpdGUsCiAgSUFWSVN0cmVhbV9mbkRlbGV0ZSwKICBJQVZJU3RyZWFtX2ZuUmVhZERhdGEsCiAgSUFWSVN0cmVhbV9mbldyaXRlRGF0YSwKICBJQVZJU3RyZWFtX2ZuU2V0SW5mbwp9OwoKdHlwZWRlZiBzdHJ1Y3QgX0lBVklGaWxlSW1wbCBJQVZJRmlsZUltcGw7Cgp0eXBlZGVmIHN0cnVjdCBfSVBlcnNpc3RGaWxlSW1wbCB7CiAgLyogSVVua25vd24gc3R1ZmYgKi8KICBJUGVyc2lzdEZpbGVWdGJsICpscFZ0Ymw7CgogIC8qIElQZXJzaXN0RmlsZSBzdHVmZiAqLwogIElBVklGaWxlSW1wbCAgICAgKnBhZjsKfSBJUGVyc2lzdEZpbGVJbXBsOwoKdHlwZWRlZiBzdHJ1Y3QgX0lBVklTdHJlYW1JbXBsIHsKICAvKiBJVW5rbm93biBzdHVmZiAqLwogIElBVklTdHJlYW1WdGJsICAgKmxwVnRibDsKICBEV09SRAkJICAgIHJlZjsKCiAgLyogSUFWSVN0cmVhbSBzdHVmZiAqLwogIElBVklGaWxlSW1wbCAgICAgKnBhZjsKICBEV09SRCAgICAgICAgICAgICBuU3RyZWFtOyAgICAgICAvKiB0aGUgbi10aCBzdHJlYW0gaW4gZmlsZSAqLwogIEFWSVNUUkVBTUlORk9XICAgIHNJbmZvOwoKICBMUFZPSUQgICAgICAgICAgICBscEZvcm1hdDsKICBEV09SRCAgICAgICAgICAgICBjYkZvcm1hdDsKCiAgTFBWT0lEICAgICAgICAgICAgbHBIYW5kbGVyRGF0YTsKICBEV09SRCAgICAgICAgICAgICBjYkhhbmRsZXJEYXRhOwoKICBFWFRSQUNIVU5LUyAgICAgICBleHRyYTsKCiAgTFBEV09SRCAgICAgICAgICAgbHBCdWZmZXI7CiAgRFdPUkQgICAgICAgICAgICAgY2JCdWZmZXI7ICAgICAgIC8qIHNpemUgb2YgbHBCdWZmZXIgKi8KICBEV09SRCAgICAgICAgICAgICBkd0N1cnJlbnRGcmFtZTsgLyogZnJhbWUvYmxvY2sgY3VycmVudGx5IGluIGxwQnVmZmVyICovCgogIExPTkcgICAgICAgICAgICAgIGxMYXN0RnJhbWU7ICAgIC8qIGxhc3QgY29ycmVjdCBpbmRleCBpbiBpZHhGcmFtZXMgKi8KICBBVklJTkRFWEVOVFJZICAgICppZHhGcmFtZXM7CiAgRFdPUkQgICAgICAgICAgICAgbklkeEZyYW1lczsgICAgIC8qIHVwcGVyIGluZGV4IGxpbWl0IG9mIGlkeEZyYW1lcyAqLwogIEFWSUlOREVYRU5UUlkgICAgKmlkeEZtdENoYW5nZXM7CiAgRFdPUkQgICAgICAgICAgICAgbklkeEZtdENoYW5nZXM7IC8qIHVwcGVyIGluZGV4IGxpbWl0IG9mIGlkeEZtdENoYW5nZXMgKi8KfSBJQVZJU3RyZWFtSW1wbDsKCnN0cnVjdCBfSUFWSUZpbGVJbXBsIHsKICAvKiBJVW5rbm93biBzdHVmZiAqLwogIElBVklGaWxlVnRibCAgICAgKmxwVnRibDsKICBEV09SRAkJICAgIHJlZjsKCiAgLyogSUFWSUZpbGUgc3R1ZmYuLi4gKi8KICBJUGVyc2lzdEZpbGVJbXBsICBpUGVyc2lzdEZpbGU7CgogIEFWSUZJTEVJTkZPVyAgICAgIGZJbmZvOwogIElBVklTdHJlYW1JbXBsICAgKnBwU3RyZWFtc1tNQVhfQVZJU1RSRUFNU107CgogIEVYVFJBQ0hVTktTICAgICAgIGZpbGVleHRyYTsKCiAgRFdPUkQgICAgICAgICAgICAgZHdNb3ZpQ2h1bmtQb3M7ICAvKiBzb21lIHN0dWZmIGZvciBzYXZpbmcgLi4uICovCiAgRFdPUkQgICAgICAgICAgICAgZHdJZHhDaHVua1BvczsKICBEV09SRCAgICAgICAgICAgICBkd05leHRGcmFtZVBvczsKICBEV09SRCAgICAgICAgICAgICBkd0luaXRpYWxGcmFtZXM7CgogIE1NQ0tJTkZPICAgICAgICAgIGNrTGFzdFJlY29yZDsKICBBVklJTkRFWEVOVFJZICAgICppZHhSZWNvcmRzOyAgICAgIC8qIHdvbid0IGJlIHVwZGF0ZWQgd2hpbGUgbG9hZGluZyAqLwogIERXT1JEICAgICAgICAgICAgIG5JZHhSZWNvcmRzOyAgICAgLyogY3VycmVudCBmaWxsIGxldmVsICovCiAgRFdPUkQgICAgICAgICAgICAgY2JJZHhSZWNvcmRzOyAgICAvKiBzaXplIG9mIGlkeFJlY29yZHMgKi8KCiAgLyogSVBlcnNpc3RGaWxlIHN0dWZmIC4uLiAqLwogIEhNTUlPICAgICAgICAgICAgIGhtbWlvOwogIExQV1NUUiAgICAgICAgICAgIHN6RmlsZU5hbWU7CiAgVUlOVCAgICAgICAgICAgICAgdU1vZGU7CiAgQk9PTCAgICAgICAgICAgICAgZkRpcnR5Owp9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9BZGRGcmFtZShJQVZJU3RyZWFtSW1wbCAqVGhpcywgRFdPUkQgY2tpZCwgRFdPUkQgc2l6ZSwKCQkJCURXT1JEIG9mZnNldCwgRFdPUkQgZmxhZ3MpOwpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX0FkZFJlY29yZChJQVZJRmlsZUltcGwgKlRoaXMpOwpzdGF0aWMgRFdPUkQgICBBVklGSUxFX0NvbXB1dGVNb3ZpU3RhcnQoSUFWSUZpbGVJbXBsICpUaGlzKTsKc3RhdGljIHZvaWQgICAgQVZJRklMRV9Db25zdHJ1Y3RBVklTdHJlYW0oSUFWSUZpbGVJbXBsICpwYWYsIERXT1JEIG5yLAoJCQkJCSAgTFBBVklTVFJFQU1JTkZPVyBhc2kpOwpzdGF0aWMgdm9pZCAgICBBVklGSUxFX0Rlc3RydWN0QVZJU3RyZWFtKElBVklTdHJlYW1JbXBsICpUaGlzKTsKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9Mb2FkRmlsZShJQVZJRmlsZUltcGwgKlRoaXMpOwpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX0xvYWRJbmRleChJQVZJRmlsZUltcGwgKlRoaXMsIERXT1JEIHNpemUsIERXT1JEIG9mZnNldCk7CnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfUGFyc2VJbmRleChJQVZJRmlsZUltcGwgKlRoaXMsIEFWSUlOREVYRU5UUlkgKmxwLAoJCQkJICBMT05HIGNvdW50LCBEV09SRCBwb3MsIEJPT0wgKmJBYnNvbHV0ZSk7CnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfUmVhZEJsb2NrKElBVklTdHJlYW1JbXBsICpUaGlzLCBEV09SRCBzdGFydCwKCQkJCSBMUFZPSUQgYnVmZmVyLCBMT05HIHNpemUpOwpzdGF0aWMgdm9pZCAgICBBVklGSUxFX1NhbXBsZXNUb0Jsb2NrKElBVklTdHJlYW1JbXBsICpUaGlzLCBMUExPTkcgcG9zLAoJCQkJICAgICAgTFBMT05HIG9mZnNldCk7CnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfU2F2ZUZpbGUoSUFWSUZpbGVJbXBsICpUaGlzKTsKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9TYXZlSW5kZXgoSUFWSUZpbGVJbXBsICpUaGlzKTsKc3RhdGljIFVMT05HICAgQVZJRklMRV9TZWFyY2hTdHJlYW0oSUFWSUZpbGVJbXBsICpUaGlzLCBEV09SRCBmY2NUeXBlLAoJCQkJICAgIExPTkcgbFNraXApOwpzdGF0aWMgdm9pZCAgICBBVklGSUxFX1VwZGF0ZUluZm8oSUFWSUZpbGVJbXBsICpUaGlzKTsKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9Xcml0ZUJsb2NrKElBVklTdHJlYW1JbXBsICpUaGlzLCBEV09SRCBibG9jaywKCQkJCSAgRk9VUkNDIGNraWQsIERXT1JEIGZsYWdzLCBMUFZPSUQgYnVmZmVyLAoJCQkJICBMT05HIHNpemUpOwoKSFJFU1VMVCBBVklGSUxFX0NyZWF0ZUFWSUZpbGUoUkVGSUlEIHJpaWQsIExQVk9JRCAqcHB2KQp7CiAgSUFWSUZpbGVJbXBsICpwZmlsZTsKICBIUkVTVUxUICAgICAgIGhyOwoKICBhc3NlcnQocmlpZCAhPSBOVUxMICYmIHBwdiAhPSBOVUxMKTsKCiAgKnBwdiA9IE5VTEw7CgogIHBmaWxlID0gKElBVklGaWxlSW1wbCopTG9jYWxBbGxvYyhMUFRSLCBzaXplb2YoSUFWSUZpbGVJbXBsKSk7CiAgaWYgKHBmaWxlID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgcGZpbGUtPmxwVnRibCA9ICZpYXZpZnQ7CiAgcGZpbGUtPnJlZiA9IDA7CiAgcGZpbGUtPmlQZXJzaXN0RmlsZS5scFZ0YmwgPSAmaXBlcnNpc3RmdDsKICBwZmlsZS0+aVBlcnNpc3RGaWxlLnBhZiA9IHBmaWxlOwoKICBociA9IElBVklGaWxlX1F1ZXJ5SW50ZXJmYWNlKChJQVZJRmlsZSopcGZpbGUsIHJpaWQsIHBwdik7CiAgaWYgKEZBSUxFRChocikpCiAgICBMb2NhbEZyZWUoKEhMT0NBTClwZmlsZSk7CgogIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuUXVlcnlJbnRlcmZhY2UoSUFWSUZpbGUgKmlmYWNlLCBSRUZJSUQgcmVmaWlkLAoJCQkJCQlMUFZPSUQgKm9iaikKewogIElBVklGaWxlSW1wbCAqVGhpcyA9IChJQVZJRmlsZUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlcywlcClcbiIsIFRoaXMsIGRlYnVnc3RyX2d1aWQocmVmaWlkKSwgb2JqKTsKCiAgaWYgKElzRXF1YWxHVUlEKCZJSURfSVVua25vd24sIHJlZmlpZCkgfHwKICAgICAgSXNFcXVhbEdVSUQoJklJRF9JQVZJRmlsZSwgcmVmaWlkKSkgewogICAgKm9iaiA9IGlmYWNlOwogICAgSUFWSUZpbGVfQWRkUmVmKGlmYWNlKTsKCiAgICByZXR1cm4gU19PSzsKICB9IGVsc2UgaWYgKElzRXF1YWxHVUlEKCZJSURfSVBlcnNpc3RGaWxlLCByZWZpaWQpKSB7CiAgICAqb2JqID0gJlRoaXMtPmlQZXJzaXN0RmlsZTsKICAgIElBVklGaWxlX0FkZFJlZihpZmFjZSk7CgogICAgcmV0dXJuIFNfT0s7CiAgfQoKICByZXR1cm4gT0xFX0VfRU5VTV9OT01PUkU7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSUFWSUZpbGVfZm5BZGRSZWYoSUFWSUZpbGUgKmlmYWNlKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKElBVklGaWxlSW1wbCAqKWlmYWNlOwogIFVMT05HIHJlZiA9IEludGVybG9ja2VkSW5jcmVtZW50KCZUaGlzLT5yZWYpOwoKICBUUkFDRSgiKCVwKSAtPiAlbGRcbiIsIGlmYWNlLCByZWYpOwoKICByZXR1cm4gcmVmOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIElBVklGaWxlX2ZuUmVsZWFzZShJQVZJRmlsZSAqaWZhY2UpCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoSUFWSUZpbGVJbXBsICopaWZhY2U7CiAgVUlOVCBpOwogIFVMT05HIHJlZiA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5yZWYpOwoKICBUUkFDRSgiKCVwKSAtPiAlbGRcbiIsIGlmYWNlLCByZWYpOwoKICBpZiAoIXJlZikgewogICAgaWYgKFRoaXMtPmZEaXJ0eSkgewogICAgICAvKiBuZWVkIHRvIHdyaXRlIGhlYWRlcnMgdG8gZmlsZSAqLwogICAgICBBVklGSUxFX1NhdmVGaWxlKFRoaXMpOwogICAgfQoKICAgIGZvciAoaSA9IDA7IGkgPCBUaGlzLT5mSW5mby5kd1N0cmVhbXM7IGkrKykgewogICAgICBpZiAoVGhpcy0+cHBTdHJlYW1zW2ldICE9IE5VTEwpIHsKCWlmIChUaGlzLT5wcFN0cmVhbXNbaV0tPnJlZiAhPSAwKSB7CgkgIEVSUigiOiBzb21lb25lIGhhcyBzdGlsbCAlbHUgcmVmZXJlbmNlIHRvIHN0cmVhbSAldSAoJXApIVxuIiwKCSAgICAgICBUaGlzLT5wcFN0cmVhbXNbaV0tPnJlZiwgaSwgVGhpcy0+cHBTdHJlYW1zW2ldKTsKCX0KCUFWSUZJTEVfRGVzdHJ1Y3RBVklTdHJlYW0oVGhpcy0+cHBTdHJlYW1zW2ldKTsKCUxvY2FsRnJlZSgoSExPQ0FMKVRoaXMtPnBwU3RyZWFtc1tpXSk7CglUaGlzLT5wcFN0cmVhbXNbaV0gPSBOVUxMOwogICAgICB9CiAgICB9CgogICAgaWYgKFRoaXMtPmlkeFJlY29yZHMgIT0gTlVMTCkgewogICAgICBHbG9iYWxGcmVlUHRyKFRoaXMtPmlkeFJlY29yZHMpOwogICAgICBUaGlzLT5pZHhSZWNvcmRzICA9IE5VTEw7CiAgICAgIFRoaXMtPm5JZHhSZWNvcmRzID0gMDsKICAgIH0KCiAgICBpZiAoVGhpcy0+ZmlsZWV4dHJhLmxwICE9IE5VTEwpIHsKICAgICAgR2xvYmFsRnJlZVB0cihUaGlzLT5maWxlZXh0cmEubHApOwogICAgICBUaGlzLT5maWxlZXh0cmEubHAgPSBOVUxMOwogICAgICBUaGlzLT5maWxlZXh0cmEuY2IgPSAwOwogICAgfQoKICAgIGlmIChUaGlzLT5zekZpbGVOYW1lICE9IE5VTEwpIHsKICAgICAgTG9jYWxGcmVlKChITE9DQUwpVGhpcy0+c3pGaWxlTmFtZSk7CiAgICAgIFRoaXMtPnN6RmlsZU5hbWUgPSBOVUxMOwogICAgfQogICAgaWYgKFRoaXMtPmhtbWlvICE9IE5VTEwpIHsKICAgICAgbW1pb0Nsb3NlKFRoaXMtPmhtbWlvLCAwKTsKICAgICAgVGhpcy0+aG1taW8gPSBOVUxMOwogICAgfQoKICAgIExvY2FsRnJlZSgoSExPQ0FMKVRoaXMpOwogIH0KICByZXR1cm4gcmVmOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5JbmZvKElBVklGaWxlICppZmFjZSwgTFBBVklGSUxFSU5GT1cgYWZpLAoJCQkJICAgICAgTE9ORyBzaXplKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKElBVklGaWxlSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVwLCVsZClcbiIsaWZhY2UsYWZpLHNpemUpOwoKICBpZiAoYWZpID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIGlmIChzaXplIDwgMCkKICAgIHJldHVybiBBVklFUlJfQkFEU0laRTsKCiAgQVZJRklMRV9VcGRhdGVJbmZvKFRoaXMpOwoKICBtZW1jcHkoYWZpLCAmVGhpcy0+ZkluZm8sIG1pbigoRFdPUkQpc2l6ZSwgc2l6ZW9mKFRoaXMtPmZJbmZvKSkpOwoKICBpZiAoKERXT1JEKXNpemUgPCBzaXplb2YoVGhpcy0+ZkluZm8pKQogICAgcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5HZXRTdHJlYW0oSUFWSUZpbGUgKmlmYWNlLCBQQVZJU1RSRUFNICphdmlzLAoJCQkJCSAgIERXT1JEIGZjY1R5cGUsIExPTkcgbFBhcmFtKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKElBVklGaWxlSW1wbCAqKWlmYWNlOwoKICBVTE9ORyBuU3RyZWFtOwoKICBUUkFDRSgiKCVwLCVwLDB4JTA4bFgsJWxkKVxuIiwgaWZhY2UsIGF2aXMsIGZjY1R5cGUsIGxQYXJhbSk7CgogIGlmIChhdmlzID09IE5VTEwgfHwgbFBhcmFtIDwgMCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIG5TdHJlYW0gPSBBVklGSUxFX1NlYXJjaFN0cmVhbShUaGlzLCBmY2NUeXBlLCBsUGFyYW0pOwoKICAvKiBEb2VzIHRoZSByZXF1ZXN0ZWQgc3RyZWFtIGV4aXN0PyAqLwogIGlmIChuU3RyZWFtIDwgVGhpcy0+ZkluZm8uZHdTdHJlYW1zICYmCiAgICAgIFRoaXMtPnBwU3RyZWFtc1tuU3RyZWFtXSAhPSBOVUxMKSB7CiAgICAqYXZpcyA9IChQQVZJU1RSRUFNKVRoaXMtPnBwU3RyZWFtc1tuU3RyZWFtXTsKICAgIElBVklTdHJlYW1fQWRkUmVmKCphdmlzKTsKCiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0KCiAgLyogU29ycnksIGJ1dCB0aGUgc3BlY2lmaWVkIHN0cmVhbSBkb2Vzbid0IGV4aXN0ICovCiAgcmV0dXJuIEFWSUVSUl9OT0RBVEE7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkNyZWF0ZVN0cmVhbShJQVZJRmlsZSAqaWZhY2UsUEFWSVNUUkVBTSAqYXZpcywKCQkJCQkgICAgICBMUEFWSVNUUkVBTUlORk9XIGFzaSkKewogIElBVklGaWxlSW1wbCAqVGhpcyA9IChJQVZJRmlsZUltcGwgKilpZmFjZTsKCiAgRFdPUkQgbjsKCiAgVFJBQ0UoIiglcCwlcCwlcClcbiIsIGlmYWNlLCBhdmlzLCBhc2kpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKGF2aXMgPT0gTlVMTCB8fCBhc2kgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICphdmlzID0gTlVMTDsKCiAgLyogRG9lcyB0aGUgdXNlciBoYXZlIHdyaXRlIHBlcm1pc3Npb24/ICovCiAgaWYgKChUaGlzLT51TW9kZSAmIE1NSU9fUldNT0RFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgLyogQ2FuIHdlIGFkZCBhbm90aGVyIHN0cmVhbT8gKi8KICBuID0gVGhpcy0+ZkluZm8uZHdTdHJlYW1zOwogIGlmIChuID49IE1BWF9BVklTVFJFQU1TIHx8IFRoaXMtPmR3TW92aUNodW5rUG9zICE9IDApIHsKICAgIC8qIGFscmVhZHkgcmVhY2hlZCBtYXggbnIgb2Ygc3RyZWFtcwogICAgICogb3IgaGF2ZSBhbHJlYWR5IHdyaXR0ZW4gZnJhbWVzIHRvIGRpc2sgKi8KICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CiAgfQoKICAvKiBjaGVjayBBVklTVFJFQU1JTkZPIGZvciBzb21lIHJlYWxseSBuZWVkZWQgdGhpbmdzICovCiAgaWYgKGFzaS0+ZmNjVHlwZSA9PSAwIHx8IGFzaS0+ZHdTY2FsZSA9PSAwIHx8IGFzaS0+ZHdSYXRlID09IDApCiAgICByZXR1cm4gQVZJRVJSX0JBREZPUk1BVDsKCiAgLyogbm93IGl0IHNlZW1zIHRvIGJlIHNhdmUgdG8gYWRkIHRoZSBzdHJlYW0gKi8KICBhc3NlcnQoVGhpcy0+cHBTdHJlYW1zW25dID09IE5VTEwpOwogIFRoaXMtPnBwU3RyZWFtc1tuXSA9IChJQVZJU3RyZWFtSW1wbCopTG9jYWxBbGxvYyhMUFRSLAoJCQkJCQkgICBzaXplb2YoSUFWSVN0cmVhbUltcGwpKTsKICBpZiAoVGhpcy0+cHBTdHJlYW1zW25dID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgLyogaW5pdGlhbGl6ZSB0aGUgbmV3IGFsbG9jYXRlZCBzdHJlYW0gKi8KICBBVklGSUxFX0NvbnN0cnVjdEFWSVN0cmVhbShUaGlzLCBuLCBhc2kpOwoKICBUaGlzLT5mSW5mby5kd1N0cmVhbXMrKzsKICBUaGlzLT5mRGlydHkgPSBUUlVFOwoKICAvKiB1cGRhdGUgb3VyIEFWSUZJTEVJTkZPIHN0cnVjdHVyZSAqLwogIEFWSUZJTEVfVXBkYXRlSW5mbyhUaGlzKTsKCiAgLyogcmV0dXJuIGl0ICovCiAgKmF2aXMgPSAoUEFWSVNUUkVBTSlUaGlzLT5wcFN0cmVhbXNbbl07CiAgSUFWSVN0cmVhbV9BZGRSZWYoKmF2aXMpOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5Xcml0ZURhdGEoSUFWSUZpbGUgKmlmYWNlLCBEV09SRCBja2lkLAoJCQkJCSAgIExQVk9JRCBscERhdGEsIExPTkcgc2l6ZSkKewogIElBVklGaWxlSW1wbCAqVGhpcyA9IChJQVZJRmlsZUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwweCUwOGxYLCVwLCVsZClcbiIsIGlmYWNlLCBja2lkLCBscERhdGEsIHNpemUpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKGxwRGF0YSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICBpZiAoc2l6ZSA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CgogIC8qIERvIHdlIGhhdmUgd3JpdGUgcGVybWlzc2lvbj8gKi8KICBpZiAoKFRoaXMtPnVNb2RlICYgTU1JT19SV01PREUpID09IDApCiAgICByZXR1cm4gQVZJRVJSX1JFQURPTkxZOwoKICBUaGlzLT5mRGlydHkgPSBUUlVFOwoKICByZXR1cm4gV3JpdGVFeHRyYUNodW5rKCZUaGlzLT5maWxlZXh0cmEsIGNraWQsIGxwRGF0YSwgc2l6ZSk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mblJlYWREYXRhKElBVklGaWxlICppZmFjZSwgRFdPUkQgY2tpZCwKCQkJCQkgIExQVk9JRCBscERhdGEsIExPTkcgKnNpemUpCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoSUFWSUZpbGVJbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsMHglMDhsWCwlcCwlcClcbiIsIGlmYWNlLCBja2lkLCBscERhdGEsIHNpemUpOwoKICByZXR1cm4gUmVhZEV4dHJhQ2h1bmsoJlRoaXMtPmZpbGVleHRyYSwgY2tpZCwgbHBEYXRhLCBzaXplKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuRW5kUmVjb3JkKElBVklGaWxlICppZmFjZSkKewogIElBVklGaWxlSW1wbCAqVGhpcyA9IChJQVZJRmlsZUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcClcbiIsaWZhY2UpOwoKICBpZiAoKFRoaXMtPnVNb2RlICYgTU1JT19SV01PREUpID09IDApCiAgICByZXR1cm4gQVZJRVJSX1JFQURPTkxZOwoKICBUaGlzLT5mRGlydHkgPSBUUlVFOwoKICAvKiBubyBmcmFtZXMgd3JpdHRlbiB0byBhbnkgc3RyZWFtPyAtLSBjb21wdXRlIHN0YXJ0IG9mICdtb3ZpJy1jaHVuayAqLwogIGlmIChUaGlzLT5kd01vdmlDaHVua1BvcyA9PSAwKQogICAgQVZJRklMRV9Db21wdXRlTW92aVN0YXJ0KFRoaXMpOwoKICBUaGlzLT5mSW5mby5kd0ZsYWdzICB8PSBBVklGSUxFSU5GT19JU0lOVEVSTEVBVkVEOwoKICAvKiBhbHJlYWR5IHdyaXR0ZW4gZnJhbWVzIHRvIGFueSBzdHJlYW0sIC4uLiAqLwogIGlmIChUaGlzLT5ja0xhc3RSZWNvcmQuZHdGbGFncyAmIE1NSU9fRElSVFkpIHsKICAgIC8qIGNsb3NlIGxhc3QgcmVjb3JkICovCiAgICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJlRoaXMtPmNrTGFzdFJlY29yZCwgMCkgIT0gMCkKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogICAgQVZJRklMRV9BZGRSZWNvcmQoVGhpcyk7CgogICAgaWYgKFRoaXMtPmZJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA8IFRoaXMtPmNrTGFzdFJlY29yZC5ja3NpemUgKyAzICogc2l6ZW9mKERXT1JEKSkKICAgICAgVGhpcy0+ZkluZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplID0gVGhpcy0+Y2tMYXN0UmVjb3JkLmNrc2l6ZSArIDMgKiBzaXplb2YoRFdPUkQpOwogIH0KCiAgLyogd3JpdGUgb3V0IGEgbmV3IHJlY29yZCBpbnRvIGZpbGUsIGJ1dCBkb24ndCBjbG9zZSBpdCAqLwogIFRoaXMtPmNrTGFzdFJlY29yZC5ja3NpemUgID0gMDsKICBUaGlzLT5ja0xhc3RSZWNvcmQuZmNjVHlwZSA9IGxpc3R0eXBlQVZJUkVDT1JEOwogIGlmIChtbWlvU2VlayhUaGlzLT5obW1pbywgVGhpcy0+ZHdOZXh0RnJhbWVQb3MsIFNFRUtfU0VUKSA9PSAtMSkKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogIGlmIChtbWlvQ3JlYXRlQ2h1bmsoVGhpcy0+aG1taW8sICZUaGlzLT5ja0xhc3RSZWNvcmQsIE1NSU9fQ1JFQVRFTElTVCkgIT0gMCkKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogIFRoaXMtPmR3TmV4dEZyYW1lUG9zICs9IDMgKiBzaXplb2YoRFdPUkQpOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5EZWxldGVTdHJlYW0oSUFWSUZpbGUgKmlmYWNlLCBEV09SRCBmY2NUeXBlLAoJCQkJCSAgICAgIExPTkcgbFBhcmFtKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKElBVklGaWxlSW1wbCAqKWlmYWNlOwoKICBVTE9ORyBuU3RyZWFtOwoKICBUUkFDRSgiKCVwLDB4JTA4bFgsJWxkKVxuIiwgaWZhY2UsIGZjY1R5cGUsIGxQYXJhbSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlciAqLwogIGlmIChsUGFyYW0gPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogSGF2ZSB1c2VyIHdyaXRlIHBlcm1pc3Npb25zPyAqLwogIGlmICgoVGhpcy0+dU1vZGUgJiBNTUlPX1JXTU9ERSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIG5TdHJlYW0gPSBBVklGSUxFX1NlYXJjaFN0cmVhbShUaGlzLCBmY2NUeXBlLCBsUGFyYW0pOwoKICAvKiBEb2VzIHRoZSByZXF1ZXN0ZWQgc3RyZWFtIGV4aXN0PyAqLwogIGlmIChuU3RyZWFtIDwgVGhpcy0+ZkluZm8uZHdTdHJlYW1zICYmCiAgICAgIFRoaXMtPnBwU3RyZWFtc1tuU3RyZWFtXSAhPSBOVUxMKSB7CiAgICAvKiAuLi4gc28gZGVsZXRlIGl0IG5vdyAqLwogICAgTG9jYWxGcmVlKChITE9DQUwpVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dKTsKCiAgICBpZiAoVGhpcy0+ZkluZm8uZHdTdHJlYW1zIC0gblN0cmVhbSA+IDApCiAgICAgIG1lbWNweShUaGlzLT5wcFN0cmVhbXMgKyBuU3RyZWFtLCBUaGlzLT5wcFN0cmVhbXMgKyBuU3RyZWFtICsgMSwKCSAgICAgKFRoaXMtPmZJbmZvLmR3U3RyZWFtcyAtIG5TdHJlYW0pICogc2l6ZW9mKElBVklTdHJlYW1JbXBsKikpOwoKICAgIFRoaXMtPnBwU3RyZWFtc1tUaGlzLT5mSW5mby5kd1N0cmVhbXNdID0gTlVMTDsKICAgIFRoaXMtPmZJbmZvLmR3U3RyZWFtcy0tOwogICAgVGhpcy0+ZkRpcnR5ID0gVFJVRTsKCiAgICAvKiBUaGlzLT5mSW5mbyB3aWxsIGJlIHVwZGF0ZWQgZnVydGhlciB3aGVuIGFza2VkIGZvciAqLwogICAgcmV0dXJuIEFWSUVSUl9PSzsKICB9IGVsc2UKICAgIHJldHVybiBBVklFUlJfTk9EQVRBOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuUXVlcnlJbnRlcmZhY2UoSVBlcnNpc3RGaWxlICppZmFjZSwKCQkJCQkJICAgIFJFRklJRCByZWZpaWQsIExQVk9JRCAqb2JqKQp7CiAgSVBlcnNpc3RGaWxlSW1wbCAqVGhpcyA9IChJUGVyc2lzdEZpbGVJbXBsICopaWZhY2U7CgogIGFzc2VydChUaGlzLT5wYWYgIT0gTlVMTCk7CgogIHJldHVybiBJQVZJRmlsZV9RdWVyeUludGVyZmFjZSgoUEFWSUZJTEUpVGhpcy0+cGFmLCByZWZpaWQsIG9iaik7Cn0KCnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5BZGRSZWYoSVBlcnNpc3RGaWxlICppZmFjZSkKewogIElQZXJzaXN0RmlsZUltcGwgKlRoaXMgPSAoSVBlcnNpc3RGaWxlSW1wbCAqKWlmYWNlOwoKICBhc3NlcnQoVGhpcy0+cGFmICE9IE5VTEwpOwoKICByZXR1cm4gSUFWSUZpbGVfQWRkUmVmKChQQVZJRklMRSlUaGlzLT5wYWYpOwp9CgpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuUmVsZWFzZShJUGVyc2lzdEZpbGUgKmlmYWNlKQp7CiAgSVBlcnNpc3RGaWxlSW1wbCAqVGhpcyA9IChJUGVyc2lzdEZpbGVJbXBsICopaWZhY2U7CgogIGFzc2VydChUaGlzLT5wYWYgIT0gTlVMTCk7CgogIHJldHVybiBJQVZJRmlsZV9SZWxlYXNlKChQQVZJRklMRSlUaGlzLT5wYWYpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuR2V0Q2xhc3NJRChJUGVyc2lzdEZpbGUgKmlmYWNlLAoJCQkJCQlMUENMU0lEIHBDbGFzc0lEKQp7CiAgVFJBQ0UoIiglcCwlcClcbiIsIGlmYWNlLCBwQ2xhc3NJRCk7CgogIGlmIChwQ2xhc3NJRCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgbWVtY3B5KHBDbGFzc0lELCAmQ0xTSURfQVZJRmlsZSwgc2l6ZW9mKENMU0lEX0FWSUZpbGUpKTsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mbklzRGlydHkoSVBlcnNpc3RGaWxlICppZmFjZSkKewogIElQZXJzaXN0RmlsZUltcGwgKlRoaXMgPSAoSVBlcnNpc3RGaWxlSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwKVxuIiwgaWZhY2UpOwoKICBhc3NlcnQoVGhpcy0+cGFmICE9IE5VTEwpOwoKICByZXR1cm4gKFRoaXMtPnBhZi0+ZkRpcnR5ID8gU19PSyA6IFNfRkFMU0UpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuTG9hZChJUGVyc2lzdEZpbGUgKmlmYWNlLAoJCQkJCSAgTFBDT0xFU1RSIHBzekZpbGVOYW1lLCBEV09SRCBkd01vZGUpCnsKICBJUGVyc2lzdEZpbGVJbXBsICpUaGlzID0gKElQZXJzaXN0RmlsZUltcGwgKilpZmFjZTsKCiAgaW50IGxlbjsKCiAgVFJBQ0UoIiglcCwlcywweCUwOGxYKVxuIiwgaWZhY2UsIGRlYnVnc3RyX3cocHN6RmlsZU5hbWUpLCBkd01vZGUpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXIgKi8KICBpZiAocHN6RmlsZU5hbWUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIGFzc2VydChUaGlzLT5wYWYgIT0gTlVMTCk7CiAgaWYgKFRoaXMtPnBhZi0+aG1taW8gIT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfRVJST1I7IC8qIE5vIHJldXNlIG9mIHRoaXMgb2JqZWN0IGZvciBhbm90aGVyIGZpbGUhICovCgogIC8qIHJlbWViZXIgbW9kZSBhbmQgbmFtZSAqLwogIFRoaXMtPnBhZi0+dU1vZGUgPSBkd01vZGU7CgogIGxlbiA9IGxzdHJsZW5XKHBzekZpbGVOYW1lKSArIDE7CiAgVGhpcy0+cGFmLT5zekZpbGVOYW1lID0gKExQV1NUUilMb2NhbEFsbG9jKExQVFIsIGxlbiAqIHNpemVvZihXQ0hBUikpOwogIGlmIChUaGlzLT5wYWYtPnN6RmlsZU5hbWUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogIGxzdHJjcHlXKFRoaXMtPnBhZi0+c3pGaWxlTmFtZSwgcHN6RmlsZU5hbWUpOwoKICAvKiB0cnkgdG8gb3BlbiB0aGUgZmlsZSAqLwogIFRoaXMtPnBhZi0+aG1taW8gPSBtbWlvT3BlblcoVGhpcy0+cGFmLT5zekZpbGVOYW1lLCBOVUxMLAoJCQkgICAgICAgTU1JT19BTExPQ0JVRiB8IGR3TW9kZSk7CiAgaWYgKFRoaXMtPnBhZi0+aG1taW8gPT0gTlVMTCkgewogICAgLyogbW1pb09wZW5XIG5vdCBpbiBuYXRpdmUgRExMcyBvZiBXaW45eCAtLSB0cnkgbW1pb09wZW5BICovCiAgICBMUFNUUiBzekZpbGVOYW1lOwoKICAgIGxlbiA9IFdpZGVDaGFyVG9NdWx0aUJ5dGUoQ1BfQUNQLCAwLCBUaGlzLT5wYWYtPnN6RmlsZU5hbWUsIC0xLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgMCwgTlVMTCwgTlVMTCk7CiAgICBzekZpbGVOYW1lID0gTG9jYWxBbGxvYyhMUFRSLCBsZW4gKiBzaXplb2YoQ0hBUikpOwogICAgaWYgKHN6RmlsZU5hbWUgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogICAgV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIFRoaXMtPnBhZi0+c3pGaWxlTmFtZSwgLTEsIHN6RmlsZU5hbWUsCgkJCWxlbiwgTlVMTCwgTlVMTCk7CgogICAgVGhpcy0+cGFmLT5obW1pbyA9IG1taW9PcGVuQShzekZpbGVOYW1lLCBOVUxMLCBNTUlPX0FMTE9DQlVGIHwgZHdNb2RlKTsKICAgIExvY2FsRnJlZSgoSExPQ0FMKXN6RmlsZU5hbWUpOwogICAgaWYgKFRoaXMtPnBhZi0+aG1taW8gPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFT1BFTjsKICB9CgogIC8qIHNob3VsZCB3ZSBjcmVhdGUgYSBuZXcgZmlsZT8gKi8KICBpZiAoZHdNb2RlICYgT0ZfQ1JFQVRFKSB7CiAgICBtZW1zZXQoJiBUaGlzLT5wYWYtPmZJbmZvLCAwLCBzaXplb2YoVGhpcy0+cGFmLT5mSW5mbykpOwogICAgVGhpcy0+cGFmLT5mSW5mby5kd0ZsYWdzID0gQVZJRklMRUlORk9fSEFTSU5ERVggfCBBVklGSUxFSU5GT19UUlVTVENLVFlQRTsKCiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0gZWxzZQogICAgcmV0dXJuIEFWSUZJTEVfTG9hZEZpbGUoVGhpcy0+cGFmKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mblNhdmUoSVBlcnNpc3RGaWxlICppZmFjZSwKCQkJCQkgIExQQ09MRVNUUiBwc3pGaWxlTmFtZSxCT09MIGZSZW1lbWJlcikKewogIFRSQUNFKCIoJXAsJXMsJWQpXG4iLCBpZmFjZSwgZGVidWdzdHJfdyhwc3pGaWxlTmFtZSksIGZSZW1lbWJlcik7CgogIC8qIFdlIHdyaXRlIGRpcmVjdGx5IHRvIGRpc2ssIHNvIG5vdGhpbmcgdG8gZG8uICovCgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5TYXZlQ29tcGxldGVkKElQZXJzaXN0RmlsZSAqaWZhY2UsCgkJCQkJCSAgIExQQ09MRVNUUiBwc3pGaWxlTmFtZSkKewogIFRSQUNFKCIoJXAsJXMpXG4iLCBpZmFjZSwgZGVidWdzdHJfdyhwc3pGaWxlTmFtZSkpOwoKICAvKiBXZSB3cml0ZSBkaXJlY3RseSB0byBkaXNrLCBzbyBub3RoaW5nIHRvIGRvLiAqLwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuR2V0Q3VyRmlsZShJUGVyc2lzdEZpbGUgKmlmYWNlLAoJCQkJCQlMUE9MRVNUUiAqcHBzekZpbGVOYW1lKQp7CiAgSVBlcnNpc3RGaWxlSW1wbCAqVGhpcyA9IChJUGVyc2lzdEZpbGVJbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJXApXG4iLCBpZmFjZSwgcHBzekZpbGVOYW1lKTsKCiAgaWYgKHBwc3pGaWxlTmFtZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgKnBwc3pGaWxlTmFtZSA9IE5VTEw7CgogIGFzc2VydChUaGlzLT5wYWYgIT0gTlVMTCk7CgogIGlmIChUaGlzLT5wYWYtPnN6RmlsZU5hbWUgIT0gTlVMTCkgewogICAgaW50IGxlbiA9IGxzdHJsZW5XKFRoaXMtPnBhZi0+c3pGaWxlTmFtZSkgKyAxOwoKICAgICpwcHN6RmlsZU5hbWUgPSAoTFBPTEVTVFIpR2xvYmFsQWxsb2NQdHIoR0hORCwgbGVuICogc2l6ZW9mKFdDSEFSKSk7CiAgICBpZiAoKnBwc3pGaWxlTmFtZSA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgICBzdHJjcHlXKCpwcHN6RmlsZU5hbWUsIFRoaXMtPnBhZi0+c3pGaWxlTmFtZSk7CiAgfQoKICByZXR1cm4gQVZJRVJSX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblF1ZXJ5SW50ZXJmYWNlKElBVklTdHJlYW0gKmlmYWNlLAoJCQkJCQkgIFJFRklJRCByZWZpaWQsIExQVk9JRCAqb2JqKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlcywlcClcbiIsIGlmYWNlLCBkZWJ1Z3N0cl9ndWlkKHJlZmlpZCksIG9iaik7CgogIGlmIChJc0VxdWFsR1VJRCgmSUlEX0lVbmtub3duLCByZWZpaWQpIHx8CiAgICAgIElzRXF1YWxHVUlEKCZJSURfSUFWSVN0cmVhbSwgcmVmaWlkKSkgewogICAgKm9iaiA9IFRoaXM7CiAgICBJQVZJU3RyZWFtX0FkZFJlZihpZmFjZSk7CgogICAgcmV0dXJuIFNfT0s7CiAgfQogIC8qIEZJWE1FOiBJQVZJU3RyZWFtaW5nIGludGVyZmFjZSAqLwoKICByZXR1cm4gT0xFX0VfRU5VTV9OT01PUkU7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSUFWSVN0cmVhbV9mbkFkZFJlZihJQVZJU3RyZWFtICppZmFjZSkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CiAgVUxPTkcgcmVmID0gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPnJlZik7CgogIFRSQUNFKCIoJXApIC0+ICVsZFxuIiwgaWZhY2UsIHJlZik7CgogIC8qIGFsc28gYWRkIHJlZiB0byBwYXJlbnQsIHNvIHRoYXQgaXQgZG9lc24ndCBraWxsIHVzICovCiAgaWYgKFRoaXMtPnBhZiAhPSBOVUxMKQogICAgSUFWSUZpbGVfQWRkUmVmKChQQVZJRklMRSlUaGlzLT5wYWYpOwoKICByZXR1cm4gcmVmOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIElBVklTdHJlYW1fZm5SZWxlYXNlKElBVklTdHJlYW0qIGlmYWNlKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+cmVmKTsKCiAgVFJBQ0UoIiglcCkgLT4gJWxkXG4iLCBpZmFjZSwgcmVmKTsKCiAgaWYgKFRoaXMtPnBhZiAhPSBOVUxMKQogICAgSUFWSUZpbGVfUmVsZWFzZSgoUEFWSUZJTEUpVGhpcy0+cGFmKTsKCiAgcmV0dXJuIHJlZjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5DcmVhdGUoSUFWSVN0cmVhbSAqaWZhY2UsIExQQVJBTSBsUGFyYW0xLAoJCQkJCSAgTFBBUkFNIGxQYXJhbTIpCnsKICBUUkFDRSgiKCVwLDB4JTA4bFgsMHglMDhsWClcbiIsIGlmYWNlLCBsUGFyYW0xLCBsUGFyYW0yKTsKCiAgLyogVGhpcyBJQVZJU3RyZWFtIGludGVyZmFjZSBuZWVkcyBhbiBBVklGaWxlICovCiAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5JbmZvKElBVklTdHJlYW0gKmlmYWNlLExQQVZJU1RSRUFNSU5GT1cgcHNpLAoJCQkJCUxPTkcgc2l6ZSkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJXAsJWxkKVxuIiwgaWZhY2UsIHBzaSwgc2l6ZSk7CgogIGlmIChwc2kgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgaWYgKHNpemUgPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURTSVpFOwoKICBtZW1jcHkocHNpLCAmVGhpcy0+c0luZm8sIG1pbigoRFdPUkQpc2l6ZSwgc2l6ZW9mKFRoaXMtPnNJbmZvKSkpOwoKICBpZiAoKERXT1JEKXNpemUgPCBzaXplb2YoVGhpcy0+c0luZm8pKQogICAgcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgTE9ORyBXSU5BUEkgSUFWSVN0cmVhbV9mbkZpbmRTYW1wbGUoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgcG9zLAoJCQkJCSAgIExPTkcgZmxhZ3MpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBMT05HIG9mZnNldCA9IDA7CgogIFRSQUNFKCIoJXAsJWxkLDB4JTA4bFgpXG4iLGlmYWNlLHBvcyxmbGFncyk7CgogIGlmIChmbGFncyAmIEZJTkRfRlJPTV9TVEFSVCkgewogICAgcG9zID0gVGhpcy0+c0luZm8uZHdTdGFydDsKICAgIGZsYWdzICY9IH4oRklORF9GUk9NX1NUQVJUfEZJTkRfUFJFVik7CiAgICBmbGFncyB8PSBGSU5EX05FWFQ7CiAgfQoKICBpZiAoVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplICE9IDApIHsKICAgIC8qIGNvbnZlcnQgc2FtcGxlcyBpbnRvIGJsb2NrIG51bWJlciB3aXRoIG9mZnNldCAqLwogICAgQVZJRklMRV9TYW1wbGVzVG9CbG9jayhUaGlzLCAmcG9zLCAmb2Zmc2V0KTsKICB9CgogIGlmIChmbGFncyAmIEZJTkRfVFlQRSkgewogICAgaWYgKGZsYWdzICYgRklORF9LRVkpIHsKICAgICAgd2hpbGUgKDAgPD0gcG9zICYmIHBvcyA8PSBUaGlzLT5sTGFzdEZyYW1lKSB7CglpZiAoVGhpcy0+aWR4RnJhbWVzW3Bvc10uZHdGbGFncyAmIEFWSUlGX0tFWUZSQU1FKQoJICBnb3RvIFJFVFVSTl9GT1VORDsKCglpZiAoZmxhZ3MgJiBGSU5EX05FWFQpCgkgIHBvcysrOwoJZWxzZQoJICBwb3MtLTsKICAgICAgfTsKICAgIH0gZWxzZSBpZiAoZmxhZ3MgJiBGSU5EX0FOWSkgewogICAgICB3aGlsZSAoMCA8PSBwb3MgJiYgcG9zIDw9IFRoaXMtPmxMYXN0RnJhbWUpIHsKCWlmIChUaGlzLT5pZHhGcmFtZXNbcG9zXS5kd0NodW5rTGVuZ3RoID4gMCkKCSAgZ290byBSRVRVUk5fRk9VTkQ7CgoJaWYgKGZsYWdzICYgRklORF9ORVhUKQoJICBwb3MrKzsKCWVsc2UKCSAgcG9zLS07CgogICAgICB9OwogICAgfSBlbHNlIGlmICgoZmxhZ3MgJiBGSU5EX0ZPUk1BVCkgJiYgVGhpcy0+aWR4Rm10Q2hhbmdlcyAhPSBOVUxMICYmCgkgICAgICAgVGhpcy0+c0luZm8uZmNjVHlwZSA9PSBzdHJlYW10eXBlVklERU8pIHsKICAgICAgaWYgKGZsYWdzICYgRklORF9ORVhUKSB7CglVTE9ORyBuOwoKCWZvciAobiA9IDA7IG4gPCBUaGlzLT5zSW5mby5kd0Zvcm1hdENoYW5nZUNvdW50OyBuKyspCgkgIGlmIChUaGlzLT5pZHhGbXRDaGFuZ2VzW25dLmNraWQgPj0gcG9zKSB7CiAgICAgICAgICAgIHBvcyA9IFRoaXMtPmlkeEZtdENoYW5nZXNbbl0uY2tpZDsKCSAgICBnb3RvIFJFVFVSTl9GT1VORDsKICAgICAgICAgIH0KICAgICAgfSBlbHNlIHsKCUxPTkcgbjsKCglmb3IgKG4gPSAoTE9ORylUaGlzLT5zSW5mby5kd0Zvcm1hdENoYW5nZUNvdW50OyBuID49IDA7IG4tLSkgewoJICBpZiAoVGhpcy0+aWR4Rm10Q2hhbmdlc1tuXS5ja2lkIDw9IHBvcykgewogICAgICAgICAgICBwb3MgPSBUaGlzLT5pZHhGbXRDaGFuZ2VzW25dLmNraWQ7CgkgICAgZ290byBSRVRVUk5fRk9VTkQ7CiAgICAgICAgICB9Cgl9CgoJaWYgKHBvcyA+IChMT05HKVRoaXMtPnNJbmZvLmR3U3RhcnQpCgkgIHJldHVybiAwOyAvKiBmb3JtYXQgY2hhbmdlcyBhbHdheXMgZm9yIGZpcnN0IGZyYW1lICovCiAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gLTE7CiAgfQoKIFJFVFVSTl9GT1VORDoKICBpZiAocG9zIDwgKExPTkcpVGhpcy0+c0luZm8uZHdTdGFydCkKICAgIHJldHVybiAtMTsKCiAgc3dpdGNoIChmbGFncyAmIEZJTkRfUkVUKSB7CiAgY2FzZSBGSU5EX0xFTkdUSDoKICAgIC8qIHBoeXNpY2FsIHNpemUgKi8KICAgIHBvcyA9IFRoaXMtPmlkeEZyYW1lc1twb3NdLmR3Q2h1bmtMZW5ndGg7CiAgICBicmVhazsKICBjYXNlIEZJTkRfT0ZGU0VUOgogICAgLyogcGh5c2ljYWwgcG9zaXRpb24gKi8KICAgIHBvcyA9IFRoaXMtPmlkeEZyYW1lc1twb3NdLmR3Q2h1bmtPZmZzZXQgKyAyICogc2l6ZW9mKERXT1JEKQogICAgICArIG9mZnNldCAqIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZTsKICAgIGJyZWFrOwogIGNhc2UgRklORF9TSVpFOgogICAgLyogbG9naWNhbCBzaXplICovCiAgICBpZiAoVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplKQogICAgICBwb3MgPSBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemU7CiAgICBlbHNlCiAgICAgIHBvcyA9IDE7CiAgICBicmVhazsKICBjYXNlIEZJTkRfSU5ERVg6CiAgICBGSVhNRSgiOiBGSU5EX0lOREVYIGZsYWcgaXMgbm90IHN1cHBvcnRlZCFcbiIpOwogICAgLyogVGhpcyBpcyBhbiBpbmRleCBpbiB0aGUgaW5kZXgtdGFibGUgb24gZGlzYy4gKi8KICAgIGJyZWFrOwogIH07IC8qIGVsc2UgbG9naWNhbCBwb3NpdGlvbiAqLwoKICByZXR1cm4gcG9zOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblJlYWRGb3JtYXQoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgcG9zLAoJCQkJCSAgICAgIExQVk9JRCBmb3JtYXQsIExPTkcgKmZvcm1hdHNpemUpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVsZCwlcCwlcClcbiIsIGlmYWNlLCBwb3MsIGZvcm1hdCwgZm9ybWF0c2l6ZSk7CgogIGlmIChmb3JtYXRzaXplID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBvbmx5IGludGVyZXN0ZWQgaW4gbmVlZGVkIGJ1ZmZlcnNpemU/ICovCiAgaWYgKGZvcm1hdCA9PSBOVUxMIHx8ICpmb3JtYXRzaXplIDw9IDApIHsKICAgICpmb3JtYXRzaXplID0gVGhpcy0+Y2JGb3JtYXQ7CgogICAgcmV0dXJuIEFWSUVSUl9PSzsKICB9CgogIC8qIGNvcHkgaW5pdGlhbCBmb3JtYXQgKG9ubHkgYXMgbXVjaCBhcyB3aWxsIGZpdCkgKi8KICBtZW1jcHkoZm9ybWF0LCBUaGlzLT5scEZvcm1hdCwgbWluKCooRFdPUkQqKWZvcm1hdHNpemUsIFRoaXMtPmNiRm9ybWF0KSk7CiAgaWYgKCooRFdPUkQqKWZvcm1hdHNpemUgPCBUaGlzLT5jYkZvcm1hdCkgewogICAgKmZvcm1hdHNpemUgPSBUaGlzLT5jYkZvcm1hdDsKICAgIHJldHVybiBBVklFUlJfQlVGRkVSVE9PU01BTEw7CiAgfQoKICAvKiBDb3VsZCBmb3JtYXQgY2hhbmdlPyBXaGVuIHllcyB3aWxsIGl0IGNoYW5nZT8gKi8KICBpZiAoKFRoaXMtPnNJbmZvLmR3RmxhZ3MgJiBBVklTVFJFQU1JTkZPX0ZPUk1BVENIQU5HRVMpICYmCiAgICAgIHBvcyA+IFRoaXMtPnNJbmZvLmR3U3RhcnQpIHsKICAgIExPTkcgbExhc3RGbXQ7CgogICAgbExhc3RGbXQgPSBJQVZJU3RyZWFtX2ZuRmluZFNhbXBsZShpZmFjZSwgcG9zLCBGSU5EX0ZPUk1BVHxGSU5EX1BSRVYpOwogICAgaWYgKGxMYXN0Rm10ID4gMCkgewogICAgICBGSVhNRSgiOiBuZWVkIHRvIHJlYWQgZm9ybWF0Y2hhbmdlIGZvciAlbGQgLS0gdW5pbXBsZW1lbnRlZCFcbiIsbExhc3RGbXQpOwogICAgfQogIH0KCiAgKmZvcm1hdHNpemUgPSBUaGlzLT5jYkZvcm1hdDsKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblNldEZvcm1hdChJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBwb3MsCgkJCQkJICAgICBMUFZPSUQgZm9ybWF0LCBMT05HIGZvcm1hdHNpemUpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBMUEJJVE1BUElORk9IRUFERVIgbHBiaU5ldyA9IChMUEJJVE1BUElORk9IRUFERVIpZm9ybWF0OwoKICBUUkFDRSgiKCVwLCVsZCwlcCwlbGQpXG4iLCBpZmFjZSwgcG9zLCBmb3JtYXQsIGZvcm1hdHNpemUpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKGZvcm1hdCA9PSBOVUxMIHx8IGZvcm1hdHNpemUgPD0gMCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIC8qIERvIHdlIGhhdmUgd3JpdGUgcGVybWlzc2lvbj8gKi8KICBpZiAoKFRoaXMtPnBhZi0+dU1vZGUgJiBNTUlPX1JXTU9ERSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIC8qIGNhbiBvbmx5IHNldCBmb3JtYXQgYmVmb3JlIGZyYW1lIGlzIHdyaXR0ZW4hICovCiAgaWYgKFRoaXMtPmxMYXN0RnJhbWUgPiBwb3MpCiAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICAvKiBpbml0aWFsIGZvcm1hdCBvciBhIGZvcm1hdGNoYW5nZT8gKi8KICBpZiAoVGhpcy0+bHBGb3JtYXQgPT0gTlVMTCkgewogICAgLyogaW5pdGlhbCBmb3JtYXQgKi8KICAgIGlmIChUaGlzLT5wYWYtPmR3TW92aUNodW5rUG9zICE9IDApCiAgICAgIHJldHVybiBBVklFUlJfRVJST1I7IC8qIHVzZXIgaGFzIHVzZWQgQVBJIGluIHdyb25nIHNlcXVuZWNlISAqLwoKICAgIFRoaXMtPmxwRm9ybWF0ID0gR2xvYmFsQWxsb2NQdHIoR01FTV9NT1ZFQUJMRSwgZm9ybWF0c2l6ZSk7CiAgICBpZiAoVGhpcy0+bHBGb3JtYXQgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgICBUaGlzLT5jYkZvcm1hdCA9IGZvcm1hdHNpemU7CgogICAgbWVtY3B5KFRoaXMtPmxwRm9ybWF0LCBmb3JtYXQsIGZvcm1hdHNpemUpOwoKICAgIC8qIHVwZGF0ZSBzb21lIGluZm9zIGFib3V0IHN0cmVhbSAqLwogICAgaWYgKFRoaXMtPnNJbmZvLmZjY1R5cGUgPT0gc3RyZWFtdHlwZVZJREVPKSB7CiAgICAgIExPTkcgbERpbTsKCiAgICAgIGxEaW0gPSBUaGlzLT5zSW5mby5yY0ZyYW1lLnJpZ2h0IC0gVGhpcy0+c0luZm8ucmNGcmFtZS5sZWZ0OwogICAgICBpZiAobERpbSA8IGxwYmlOZXctPmJpV2lkdGgpCglUaGlzLT5zSW5mby5yY0ZyYW1lLnJpZ2h0ID0gVGhpcy0+c0luZm8ucmNGcmFtZS5sZWZ0ICsgbHBiaU5ldy0+YmlXaWR0aDsKICAgICAgbERpbSA9IFRoaXMtPnNJbmZvLnJjRnJhbWUuYm90dG9tIC0gVGhpcy0+c0luZm8ucmNGcmFtZS50b3A7CiAgICAgIGlmIChsRGltIDwgbHBiaU5ldy0+YmlIZWlnaHQpCglUaGlzLT5zSW5mby5yY0ZyYW1lLmJvdHRvbSA9IFRoaXMtPnNJbmZvLnJjRnJhbWUudG9wICsgbHBiaU5ldy0+YmlIZWlnaHQ7CiAgICB9IGVsc2UgaWYgKFRoaXMtPnNJbmZvLmZjY1R5cGUgPT0gc3RyZWFtdHlwZUFVRElPKQogICAgICBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUgPSAoKExQV0FWRUZPUk1BVEVYKVRoaXMtPmxwRm9ybWF0KS0+bkJsb2NrQWxpZ247CgogICAgcmV0dXJuIEFWSUVSUl9PSzsKICB9IGVsc2UgewogICAgTU1DS0lORk8gICAgICAgICAgIGNrOwogICAgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmlPbGQgPSAoTFBCSVRNQVBJTkZPSEVBREVSKVRoaXMtPmxwRm9ybWF0OwogICAgUkdCUVVBRCAgICAgICAgICAgKnJnYk5ldyAgPSAoUkdCUVVBRCopKChMUEJZVEUpbHBiaU5ldyArIGxwYmlOZXctPmJpU2l6ZSk7CiAgICBBVklQQUxDSEFOR0UgICAgICAqbHBwYyA9IE5VTEw7CiAgICBVSU5UICAgICAgICAgICAgICAgbjsKCiAgICAvKiBwZXJoYXBzIGZvcm1hdCBjaGFuZ2UsIGNoZWNrIGl0IC4uLiAqLwogICAgaWYgKFRoaXMtPmNiRm9ybWF0ICE9IGZvcm1hdHNpemUpCiAgICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CgogICAgLyogbm8gZm9ybWF0IGNoYW5nZSwgb25seSB0aGUgaW5pdGlhbCBvbmUgKi8KICAgIGlmIChtZW1jbXAoVGhpcy0+bHBGb3JtYXQsIGZvcm1hdCwgZm9ybWF0c2l6ZSkgPT0gMCkKICAgICAgcmV0dXJuIEFWSUVSUl9PSzsKCiAgICAvKiBjaGVjayB0aGF0J3Mgb25seSB0aGUgcGFsZXR0ZSwgd2hpY2ggY2hhbmdlcyAqLwogICAgaWYgKGxwYmlPbGQtPmJpU2l6ZSAgICAgICAgIT0gbHBiaU5ldy0+YmlTaXplIHx8CglscGJpT2xkLT5iaVdpZHRoICAgICAgICE9IGxwYmlOZXctPmJpV2lkdGggfHwKCWxwYmlPbGQtPmJpSGVpZ2h0ICAgICAgIT0gbHBiaU5ldy0+YmlIZWlnaHQgfHwKCWxwYmlPbGQtPmJpUGxhbmVzICAgICAgIT0gbHBiaU5ldy0+YmlQbGFuZXMgfHwKCWxwYmlPbGQtPmJpQml0Q291bnQgICAgIT0gbHBiaU5ldy0+YmlCaXRDb3VudCB8fAoJbHBiaU9sZC0+YmlDb21wcmVzc2lvbiAhPSBscGJpTmV3LT5iaUNvbXByZXNzaW9uIHx8CglscGJpT2xkLT5iaUNsclVzZWQgICAgICE9IGxwYmlOZXctPmJpQ2xyVXNlZCkKICAgICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKCiAgICBUaGlzLT5zSW5mby5kd0ZsYWdzIHw9IEFWSVNUUkVBTUlORk9fRk9STUFUQ0hBTkdFUzsKCiAgICAvKiBzaW1wbHkgc2F5IGFsbCBjb2xvcnMgaGF2ZSBjaGFuZ2VkICovCiAgICBjay5ja2lkICAgPSBNQUtFQVZJQ0tJRChja3R5cGVQQUxjaGFuZ2UsIFRoaXMtPm5TdHJlYW0pOwogICAgY2suY2tzaXplID0gMiAqIHNpemVvZihXT1JEKSArIGxwYmlPbGQtPmJpQ2xyVXNlZCAqIHNpemVvZihQQUxFVFRFRU5UUlkpOwogICAgbHBwYyA9IChBVklQQUxDSEFOR0UqKUdsb2JhbEFsbG9jUHRyKEdNRU1fTU9WRUFCTEUsIGNrLmNrc2l6ZSk7CiAgICBpZiAobHBwYyA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgICBscHBjLT5iRmlyc3RFbnRyeSA9IDA7CiAgICBscHBjLT5iTnVtRW50cmllcyA9IChscGJpT2xkLT5iaUNsclVzZWQgPCAyNTYgPyBscGJpT2xkLT5iaUNsclVzZWQgOiAwKTsKICAgIGxwcGMtPndGbGFncyAgICAgID0gMDsKICAgIGZvciAobiA9IDA7IG4gPCBscGJpT2xkLT5iaUNsclVzZWQ7IG4rKykgewogICAgICBscHBjLT5wZU5ld1tuXS5wZVJlZCAgID0gcmdiTmV3W25dLnJnYlJlZDsKICAgICAgbHBwYy0+cGVOZXdbbl0ucGVHcmVlbiA9IHJnYk5ld1tuXS5yZ2JHcmVlbjsKICAgICAgbHBwYy0+cGVOZXdbbl0ucGVCbHVlICA9IHJnYk5ld1tuXS5yZ2JCbHVlOwogICAgICBscHBjLT5wZU5ld1tuXS5wZUZsYWdzID0gMDsKICAgIH0KCiAgICBpZiAobW1pb1NlZWsoVGhpcy0+cGFmLT5obW1pbywgVGhpcy0+cGFmLT5kd05leHRGcmFtZVBvcywgU0VFS19TRVQpID09IC0xKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgIGlmIChtbWlvQ3JlYXRlQ2h1bmsoVGhpcy0+cGFmLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgIGlmIChtbWlvV3JpdGUoVGhpcy0+cGFmLT5obW1pbywgKEhQU1RSKWxwcGMsIGNrLmNrc2l6ZSkgIT0gY2suY2tzaXplKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgIGlmIChtbWlvQXNjZW5kKFRoaXMtPnBhZi0+aG1taW8sICZjaywgMCkgIT0gU19PSykKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICBUaGlzLT5wYWYtPmR3TmV4dEZyYW1lUG9zICs9IGNrLmNrc2l6ZSArIDIgKiBzaXplb2YoRFdPUkQpOwoKICAgIEdsb2JhbEZyZWVQdHIobHBwYyk7CgogICAgcmV0dXJuIEFWSUZJTEVfQWRkRnJhbWUoVGhpcywgY2t0eXBlUEFMY2hhbmdlLCBuLCBjay5kd0RhdGFPZmZzZXQsIDApOwogIH0KfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5SZWFkKElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHN0YXJ0LAoJCQkJCUxPTkcgc2FtcGxlcywgTFBWT0lEIGJ1ZmZlciwKCQkJCQlMT05HIGJ1ZmZlcnNpemUsIExQTE9ORyBieXRlc3JlYWQsCgkJCQkJTFBMT05HIHNhbXBsZXNyZWFkKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgRFdPUkQgICAgc2l6ZTsKICBIUkVTVUxUICBocjsKCiAgVFJBQ0UoIiglcCwlbGQsJWxkLCVwLCVsZCwlcCwlcClcbiIsIGlmYWNlLCBzdGFydCwgc2FtcGxlcywgYnVmZmVyLAogCWJ1ZmZlcnNpemUsIGJ5dGVzcmVhZCwgc2FtcGxlc3JlYWQpOwoKICAvKiBjbGVhciByZXR1cm4gcGFyYW1ldGVycyBpZiBnaXZlbiAqLwogIGlmIChieXRlc3JlYWQgIT0gTlVMTCkKICAgICpieXRlc3JlYWQgPSAwOwogIGlmIChzYW1wbGVzcmVhZCAhPSBOVUxMKQogICAgKnNhbXBsZXNyZWFkID0gMDsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmICgoTE9ORylUaGlzLT5zSW5mby5kd1N0YXJ0ID4gc3RhcnQpCiAgICByZXR1cm4gQVZJRVJSX05PREFUQTsgLyogY291bGRuJ3QgcmVhZCBiZWZvcmUgc3RhcnQgb2Ygc3RyZWFtICovCiAgaWYgKFRoaXMtPnNJbmZvLmR3U3RhcnQgKyBUaGlzLT5zSW5mby5kd0xlbmd0aCA8IChEV09SRClzdGFydCkKICAgIHJldHVybiBBVklFUlJfTk9EQVRBOyAvKiBzdGFydCBpcyBwYXN0IGVuZCBvZiBzdHJlYW0gKi8KCiAgLyogc2hvdWxkIHdlIHJlYWQgYXMgbXVjaCBhcyBwb3NzaWJsZT8gKi8KICBpZiAoc2FtcGxlcyA9PSAtMSkgewogICAgLyogVXNlciBzaG91bGQga25vdyBob3cgbXVjaCB3ZSBoYXZlIHJlYWQgKi8KICAgIGlmIChieXRlc3JlYWQgPT0gTlVMTCAmJiBzYW1wbGVzcmVhZCA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAgIGlmIChUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUgIT0gMCkKICAgICAgc2FtcGxlcyA9IGJ1ZmZlcnNpemUgLyBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemU7CiAgICBlbHNlCiAgICAgIHNhbXBsZXMgPSAxOwogIH0KCiAgLyogbGltaXQgdG8gZW5kIG9mIHN0cmVhbSAqLwogIGlmICgoTE9ORylUaGlzLT5zSW5mby5kd0xlbmd0aCA8IHNhbXBsZXMpCiAgICBzYW1wbGVzID0gVGhpcy0+c0luZm8uZHdMZW5ndGg7CiAgaWYgKChzdGFydCAtIFRoaXMtPnNJbmZvLmR3U3RhcnQpID4gKFRoaXMtPnNJbmZvLmR3TGVuZ3RoIC0gc2FtcGxlcykpCiAgICBzYW1wbGVzID0gVGhpcy0+c0luZm8uZHdMZW5ndGggLSAoc3RhcnQgLSBUaGlzLT5zSW5mby5kd1N0YXJ0KTsKCiAgLyogbm90aGluZyB0byByZWFkPyBUaGVuIGxlYXZlIC4uLiAqLwogIGlmIChzYW1wbGVzID09IDApCiAgICByZXR1cm4gQVZJRVJSX09LOwoKICBpZiAoVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplICE9IDApIHsKICAgIC8qIGZpeGVkIHNhbXBsZXNpemUgLS0gd2UgY2FuIHJlYWQgb3ZlciBmcmFtZS9ibG9jayBib3VuZGFyaWVzICovCiAgICBVTE9ORyBibG9jayA9IHN0YXJ0OwogICAgTE9ORyBvZmZzZXQgPSAwOwoKICAgIC8qIGNvbnZlcnQgc3RhcnQgc2FtcGxlIHRvIGJsb2NrLG9mZnNldCBwYWlyICovCiAgICBBVklGSUxFX1NhbXBsZXNUb0Jsb2NrKFRoaXMsICZibG9jaywgJm9mZnNldCk7CgogICAgLyogY29udmVydCBzYW1wbGVzIHRvIGJ5dGVzICovCiAgICBzYW1wbGVzICo9IFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZTsKCiAgICB3aGlsZSAoc2FtcGxlcyA+IDAgJiYgYnVmZmVyc2l6ZSA+IDApIHsKICAgICAgaWYgKGJsb2NrICE9IFRoaXMtPmR3Q3VycmVudEZyYW1lKSB7CglociA9IEFWSUZJTEVfUmVhZEJsb2NrKFRoaXMsIGJsb2NrLCBOVUxMLCAwKTsKCWlmIChGQUlMRUQoaHIpKQoJICByZXR1cm4gaHI7CiAgICAgIH0KCiAgICAgIHNpemUgPSBtaW4oKERXT1JEKXNhbXBsZXMsIChEV09SRClidWZmZXJzaXplKTsKICAgICAgc2l6ZSA9IG1pbihzaXplLCBUaGlzLT5jYkJ1ZmZlciAtIG9mZnNldCk7CiAgICAgIG1lbWNweShidWZmZXIsICgoQllURSopJlRoaXMtPmxwQnVmZmVyWzJdKSArIG9mZnNldCwgc2l6ZSk7CgogICAgICBibG9jaysrOwogICAgICBvZmZzZXQgPSAwOwogICAgICBidWZmZXIgPSAoKExQQllURSlidWZmZXIpK3NpemU7CiAgICAgIHNhbXBsZXMgICAgLT0gc2l6ZTsKICAgICAgYnVmZmVyc2l6ZSAtPSBzaXplOwoKICAgICAgLyogZmlsbCBvdXQgcmV0dXJuIHBhcmFtZXRlcnMgaWYgZ2l2ZW4gKi8KICAgICAgaWYgKGJ5dGVzcmVhZCAhPSBOVUxMKQoJKmJ5dGVzcmVhZCAgICs9IHNpemU7CiAgICAgIGlmIChzYW1wbGVzcmVhZCAhPSBOVUxMKQoJKnNhbXBsZXNyZWFkICs9IHNpemUgLyBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemU7CiAgICB9CgogICAgaWYgKHNhbXBsZXMgPT0gMCkKICAgICAgcmV0dXJuIEFWSUVSUl9PSzsKICAgIGVsc2UKICAgICAgcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKICB9IGVsc2UgewogICAgLyogdmFyaWFibGUgc2FtcGxlc2l6ZSAtLSB3ZSBjYW4gb25seSByZWFkIG9uZSBmdWxsIGZyYW1lL2Jsb2NrICovCiAgICBpZiAoc2FtcGxlcyA+IDEpCiAgICAgIHNhbXBsZXMgPSAxOwoKICAgIGFzc2VydChzdGFydCA8PSBUaGlzLT5sTGFzdEZyYW1lKTsKICAgIHNpemUgPSBUaGlzLT5pZHhGcmFtZXNbc3RhcnRdLmR3Q2h1bmtMZW5ndGg7CiAgICBpZiAoYnVmZmVyICE9IE5VTEwgJiYgYnVmZmVyc2l6ZSA+PSBzaXplKSB7CiAgICAgIGhyID0gQVZJRklMRV9SZWFkQmxvY2soVGhpcywgc3RhcnQsIGJ1ZmZlciwgc2l6ZSk7CiAgICAgIGlmIChGQUlMRUQoaHIpKQoJcmV0dXJuIGhyOwogICAgfSBlbHNlIGlmIChidWZmZXIgIT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKCiAgICAvKiBmaWxsIG91dCByZXR1cm4gcGFyYW1ldGVycyBpZiBnaXZlbiAqLwogICAgaWYgKGJ5dGVzcmVhZCAhPSBOVUxMKQogICAgICAqYnl0ZXNyZWFkID0gc2l6ZTsKICAgIGlmIChzYW1wbGVzcmVhZCAhPSBOVUxMKQogICAgICAqc2FtcGxlc3JlYWQgPSBzYW1wbGVzOwoKICAgIHJldHVybiBBVklFUlJfT0s7CiAgfQp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbldyaXRlKElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHN0YXJ0LAoJCQkJCSBMT05HIHNhbXBsZXMsIExQVk9JRCBidWZmZXIsCgkJCQkJIExPTkcgYnVmZmVyc2l6ZSwgRFdPUkQgZmxhZ3MsCgkJCQkJIExQTE9ORyBzYW1wd3JpdHRlbiwKCQkJCQkgTFBMT05HIGJ5dGVzd3JpdHRlbikKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIEZPVVJDQyAgY2tpZDsKICBIUkVTVUxUIGhyOwoKICBUUkFDRSgiKCVwLCVsZCwlbGQsJXAsJWxkLDB4JTA4bFgsJXAsJXApXG4iLCBpZmFjZSwgc3RhcnQsIHNhbXBsZXMsCglidWZmZXIsIGJ1ZmZlcnNpemUsIGZsYWdzLCBzYW1wd3JpdHRlbiwgYnl0ZXN3cml0dGVuKTsKCiAgLyogY2xlYXIgcmV0dXJuIHBhcmFtZXRlcnMgaWYgZ2l2ZW4gKi8KICBpZiAoc2FtcHdyaXR0ZW4gIT0gTlVMTCkKICAgICpzYW1wd3JpdHRlbiA9IDA7CiAgaWYgKGJ5dGVzd3JpdHRlbiAhPSBOVUxMKQogICAgKmJ5dGVzd3JpdHRlbiA9IDA7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoYnVmZmVyID09IE5VTEwgJiYgKGJ1ZmZlcnNpemUgPiAwIHx8IHNhbXBsZXMgPiAwKSkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIC8qIEhhdmUgd2Ugd3JpdGUgcGVybWlzc2lvbj8gKi8KICBpZiAoKFRoaXMtPnBhZi0+dU1vZGUgJiBNTUlPX1JXTU9ERSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIHN3aXRjaCAoVGhpcy0+c0luZm8uZmNjVHlwZSkgewogIGNhc2Ugc3RyZWFtdHlwZUFVRElPOgogICAgY2tpZCA9IE1BS0VBVklDS0lEKGNrdHlwZVdBVkVieXRlcywgVGhpcy0+blN0cmVhbSk7CiAgICBicmVhazsKICBkZWZhdWx0OgogICAgaWYgKChmbGFncyAmIEFWSUlGX0tFWUZSQU1FKSAmJiBidWZmZXJzaXplICE9IDApCiAgICAgIGNraWQgPSBNQUtFQVZJQ0tJRChja3R5cGVESUJiaXRzLCBUaGlzLT5uU3RyZWFtKTsKICAgIGVsc2UKICAgICAgY2tpZCA9IE1BS0VBVklDS0lEKGNrdHlwZURJQmNvbXByZXNzZWQsIFRoaXMtPm5TdHJlYW0pOwogICAgYnJlYWs7CiAgfTsKCiAgLyogYXBwZW5kIHRvIGVuZCBvZiBzdHJlYW0/ICovCiAgaWYgKHN0YXJ0ID09IC0xKSB7CiAgICBpZiAoVGhpcy0+bExhc3RGcmFtZSA9PSAtMSkKICAgICAgc3RhcnQgPSBUaGlzLT5zSW5mby5kd1N0YXJ0OwogICAgZWxzZQogICAgICBzdGFydCA9IFRoaXMtPnNJbmZvLmR3TGVuZ3RoOwogIH0gZWxzZSBpZiAoVGhpcy0+bExhc3RGcmFtZSA9PSAtMSkKICAgIFRoaXMtPnNJbmZvLmR3U3RhcnQgPSBzdGFydDsKCiAgaWYgKFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSAhPSAwKSB7CiAgICAvKiBmaXhlZCBzYW1wbGUgc2l6ZSAtLSBhdWRpbyBsaWtlICovCiAgICBpZiAoc2FtcGxlcyAqIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSAhPSBidWZmZXJzaXplKQogICAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAgIC8qIENvdWxkbid0IHNraXAgYXVkaW8tbGlrZSBkYXRhIC0tIFVzZXIgbXVzdCBzdXBwbHkgYXBwcm9wcmlhdGUgc2lsZW5jZSAqLwogICAgaWYgKFRoaXMtPnNJbmZvLmR3TGVuZ3RoICE9IHN0YXJ0KQogICAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICAgIC8qIENvbnZlcnQgcG9zaXRpb24gdG8gZnJhbWUvYmxvY2sgKi8KICAgIHN0YXJ0ID0gVGhpcy0+bExhc3RGcmFtZSArIDE7CgogICAgaWYgKChUaGlzLT5wYWYtPmZJbmZvLmR3RmxhZ3MgJiBBVklGSUxFSU5GT19JU0lOVEVSTEVBVkVEKSA9PSAwKSB7CiAgICAgIEZJWE1FKCI6IG5vdCBpbnRlcmxlYXZlZCwgY291bGQgY29sbGVjdCBhdWRpbyBkYXRhIVxuIik7CiAgICB9CiAgfSBlbHNlIHsKICAgIC8qIHZhcmlhYmxlIHNhbXBsZSBzaXplIC0tIHZpZGVvIGxpa2UgKi8KICAgIGlmIChzYW1wbGVzID4gMSkKICAgICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKCiAgICAvKiBtdXN0IHdlIGZpbGwgdXAgd2l0aCBlbXB0eSBmcmFtZXM/ICovCiAgICBpZiAoVGhpcy0+bExhc3RGcmFtZSAhPSAtMSkgewogICAgICBGT1VSQ0MgY2tpZDIgPSBNQUtFQVZJQ0tJRChja3R5cGVESUJjb21wcmVzc2VkLCBUaGlzLT5uU3RyZWFtKTsKCiAgICAgIHdoaWxlIChzdGFydCA+IFRoaXMtPmxMYXN0RnJhbWUgKyAxKSB7CglociA9IEFWSUZJTEVfV3JpdGVCbG9jayhUaGlzLCBUaGlzLT5sTGFzdEZyYW1lICsgMSwgY2tpZDIsIDAsIE5VTEwsIDApOwoJaWYgKEZBSUxFRChocikpCgkgIHJldHVybiBocjsKICAgICAgfQogICAgfQogIH0KCiAgLyogd3JpdGUgdGhlIGJsb2NrIG5vdyAqLwogIGhyID0gQVZJRklMRV9Xcml0ZUJsb2NrKFRoaXMsIHN0YXJ0LCBja2lkLCBmbGFncywgYnVmZmVyLCBidWZmZXJzaXplKTsKICBpZiAoU1VDQ0VFREVEKGhyKSkgewogICAgLyogZmlsbCBvdXQgcmV0dXJuIHBhcmFtZXRlcnMgaWYgZ2l2ZW4gKi8KICAgIGlmIChzYW1wd3JpdHRlbiAhPSBOVUxMKQogICAgICAqc2FtcHdyaXR0ZW4gPSBzYW1wbGVzOwogICAgaWYgKGJ5dGVzd3JpdHRlbiAhPSBOVUxMKQogICAgICAqYnl0ZXN3cml0dGVuID0gYnVmZmVyc2l6ZTsKICB9CgogIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5EZWxldGUoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgc3RhcnQsCgkJCQkJICBMT05HIHNhbXBsZXMpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBGSVhNRSgiKCVwLCVsZCwlbGQpOiBzdHViXG4iLCBpZmFjZSwgc3RhcnQsIHNhbXBsZXMpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKHN0YXJ0IDwgMCB8fCBzYW1wbGVzIDwgMCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIC8qIERlbGV0ZSBiZWZvcmUgc3RhcnQgb2Ygc3RyZWFtPyAqLwogIGlmIChzdGFydCArIHNhbXBsZXMgPCBUaGlzLT5zSW5mby5kd1N0YXJ0KQogICAgcmV0dXJuIEFWSUVSUl9PSzsKCiAgLyogRGVsZXRlIGFmdGVyIGVuZCBvZiBzdHJlYW0/ICovCiAgaWYgKHN0YXJ0ID4gVGhpcy0+c0luZm8uZHdMZW5ndGgpCiAgICByZXR1cm4gQVZJRVJSX09LOwoKICAvKiBGb3IgdGhlIHJlc3Qgd2UgbmVlZCB3cml0ZSBwZXJtaXNzaW9ucyAqLwogIGlmICgoVGhpcy0+cGFmLT51TW9kZSAmIE1NSU9fUldNT0RFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgLyogMS4gb3ZlcndyaXRlIHRoZSBkYXRhIHdpdGggSlVOSwogICAqCiAgICogaWYgSVNJTlRFUkxFQVZFRCB7CiAgICogICAyLiBjb25jYXQgYWxsIG5laWdoYm91cmVkIEpVTkstYmxvY2tzIGluIHRoaXMgcmVjb3JkIHRvIG9uZQogICAqICAgMy4gaWYgdGhpcyByZWNvcmQgb25seSBjb250YWlucyBKVU5LIGFuZCBpcyBhdCBlbmQgc2V0IGR3TmV4dEZyYW1lUG9zCiAgICogICAgICB0byBzdGFydCBvZiB0aGlzIHJlY29yZCwgcmVwZWF0IHRoaXMuCiAgICogfSBlbHNlIHsKICAgKiAgIDIuIGNvbmNhdCBhbGwgbmVpZ2hib3VyZWQgSlVOSy1ibG9ja3MuCiAgICogICAzLiBpZiB0aGUgSlVOSyBibG9jayBpcyBhdCB0aGUgZW5kLCB0aGVuIHNldCBkd05leHRGcmFtZVBvcyB0bwogICAqICAgICAgc3RhcnQgb2YgdGhpcyBibG9jay4KICAgKiB9CiAgICovCgogIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUmVhZERhdGEoSUFWSVN0cmVhbSAqaWZhY2UsIERXT1JEIGZjYywKCQkJCQkgICAgTFBWT0lEIGxwLCBMUExPTkcgbHByZWFkKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwweCUwOGxYLCVwLCVwKVxuIiwgaWZhY2UsIGZjYywgbHAsIGxwcmVhZCk7CgogIGlmIChmY2MgPT0gY2tpZFNUUkVBTUhBTkRMRVJEQVRBKSB7CiAgICBpZiAoVGhpcy0+bHBIYW5kbGVyRGF0YSAhPSBOVUxMICYmIFRoaXMtPmNiSGFuZGxlckRhdGEgPiAwKSB7CiAgICAgIGlmIChscCA9PSBOVUxMIHx8ICpscHJlYWQgPD0gMCkgewoJKmxwcmVhZCA9IFRoaXMtPmNiSGFuZGxlckRhdGE7CglyZXR1cm4gQVZJRVJSX09LOwogICAgICB9CgogICAgICBtZW1jcHkobHAsIFRoaXMtPmxwSGFuZGxlckRhdGEsIG1pbihUaGlzLT5jYkhhbmRsZXJEYXRhLCAqbHByZWFkKSk7CiAgICAgIGlmICgqbHByZWFkIDwgVGhpcy0+Y2JIYW5kbGVyRGF0YSkKCXJldHVybiBBVklFUlJfQlVGRkVSVE9PU01BTEw7CiAgICAgIHJldHVybiBBVklFUlJfT0s7CiAgICB9IGVsc2UKICAgICAgcmV0dXJuIEFWSUVSUl9OT0RBVEE7CiAgfSBlbHNlCiAgICByZXR1cm4gUmVhZEV4dHJhQ2h1bmsoJlRoaXMtPmV4dHJhLCBmY2MsIGxwLCBscHJlYWQpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbldyaXRlRGF0YShJQVZJU3RyZWFtICppZmFjZSwgRFdPUkQgZmNjLAoJCQkJCSAgICAgTFBWT0lEIGxwLCBMT05HIHNpemUpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLDB4JTA4bHgsJXAsJWxkKVxuIiwgaWZhY2UsIGZjYywgbHAsIHNpemUpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKGxwID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIGlmIChzaXplIDw9IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CgogIC8qIG5lZWQgd3JpdGUgcGVybWlzc2lvbiAqLwogIGlmICgoVGhpcy0+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+c3pGaWxlTmFtZSksIHN6VHlwZSwgY291bnQpOwoJICB9CgkgIGJyZWFrOwoJY2FzZSBja2lkU1RSRUFNTkFNRToKCSAgeyAvKiBzdHJlYW1uYW1lIHdpbGwgYmUgc2F2ZWQgYXMgQVNDSUkgc3RyaW5nICovCgkgICAgTFBTVFIgc3RyID0gKExQU1RSKUxvY2FsQWxsb2MoTE1FTV9GSVhFRCwgY2suY2tzaXplKTsKCSAgICBpZiAoc3RyID09IE5VTEwpCgkgICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCgkgICAgaWYgKG1taW9SZWFkKFRoaXMtPmhtbWlvLCAoSFBTVFIpc3RyLCBjay5ja3NpemUpICE9IGNrLmNrc2l6ZSkKCSAgICB7CgkgICAgICBMb2NhbEZyZWUoKEhMT0NBTClzdHIpOwoJICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCSAgICB9CgoJICAgIE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBzdHIsIC0xLCBwU3RyZWFtLT5zSW5mby5zek5hbWUsCgkJCQlzaXplb2YocFN0cmVhbS0+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+ZkluZm8uZHdTdHJlYW1zKQogICAgICByZXR1cm4gQVZJRVJSX0JBREZPUk1BVDsKCiAgICBpZiAoKmJBYnNvbHV0ZSAmJiBscC0+ZHdDaHVua09mZnNldCA8IFRoaXMtPmR3TW92aUNodW5rUG9zKQogICAgICAqYkFic29sdXRlID0gRkFMU0U7CgogICAgaWYgKCpiQWJzb2x1dGUpCiAgICAgIGxwLT5kd0NodW5rT2Zmc2V0ICs9IHNpemVvZihEV09SRCk7CiAgICBlbHNlCiAgICAgIGxwLT5kd0NodW5rT2Zmc2V0ICs9IHBvczsKCiAgICBpZiAoRkFJTEVEKEFWSUZJTEVfQWRkRnJhbWUoVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dLCBscC0+Y2tpZCwgbHAtPmR3Q2h1bmtMZW5ndGgsIGxwLT5kd0NodW5rT2Zmc2V0LCBscC0+ZHdGbGFncykpKQogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKICB9CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfUmVhZEJsb2NrKElBVklTdHJlYW1JbXBsICpUaGlzLCBEV09SRCBwb3MsCgkJCQkgTFBWT0lEIGJ1ZmZlciwgTE9ORyBzaXplKQp7CiAgLyogcHJlLWNvbmRpdGlvbnMgKi8KICBhc3NlcnQoVGhpcyAhPSBOVUxMKTsKICBhc3NlcnQoVGhpcy0+cGFmICE9IE5VTEwpOwogIGFzc2VydChUaGlzLT5wYWYtPmhtbWlvICE9IE5VTEwpOwogIGFzc2VydChUaGlzLT5zSW5mby5kd1N0YXJ0IDw9IHBvcyAmJiBwb3MgPCBUaGlzLT5zSW5mby5kd0xlbmd0aCk7CiAgYXNzZXJ0KHBvcyA8PSBUaGlzLT5sTGFzdEZyYW1lKTsKCiAgLyogc2hvdWxkIHdlIHJlYWQgYXMgbXVjaCBhcyBibG9jayBnaXZlcyB1cz8gKi8KICBpZiAoc2l6ZSA9PSAwIHx8IHNpemUgPiBUaGlzLT5pZHhGcmFtZXNbcG9zXS5kd0NodW5rTGVuZ3RoKQogICAgc2l6ZSA9IFRoaXMtPmlkeEZyYW1lc1twb3NdLmR3Q2h1bmtMZW5ndGg7CgogIC8qIHJlYWQgaW50byBvdXQgb3duIGJ1ZmZlciBvciBnaXZlbiBvbmU/ICovCiAgaWYgKGJ1ZmZlciA9PSBOVUxMKSB7CiAgICAvKiB3ZSBhbHNvIHJlYWQgdGhlIGNodW5rICovCiAgICBzaXplICs9IDIgKiBzaXplb2YoRFdPUkQpOwoKICAgIC8qIGNoZWNrIHRoYXQgYnVmZmVyIGlzIGJpZyBlbm91Z2ggLS0gZG9uJ3QgdHJ1c3QgZHdTdWdnZXN0ZWRCdWZmZXJTaXplICovCiAgICBpZiAoVGhpcy0+bHBCdWZmZXIgPT0gTlVMTCB8fCBzaXplIDwgVGhpcy0+Y2JCdWZmZXIpIHsKICAgICAgRFdPUkQgbWF4U2l6ZSA9IG1heChzaXplLCBUaGlzLT5zSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUpOwoKICAgICAgaWYgKFRoaXMtPmxwQnVmZmVyID09IE5VTEwpCglUaGlzLT5scEJ1ZmZlciA9IChMUERXT1JEKUdsb2JhbEFsbG9jUHRyKEdNRU1fTU9WRUFCTEUsIG1heFNpemUpOwogICAgICBlbHNlCglUaGlzLT5scEJ1ZmZlciA9CgkgIChMUERXT1JEKUdsb2JhbFJlQWxsb2NQdHIoVGhpcy0+bHBCdWZmZXIsIG1heFNpemUsIEdNRU1fTU9WRUFCTEUpOwogICAgICBpZiAoVGhpcy0+bHBCdWZmZXIgPT0gTlVMTCkKCXJldHVybiBBVklFUlJfTUVNT1JZOwogICAgICBUaGlzLT5jYkJ1ZmZlciA9IG1heChzaXplLCBUaGlzLT5zSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUpOwogICAgfQoKICAgIC8qIG5vdyByZWFkIHRoZSBjb21wbGV0ZSBjaHVuayBpbnRvIG91ciBidWZmZXIgKi8KICAgIGlmIChtbWlvU2VlayhUaGlzLT5wYWYtPmhtbWlvLCBUaGlzLT5pZHhGcmFtZXNbcG9zXS5kd0NodW5rT2Zmc2V0LCBTRUVLX1NFVCkgPT0gLTEpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CiAgICBpZiAobW1pb1JlYWQoVGhpcy0+cGFmLT5obW1pbywgKEhQU1RSKVRoaXMtPmxwQnVmZmVyLCBzaXplKSAhPSBzaXplKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwoKICAgIC8qIGNoZWNrIGlmIGl0IHdhcyB0aGUgY29ycmVjdCBibG9jayB3aGljaCB3ZSBoYXZlIHJlYWQgKi8KICAgIGlmIChUaGlzLT5scEJ1ZmZlclswXSAhPSBUaGlzLT5pZHhGcmFtZXNbcG9zXS5ja2lkIHx8CglUaGlzLT5scEJ1ZmZlclsxXSAhPSBUaGlzLT5pZHhGcmFtZXNbcG9zXS5kd0NodW5rTGVuZ3RoKSB7CiAgICAgIEVSUigiOiBibG9jayAlbGQgbm90IGZvdW5kIGF0IDB4JTA4bFhcbiIsIHBvcywgVGhpcy0+aWR4RnJhbWVzW3Bvc10uZHdDaHVua09mZnNldCk7CiAgICAgIEVSUigiOiBJbmRleCBzYXlzOiAnJTQuNHMnKDB4JTA4bFgpIHNpemUgMHglMDhsWFxuIiwKCSAgKGNoYXIqKSZUaGlzLT5pZHhGcmFtZXNbcG9zXS5ja2lkLCBUaGlzLT5pZHhGcmFtZXNbcG9zXS5ja2lkLAoJICBUaGlzLT5pZHhGcmFtZXNbcG9zXS5kd0NodW5rTGVuZ3RoKTsKICAgICAgRVJSKCI6IERhdGEgIHNheXM6ICclNC40cycoMHglMDhsWCkgc2l6ZSAweCUwOGxYXG4iLAoJICAoY2hhciopJlRoaXMtPmxwQnVmZmVyWzBdLCBUaGlzLT5scEJ1ZmZlclswXSwgVGhpcy0+bHBCdWZmZXJbMV0pOwogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwogICAgfQogIH0gZWxzZSB7CiAgICBpZiAobW1pb1NlZWsoVGhpcy0+cGFmLT5obW1pbywgVGhpcy0+aWR4RnJhbWVzW3Bvc10uZHdDaHVua09mZnNldCArIDIgKiBzaXplb2YoRFdPUkQpLCBTRUVLX1NFVCkgPT0gLTEpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CiAgICBpZiAobW1pb1JlYWQoVGhpcy0+cGFmLT5obW1pbywgKEhQU1RSKWJ1ZmZlciwgc2l6ZSkgIT0gc2l6ZSkKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKICB9CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyB2b2lkICAgIEFWSUZJTEVfU2FtcGxlc1RvQmxvY2soSUFWSVN0cmVhbUltcGwgKlRoaXMsIExQTE9ORyBwb3MsCgkJCQkgICAgICBMUExPTkcgb2Zmc2V0KQp7CiAgTE9ORyBibG9jazsKCiAgLyogcHJlLWNvbmRpdGlvbnMgKi8KICBhc3NlcnQoVGhpcyAhPSBOVUxMKTsKICBhc3NlcnQocG9zICE9IE5VTEwpOwogIGFzc2VydChvZmZzZXQgIT0gTlVMTCk7CiAgYXNzZXJ0KFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSAhPSAwKTsKICBhc3NlcnQoKnBvcyA+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=