LyoKICogQ29weXJpZ2h0IDE5OTkgTWFyY3VzIE1laXNzbmVyCiAqIENvcHlyaWdodCAyMDAyLTIwMDMgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgovKiBUT0RPOgogKiAgLSBJQVZJU3RyZWFtaW5nIGludGVyZmFjZSBpcyBtaXNzaW5nIGZvciB0aGUgSUFWSVN0cmVhbUltcGwKICogIC0gSUFWSVN0cmVhbV9mbkZpbmRTYW1wbGU6IEZJTkRfSU5ERVggaXNuJ3Qgc3VwcG9ydGVkLgogKiAgLSBJQVZJU3RyZWFtX2ZuUmVhZEZvcm1hdDogZm9ybWF0Y2hhbmdlcyBhcmVuJ3QgcmVhZCBpbi4KICogIC0gSUFWSVN0cmVhbV9mbkRlbGV0ZTogYSBzdHViLgogKiAgLSBJQVZJU3RyZWFtX2ZuU2V0SW5mbzogYSBzdHViLgogKiAgLSBtYWtlIHRocmVhZCBzYWZlCiAqCiAqIEtOT1dOIEJ1Z3M6CiAqICAtIG5hdGl2ZSB2ZXJzaW9uIGNhbiBoYW5ndXAgd2hlbiByZWFkaW5nIGEgZmlsZSBnZW5lcmF0ZWQgd2l0aCB0aGlzIERMTC4KICogICAgV2hlbiBpbmRleCBpcyBtaXNzaW5nIGl0IHdvcmtzLCBidXQgaW5kZXggc2VlbXMgdG8gYmUgb2theS4KICovCgojZGVmaW5lIENPTV9OT19XSU5ET1dTX0gKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbmRvd3N4LmgiCiNpbmNsdWRlICJtbXN5c3RlbS5oIgojaW5jbHVkZSAidmZ3LmgiCgojaW5jbHVkZSAiYXZpZmlsZV9wcml2YXRlLmgiCiNpbmNsdWRlICJleHRyYWNodW5rLmgiCgojaW5jbHVkZSAid2luZS91bmljb2RlLmgiCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChhdmlmaWxlKTsKCiNpZm5kZWYgSURYX1BFUl9CTE9DSwojZGVmaW5lIElEWF9QRVJfQkxPQ0sgMjczMAojZW5kaWYKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mblF1ZXJ5SW50ZXJmYWNlKElBVklGaWxlKiBpZmFjZSxSRUZJSUQgcmVmaWlkLExQVk9JRCAqb2JqKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElBVklGaWxlX2ZuQWRkUmVmKElBVklGaWxlKiBpZmFjZSk7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJQVZJRmlsZV9mblJlbGVhc2UoSUFWSUZpbGUqIGlmYWNlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuSW5mbyhJQVZJRmlsZSppZmFjZSxBVklGSUxFSU5GT1cqYWZpLExPTkcgc2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkdldFN0cmVhbShJQVZJRmlsZSppZmFjZSxQQVZJU1RSRUFNKmF2aXMsRFdPUkQgZmNjVHlwZSxMT05HIGxQYXJhbSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkNyZWF0ZVN0cmVhbShJQVZJRmlsZSppZmFjZSxQQVZJU1RSRUFNKmF2aXMsQVZJU1RSRUFNSU5GT1cqYXNpKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuV3JpdGVEYXRhKElBVklGaWxlKmlmYWNlLERXT1JEIGNraWQsTFBWT0lEIGxwRGF0YSxMT05HIHNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5SZWFkRGF0YShJQVZJRmlsZSppZmFjZSxEV09SRCBja2lkLExQVk9JRCBscERhdGEsTE9ORyAqc2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkVuZFJlY29yZChJQVZJRmlsZSppZmFjZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkRlbGV0ZVN0cmVhbShJQVZJRmlsZSppZmFjZSxEV09SRCBmY2NUeXBlLExPTkcgbFBhcmFtKTsKCnN0cnVjdCBJQVZJRmlsZVZ0YmwgaWF2aWZ0ID0gewogIElBVklGaWxlX2ZuUXVlcnlJbnRlcmZhY2UsCiAgSUFWSUZpbGVfZm5BZGRSZWYsCiAgSUFWSUZpbGVfZm5SZWxlYXNlLAogIElBVklGaWxlX2ZuSW5mbywKICBJQVZJRmlsZV9mbkdldFN0cmVhbSwKICBJQVZJRmlsZV9mbkNyZWF0ZVN0cmVhbSwKICBJQVZJRmlsZV9mbldyaXRlRGF0YSwKICBJQVZJRmlsZV9mblJlYWREYXRhLAogIElBVklGaWxlX2ZuRW5kUmVjb3JkLAogIElBVklGaWxlX2ZuRGVsZXRlU3RyZWFtCn07CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuUXVlcnlJbnRlcmZhY2UoSVBlcnNpc3RGaWxlKmlmYWNlLFJFRklJRCByZWZpaWQsTFBWT0lEKm9iaik7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5BZGRSZWYoSVBlcnNpc3RGaWxlKmlmYWNlKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElQZXJzaXN0RmlsZV9mblJlbGVhc2UoSVBlcnNpc3RGaWxlKmlmYWNlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkdldENsYXNzSUQoSVBlcnNpc3RGaWxlKmlmYWNlLENMU0lEKnBDbGFzc0lEKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mbklzRGlydHkoSVBlcnNpc3RGaWxlKmlmYWNlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkxvYWQoSVBlcnNpc3RGaWxlKmlmYWNlLExQQ09MRVNUUiBwc3pGaWxlTmFtZSxEV09SRCBkd01vZGUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuU2F2ZShJUGVyc2lzdEZpbGUqaWZhY2UsTFBDT0xFU1RSIHBzekZpbGVOYW1lLEJPT0wgZlJlbWVtYmVyKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mblNhdmVDb21wbGV0ZWQoSVBlcnNpc3RGaWxlKmlmYWNlLExQQ09MRVNUUiBwc3pGaWxlTmFtZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5HZXRDdXJGaWxlKElQZXJzaXN0RmlsZSppZmFjZSxMUE9MRVNUUipwcHN6RmlsZU5hbWUpOwoKc3RydWN0IElQZXJzaXN0RmlsZVZ0YmwgaXBlcnNpc3RmdCA9IHsKICBJUGVyc2lzdEZpbGVfZm5RdWVyeUludGVyZmFjZSwKICBJUGVyc2lzdEZpbGVfZm5BZGRSZWYsCiAgSVBlcnNpc3RGaWxlX2ZuUmVsZWFzZSwKICBJUGVyc2lzdEZpbGVfZm5HZXRDbGFzc0lELAogIElQZXJzaXN0RmlsZV9mbklzRGlydHksCiAgSVBlcnNpc3RGaWxlX2ZuTG9hZCwKICBJUGVyc2lzdEZpbGVfZm5TYXZlLAogIElQZXJzaXN0RmlsZV9mblNhdmVDb21wbGV0ZWQsCiAgSVBlcnNpc3RGaWxlX2ZuR2V0Q3VyRmlsZQp9OwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5RdWVyeUludGVyZmFjZShJQVZJU3RyZWFtKmlmYWNlLFJFRklJRCByZWZpaWQsTFBWT0lEICpvYmopOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUFWSVN0cmVhbV9mbkFkZFJlZihJQVZJU3RyZWFtKmlmYWNlKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElBVklTdHJlYW1fZm5SZWxlYXNlKElBVklTdHJlYW0qIGlmYWNlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5DcmVhdGUoSUFWSVN0cmVhbSppZmFjZSxMUEFSQU0gbFBhcmFtMSxMUEFSQU0gbFBhcmFtMik7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuSW5mbyhJQVZJU3RyZWFtKmlmYWNlLEFWSVNUUkVBTUlORk9XICpwc2ksTE9ORyBzaXplKTsKc3RhdGljIExPTkcgICAgV0lOQVBJIElBVklTdHJlYW1fZm5GaW5kU2FtcGxlKElBVklTdHJlYW0qaWZhY2UsTE9ORyBwb3MsTE9ORyBmbGFncyk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUmVhZEZvcm1hdChJQVZJU3RyZWFtKmlmYWNlLExPTkcgcG9zLExQVk9JRCBmb3JtYXQsTE9ORyAqZm9ybWF0c2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuU2V0Rm9ybWF0KElBVklTdHJlYW0qaWZhY2UsTE9ORyBwb3MsTFBWT0lEIGZvcm1hdCxMT05HIGZvcm1hdHNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblJlYWQoSUFWSVN0cmVhbSppZmFjZSxMT05HIHN0YXJ0LExPTkcgc2FtcGxlcyxMUFZPSUQgYnVmZmVyLExPTkcgYnVmZmVyc2l6ZSxMT05HICpieXRlc3JlYWQsTE9ORyAqc2FtcGxlc3JlYWQpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbldyaXRlKElBVklTdHJlYW0qaWZhY2UsTE9ORyBzdGFydCxMT05HIHNhbXBsZXMsTFBWT0lEIGJ1ZmZlcixMT05HIGJ1ZmZlcnNpemUsRFdPUkQgZmxhZ3MsTE9ORyAqc2FtcHdyaXR0ZW4sTE9ORyAqYnl0ZXN3cml0dGVuKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5EZWxldGUoSUFWSVN0cmVhbSppZmFjZSxMT05HIHN0YXJ0LExPTkcgc2FtcGxlcyk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUmVhZERhdGEoSUFWSVN0cmVhbSppZmFjZSxEV09SRCBmY2MsTFBWT0lEIGxwLExPTkcgKmxwcmVhZCk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuV3JpdGVEYXRhKElBVklTdHJlYW0qaWZhY2UsRFdPUkQgZmNjLExQVk9JRCBscCxMT05HIHNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblNldEluZm8oSUFWSVN0cmVhbSppZmFjZSxBVklTVFJFQU1JTkZPVyppbmZvLExPTkcgaW5mb2xlbik7CgpzdHJ1Y3QgSUFWSVN0cmVhbVZ0YmwgaWF2aXN0ID0gewogIElBVklTdHJlYW1fZm5RdWVyeUludGVyZmFjZSwKICBJQVZJU3RyZWFtX2ZuQWRkUmVmLAogIElBVklTdHJlYW1fZm5SZWxlYXNlLAogIElBVklTdHJlYW1fZm5DcmVhdGUsCiAgSUFWSVN0cmVhbV9mbkluZm8sCiAgSUFWSVN0cmVhbV9mbkZpbmRTYW1wbGUsCiAgSUFWSVN0cmVhbV9mblJlYWRGb3JtYXQsCiAgSUFWSVN0cmVhbV9mblNldEZvcm1hdCwKICBJQVZJU3RyZWFtX2ZuUmVhZCwKICBJQVZJU3RyZWFtX2ZuV3JpdGUsCiAgSUFWSVN0cmVhbV9mbkRlbGV0ZSwKICBJQVZJU3RyZWFtX2ZuUmVhZERhdGEsCiAgSUFWSVN0cmVhbV9mbldyaXRlRGF0YSwKICBJQVZJU3RyZWFtX2ZuU2V0SW5mbwp9OwoKdHlwZWRlZiBzdHJ1Y3QgX0lBVklGaWxlSW1wbCBJQVZJRmlsZUltcGw7Cgp0eXBlZGVmIHN0cnVjdCBfSVBlcnNpc3RGaWxlSW1wbCB7CiAgLyogSVVua25vd24gc3R1ZmYgKi8KICBJUGVyc2lzdEZpbGVWdGJsICpscFZ0Ymw7CgogIC8qIElQZXJzaXN0RmlsZSBzdHVmZiAqLwogIElBVklGaWxlSW1wbCAgICAgKnBhZjsKfSBJUGVyc2lzdEZpbGVJbXBsOwoKdHlwZWRlZiBzdHJ1Y3QgX0lBVklTdHJlYW1JbXBsIHsKICAvKiBJVW5rbm93biBzdHVmZiAqLwogIElBVklTdHJlYW1WdGJsICAgKmxwVnRibDsKICBEV09SRAkJICAgIHJlZjsKCiAgLyogSUFWSVN0cmVhbSBzdHVmZiAqLwogIElBVklGaWxlSW1wbCAgICAgKnBhZjsKICBEV09SRCAgICAgICAgICAgICBuU3RyZWFtOyAgICAgICAvKiB0aGUgbi10aCBzdHJlYW0gaW4gZmlsZSAqLwogIEFWSVNUUkVBTUlORk9XICAgIHNJbmZvOwoKICBMUFZPSUQgICAgICAgICAgICBscEZvcm1hdDsKICBEV09SRCAgICAgICAgICAgICBjYkZvcm1hdDsKCiAgTFBWT0lEICAgICAgICAgICAgbHBIYW5kbGVyRGF0YTsKICBEV09SRCAgICAgICAgICAgICBjYkhhbmRsZXJEYXRhOwoKICBFWFRSQUNIVU5LUyAgICAgICBleHRyYTsKCiAgTFBEV09SRCAgICAgICAgICAgbHBCdWZmZXI7CiAgRFdPUkQgICAgICAgICAgICAgY2JCdWZmZXI7ICAgICAgIC8qIHNpemUgb2YgbHBCdWZmZXIgKi8KICBEV09SRCAgICAgICAgICAgICBkd0N1cnJlbnRGcmFtZTsgLyogZnJhbWUvYmxvY2sgY3VycmVudGx5IGluIGxwQnVmZmVyICovCgogIExPTkcgICAgICAgICAgICAgIGxMYXN0RnJhbWU7ICAgIC8qIGxhc3QgY29ycmVjdCBpbmRleCBpbiBpZHhGcmFtZXMgKi8KICBBVklJTkRFWEVOVFJZICAgICppZHhGcmFtZXM7CiAgRFdPUkQgICAgICAgICAgICAgbklkeEZyYW1lczsgICAgIC8qIHVwcGVyIGluZGV4IGxpbWl0IG9mIGlkeEZyYW1lcyAqLwogIEFWSUlOREVYRU5UUlkgICAgKmlkeEZtdENoYW5nZXM7CiAgRFdPUkQgICAgICAgICAgICAgbklkeEZtdENoYW5nZXM7IC8qIHVwcGVyIGluZGV4IGxpbWl0IG9mIGlkeEZtdENoYW5nZXMgKi8KfSBJQVZJU3RyZWFtSW1wbDsKCnN0cnVjdCBfSUFWSUZpbGVJbXBsIHsKICAvKiBJVW5rbm93biBzdHVmZiAqLwogIElBVklGaWxlVnRibCAgICAgKmxwVnRibDsKICBEV09SRAkJICAgIHJlZjsKCiAgLyogSUFWSUZpbGUgc3R1ZmYuLi4gKi8KICBJUGVyc2lzdEZpbGVJbXBsICBpUGVyc2lzdEZpbGU7CgogIEFWSUZJTEVJTkZPVyAgICAgIGZJbmZvOwogIElBVklTdHJlYW1JbXBsICAgKnBwU3RyZWFtc1tNQVhfQVZJU1RSRUFNU107CgogIEVYVFJBQ0hVTktTICAgICAgIGZpbGVleHRyYTsKCiAgRFdPUkQgICAgICAgICAgICAgZHdNb3ZpQ2h1bmtQb3M7ICAvKiBzb21lIHN0dWZmIGZvciBzYXZpbmcgLi4uICovCiAgRFdPUkQgICAgICAgICAgICAgZHdJZHhDaHVua1BvczsKICBEV09SRCAgICAgICAgICAgICBkd05leHRGcmFtZVBvczsKICBEV09SRCAgICAgICAgICAgICBkd0luaXRpYWxGcmFtZXM7CgogIE1NQ0tJTkZPICAgICAgICAgIGNrTGFzdFJlY29yZDsKICBBVklJTkRFWEVOVFJZICAgICppZHhSZWNvcmRzOyAgICAgIC8qIHdvbid0IGJlIHVwZGF0ZWQgd2hpbGUgbG9hZGluZyAqLwogIERXT1JEICAgICAgICAgICAgIG5JZHhSZWNvcmRzOyAgICAgLyogY3VycmVudCBmaWxsIGxldmVsICovCiAgRFdPUkQgICAgICAgICAgICAgY2JJZHhSZWNvcmRzOyAgICAvKiBzaXplIG9mIGlkeFJlY29yZHMgKi8KCiAgLyogSVBlcnNpc3RGaWxlIHN0dWZmIC4uLiAqLwogIEhNTUlPICAgICAgICAgICAgIGhtbWlvOwogIExQV1NUUiAgICAgICAgICAgIHN6RmlsZU5hbWU7CiAgVUlOVCAgICAgICAgICAgICAgdU1vZGU7CiAgQk9PTCAgICAgICAgICAgICAgZkRpcnR5Owp9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9BZGRGcmFtZShJQVZJU3RyZWFtSW1wbCAqVGhpcywgRFdPUkQgY2tpZCwgRFdPUkQgc2l6ZSwKCQkJCURXT1JEIG9mZnNldCwgRFdPUkQgZmxhZ3MpOwpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX0FkZFJlY29yZChJQVZJRmlsZUltcGwgKlRoaXMpOwpzdGF0aWMgRFdPUkQgICBBVklGSUxFX0NvbXB1dGVNb3ZpU3RhcnQoSUFWSUZpbGVJbXBsICpUaGlzKTsKc3RhdGljIHZvaWQgICAgQVZJRklMRV9Db25zdHJ1Y3RBVklTdHJlYW0oSUFWSUZpbGVJbXBsICpwYWYsIERXT1JEIG5yLAoJCQkJCSAgTFBBVklTVFJFQU1JTkZPVyBhc2kpOwpzdGF0aWMgdm9pZCAgICBBVklGSUxFX0Rlc3RydWN0QVZJU3RyZWFtKElBVklTdHJlYW1JbXBsICpUaGlzKTsKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9Mb2FkRmlsZShJQVZJRmlsZUltcGwgKlRoaXMpOwpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX0xvYWRJbmRleChJQVZJRmlsZUltcGwgKlRoaXMsIERXT1JEIHNpemUsIERXT1JEIG9mZnNldCk7CnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfUGFyc2VJbmRleChJQVZJRmlsZUltcGwgKlRoaXMsIEFWSUlOREVYRU5UUlkgKmxwLAoJCQkJICBMT05HIGNvdW50LCBEV09SRCBwb3MsIEJPT0wgKmJBYnNvbHV0ZSk7CnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfUmVhZEJsb2NrKElBVklTdHJlYW1JbXBsICpUaGlzLCBEV09SRCBzdGFydCwKCQkJCSBMUFZPSUQgYnVmZmVyLCBMT05HIHNpemUpOwpzdGF0aWMgdm9pZCAgICBBVklGSUxFX1NhbXBsZXNUb0Jsb2NrKElBVklTdHJlYW1JbXBsICpUaGlzLCBMUExPTkcgcG9zLAoJCQkJICAgICAgTFBMT05HIG9mZnNldCk7CnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfU2F2ZUZpbGUoSUFWSUZpbGVJbXBsICpUaGlzKTsKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9TYXZlSW5kZXgoSUFWSUZpbGVJbXBsICpUaGlzKTsKc3RhdGljIFVMT05HICAgQVZJRklMRV9TZWFyY2hTdHJlYW0oSUFWSUZpbGVJbXBsICpUaGlzLCBEV09SRCBmY2NUeXBlLAoJCQkJICAgIExPTkcgbFNraXApOwpzdGF0aWMgdm9pZCAgICBBVklGSUxFX1VwZGF0ZUluZm8oSUFWSUZpbGVJbXBsICpUaGlzKTsKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9Xcml0ZUJsb2NrKElBVklTdHJlYW1JbXBsICpUaGlzLCBEV09SRCBibG9jaywKCQkJCSAgRk9VUkNDIGNraWQsIERXT1JEIGZsYWdzLCBMUFZPSUQgYnVmZmVyLAoJCQkJICBMT05HIHNpemUpOwoKSFJFU1VMVCBBVklGSUxFX0NyZWF0ZUFWSUZpbGUoUkVGSUlEIHJpaWQsIExQVk9JRCAqcHB2KQp7CiAgSUFWSUZpbGVJbXBsICpwZmlsZTsKICBIUkVTVUxUICAgICAgIGhyOwoKICBhc3NlcnQocmlpZCAhPSBOVUxMICYmIHBwdiAhPSBOVUxMKTsKCiAgKnBwdiA9IE5VTEw7CgogIHBmaWxlID0gKElBVklGaWxlSW1wbCopTG9jYWxBbGxvYyhMUFRSLCBzaXplb2YoSUFWSUZpbGVJbXBsKSk7CiAgaWYgKHBmaWxlID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgcGZpbGUtPmxwVnRibCA9ICZpYXZpZnQ7CiAgcGZpbGUtPnJlZiA9IDA7CiAgcGZpbGUtPmlQZXJzaXN0RmlsZS5scFZ0YmwgPSAmaXBlcnNpc3RmdDsKICBwZmlsZS0+aVBlcnNpc3RGaWxlLnBhZiA9IHBmaWxlOwoKICBociA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKChJVW5rbm93biopcGZpbGUsIHJpaWQsIHBwdik7CiAgaWYgKEZBSUxFRChocikpCiAgICBMb2NhbEZyZWUoKEhMT0NBTClwZmlsZSk7CgogIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuUXVlcnlJbnRlcmZhY2UoSUFWSUZpbGUgKmlmYWNlLCBSRUZJSUQgcmVmaWlkLAoJCQkJCQlMUFZPSUQgKm9iaikKewogIElBVklGaWxlSW1wbCAqVGhpcyA9IChJQVZJRmlsZUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlcywlcClcbiIsIFRoaXMsIGRlYnVnc3RyX2d1aWQocmVmaWlkKSwgb2JqKTsKCiAgaWYgKElzRXF1YWxHVUlEKCZJSURfSVVua25vd24sIHJlZmlpZCkgfHwKICAgICAgSXNFcXVhbEdVSUQoJklJRF9JQVZJRmlsZSwgcmVmaWlkKSkgewogICAgKm9iaiA9IGlmYWNlOwogICAgSUFWSUZpbGVfQWRkUmVmKGlmYWNlKTsKCiAgICByZXR1cm4gU19PSzsKICB9IGVsc2UgaWYgKElzRXF1YWxHVUlEKCZJSURfSVBlcnNpc3RGaWxlLCByZWZpaWQpKSB7CiAgICAqb2JqID0gJlRoaXMtPmlQZXJzaXN0RmlsZTsKICAgIElBVklGaWxlX0FkZFJlZihpZmFjZSk7CgogICAgcmV0dXJuIFNfT0s7CiAgfQoKICByZXR1cm4gT0xFX0VfRU5VTV9OT01PUkU7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSUFWSUZpbGVfZm5BZGRSZWYoSUFWSUZpbGUgKmlmYWNlKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKElBVklGaWxlSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwKSAtPiAlbGRcbiIsIGlmYWNlLCBUaGlzLT5yZWYgKyAxKTsKICByZXR1cm4gKysoVGhpcy0+cmVmKTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBJQVZJRmlsZV9mblJlbGVhc2UoSUFWSUZpbGUgKmlmYWNlKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKElBVklGaWxlSW1wbCAqKWlmYWNlOwogIFVJTlQgaTsKCiAgVFJBQ0UoIiglcCkgLT4gJWxkXG4iLCBpZmFjZSwgVGhpcy0+cmVmIC0gMSk7CgogIGlmICghLS0oVGhpcy0+cmVmKSkgewogICAgaWYgKFRoaXMtPmZEaXJ0eSkgewogICAgICAvKiBuZWVkIHRvIHdyaXRlIGhlYWRlcnMgdG8gZmlsZSAqLwogICAgICBBVklGSUxFX1NhdmVGaWxlKFRoaXMpOwogICAgfQoKICAgIGZvciAoaSA9IDA7IGkgPCBUaGlzLT5mSW5mby5kd1N0cmVhbXM7IGkrKykgewogICAgICBpZiAoVGhpcy0+cHBTdHJlYW1zW2ldICE9IE5VTEwpIHsKCWlmIChUaGlzLT5wcFN0cmVhbXNbaV0tPnJlZiAhPSAwKSB7CgkgIEVSUigiOiBzb21lb25lIGhhcyBzdGlsbCAlbHUgcmVmZXJlbmNlIHRvIHN0cmVhbSAldSAoJXApIVxuIiwKCSAgICAgICBUaGlzLT5wcFN0cmVhbXNbaV0tPnJlZiwgaSwgVGhpcy0+cHBTdHJlYW1zW2ldKTsKCX0KCUFWSUZJTEVfRGVzdHJ1Y3RBVklTdHJlYW0oVGhpcy0+cHBTdHJlYW1zW2ldKTsKCUxvY2FsRnJlZSgoSExPQ0FMKVRoaXMtPnBwU3RyZWFtc1tpXSk7CglUaGlzLT5wcFN0cmVhbXNbaV0gPSBOVUxMOwogICAgICB9CiAgICB9CgogICAgaWYgKFRoaXMtPmlkeFJlY29yZHMgIT0gTlVMTCkgewogICAgICBHbG9iYWxGcmVlUHRyKFRoaXMtPmlkeFJlY29yZHMpOwogICAgICBUaGlzLT5pZHhSZWNvcmRzICA9IE5VTEw7CiAgICAgIFRoaXMtPm5JZHhSZWNvcmRzID0gMDsKICAgIH0KCiAgICBpZiAoVGhpcy0+ZmlsZWV4dHJhLmxwICE9IE5VTEwpIHsKICAgICAgR2xvYmFsRnJlZVB0cihUaGlzLT5maWxlZXh0cmEubHApOwogICAgICBUaGlzLT5maWxlZXh0cmEubHAgPSBOVUxMOwogICAgICBUaGlzLT5maWxlZXh0cmEuY2IgPSAwOwogICAgfQoKICAgIGlmIChUaGlzLT5zekZpbGVOYW1lICE9IE5VTEwpIHsKICAgICAgTG9jYWxGcmVlKChITE9DQUwpVGhpcy0+c3pGaWxlTmFtZSk7CiAgICAgIFRoaXMtPnN6RmlsZU5hbWUgPSBOVUxMOwogICAgfQogICAgaWYgKFRoaXMtPmhtbWlvICE9IE5VTEwpIHsKICAgICAgbW1pb0Nsb3NlKFRoaXMtPmhtbWlvLCAwKTsKICAgICAgVGhpcy0+aG1taW8gPSBOVUxMOwogICAgfQoKICAgIExvY2FsRnJlZSgoSExPQ0FMKVRoaXMpOwogICAgcmV0dXJuIDA7CiAgfQogIHJldHVybiBUaGlzLT5yZWY7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkluZm8oSUFWSUZpbGUgKmlmYWNlLCBMUEFWSUZJTEVJTkZPVyBhZmksCgkJCQkgICAgICBMT05HIHNpemUpCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoSUFWSUZpbGVJbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJXAsJWxkKVxuIixpZmFjZSxhZmksc2l6ZSk7CgogIGlmIChhZmkgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgaWYgKHNpemUgPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURTSVpFOwoKICBBVklGSUxFX1VwZGF0ZUluZm8oVGhpcyk7CgogIG1lbWNweShhZmksICZUaGlzLT5mSW5mbywgbWluKChEV09SRClzaXplLCBzaXplb2YoVGhpcy0+ZkluZm8pKSk7CgogIGlmICgoRFdPUkQpc2l6ZSA8IHNpemVvZihUaGlzLT5mSW5mbykpCiAgICByZXR1cm4gQVZJRVJSX0JVRkZFUlRPT1NNQUxMOwogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkdldFN0cmVhbShJQVZJRmlsZSAqaWZhY2UsIFBBVklTVFJFQU0gKmF2aXMsCgkJCQkJICAgRFdPUkQgZmNjVHlwZSwgTE9ORyBsUGFyYW0pCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoSUFWSUZpbGVJbXBsICopaWZhY2U7CgogIFVMT05HIG5TdHJlYW07CgogIFRSQUNFKCIoJXAsJXAsMHglMDhsWCwlbGQpXG4iLCBpZmFjZSwgYXZpcywgZmNjVHlwZSwgbFBhcmFtKTsKCiAgaWYgKGF2aXMgPT0gTlVMTCB8fCBsUGFyYW0gPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgblN0cmVhbSA9IEFWSUZJTEVfU2VhcmNoU3RyZWFtKFRoaXMsIGZjY1R5cGUsIGxQYXJhbSk7CgogIC8qIERvZXMgdGhlIHJlcXVlc3RlZCBzdHJlYW0gZXhpc3Q/ICovCiAgaWYgKG5TdHJlYW0gPCBUaGlzLT5mSW5mby5kd1N0cmVhbXMgJiYKICAgICAgVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dICE9IE5VTEwpIHsKICAgICphdmlzID0gKFBBVklTVFJFQU0pVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dOwogICAgSUFWSVN0cmVhbV9BZGRSZWYoKmF2aXMpOwoKICAgIHJldHVybiBBVklFUlJfT0s7CiAgfQoKICAvKiBTb3JyeSwgYnV0IHRoZSBzcGVjaWZpZWQgc3RyZWFtIGRvZXNuJ3QgZXhpc3QgKi8KICByZXR1cm4gQVZJRVJSX05PREFUQTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuQ3JlYXRlU3RyZWFtKElBVklGaWxlICppZmFjZSxQQVZJU1RSRUFNICphdmlzLAoJCQkJCSAgICAgIExQQVZJU1RSRUFNSU5GT1cgYXNpKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKElBVklGaWxlSW1wbCAqKWlmYWNlOwoKICBEV09SRCBuOwoKICBUUkFDRSgiKCVwLCVwLCVwKVxuIiwgaWZhY2UsIGF2aXMsIGFzaSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoYXZpcyA9PSBOVUxMIHx8IGFzaSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgKmF2aXMgPSBOVUxMOwoKICAvKiBEb2VzIHRoZSB1c2VyIGhhdmUgd3JpdGUgcGVybWlzc2lvbj8gKi8KICBpZiAoKFRoaXMtPnVNb2RlICYgTU1JT19SV01PREUpID09IDApCiAgICByZXR1cm4gQVZJRVJSX1JFQURPTkxZOwoKICAvKiBDYW4gd2UgYWRkIGFub3RoZXIgc3RyZWFtPyAqLwogIG4gPSBUaGlzLT5mSW5mby5kd1N0cmVhbXM7CiAgaWYgKG4gPj0gTUFYX0FWSVNUUkVBTVMgfHwgVGhpcy0+ZHdNb3ZpQ2h1bmtQb3MgIT0gMCkgewogICAgLyogYWxyZWFkeSByZWFjaGVkIG1heCBuciBvZiBzdHJlYW1zCiAgICAgKiBvciBoYXZlIGFscmVhZHkgd3JpdHRlbiBmcmFtZXMgdG8gZGlzayAqLwogICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKICB9CgogIC8qIGNoZWNrIEFWSVNUUkVBTUlORk8gZm9yIHNvbWUgcmVhbGx5IG5lZWRlZCB0aGluZ3MgKi8KICBpZiAoYXNpLT5mY2NUeXBlID09IDAgfHwgYXNpLT5kd1NjYWxlID09IDAgfHwgYXNpLT5kd1JhdGUgPT0gMCkKICAgIHJldHVybiBBVklFUlJfQkFERk9STUFUOwoKICAvKiBub3cgaXQgc2VlbXMgdG8gYmUgc2F2ZSB0byBhZGQgdGhlIHN0cmVhbSAqLwogIGFzc2VydChUaGlzLT5wcFN0cmVhbXNbbl0gPT0gTlVMTCk7CiAgVGhpcy0+cHBTdHJlYW1zW25dID0gKElBVklTdHJlYW1JbXBsKilMb2NhbEFsbG9jKExQVFIsCgkJCQkJCSAgIHNpemVvZihJQVZJU3RyZWFtSW1wbCkpOwogIGlmIChUaGlzLT5wcFN0cmVhbXNbbl0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICAvKiBpbml0aWFsaXplIHRoZSBuZXcgYWxsb2NhdGVkIHN0cmVhbSAqLwogIEFWSUZJTEVfQ29uc3RydWN0QVZJU3RyZWFtKFRoaXMsIG4sIGFzaSk7CgogIFRoaXMtPmZJbmZvLmR3U3RyZWFtcysrOwogIFRoaXMtPmZEaXJ0eSA9IFRSVUU7CgogIC8qIHVwZGF0ZSBvdXIgQVZJRklMRUlORk8gc3RydWN0dXJlICovCiAgQVZJRklMRV9VcGRhdGVJbmZvKFRoaXMpOwoKICAvKiByZXR1cm4gaXQgKi8KICAqYXZpcyA9IChQQVZJU1RSRUFNKVRoaXMtPnBwU3RyZWFtc1tuXTsKICBJQVZJU3RyZWFtX0FkZFJlZigqYXZpcyk7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbldyaXRlRGF0YShJQVZJRmlsZSAqaWZhY2UsIERXT1JEIGNraWQsCgkJCQkJICAgTFBWT0lEIGxwRGF0YSwgTE9ORyBzaXplKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKElBVklGaWxlSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLDB4JTA4bFgsJXAsJWxkKVxuIiwgaWZhY2UsIGNraWQsIGxwRGF0YSwgc2l6ZSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAobHBEYXRhID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIGlmIChzaXplIDwgMCkKICAgIHJldHVybiBBVklFUlJfQkFEU0laRTsKCiAgLyogRG8gd2UgaGF2ZSB3cml0ZSBwZXJtaXNzaW9uPyAqLwogIGlmICgoVGhpcy0+dU1vZGUgJiBNTUlPX1JXTU9ERSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIFRoaXMtPmZEaXJ0eSA9IFRSVUU7CgogIHJldHVybiBXcml0ZUV4dHJhQ2h1bmsoJlRoaXMtPmZpbGVleHRyYSwgY2tpZCwgbHBEYXRhLCBzaXplKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuUmVhZERhdGEoSUFWSUZpbGUgKmlmYWNlLCBEV09SRCBja2lkLAoJCQkJCSAgTFBWT0lEIGxwRGF0YSwgTE9ORyAqc2l6ZSkKewogIElBVklGaWxlSW1wbCAqVGhpcyA9IChJQVZJRmlsZUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwweCUwOGxYLCVwLCVwKVxuIiwgaWZhY2UsIGNraWQsIGxwRGF0YSwgc2l6ZSk7CgogIHJldHVybiBSZWFkRXh0cmFDaHVuaygmVGhpcy0+ZmlsZWV4dHJhLCBja2lkLCBscERhdGEsIHNpemUpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5FbmRSZWNvcmQoSUFWSUZpbGUgKmlmYWNlKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKElBVklGaWxlSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwKVxuIixpZmFjZSk7CgogIGlmICgoVGhpcy0+dU1vZGUgJiBNTUlPX1JXTU9ERSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIFRoaXMtPmZEaXJ0eSA9IFRSVUU7CgogIC8qIG5vIGZyYW1lcyB3cml0dGVuIHRvIGFueSBzdHJlYW0/IC0tIGNvbXB1dGUgc3RhcnQgb2YgJ21vdmknLWNodW5rICovCiAgaWYgKFRoaXMtPmR3TW92aUNodW5rUG9zID09IDApCiAgICBBVklGSUxFX0NvbXB1dGVNb3ZpU3RhcnQoVGhpcyk7CgogIFRoaXMtPmZJbmZvLmR3RmxhZ3MgIHw9IEFWSUZJTEVJTkZPX0lTSU5URVJMRUFWRUQ7CgogIC8qIGFscmVhZHkgd3JpdHRlbiBmcmFtZXMgdG8gYW55IHN0cmVhbSwgLi4uICovCiAgaWYgKFRoaXMtPmNrTGFzdFJlY29yZC5kd0ZsYWdzICYgTU1JT19ESVJUWSkgewogICAgLyogY2xvc2UgbGFzdCByZWNvcmQgKi8KICAgIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmVGhpcy0+Y2tMYXN0UmVjb3JkLCAwKSAhPSAwKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgICBBVklGSUxFX0FkZFJlY29yZChUaGlzKTsKCiAgICBpZiAoVGhpcy0+ZkluZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplIDwgVGhpcy0+Y2tMYXN0UmVjb3JkLmNrc2l6ZSArIDMgKiBzaXplb2YoRFdPUkQpKQogICAgICBUaGlzLT5mSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPSBUaGlzLT5ja0xhc3RSZWNvcmQuY2tzaXplICsgMyAqIHNpemVvZihEV09SRCk7CiAgfQoKICAvKiB3cml0ZSBvdXQgYSBuZXcgcmVjb3JkIGludG8gZmlsZSwgYnV0IGRvbid0IGNsb3NlIGl0ICovCiAgVGhpcy0+Y2tMYXN0UmVjb3JkLmNrc2l6ZSAgPSAwOwogIFRoaXMtPmNrTGFzdFJlY29yZC5mY2NUeXBlID0gbGlzdHR5cGVBVklSRUNPUkQ7CiAgaWYgKG1taW9TZWVrKFRoaXMtPmhtbWlvLCBUaGlzLT5kd05leHRGcmFtZVBvcywgU0VFS19TRVQpID09IC0xKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJlRoaXMtPmNrTGFzdFJlY29yZCwgTU1JT19DUkVBVEVMSVNUKSAhPSAwKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgVGhpcy0+ZHdOZXh0RnJhbWVQb3MgKz0gMyAqIHNpemVvZihEV09SRCk7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkRlbGV0ZVN0cmVhbShJQVZJRmlsZSAqaWZhY2UsIERXT1JEIGZjY1R5cGUsCgkJCQkJICAgICAgTE9ORyBsUGFyYW0pCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoSUFWSUZpbGVJbXBsICopaWZhY2U7CgogIFVMT05HIG5TdHJlYW07CgogIFRSQUNFKCIoJXAsMHglMDhsWCwlbGQpXG4iLCBpZmFjZSwgZmNjVHlwZSwgbFBhcmFtKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVyICovCiAgaWYgKGxQYXJhbSA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBIYXZlIHVzZXIgd3JpdGUgcGVybWlzc2lvbnM/ICovCiAgaWYgKChUaGlzLT51TW9kZSAmIE1NSU9fUldNT0RFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgblN0cmVhbSA9IEFWSUZJTEVfU2VhcmNoU3RyZWFtKFRoaXMsIGZjY1R5cGUsIGxQYXJhbSk7CgogIC8qIERvZXMgdGhlIHJlcXVlc3RlZCBzdHJlYW0gZXhpc3Q/ICovCiAgaWYgKG5TdHJlYW0gPCBUaGlzLT5mSW5mby5kd1N0cmVhbXMgJiYKICAgICAgVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dICE9IE5VTEwpIHsKICAgIC8qIC4uLiBzbyBkZWxldGUgaXQgbm93ICovCiAgICBMb2NhbEZyZWUoKEhMT0NBTClUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV0pOwoKICAgIGlmIChUaGlzLT5mSW5mby5kd1N0cmVhbXMgLSBuU3RyZWFtID4gMCkKICAgICAgbWVtY3B5KFRoaXMtPnBwU3RyZWFtcyArIG5TdHJlYW0sIFRoaXMtPnBwU3RyZWFtcyArIG5TdHJlYW0gKyAxLAoJICAgICAoVGhpcy0+ZkluZm8uZHdTdHJlYW1zIC0gblN0cmVhbSkgKiBzaXplb2YoSUFWSVN0cmVhbUltcGwqKSk7CgogICAgVGhpcy0+cHBTdHJlYW1zW1RoaXMtPmZJbmZvLmR3U3RyZWFtc10gPSBOVUxMOwogICAgVGhpcy0+ZkluZm8uZHdTdHJlYW1zLS07CiAgICBUaGlzLT5mRGlydHkgPSBUUlVFOwoKICAgIC8qIFRoaXMtPmZJbmZvIHdpbGwgYmUgdXBkYXRlZCBmdXJ0aGVyIHdoZW4gYXNrZWQgZm9yICovCiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0gZWxzZQogICAgcmV0dXJuIEFWSUVSUl9OT0RBVEE7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5RdWVyeUludGVyZmFjZShJUGVyc2lzdEZpbGUgKmlmYWNlLAoJCQkJCQkgICAgUkVGSUlEIHJlZmlpZCwgTFBWT0lEICpvYmopCnsKICBJUGVyc2lzdEZpbGVJbXBsICpUaGlzID0gKElQZXJzaXN0RmlsZUltcGwgKilpZmFjZTsKCiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklGaWxlX1F1ZXJ5SW50ZXJmYWNlKChQQVZJRklMRSlUaGlzLT5wYWYsIHJlZmlpZCwgb2JqKTsKfQoKc3RhdGljIFVMT05HICAgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkFkZFJlZihJUGVyc2lzdEZpbGUgKmlmYWNlKQp7CiAgSVBlcnNpc3RGaWxlSW1wbCAqVGhpcyA9IChJUGVyc2lzdEZpbGVJbXBsICopaWZhY2U7CgogIGFzc2VydChUaGlzLT5wYWYgIT0gTlVMTCk7CgogIHJldHVybiBJQVZJRmlsZV9BZGRSZWYoKFBBVklGSUxFKVRoaXMtPnBhZik7Cn0KCnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5SZWxlYXNlKElQZXJzaXN0RmlsZSAqaWZhY2UpCnsKICBJUGVyc2lzdEZpbGVJbXBsICpUaGlzID0gKElQZXJzaXN0RmlsZUltcGwgKilpZmFjZTsKCiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklGaWxlX1JlbGVhc2UoKFBBVklGSUxFKVRoaXMtPnBhZik7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5HZXRDbGFzc0lEKElQZXJzaXN0RmlsZSAqaWZhY2UsCgkJCQkJCUxQQ0xTSUQgcENsYXNzSUQpCnsKICBUUkFDRSgiKCVwLCVwKVxuIiwgaWZhY2UsIHBDbGFzc0lEKTsKCiAgaWYgKHBDbGFzc0lEID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICBtZW1jcHkocENsYXNzSUQsICZDTFNJRF9BVklGaWxlLCBzaXplb2YoQ0xTSURfQVZJRmlsZSkpOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuSXNEaXJ0eShJUGVyc2lzdEZpbGUgKmlmYWNlKQp7CiAgSVBlcnNpc3RGaWxlSW1wbCAqVGhpcyA9IChJUGVyc2lzdEZpbGVJbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXApXG4iLCBpZmFjZSk7CgogIGFzc2VydChUaGlzLT5wYWYgIT0gTlVMTCk7CgogIHJldHVybiAoVGhpcy0+cGFmLT5mRGlydHkgPyBTX09LIDogU19GQUxTRSk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5Mb2FkKElQZXJzaXN0RmlsZSAqaWZhY2UsCgkJCQkJICBMUENPTEVTVFIgcHN6RmlsZU5hbWUsIERXT1JEIGR3TW9kZSkKewogIElQZXJzaXN0RmlsZUltcGwgKlRoaXMgPSAoSVBlcnNpc3RGaWxlSW1wbCAqKWlmYWNlOwoKICBpbnQgbGVuOwoKICBUUkFDRSgiKCVwLCVzLDB4JTA4bFgpXG4iLCBpZmFjZSwgZGVidWdzdHJfdyhwc3pGaWxlTmFtZSksIGR3TW9kZSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlciAqLwogIGlmIChwc3pGaWxlTmFtZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKICBpZiAoVGhpcy0+cGFmLT5obW1pbyAhPSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9FUlJPUjsgLyogTm8gcmV1c2Ugb2YgdGhpcyBvYmplY3QgZm9yIGFub3RoZXIgZmlsZSEgKi8KCiAgLyogcmVtZWJlciBtb2RlIGFuZCBuYW1lICovCiAgVGhpcy0+cGFmLT51TW9kZSA9IGR3TW9kZTsKCiAgbGVuID0gbHN0cmxlblcocHN6RmlsZU5hbWUpICsgMTsKICBUaGlzLT5wYWYtPnN6RmlsZU5hbWUgPSAoTFBXU1RSKUxvY2FsQWxsb2MoTFBUUiwgbGVuICogc2l6ZW9mKFdDSEFSKSk7CiAgaWYgKFRoaXMtPnBhZi0+c3pGaWxlTmFtZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgbHN0cmNweVcoVGhpcy0+cGFmLT5zekZpbGVOYW1lLCBwc3pGaWxlTmFtZSk7CgogIC8qIHRyeSB0byBvcGVuIHRoZSBmaWxlICovCiAgVGhpcy0+cGFmLT5obW1pbyA9IG1taW9PcGVuVyhUaGlzLT5wYWYtPnN6RmlsZU5hbWUsIE5VTEwsCgkJCSAgICAgICBNTUlPX0FMTE9DQlVGIHwgZHdNb2RlKTsKICBpZiAoVGhpcy0+cGFmLT5obW1pbyA9PSBOVUxMKSB7CiAgICAvKiBtbWlvT3Blblcgbm90IGluIG5hdGl2ZSBETExzIG9mIFdpbjl4IC0tIHRyeSBtbWlvT3BlbkEgKi8KICAgIExQU1RSIHN6RmlsZU5hbWU7CgogICAgbGVuID0gV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIFRoaXMtPnBhZi0+c3pGaWxlTmFtZSwgLTEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCAwLCBOVUxMLCBOVUxMKTsKICAgIHN6RmlsZU5hbWUgPSBMb2NhbEFsbG9jKExQVFIsIGxlbiAqIHNpemVvZihDSEFSKSk7CiAgICBpZiAoc3pGaWxlTmFtZSA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgICBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgVGhpcy0+cGFmLT5zekZpbGVOYW1lLCAtMSwgc3pGaWxlTmFtZSwKCQkJbGVuLCBOVUxMLCBOVUxMKTsKCiAgICBUaGlzLT5wYWYtPmhtbWlvID0gbW1pb09wZW5BKHN6RmlsZU5hbWUsIE5VTEwsIE1NSU9fQUxMT0NCVUYgfCBkd01vZGUpOwogICAgTG9jYWxGcmVlKChITE9DQUwpc3pGaWxlTmFtZSk7CiAgICBpZiAoVGhpcy0+cGFmLT5obW1pbyA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVPUEVOOwogIH0KCiAgLyogc2hvdWxkIHdlIGNyZWF0ZSBhIG5ldyBmaWxlPyAqLwogIGlmIChkd01vZGUgJiBPRl9DUkVBVEUpIHsKICAgIG1lbXNldCgmIFRoaXMtPnBhZi0+ZkluZm8sIDAsIHNpemVvZihUaGlzLT5wYWYtPmZJbmZvKSk7CiAgICBUaGlzLT5wYWYtPmZJbmZvLmR3RmxhZ3MgPSBBVklGSUxFSU5GT19IQVNJTkRFWCB8IEFWSUZJTEVJTkZPX1RSVVNUQ0tUWVBFOwoKICAgIHJldHVybiBBVklFUlJfT0s7CiAgfSBlbHNlCiAgICByZXR1cm4gQVZJRklMRV9Mb2FkRmlsZShUaGlzLT5wYWYpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuU2F2ZShJUGVyc2lzdEZpbGUgKmlmYWNlLAoJCQkJCSAgTFBDT0xFU1RSIHBzekZpbGVOYW1lLEJPT0wgZlJlbWVtYmVyKQp7CiAgVFJBQ0UoIiglcCwlcywlZClcbiIsIGlmYWNlLCBkZWJ1Z3N0cl93KHBzekZpbGVOYW1lKSwgZlJlbWVtYmVyKTsKCiAgLyogV2Ugd3JpdGUgZGlyZWN0bHkgdG8gZGlzaywgc28gbm90aGluZyB0byBkby4gKi8KCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mblNhdmVDb21wbGV0ZWQoSVBlcnNpc3RGaWxlICppZmFjZSwKCQkJCQkJICAgTFBDT0xFU1RSIHBzekZpbGVOYW1lKQp7CiAgVFJBQ0UoIiglcCwlcylcbiIsIGlmYWNlLCBkZWJ1Z3N0cl93KHBzekZpbGVOYW1lKSk7CgogIC8qIFdlIHdyaXRlIGRpcmVjdGx5IHRvIGRpc2ssIHNvIG5vdGhpbmcgdG8gZG8uICovCgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5HZXRDdXJGaWxlKElQZXJzaXN0RmlsZSAqaWZhY2UsCgkJCQkJCUxQT0xFU1RSICpwcHN6RmlsZU5hbWUpCnsKICBJUGVyc2lzdEZpbGVJbXBsICpUaGlzID0gKElQZXJzaXN0RmlsZUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlcClcbiIsIGlmYWNlLCBwcHN6RmlsZU5hbWUpOwoKICBpZiAocHBzekZpbGVOYW1lID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAqcHBzekZpbGVOYW1lID0gTlVMTDsKCiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKCiAgaWYgKFRoaXMtPnBhZi0+c3pGaWxlTmFtZSAhPSBOVUxMKSB7CiAgICBpbnQgbGVuID0gbHN0cmxlblcoVGhpcy0+cGFmLT5zekZpbGVOYW1lKSArIDE7CgogICAgKnBwc3pGaWxlTmFtZSA9IChMUE9MRVNUUilHbG9iYWxBbGxvY1B0cihHSE5ELCBsZW4gKiBzaXplb2YoV0NIQVIpKTsKICAgIGlmICgqcHBzekZpbGVOYW1lID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICAgIHN0cmNweVcoKnBwc3pGaWxlTmFtZSwgVGhpcy0+cGFmLT5zekZpbGVOYW1lKTsKICB9CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUXVlcnlJbnRlcmZhY2UoSUFWSVN0cmVhbSAqaWZhY2UsCgkJCQkJCSAgUkVGSUlEIHJlZmlpZCwgTFBWT0lEICpvYmopCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVzLCVwKVxuIiwgaWZhY2UsIGRlYnVnc3RyX2d1aWQocmVmaWlkKSwgb2JqKTsKCiAgaWYgKElzRXF1YWxHVUlEKCZJSURfSVVua25vd24sIHJlZmlpZCkgfHwKICAgICAgSXNFcXVhbEdVSUQoJklJRF9JQVZJU3RyZWFtLCByZWZpaWQpKSB7CiAgICAqb2JqID0gVGhpczsKICAgIElBVklTdHJlYW1fQWRkUmVmKGlmYWNlKTsKCiAgICByZXR1cm4gU19PSzsKICB9CiAgLyogRklYTUU6IElBVklTdHJlYW1pbmcgaW50ZXJmYWNlICovCgogIHJldHVybiBPTEVfRV9FTlVNX05PTU9SRTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBJQVZJU3RyZWFtX2ZuQWRkUmVmKElBVklTdHJlYW0gKmlmYWNlKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCkgLT4gJWxkXG4iLCBpZmFjZSwgVGhpcy0+cmVmICsgMSk7CgogIC8qIGFsc28gYWRkIHJlZiB0byBwYXJlbnQsIHNvIHRoYXQgaXQgZG9lc24ndCBraWxsIHVzICovCiAgaWYgKFRoaXMtPnBhZiAhPSBOVUxMKQogICAgSUFWSUZpbGVfQWRkUmVmKChQQVZJRklMRSlUaGlzLT5wYWYpOwoKICByZXR1cm4gKysoVGhpcy0+cmVmKTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUmVsZWFzZShJQVZJU3RyZWFtKiBpZmFjZSkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXApIC0+ICVsZFxuIiwgaWZhY2UsIFRoaXMtPnJlZiAtIDEpOwoKICAvKiB3ZSBiZWxvbmcgdG8gdGhlIEFWSUZpbGUsIHdoaWNoIG11c3QgZnJlZSB1cyEgKi8KICBpZiAoVGhpcy0+cmVmID09IDApIHsKICAgIEVSUigiOiBhbHJlYWR5IHJlbGVhc2VkIVxuIik7CiAgICByZXR1cm4gMDsKICB9CgogIFRoaXMtPnJlZi0tOwoKICBpZiAoVGhpcy0+cGFmICE9IE5VTEwpCiAgICBJQVZJRmlsZV9SZWxlYXNlKChQQVZJRklMRSlUaGlzLT5wYWYpOwoKICByZXR1cm4gVGhpcy0+cmVmOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbkNyZWF0ZShJQVZJU3RyZWFtICppZmFjZSwgTFBBUkFNIGxQYXJhbTEsCgkJCQkJICBMUEFSQU0gbFBhcmFtMikKewogIFRSQUNFKCIoJXAsMHglMDhsWCwweCUwOGxYKVxuIiwgaWZhY2UsIGxQYXJhbTEsIGxQYXJhbTIpOwoKICAvKiBUaGlzIElBVklTdHJlYW0gaW50ZXJmYWNlIG5lZWRzIGFuIEFWSUZpbGUgKi8KICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbkluZm8oSUFWSVN0cmVhbSAqaWZhY2UsTFBBVklTVFJFQU1JTkZPVyBwc2ksCgkJCQkJTE9ORyBzaXplKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlcCwlbGQpXG4iLCBpZmFjZSwgcHNpLCBzaXplKTsKCiAgaWYgKHBzaSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICBpZiAoc2l6ZSA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CgogIG1lbWNweShwc2ksICZUaGlzLT5zSW5mbywgbWluKChEV09SRClzaXplLCBzaXplb2YoVGhpcy0+c0luZm8pKSk7CgogIGlmICgoRFdPUkQpc2l6ZSA8IHNpemVvZihUaGlzLT5zSW5mbykpCiAgICByZXR1cm4gQVZJRVJSX0JVRkZFUlRPT1NNQUxMOwogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBMT05HIFdJTkFQSSBJQVZJU3RyZWFtX2ZuRmluZFNhbXBsZShJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBwb3MsCgkJCQkJICAgTE9ORyBmbGFncykKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIExPTkcgb2Zmc2V0ID0gMDsKCiAgVFJBQ0UoIiglcCwlbGQsMHglMDhsWClcbiIsaWZhY2UscG9zLGZsYWdzKTsKCiAgaWYgKGZsYWdzICYgRklORF9GUk9NX1NUQVJUKSB7CiAgICBwb3MgPSBUaGlzLT5zSW5mby5kd1N0YXJ0OwogICAgZmxhZ3MgJj0gfihGSU5EX0ZST01fU1RBUlR8RklORF9QUkVWKTsKICAgIGZsYWdzIHw9IEZJTkRfTkVYVDsKICB9CgogIGlmIChUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUgIT0gMCkgewogICAgLyogY29udmVydCBzYW1wbGVzIGludG8gYmxvY2sgbnVtYmVyIHdpdGggb2Zmc2V0ICovCiAgICBBVklGSUxFX1NhbXBsZXNUb0Jsb2NrKFRoaXMsICZwb3MsICZvZmZzZXQpOwogIH0KCiAgaWYgKGZsYWdzICYgRklORF9UWVBFKSB7CiAgICBpZiAoZmxhZ3MgJiBGSU5EX0tFWSkgewogICAgICB3aGlsZSAoMCA8PSBwb3MgJiYgcG9zIDw9IFRoaXMtPmxMYXN0RnJhbWUpIHsKCWlmIChUaGlzLT5pZHhGcmFtZXNbcG9zXS5kd0ZsYWdzICYgQVZJSUZfS0VZRlJBTUUpCgkgIGdvdG8gUkVUVVJOX0ZPVU5EOwoKCWlmIChmbGFncyAmIEZJTkRfTkVYVCkKCSAgcG9zKys7CgllbHNlCgkgIHBvcy0tOwogICAgICB9OwogICAgfSBlbHNlIGlmIChmbGFncyAmIEZJTkRfQU5ZKSB7CiAgICAgIHdoaWxlICgwIDw9IHBvcyAmJiBwb3MgPD0gVGhpcy0+bExhc3RGcmFtZSkgewoJaWYgKFRoaXMtPmlkeEZyYW1lc1twb3NdLmR3Q2h1bmtMZW5ndGggPiAwKQoJICBnb3RvIFJFVFVSTl9GT1VORDsKCglpZiAoZmxhZ3MgJiBGSU5EX05FWFQpCgkgIHBvcysrOwoJZWxzZQoJICBwb3MtLTsKCiAgICAgIH07CiAgICB9IGVsc2UgaWYgKChmbGFncyAmIEZJTkRfRk9STUFUKSAmJiBUaGlzLT5pZHhGbXRDaGFuZ2VzICE9IE5VTEwgJiYKCSAgICAgICBUaGlzLT5zSW5mby5mY2NUeXBlID09IHN0cmVhbXR5cGVWSURFTykgewogICAgICBpZiAoZmxhZ3MgJiBGSU5EX05FWFQpIHsKCVVMT05HIG47CgoJZm9yIChuID0gMDsgbiA8IFRoaXMtPnNJbmZvLmR3Rm9ybWF0Q2hhbmdlQ291bnQ7IG4rKykKCSAgaWYgKFRoaXMtPmlkeEZtdENoYW5nZXNbbl0uY2tpZCA+PSBwb3MpIHsKICAgICAgICAgICAgcG9zID0gVGhpcy0+aWR4Rm10Q2hhbmdlc1tuXS5ja2lkOwoJICAgIGdvdG8gUkVUVVJOX0ZPVU5EOwogICAgICAgICAgfQogICAgICB9IGVsc2UgewoJTE9ORyBuOwoKCWZvciAobiA9IChMT05HKVRoaXMtPnNJbmZvLmR3Rm9ybWF0Q2hhbmdlQ291bnQ7IG4gPj0gMDsgbi0tKSB7CgkgIGlmIChUaGlzLT5pZHhGbXRDaGFuZ2VzW25dLmNraWQgPD0gcG9zKSB7CiAgICAgICAgICAgIHBvcyA9IFRoaXMtPmlkeEZtdENoYW5nZXNbbl0uY2tpZDsKCSAgICBnb3RvIFJFVFVSTl9GT1VORDsKICAgICAgICAgIH0KCX0KCglpZiAocG9zID4gKExPTkcpVGhpcy0+c0luZm8uZHdTdGFydCkKCSAgcmV0dXJuIDA7IC8qIGZvcm1hdCBjaGFuZ2VzIGFsd2F5cyBmb3IgZmlyc3QgZnJhbWUgKi8KICAgICAgfQogICAgfQoKICAgIHJldHVybiAtMTsKICB9CgogUkVUVVJOX0ZPVU5EOgogIGlmIChwb3MgPCAoTE9ORylUaGlzLT5zSW5mby5kd1N0YXJ0KQogICAgcmV0dXJuIC0xOwoKICBzd2l0Y2ggKGZsYWdzICYgRklORF9SRVQpIHsKICBjYXNlIEZJTkRfTEVOR1RIOgogICAgLyogcGh5c2ljYWwgc2l6ZSAqLwogICAgcG9zID0gVGhpcy0+aWR4RnJhbWVzW3Bvc10uZHdDaHVua0xlbmd0aDsKICAgIGJyZWFrOwogIGNhc2UgRklORF9PRkZTRVQ6CiAgICAvKiBwaHlzaWNhbCBwb3NpdGlvbiAqLwogICAgcG9zID0gVGhpcy0+aWR4RnJhbWVzW3Bvc10uZHdDaHVua09mZnNldCArIDIgKiBzaXplb2YoRFdPUkQpCiAgICAgICsgb2Zmc2V0ICogVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplOwogICAgYnJlYWs7CiAgY2FzZSBGSU5EX1NJWkU6CiAgICAvKiBsb2dpY2FsIHNpemUgKi8KICAgIGlmIChUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUpCiAgICAgIHBvcyA9IFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZTsKICAgIGVsc2UKICAgICAgcG9zID0gMTsKICAgIGJyZWFrOwogIGNhc2UgRklORF9JTkRFWDoKICAgIEZJWE1FKCI6IEZJTkRfSU5ERVggZmxhZyBpcyBub3Qgc3VwcG9ydGVkIVxuIik7CiAgICAvKiBUaGlzIGlzIGFuIGluZGV4IGluIHRoZSBpbmRleC10YWJsZSBvbiBkaXNjLiAqLwogICAgYnJlYWs7CiAgfTsgLyogZWxzZSBsb2dpY2FsIHBvc2l0aW9uICovCgogIHJldHVybiBwb3M7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUmVhZEZvcm1hdChJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBwb3MsCgkJCQkJICAgICAgTFBWT0lEIGZvcm1hdCwgTE9ORyAqZm9ybWF0c2l6ZSkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJWxkLCVwLCVwKVxuIiwgaWZhY2UsIHBvcywgZm9ybWF0LCBmb3JtYXRzaXplKTsKCiAgaWYgKGZvcm1hdHNpemUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIC8qIG9ubHkgaW50ZXJlc3RlZCBpbiBuZWVkZWQgYnVmZmVyc2l6ZT8gKi8KICBpZiAoZm9ybWF0ID09IE5VTEwgfHwgKmZvcm1hdHNpemUgPD0gMCkgewogICAgKmZvcm1hdHNpemUgPSBUaGlzLT5jYkZvcm1hdDsKCiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0KCiAgLyogY29weSBpbml0aWFsIGZvcm1hdCAob25seSBhcyBtdWNoIGFzIHdpbGwgZml0KSAqLwogIG1lbWNweShmb3JtYXQsIFRoaXMtPmxwRm9ybWF0LCBtaW4oKihEV09SRCopZm9ybWF0c2l6ZSwgVGhpcy0+Y2JGb3JtYXQpKTsKICBpZiAoKihEV09SRCopZm9ybWF0c2l6ZSA8IFRoaXMtPmNiRm9ybWF0KSB7CiAgICAqZm9ybWF0c2l6ZSA9IFRoaXMtPmNiRm9ybWF0OwogICAgcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKICB9CgogIC8qIENvdWxkIGZvcm1hdCBjaGFuZ2U/IFdoZW4geWVzIHdpbGwgaXQgY2hhbmdlPyAqLwogIGlmICgoVGhpcy0+c0luZm8uZHdGbGFncyAmIEFWSVNUUkVBTUlORk9fRk9STUFUQ0hBTkdFUykgJiYKICAgICAgcG9zID4gVGhpcy0+c0luZm8uZHdTdGFydCkgewogICAgTE9ORyBsTGFzdEZtdDsKCiAgICBsTGFzdEZtdCA9IElBVklTdHJlYW1fZm5GaW5kU2FtcGxlKGlmYWNlLCBwb3MsIEZJTkRfRk9STUFUfEZJTkRfUFJFVik7CiAgICBpZiAobExhc3RGbXQgPiAwKSB7CiAgICAgIEZJWE1FKCI6IG5lZWQgdG8gcmVhZCBmb3JtYXRjaGFuZ2UgZm9yICVsZCAtLSB1bmltcGxlbWVudGVkIVxuIixsTGFzdEZtdCk7CiAgICB9CiAgfQoKICAqZm9ybWF0c2l6ZSA9IFRoaXMtPmNiRm9ybWF0OwogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuU2V0Rm9ybWF0KElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHBvcywKCQkJCQkgICAgIExQVk9JRCBmb3JtYXQsIExPTkcgZm9ybWF0c2l6ZSkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIExQQklUTUFQSU5GT0hFQURFUiBscGJpTmV3ID0gKExQQklUTUFQSU5GT0hFQURFUilmb3JtYXQ7CgogIFRSQUNFKCIoJXAsJWxkLCVwLCVsZClcbiIsIGlmYWNlLCBwb3MsIGZvcm1hdCwgZm9ybWF0c2l6ZSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoZm9ybWF0ID09IE5VTEwgfHwgZm9ybWF0c2l6ZSA8PSAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogRG8gd2UgaGF2ZSB3cml0ZSBwZXJtaXNzaW9uPyAqLwogIGlmICgoVGhpcy0+cGFmLT51TW9kZSAmIE1NSU9fUldNT0RFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgLyogY2FuIG9ubHkgc2V0IGZvcm1hdCBiZWZvcmUgZnJhbWUgaXMgd3JpdHRlbiEgKi8KICBpZiAoVGhpcy0+bExhc3RGcmFtZSA+IHBvcykKICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CgogIC8qIGluaXRpYWwgZm9ybWF0IG9yIGEgZm9ybWF0Y2hhbmdlPyAqLwogIGlmIChUaGlzLT5scEZvcm1hdCA9PSBOVUxMKSB7CiAgICAvKiBpbml0aWFsIGZvcm1hdCAqLwogICAgaWYgKFRoaXMtPnBhZi0+ZHdNb3ZpQ2h1bmtQb3MgIT0gMCkKICAgICAgcmV0dXJuIEFWSUVSUl9FUlJPUjsgLyogdXNlciBoYXMgdXNlZCBBUEkgaW4gd3Jvbmcgc2VxdW5lY2UhICovCgogICAgVGhpcy0+bHBGb3JtYXQgPSBHbG9iYWxBbGxvY1B0cihHTUVNX01PVkVBQkxFLCBmb3JtYXRzaXplKTsKICAgIGlmIChUaGlzLT5scEZvcm1hdCA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKICAgIFRoaXMtPmNiRm9ybWF0ID0gZm9ybWF0c2l6ZTsKCiAgICBtZW1jcHkoVGhpcy0+bHBGb3JtYXQsIGZvcm1hdCwgZm9ybWF0c2l6ZSk7CgogICAgLyogdXBkYXRlIHNvbWUgaW5mb3MgYWJvdXQgc3RyZWFtICovCiAgICBpZiAoVGhpcy0+c0luZm8uZmNjVHlwZSA9PSBzdHJlYW10eXBlVklERU8pIHsKICAgICAgTE9ORyBsRGltOwoKICAgICAgbERpbSA9IFRoaXMtPnNJbmZvLnJjRnJhbWUucmlnaHQgLSBUaGlzLT5zSW5mby5yY0ZyYW1lLmxlZnQ7CiAgICAgIGlmIChsRGltIDwgbHBiaU5ldy0+YmlXaWR0aCkKCVRoaXMtPnNJbmZvLnJjRnJhbWUucmlnaHQgPSBUaGlzLT5zSW5mby5yY0ZyYW1lLmxlZnQgKyBscGJpTmV3LT5iaVdpZHRoOwogICAgICBsRGltID0gVGhpcy0+c0luZm8ucmNGcmFtZS5ib3R0b20gLSBUaGlzLT5zSW5mby5yY0ZyYW1lLnRvcDsKICAgICAgaWYgKGxEaW0gPCBscGJpTmV3LT5iaUhlaWdodCkKCVRoaXMtPnNJbmZvLnJjRnJhbWUuYm90dG9tID0gVGhpcy0+c0luZm8ucmNGcmFtZS50b3AgKyBscGJpTmV3LT5iaUhlaWdodDsKICAgIH0gZWxzZSBpZiAoVGhpcy0+c0luZm8uZmNjVHlwZSA9PSBzdHJlYW10eXBlQVVESU8pCiAgICAgIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSA9ICgoTFBXQVZFRk9STUFURVgpVGhpcy0+bHBGb3JtYXQpLT5uQmxvY2tBbGlnbjsKCiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0gZWxzZSB7CiAgICBNTUNLSU5GTyAgICAgICAgICAgY2s7CiAgICBMUEJJVE1BUElORk9IRUFERVIgbHBiaU9sZCA9IChMUEJJVE1BUElORk9IRUFERVIpVGhpcy0+bHBGb3JtYXQ7CiAgICBSR0JRVUFEICAgICAgICAgICAqcmdiTmV3ICA9IChSR0JRVUFEKikoKExQQllURSlscGJpTmV3ICsgbHBiaU5ldy0+YmlTaXplKTsKICAgIEFWSVBBTENIQU5HRSAgICAgICpscHBjID0gTlVMTDsKICAgIFVJTlQgICAgICAgICAgICAgICBuOwoKICAgIC8qIHBlcmhhcHMgZm9ybWF0IGNoYW5nZSwgY2hlY2sgaXQgLi4uICovCiAgICBpZiAoVGhpcy0+Y2JGb3JtYXQgIT0gZm9ybWF0c2l6ZSkKICAgICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKCiAgICAvKiBubyBmb3JtYXQgY2hhbmdlLCBvbmx5IHRoZSBpbml0aWFsIG9uZSAqLwogICAgaWYgKG1lbWNtcChUaGlzLT5scEZvcm1hdCwgZm9ybWF0LCBmb3JtYXRzaXplKSA9PSAwKQogICAgICByZXR1cm4gQVZJRVJSX09LOwoKICAgIC8qIGNoZWNrIHRoYXQncyBvbmx5IHRoZSBwYWxldHRlLCB3aGljaCBjaGFuZ2VzICovCiAgICBpZiAobHBiaU9sZC0+YmlTaXplICAgICAgICAhPSBscGJpTmV3LT5iaVNpemUgfHwKCWxwYmlPbGQtPmJpV2lkdGggICAgICAgIT0gbHBiaU5ldy0+YmlXaWR0aCB8fAoJbHBiaU9sZC0+YmlIZWlnaHQgICAgICAhPSBscGJpTmV3LT5iaUhlaWdodCB8fAoJbHBiaU9sZC0+YmlQbGFuZXMgICAgICAhPSBscGJpTmV3LT5iaVBsYW5lcyB8fAoJbHBiaU9sZC0+YmlCaXRDb3VudCAgICAhPSBscGJpTmV3LT5iaUJpdENvdW50IHx8CglscGJpT2xkLT5iaUNvbXByZXNzaW9uICE9IGxwYmlOZXctPmJpQ29tcHJlc3Npb24gfHwKCWxwYmlPbGQtPmJpQ2xyVXNlZCAgICAgIT0gbHBiaU5ldy0+YmlDbHJVc2VkKQogICAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICAgIFRoaXMtPnNJbmZvLmR3RmxhZ3MgfD0gQVZJU1RSRUFNSU5GT19GT1JNQVRDSEFOR0VTOwoKICAgIC8qIHNpbXBseSBzYXkgYWxsIGNvbG9ycyBoYXZlIGNoYW5nZWQgKi8KICAgIGNrLmNraWQgICA9IE1BS0VBVklDS0lEKGNrdHlwZVBBTGNoYW5nZSwgVGhpcy0+blN0cmVhbSk7CiAgICBjay5ja3NpemUgPSAyICogc2l6ZW9mKFdPUkQpICsgbHBiaU9sZC0+YmlDbHJVc2VkICogc2l6ZW9mKFBBTEVUVEVFTlRSWSk7CiAgICBscHBjID0gKEFWSVBBTENIQU5HRSopR2xvYmFsQWxsb2NQdHIoR01FTV9NT1ZFQUJMRSwgY2suY2tzaXplKTsKICAgIGlmIChscHBjID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICAgIGxwcGMtPmJGaXJzdEVudHJ5ID0gMDsKICAgIGxwcGMtPmJOdW1FbnRyaWVzID0gKGxwYmlPbGQtPmJpQ2xyVXNlZCA8IDI1NiA/IGxwYmlPbGQtPmJpQ2xyVXNlZCA6IDApOwogICAgbHBwYy0+d0ZsYWdzICAgICAgPSAwOwogICAgZm9yIChuID0gMDsgbiA8IGxwYmlPbGQtPmJpQ2xyVXNlZDsgbisrKSB7CiAgICAgIGxwcGMtPnBlTmV3W25dLnBlUmVkICAgPSByZ2JOZXdbbl0ucmdiUmVkOwogICAgICBscHBjLT5wZU5ld1tuXS5wZUdyZWVuID0gcmdiTmV3W25dLnJnYkdyZWVuOwogICAgICBscHBjLT5wZU5ld1tuXS5wZUJsdWUgID0gcmdiTmV3W25dLnJnYkJsdWU7CiAgICAgIGxwcGMtPnBlTmV3W25dLnBlRmxhZ3MgPSAwOwogICAgfQoKICAgIGlmIChtbWlvU2VlayhUaGlzLT5wYWYtPmhtbWlvLCBUaGlzLT5wYWYtPmR3TmV4dEZyYW1lUG9zLCBTRUVLX1NFVCkgPT0gLTEpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5wYWYtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgaWYgKG1taW9Xcml0ZShUaGlzLT5wYWYtPmhtbWlvLCAoSFBTVFIpbHBwYywgY2suY2tzaXplKSAhPSBjay5ja3NpemUpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+cGFmLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgIFRoaXMtPnBhZi0+ZHdOZXh0RnJhbWVQb3MgKz0gY2suY2tzaXplICsgMiAqIHNpemVvZihEV09SRCk7CgogICAgR2xvYmFsRnJlZVB0cihscHBjKTsKCiAgICByZXR1cm4gQVZJRklMRV9BZGRGcmFtZShUaGlzLCBja3R5cGVQQUxjaGFuZ2UsIG4sIGNrLmR3RGF0YU9mZnNldCwgMCk7CiAgfQp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblJlYWQoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgc3RhcnQsCgkJCQkJTE9ORyBzYW1wbGVzLCBMUFZPSUQgYnVmZmVyLAoJCQkJCUxPTkcgYnVmZmVyc2l6ZSwgTFBMT05HIGJ5dGVzcmVhZCwKCQkJCQlMUExPTkcgc2FtcGxlc3JlYWQpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBEV09SRCAgICBzaXplOwogIEhSRVNVTFQgIGhyOwoKICBUUkFDRSgiKCVwLCVsZCwlbGQsJXAsJWxkLCVwLCVwKVxuIiwgaWZhY2UsIHN0YXJ0LCBzYW1wbGVzLCBidWZmZXIsCiAJYnVmZmVyc2l6ZSwgYnl0ZXNyZWFkLCBzYW1wbGVzcmVhZCk7CgogIC8qIGNsZWFyIHJldHVybiBwYXJhbWV0ZXJzIGlmIGdpdmVuICovCiAgaWYgKGJ5dGVzcmVhZCAhPSBOVUxMKQogICAgKmJ5dGVzcmVhZCA9IDA7CiAgaWYgKHNhbXBsZXNyZWFkICE9IE5VTEwpCiAgICAqc2FtcGxlc3JlYWQgPSAwOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKChMT05HKVRoaXMtPnNJbmZvLmR3U3RhcnQgPiBzdGFydCkKICAgIHJldHVybiBBVklFUlJfTk9EQVRBOyAvKiBjb3VsZG4ndCByZWFkIGJlZm9yZSBzdGFydCBvZiBzdHJlYW0gKi8KICBpZiAoVGhpcy0+c0luZm8uZHdTdGFydCArIFRoaXMtPnNJbmZvLmR3TGVuZ3RoIDwgKERXT1JEKXN0YXJ0KQogICAgcmV0dXJuIEFWSUVSUl9OT0RBVEE7IC8qIHN0YXJ0IGlzIHBhc3QgZW5kIG9mIHN0cmVhbSAqLwoKICAvKiBzaG91bGQgd2UgcmVhZCBhcyBtdWNoIGFzIHBvc3NpYmxlPyAqLwogIGlmIChzYW1wbGVzID09IC0xKSB7CiAgICAvKiBVc2VyIHNob3VsZCBrbm93IGhvdyBtdWNoIHdlIGhhdmUgcmVhZCAqLwogICAgaWYgKGJ5dGVzcmVhZCA9PSBOVUxMICYmIHNhbXBsZXNyZWFkID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICAgaWYgKFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSAhPSAwKQogICAgICBzYW1wbGVzID0gYnVmZmVyc2l6ZSAvIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZTsKICAgIGVsc2UKICAgICAgc2FtcGxlcyA9IDE7CiAgfQoKICAvKiBsaW1pdCB0byBlbmQgb2Ygc3RyZWFtICovCiAgaWYgKChMT05HKVRoaXMtPnNJbmZvLmR3TGVuZ3RoIDwgc2FtcGxlcykKICAgIHNhbXBsZXMgPSBUaGlzLT5zSW5mby5kd0xlbmd0aDsKICBpZiAoKHN0YXJ0IC0gVGhpcy0+c0luZm8uZHdTdGFydCkgPiAoVGhpcy0+c0luZm8uZHdMZW5ndGggLSBzYW1wbGVzKSkKICAgIHNhbXBsZXMgPSBUaGlzLT5zSW5mby5kd0xlbmd0aCAtIChzdGFydCAtIFRoaXMtPnNJbmZvLmR3U3RhcnQpOwoKICAvKiBub3RoaW5nIHRvIHJlYWQ/IFRoZW4gbGVhdmUgLi4uICovCiAgaWYgKHNhbXBsZXMgPT0gMCkKICAgIHJldHVybiBBVklFUlJfT0s7CgogIGlmIChUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUgIT0gMCkgewogICAgLyogZml4ZWQgc2FtcGxlc2l6ZSAtLSB3ZSBjYW4gcmVhZCBvdmVyIGZyYW1lL2Jsb2NrIGJvdW5kYXJpZXMgKi8KICAgIFVMT05HIGJsb2NrID0gc3RhcnQ7CiAgICBMT05HIG9mZnNldCA9IDA7CgogICAgLyogY29udmVydCBzdGFydCBzYW1wbGUgdG8gYmxvY2ssb2Zmc2V0IHBhaXIgKi8KICAgIEFWSUZJTEVfU2FtcGxlc1RvQmxvY2soVGhpcywgJmJsb2NrLCAmb2Zmc2V0KTsKCiAgICAvKiBjb252ZXJ0IHNhbXBsZXMgdG8gYnl0ZXMgKi8KICAgIHNhbXBsZXMgKj0gVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplOwoKICAgIHdoaWxlIChzYW1wbGVzID4gMCAmJiBidWZmZXJzaXplID4gMCkgewogICAgICBpZiAoYmxvY2sgIT0gVGhpcy0+ZHdDdXJyZW50RnJhbWUpIHsKCWhyID0gQVZJRklMRV9SZWFkQmxvY2soVGhpcywgYmxvY2ssIE5VTEwsIDApOwoJaWYgKEZBSUxFRChocikpCgkgIHJldHVybiBocjsKICAgICAgfQoKICAgICAgc2l6ZSA9IG1pbigoRFdPUkQpc2FtcGxlcywgKERXT1JEKWJ1ZmZlcnNpemUpOwogICAgICBzaXplID0gbWluKHNpemUsIFRoaXMtPmNiQnVmZmVyIC0gb2Zmc2V0KTsKICAgICAgbWVtY3B5KGJ1ZmZlciwgKChCWVRFKikmVGhpcy0+bHBCdWZmZXJbMl0pICsgb2Zmc2V0LCBzaXplKTsKCiAgICAgIGJsb2NrKys7CiAgICAgIG9mZnNldCA9IDA7CiAgICAgIGJ1ZmZlciA9ICgoTFBCWVRFKWJ1ZmZlcikrc2l6ZTsKICAgICAgc2FtcGxlcyAgICAtPSBzaXplOwogICAgICBidWZmZXJzaXplIC09IHNpemU7CgogICAgICAvKiBmaWxsIG91dCByZXR1cm4gcGFyYW1ldGVycyBpZiBnaXZlbiAqLwogICAgICBpZiAoYnl0ZXNyZWFkICE9IE5VTEwpCgkqYnl0ZXNyZWFkICAgKz0gc2l6ZTsKICAgICAgaWYgKHNhbXBsZXNyZWFkICE9IE5VTEwpCgkqc2FtcGxlc3JlYWQgKz0gc2l6ZSAvIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZTsKICAgIH0KCiAgICBpZiAoc2FtcGxlcyA9PSAwKQogICAgICByZXR1cm4gQVZJRVJSX09LOwogICAgZWxzZQogICAgICByZXR1cm4gQVZJRVJSX0JVRkZFUlRPT1NNQUxMOwogIH0gZWxzZSB7CiAgICAvKiB2YXJpYWJsZSBzYW1wbGVzaXplIC0tIHdlIGNhbiBvbmx5IHJlYWQgb25lIGZ1bGwgZnJhbWUvYmxvY2sgKi8KICAgIGlmIChzYW1wbGVzID4gMSkKICAgICAgc2FtcGxlcyA9IDE7CgogICAgYXNzZXJ0KHN0YXJ0IDw9IFRoaXMtPmxMYXN0RnJhbWUpOwogICAgc2l6ZSA9IFRoaXMtPmlkeEZyYW1lc1tzdGFydF0uZHdDaHVua0xlbmd0aDsKICAgIGlmIChidWZmZXIgIT0gTlVMTCAmJiBidWZmZXJzaXplID49IHNpemUpIHsKICAgICAgaHIgPSBBVklGSUxFX1JlYWRCbG9jayhUaGlzLCBzdGFydCwgYnVmZmVyLCBzaXplKTsKICAgICAgaWYgKEZBSUxFRChocikpCglyZXR1cm4gaHI7CiAgICB9IGVsc2UgaWYgKGJ1ZmZlciAhPSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX0JVRkZFUlRPT1NNQUxMOwoKICAgIC8qIGZpbGwgb3V0IHJldHVybiBwYXJhbWV0ZXJzIGlmIGdpdmVuICovCiAgICBpZiAoYnl0ZXNyZWFkICE9IE5VTEwpCiAgICAgICpieXRlc3JlYWQgPSBzaXplOwogICAgaWYgKHNhbXBsZXNyZWFkICE9IE5VTEwpCiAgICAgICpzYW1wbGVzcmVhZCA9IHNhbXBsZXM7CgogICAgcmV0dXJuIEFWSUVSUl9PSzsKICB9Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuV3JpdGUoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgc3RhcnQsCgkJCQkJIExPTkcgc2FtcGxlcywgTFBWT0lEIGJ1ZmZlciwKCQkJCQkgTE9ORyBidWZmZXJzaXplLCBEV09SRCBmbGFncywKCQkJCQkgTFBMT05HIHNhbXB3cml0dGVuLAoJCQkJCSBMUExPTkcgYnl0ZXN3cml0dGVuKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgRk9VUkNDICBja2lkOwogIEhSRVNVTFQgaHI7CgogIFRSQUNFKCIoJXAsJWxkLCVsZCwlcCwlbGQsMHglMDhsWCwlcCwlcClcbiIsIGlmYWNlLCBzdGFydCwgc2FtcGxlcywKCWJ1ZmZlciwgYnVmZmVyc2l6ZSwgZmxhZ3MsIHNhbXB3cml0dGVuLCBieXRlc3dyaXR0ZW4pOwoKICAvKiBjbGVhciByZXR1cm4gcGFyYW1ldGVycyBpZiBnaXZlbiAqLwogIGlmIChzYW1wd3JpdHRlbiAhPSBOVUxMKQogICAgKnNhbXB3cml0dGVuID0gMDsKICBpZiAoYnl0ZXN3cml0dGVuICE9IE5VTEwpCiAgICAqYnl0ZXN3cml0dGVuID0gMDsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChidWZmZXIgPT0gTlVMTCAmJiAoYnVmZmVyc2l6ZSA+IDAgfHwgc2FtcGxlcyA+IDApKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogSGF2ZSB3ZSB3cml0ZSBwZXJtaXNzaW9uPyAqLwogIGlmICgoVGhpcy0+cGFmLT51TW9kZSAmIE1NSU9fUldNT0RFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgc3dpdGNoIChUaGlzLT5zSW5mby5mY2NUeXBlKSB7CiAgY2FzZSBzdHJlYW10eXBlQVVESU86CiAgICBja2lkID0gTUFLRUFWSUNLSUQoY2t0eXBlV0FWRWJ5dGVzLCBUaGlzLT5uU3RyZWFtKTsKICAgIGJyZWFrOwogIGRlZmF1bHQ6CiAgICBpZiAoKGZsYWdzICYgQVZJSUZfS0VZRlJBTUUpICYmIGJ1ZmZlcnNpemUgIT0gMCkKICAgICAgY2tpZCA9IE1BS0VBVklDS0lEKGNrdHlwZURJQmJpdHMsIFRoaXMtPm5TdHJlYW0pOwogICAgZWxzZQogICAgICBja2lkID0gTUFLRUFWSUNLSUQoY2t0eXBlRElCY29tcHJlc3NlZCwgVGhpcy0+blN0cmVhbSk7CiAgICBicmVhazsKICB9OwoKICAvKiBhcHBlbmQgdG8gZW5kIG9mIHN0cmVhbT8gKi8KICBpZiAoc3RhcnQgPT0gLTEpIHsKICAgIGlmIChUaGlzLT5sTGFzdEZyYW1lID09IC0xKQogICAgICBzdGFydCA9IFRoaXMtPnNJbmZvLmR3U3RhcnQ7CiAgICBlbHNlCiAgICAgIHN0YXJ0ID0gVGhpcy0+c0luZm8uZHdMZW5ndGg7CiAgfSBlbHNlIGlmIChUaGlzLT5sTGFzdEZyYW1lID09IC0xKQogICAgVGhpcy0+c0luZm8uZHdTdGFydCA9IHN0YXJ0OwoKICBpZiAoVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplICE9IDApIHsKICAgIC8qIGZpeGVkIHNhbXBsZSBzaXplIC0tIGF1ZGlvIGxpa2UgKi8KICAgIGlmIChzYW1wbGVzICogVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplICE9IGJ1ZmZlcnNpemUpCiAgICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICAgLyogQ291bGRuJ3Qgc2tpcCBhdWRpby1saWtlIGRhdGEgLS0gVXNlciBtdXN0IHN1cHBseSBhcHByb3ByaWF0ZSBzaWxlbmNlICovCiAgICBpZiAoVGhpcy0+c0luZm8uZHdMZW5ndGggIT0gc3RhcnQpCiAgICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CgogICAgLyogQ29udmVydCBwb3NpdGlvbiB0byBmcmFtZS9ibG9jayAqLwogICAgc3RhcnQgPSBUaGlzLT5sTGFzdEZyYW1lICsgMTsKCiAgICBpZiAoKFRoaXMtPnBhZi0+ZkluZm8uZHdGbGFncyAmIEFWSUZJTEVJTkZPX0lTSU5URVJMRUFWRUQpID09IDApIHsKICAgICAgRklYTUUoIjogbm90IGludGVybGVhdmVkLCBjb3VsZCBjb2xsZWN0IGF1ZGlvIGRhdGEhXG4iKTsKICAgIH0KICB9IGVsc2UgewogICAgLyogdmFyaWFibGUgc2FtcGxlIHNpemUgLS0gdmlkZW8gbGlrZSAqLwogICAgaWYgKHNhbXBsZXMgPiAxKQogICAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICAgIC8qIG11c3Qgd2UgZmlsbCB1cCB3aXRoIGVtcHR5IGZyYW1lcz8gKi8KICAgIGlmIChUaGlzLT5sTGFzdEZyYW1lICE9IC0xKSB7CiAgICAgIEZPVVJDQyBja2lkMiA9IE1BS0VBVklDS0lEKGNrdHlwZURJQmNvbXByZXNzZWQsIFRoaXMtPm5TdHJlYW0pOwoKICAgICAgd2hpbGUgKHN0YXJ0ID4gVGhpcy0+bExhc3RGcmFtZSArIDEpIHsKCWhyID0gQVZJRklMRV9Xcml0ZUJsb2NrKFRoaXMsIFRoaXMtPmxMYXN0RnJhbWUgKyAxLCBja2lkMiwgMCwgTlVMTCwgMCk7CglpZiAoRkFJTEVEKGhyKSkKCSAgcmV0dXJuIGhyOwogICAgICB9CiAgICB9CiAgfQoKICAvKiB3cml0ZSB0aGUgYmxvY2sgbm93ICovCiAgaHIgPSBBVklGSUxFX1dyaXRlQmxvY2soVGhpcywgc3RhcnQsIGNraWQsIGZsYWdzLCBidWZmZXIsIGJ1ZmZlcnNpemUpOwogIGlmIChTVUNDRUVERUQoaHIpKSB7CiAgICAvKiBmaWxsIG91dCByZXR1cm4gcGFyYW1ldGVycyBpZiBnaXZlbiAqLwogICAgaWYgKHNhbXB3cml0dGVuICE9IE5VTEwpCiAgICAgICpzYW1wd3JpdHRlbiA9IHNhbXBsZXM7CiAgICBpZiAoYnl0ZXN3cml0dGVuICE9IE5VTEwpCiAgICAgICpieXRlc3dyaXR0ZW4gPSBidWZmZXJzaXplOwogIH0KCiAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbkRlbGV0ZShJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBzdGFydCwKCQkJCQkgIExPTkcgc2FtcGxlcykKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIEZJWE1FKCIoJXAsJWxkLCVsZCk6IHN0dWJcbiIsIGlmYWNlLCBzdGFydCwgc2FtcGxlcyk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoc3RhcnQgPCAwIHx8IHNhbXBsZXMgPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogRGVsZXRlIGJlZm9yZSBzdGFydCBvZiBzdHJlYW0/ICovCiAgaWYgKHN0YXJ0ICsgc2FtcGxlcyA8IFRoaXMtPnNJbmZvLmR3U3RhcnQpCiAgICByZXR1cm4gQVZJRVJSX09LOwoKICAvKiBEZWxldGUgYWZ0ZXIgZW5kIG9mIHN0cmVhbT8gKi8KICBpZiAoc3RhcnQgPiBUaGlzLT5zSW5mby5kd0xlbmd0aCkKICAgIHJldHVybiBBVklFUlJfT0s7CgogIC8qIEZvciB0aGUgcmVzdCB3ZSBuZWVkIHdyaXRlIHBlcm1pc3Npb25zICovCiAgaWYgKChUaGlzLT5wYWYtPnVNb2RlICYgTU1JT19SV01PREUpID09IDApCiAgICByZXR1cm4gQVZJRVJSX1JFQURPTkxZOwoKICAvKiAxLiBvdmVyd3JpdGUgdGhlIGRhdGEgd2l0aCBKVU5LCiAgICoKICAgKiBpZiBJU0lOVEVSTEVBVkVEIHsKICAgKiAgIDIuIGNvbmNhdCBhbGwgbmVpZ2hib3VyZWQgSlVOSy1ibG9ja3MgaW4gdGhpcyByZWNvcmQgdG8gb25lCiAgICogICAzLiBpZiB0aGlzIHJlY29yZCBvbmx5IGNvbnRhaW5zIEpVTksgYW5kIGlzIGF0IGVuZCBzZXQgZHdOZXh0RnJhbWVQb3MKICAgKiAgICAgIHRvIHN0YXJ0IG9mIHRoaXMgcmVjb3JkLCByZXBlYXQgdGhpcy4KICAgKiB9IGVsc2UgewogICAqICAgMi4gY29uY2F0IGFsbCBuZWlnaGJvdXJlZCBKVU5LLWJsb2Nrcy4KICAgKiAgIDMuIGlmIHRoZSBKVU5LIGJsb2NrIGlzIGF0IHRoZSBlbmQsIHRoZW4gc2V0IGR3TmV4dEZyYW1lUG9zIHRvCiAgICogICAgICBzdGFydCBvZiB0aGlzIGJsb2NrLgogICAqIH0KICAgKi8KCiAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5SZWFkRGF0YShJQVZJU3RyZWFtICppZmFjZSwgRFdPUkQgZmNjLAoJCQkJCSAgICBMUFZPSUQgbHAsIExQTE9ORyBscHJlYWQpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLDB4JTA4bFgsJXAsJXApXG4iLCBpZmFjZSwgZmNjLCBscCwgbHByZWFkKTsKCiAgaWYgKGZjYyA9PSBja2lkU1RSRUFNSEFORExFUkRBVEEpIHsKICAgIGlmIChUaGlzLT5scEhhbmRsZXJEYXRhICE9IE5VTEwgJiYgVGhpcy0+Y2JIYW5kbGVyRGF0YSA+IDApIHsKICAgICAgaWYgKGxwID09IE5VTEwgfHwgKmxwcmVhZCA8PSAwKSB7CgkqbHByZWFkID0gVGhpcy0+Y2JIYW5kbGVyRGF0YTsKCXJldHVybiBBVklFUlJfT0s7CiAgICAgIH0KCiAgICAgIG1lbWNweShscCwgVGhpcy0+bHBIYW5kbGVyRGF0YSwgbWluKFRoaXMtPmNiSGFuZGxlckRhdGEsICpscHJlYWQpKTsKICAgICAgaWYgKCpscHJlYWQgPCBUaGlzLT5jYkhhbmRsZXJEYXRhKQoJcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKICAgICAgcmV0dXJuIEFWSUVSUl9PSzsKICAgIH0gZWxzZQogICAgICByZXR1cm4gQVZJRVJSX05PREFUQTsKICB9IGVsc2UKICAgIHJldHVybiBSZWFkRXh0cmFDaHVuaygmVGhpcy0+ZXh0cmEsIGZjYywgbHAsIGxwcmVhZCk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuV3JpdGVEYXRhKElBVklTdHJlYW0gKmlmYWNlLCBEV09SRCBmY2MsCgkJCQkJICAgICBMUFZPSUQgbHAsIExPTkcgc2l6ZSkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsMHglMDhseCwlcCwlbGQpXG4iLCBpZmFjZSwgZmNjLCBscCwgc2l6ZSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAobHAgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgaWYgKHNpemUgPD0gMCkKICAgIHJldHVybiBBVklFUlJfQkFEU0laRTsKCiAgLyogbmVlZCB3cml0ZSBwZXJtaXNzaW9uICovCiAgaWYgKChUaGlzLT5wYWYtPnVNb2RlICYgTU1JT19SV01PREUpID09IDApCiAgICByZXR1cm4gQVZJRVJSX1JFQURPTkxZOwoKICAvKiBhbHJlYWR5IHdyaXR0ZW4gc29tZXRoaW5nIHRvIHRoaXMgZmlsZT8gKi8KICBpZiAoVGhpcy0+cGFmLT5kd01vdmlDaHVua1BvcyAhPSAwKSB7CiAgICAvKiB0aGUgZGF0YSB3aWxsIGJlIGluc2VydGVkIGJlZm9yZSB0aGUgJ21vdmknIGNodW5rLCBzbyBjaGVjayBmb3IKICAgICAqIGVub3VnaCBzcGFjZSAqLwogICAgRFdPUkQgZHdQb3MgPSBBVklGSUxFX0NvbXB1dGVNb3ZpU3RhcnQoVGhpcy0+cGFmKTsKCiAgICAvKiBja2lkLHNpemUgPT4gMiAqIHNpemVvZihEV09SRCkgKi8KICAgIGR3UG9zICs9IDIgKiBzaXplb2YoRFdPUkQpICsgc2l6ZTsKICAgIGlmIChzaXplID49IFRoaXMtPnBhZi0+ZHdNb3ZpQ2h1bmtQb3MgLSAyICogc2l6ZW9mKERXT1JEKSkKICAgICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsgLyogbm90IGVub3VnaCBzcGFjZSBsZWZ0ICovCiAgfQoKICBUaGlzLT5wYWYtPmZEaXJ0eSA9IFRSVUU7CgogIGlmIChmY2MgPT0gY2tpZFNUUkVBTUhBTkRMRVJEQVRBKSB7CiAgICBpZiAoVGhpcy0+bHBIYW5kbGVyRGF0YSAhPSBOVUxMKSB7CiAgICAgIEZJWE1FKCI6IGhhbmRsZXIgZGF0YSBhbHJlYWR5IHNldCAtLSBvdmVyd2lydGU/XG4iKTsKICAgICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKICAgIH0KCiAgICBUaGlzLT5scEhhbmRsZXJEYXRhID0gR2xvYmFsQWxsb2NQdHIoR01FTV9NT1ZFQUJMRSwgc2l6ZSk7CiAgICBpZiAoVGhpcy0+bHBIYW5kbGVyRGF0YSA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKICAgIFRoaXMtPmNiSGFuZGxlckRhdGEgPSBzaXplOwogICAgbWVtY3B5KFRoaXMtPmxwSGFuZGxlckRhdGEsIGxwLCBzaXplKTsKCiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0gZWxzZQogICAgcmV0dXJuIFdyaXRlRXh0cmFDaHVuaygmVGhpcy0+ZXh0cmEsIGZjYywgbHAsIHNpemUpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblNldEluZm8oSUFWSVN0cmVhbSAqaWZhY2UsCgkJCQkJICAgTFBBVklTVFJFQU1JTkZPVyBpbmZvLCBMT05HIGluZm9sZW4pCnsKICBGSVhNRSgiKCVwLCVwLCVsZCk6IHN0dWJcbiIsIGlmYWNlLCBpbmZvLCBpbmZvbGVuKTsKCiAgcmV0dXJuIEVfRkFJTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9BZGRGcmFtZShJQVZJU3RyZWFtSW1wbCAqVGhpcywgRFdPUkQgY2tpZCwgRFdPUkQgc2l6ZSwgRFdPUkQgb2Zmc2V0LCBEV09SRCBmbGFncykKewogIC8qIHByZS1jb25kaXRpb25zICovCiAgYXNzZXJ0KFRoaXMgIT0gTlVMTCk7CgogIHN3aXRjaCAoVFdPQ0NGcm9tRk9VUkNDKGNraWQpKSB7CiAgY2FzZSBja3R5cGVESUJiaXRzOgogICAgaWYgKFRoaXMtPnBhZi0+ZkluZm8uZHdGbGFncyAmIEFWSUZJTEVJTkZPX1RSVVNUQ0tUWVBFKQogICAgICBmbGFncyB8PSBBVklJRl9LRVlGUkFNRTsKICAgIGJyZWFrOwogIGNhc2UgY2t0eXBlRElCY29tcHJlc3NlZDoKICAgIGlmIChUaGlzLT5wYWYtPmZJbmZvLmR3RmxhZ3MgJiBBVklGSUxFSU5GT19UUlVTVENLVFlQRSkKICAgICAgZmxhZ3MgJj0gfkFWSUlGX0tFWUZSQU1FOwogICAgYnJlYWs7CiAgY2FzZSBja3R5cGVQQUxjaGFuZ2U6CiAgICBpZiAoVGhpcy0+c0luZm8uZmNjVHlwZSAhPSBzdHJlYW10eXBlVklERU8pIHsKICAgICAgRVJSKCI6IGZvdW5kIHBhbGV0dGUgY2hhbmdlIGluIG5vbi12aWRlbyBzdHJlYW0hXG4iKTsKICAgICAgcmV0dXJuIEFWSUVSUl9CQURGT1JNQVQ7CiAgICB9CiAgICBUaGlzLT5zSW5mby5kd0ZsYWdzIHw9IEFWSVNUUkVBTUlORk9fRk9STUFUQ0hBTkdFUzsKICAgIFRoaXMtPnNJbmZvLmR3Rm9ybWF0Q2hhbmdlQ291bnQrKzsKCiAgICBpZiAoVGhpcy0+aWR4Rm10Q2hhbmdlcyA9PSBOVUxMIHx8IFRoaXMtPnNJbmZvLmR3Rm9ybWF0Q2hhbmdlQ291bnQgPCBUaGlzLT5uSWR4Rm10Q2hhbmdlcykgewogICAgICBVSU5UIG4gPSBUaGlzLT5zSW5mby5kd0Zvcm1hdENoYW5nZUNvdW50OwoKICAgICAgVGhpcy0+bklkeEZtdENoYW5nZXMgKz0gMTY7CiAgICAgIGlmIChUaGlzLT5pZHhGbXRDaGFuZ2VzID09IE5VTEwpCglUaGlzLT5pZHhGbXRDaGFuZ2VzID0KCSAgR2xvYmFsQWxsb2NQdHIoR0hORCwgVGhpcy0+bklkeEZtdENoYW5nZXMgKiBzaXplb2YoQVZJSU5ERVhFTlRSWSkpOwogICAgICBlbHNlCglUaGlzLT5pZHhGbXRDaGFuZ2VzID0KCSAgR2xvYmFsUmVBbGxvY1B0cihUaGlzLT5pZHhGbXRDaGFuZ2VzLAoJCQkgICBUaGlzLT5uSWR4Rm10Q2hhbmdlcyAqIHNpemVvZihBVklJTkRFWEVOVFJZKSwgR0hORCk7CiAgICAgIGlmIChUaGlzLT5pZHhGbXRDaGFuZ2VzID09IE5VTEwpCglyZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgICAgIFRoaXMtPmlkeEZtdENoYW5nZXNbbl0uY2tpZCAgICAgICAgICA9IFRoaXMtPmxMYXN0RnJhbWU7CiAgICAgIFRoaXMtPmlkeEZtdENoYW5nZXNbbl0uZHdGbGFncyAgICAgICA9IDA7CiAgICAgIFRoaXMtPmlkeEZtdENoYW5nZXNbbl0uZHdDaHVua09mZnNldCA9IG9mZnNldDsKICAgICAgVGhpcy0+aWR4Rm10Q2hhbmdlc1tuXS5kd0NodW5rTGVuZ3RoID0gc2l6ZTsKCiAgICAgIHJldHVybiBBVklFUlJfT0s7CiAgICB9CiAgICBicmVhazsKICBjYXNlIGNrdHlwZVdBVkVieXRlczoKICAgIGlmIChUaGlzLT5wYWYtPmZJbmZvLmR3RmxhZ3MgJiBBVklGSUxFSU5GT19UUlVTVENLVFlQRSkKICAgICAgZmxhZ3MgfD0gQVZJSUZfS0VZRlJBTUU7CiAgICBicmVhazsKICBkZWZhdWx0OgogICAgV0FSTigiOiB1bmtub3duIFRXT0NDIDB4JTA0WCBmb3VuZFxuIiwgVFdPQ0NGcm9tRk9VUkNDKGNraWQpKTsKICAgIGJyZWFrOwogIH07CgogIC8qIGZpcnN0IGZyYW1lIGlzIGFsd2FzeSBhIGtleWZyYW1lICovCiAgaWYgKFRoaXMtPmxMYXN0RnJhbWUgPT0gLTEpCiAgICBmbGFncyB8PSBBVklJRl9LRVlGUkFNRTsKCiAgaWYgKFRoaXMtPnNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA8IHNpemUpCiAgICBUaGlzLT5zSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPSBzaXplOwoKICAvKiBnZXQgbWVtb3J5IGZvciBpbmRleCAqLwogIGlmIChUaGlzLT5pZHhGcmFtZXMgPT0gTlVMTCB8fCBUaGlzLT5sTGFzdEZyYW1lICsgMSA+PSBUaGlzLT5uSWR4RnJhbWVzKSB7CiAgICBUaGlzLT5uSWR4RnJhbWVzICs9IDUxMjsKICAgIGlmIChUaGlzLT5pZHhGcmFtZXMgPT0gTlVMTCkKICAgICAgVGhpcy0+aWR4RnJhbWVzID0KCUdsb2JhbEFsbG9jUHRyKEdITkQsIFRoaXMtPm5JZHhGcmFtZXMgKiBzaXplb2YoQVZJSU5ERVhFTlRSWSkpOwogICAgICBlbHNlCglUaGlzLT5pZHhGcmFtZXMgPQoJICBHbG9iYWxSZUFsbG9jUHRyKFRoaXMtPmlkeEZyYW1lcywKCQkJICAgVGhpcy0+bklkeEZyYW1lcyAqIHNpemVvZihBVklJTkRFWEVOVFJZKSwgR0hORCk7CiAgICBpZiAoVGhpcy0+aWR4RnJhbWVzID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogIH0KCiAgVGhpcy0+bExhc3RGcmFtZSsrOwogIFRoaXMtPmlkeEZyYW1lc1tUaGlzLT5sTGFzdEZyYW1lXS5ja2lkICAgICAgICAgID0gY2tpZDsKICBUaGlzLT5pZHhGcmFtZXNbVGhpcy0+bExhc3RGcmFtZV0uZHdGbGFncyAgICAgICA9IGZsYWdzOwogIFRoaXMtPmlkeEZyYW1lc1tUaGlzLT5sTGFzdEZyYW1lXS5kd0NodW5rT2Zmc2V0ID0gb2Zmc2V0OwogIFRoaXMtPmlkeEZyYW1lc1tUaGlzLT5sTGFzdEZyYW1lXS5kd0NodW5rTGVuZ3RoID0gc2l6ZTsKCiAgLyogdXBkYXRlIEFWSVNUUkVBTUlORk8gc3RydWN0dXJlIGlmIG5lY2Vzc2FyeSAqLwogIGlmIChUaGlzLT5zSW5mby5kd0xlbmd0aCA8PSBUaGlzLT5sTGFzdEZyYW1lKQogICAgVGhpcy0+c0luZm8uZHdMZW5ndGggPSBUaGlzLT5sTGFzdEZyYW1lICsgMTsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9BZGRSZWNvcmQoSUFWSUZpbGVJbXBsICpUaGlzKQp7CiAgLyogcHJlLWNvbmRpdGlvbnMgKi8KICBhc3NlcnQoVGhpcyAhPSBOVUxMICYmIFRoaXMtPnBwU3RyZWFtc1swXSAhPSBOVUxMKTsKCiAgaWYgKFRoaXMtPmlkeFJlY29yZHMgPT0gTlVMTCB8fCBUaGlzLT5jYklkeFJlY29yZHMgPT0gMCkgewogICAgVGhpcy0+Y2JJZHhSZWNvcmRzICs9IDEwMjQgKiBzaXplb2YoQVZJSU5ERVhFTlRSWSk7CiAgICBUaGlzLT5pZHhSZWNvcmRzID0gR2xvYmFsQWxsb2NQdHIoR0hORCwgVGhpcy0+Y2JJZHhSZWNvcmRzKTsKICAgIGlmIChUaGlzLT5pZHhSZWNvcmRzID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogIH0KCiAgYXNzZXJ0KFRoaXMtPm5JZHhSZWNvcmRzIDwgVGhpcy0+Y2JJZHhSZWNvcmRzL3NpemVvZihBVklJTkRFWEVOVFJZKSk7CgogIFRoaXMtPmlkeFJlY29yZHNbVGhpcy0+bklkeFJlY29yZHNdLmNraWQgICAgICAgICAgPSBsaXN0dHlwZUFWSVJFQ09SRDsKICBUaGlzLT5pZHhSZWNvcmRzW1RoaXMtPm5JZHhSZWNvcmRzXS5kd0ZsYWdzICAgICAgID0gQVZJSUZfTElTVDsKICBUaGlzLT5pZHhSZWNvcmRzW1RoaXMtPm5JZHhSZWNvcmRzXS5kd0NodW5rT2Zmc2V0ID0KICAgIFRoaXMtPmNrTGFzdFJlY29yZC5kd0RhdGFPZmZzZXQgLSAyICogc2l6ZW9mKERXT1JEKTsKICBUaGlzLT5pZHhSZWNvcmRzW1RoaXMtPm5JZHhSZWNvcmRzXS5kd0NodW5rTGVuZ3RoID0KICAgIFRoaXMtPmNrTGFzdFJlY29yZC5ja3NpemU7CiAgVGhpcy0+bklkeFJlY29yZHMrKzsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIERXT1JEICAgQVZJRklMRV9Db21wdXRlTW92aVN0YXJ0KElBVklGaWxlSW1wbCAqVGhpcykKewogIERXT1JEIGR3UG9zOwogIERXT1JEIG5TdHJlYW07CgogIC8qIFJJRkYsaGRybCxtb3ZpLGF2aWggPT4gKDMgKiAzICsgMikgKiBzaXplb2YoRFdPUkQpID0gMTEgKiBzaXplb2YoRFdPUkQpICovCiAgZHdQb3MgPSAxMSAqIHNpemVvZihEV09SRCkgKyBzaXplb2YoTWFpbkFWSUhlYWRlcik7CgogIGZvciAoblN0cmVhbSA9IDA7IG5TdHJlYW0gPCBUaGlzLT5mSW5mby5kd1N0cmVhbXM7IG5TdHJlYW0rKykgewogICAgSUFWSVN0cmVhbUltcGwgKnBTdHJlYW0gPSBUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV07CgogICAgLyogc3RybCxzdHJoLHN0cmYgPT4gKDMgKyAyICogMikgKiBzaXplb2YoRFdPUkQpID0gNyAqIHNpemVvZihEV09SRCkgKi8KICAgIGR3UG9zICs9IDcgKiBzaXplb2YoRFdPUkQpICsgc2l6ZW9mKEFWSVN0cmVhbUhlYWRlcik7CiAgICBkd1BvcyArPSAoKHBTdHJlYW0tPmNiRm9ybWF0ICsgMSkgJiB+MVUpOwogICAgaWYgKHBTdHJlYW0tPmxwSGFuZGxlckRhdGEgIT0gTlVMTCAmJiBwU3RyZWFtLT5jYkhhbmRsZXJEYXRhID4gMCkKICAgICAgZHdQb3MgKz0gMiAqIHNpemVvZihEV09SRCkgKyAoKHBTdHJlYW0tPmNiSGFuZGxlckRhdGEgKyAxKSAmIH4xVSk7CiAgICBpZiAobHN0cmxlblcocFN0cmVhbS0+c0luZm8uc3pOYW1lKSA+IDApCiAgICAgIGR3UG9zICs9IDIgKiBzaXplb2YoRFdPUkQpICsgKChsc3RybGVuVyhwU3RyZWFtLT5zSW5mby5zek5hbWUpICsgMSkgJiB+MVUpOwogIH0KCiAgaWYgKFRoaXMtPmR3TW92aUNodW5rUG9zID09IDApIHsKICAgIFRoaXMtPmR3TmV4dEZyYW1lUG9zID0gZHdQb3M7CgogICAgLyogcGFkIHRvIG11bHRpcGxlIG9mIEFWSV9IRUFERVJTSVpFIG9ubHkgaWYgd2UgYXJlIG1vcmUgdGhhbiA4IGJ5dGVzIGF3YXkgZnJvbSBpdCAqLwogICAgaWYgKCgoZHdQb3MgKyBBVklfSEVBREVSU0laRSkgJiB+KEFWSV9IRUFERVJTSVpFIC0gMSkpIC0gZHdQb3MgPiAyICogc2l6ZW9mKERXT1JEKSkKICAgICAgVGhpcy0+ZHdOZXh0RnJhbWVQb3MgPSAoZHdQb3MgKyBBVklfSEVBREVSU0laRSkgJiB+KEFWSV9IRUFERVJTSVpFIC0gMSk7CgogICAgVGhpcy0+ZHdNb3ZpQ2h1bmtQb3MgPSBUaGlzLT5kd05leHRGcmFtZVBvcyAtIHNpemVvZihEV09SRCk7CiAgfQoKICByZXR1cm4gZHdQb3M7Cn0KCnN0YXRpYyB2b2lkICAgIEFWSUZJTEVfQ29uc3RydWN0QVZJU3RyZWFtKElBVklGaWxlSW1wbCAqcGFmLCBEV09SRCBuciwgTFBBVklTVFJFQU1JTkZPVyBhc2kpCnsKICBJQVZJU3RyZWFtSW1wbCAqcHN0cmVhbTsKCiAgLyogcHJlLWNvbmRpdGlvbnMgKi8KICBhc3NlcnQocGFmICE9IE5VTEwpOwogIGFzc2VydChuciA8IE1BWF9BVklTVFJFQU1TKTsKICBhc3NlcnQocGFmLT5wcFN0cmVhbXNbbnJdICE9IE5VTEwpOwoKICBwc3RyZWFtID0gcGFmLT5wcFN0cmVhbXNbbnJdOwoKICBwc3RyZWFtLT5scFZ0YmwgICAgICAgICA9ICZpYXZpc3Q7CiAgcHN0cmVhbS0+cmVmICAgICAgICAgICAgPSAwOwogIHBzdHJlYW0tPnBhZiAgICAgICAgICAgID0gcGFmOwogIHBzdHJlYW0tPm5TdHJlYW0gICAgICAgID0gbnI7CiAgcHN0cmVhbS0+ZHdDdXJyZW50RnJhbWUgPSAoRFdPUkQpLTE7CiAgcHN0cmVhbS0+bExhc3RGcmFtZSAgICA9IC0xOwoKICBpZiAoYXNpICE9IE5VTEwpIHsKICAgIG1lbWNweSgmcHN0cmVhbS0+c0luZm8sIGFzaSwgc2l6ZW9mKHBzdHJlYW0tPnNJbmZvKSk7CgogICAgaWYgKGFzaS0+ZHdMZW5ndGggPiAwKSB7CiAgICAgIC8qIHByZS1hbGxvY2F0ZSBtZW0gZm9yIGZyYW1lLWluZGV4IHN0cnVjdHVyZSAqLwogICAgICBwc3RyZWFtLT5pZHhGcmFtZXMgPQoJKEFWSUlOREVYRU5UUlkqKUdsb2JhbEFsbG9jUHRyKEdITkQsIGFzaS0+ZHdMZW5ndGggKiBzaXplb2YoQVZJSU5ERVhFTlRSWSkpOwogICAgICBpZiAocHN0cmVhbS0+aWR4RnJhbWVzICE9IE5VTEwpCglwc3RyZWFtLT5uSWR4RnJhbWVzID0gYXNpLT5kd0xlbmd0aDsKICAgIH0KICAgIGlmIChhc2ktPmR3Rm9ybWF0Q2hhbmdlQ291bnQgPiAwKSB7CiAgICAgIC8qIHByZS1hbGxvY2F0ZSBtZW0gZm9yIGZvcm1hdGNoYW5nZS1pbmRleCBzdHJ1Y3R1cmUgKi8KICAgICAgcHN0cmVhbS0+aWR4Rm10Q2hhbmdlcyA9CgkoQVZJSU5ERVhFTlRSWSopR2xvYmFsQWxsb2NQdHIoR0hORCwgYXNpLT5kd0Zvcm1hdENoYW5nZUNvdW50ICogc2l6ZW9mKEFWSUlOREVYRU5UUlkpKTsKICAgICAgaWYgKHBzdHJlYW0tPmlkeEZtdENoYW5nZXMgIT0gTlVMTCkKCXBzdHJlYW0tPm5JZHhGbXRDaGFuZ2VzID0gYXNpLT5kd0Zvcm1hdENoYW5nZUNvdW50OwogICAgfQoKICAgIC8qIFRoZXNlIHZhbHVlcyB3aWxsIGJlIGNvbXB1dGVkICovCiAgICBwc3RyZWFtLT5zSW5mby5kd0xlbmd0aCAgICAgICAgICAgICAgPSAwOwogICAgcHN0cmVhbS0+c0luZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplID0gMDsKICAgIHBzdHJlYW0tPnNJbmZvLmR3Rm9ybWF0Q2hhbmdlQ291bnQgICA9IDA7CiAgICBwc3RyZWFtLT5zSW5mby5kd0VkaXRDb3VudCAgICAgICAgICAgPSAxOwogICAgaWYgKHBzdHJlYW0tPnNJbmZvLmR3U2FtcGxlU2l6ZSA+IDApCiAgICAgIFNldFJlY3RFbXB0eSgmcHN0cmVhbS0+c0luZm8ucmNGcmFtZSk7CiAgfQoKICBwc3RyZWFtLT5zSW5mby5kd0NhcHMgPSBBVklGSUxFQ0FQU19DQU5SRUFEfEFWSUZJTEVDQVBTX0NBTldSSVRFOwp9CgpzdGF0aWMgdm9pZCAgICBBVklGSUxFX0Rlc3RydWN0QVZJU3RyZWFtKElBVklTdHJlYW1JbXBsICpUaGlzKQp7CiAgLyogcHJlLWNvbmRpdGlvbnMgKi8KICBhc3NlcnQoVGhpcyAhPSBOVUxMKTsKCiAgVGhpcy0+ZHdDdXJyZW50RnJhbWUgPSAoRFdPUkQpLTE7CiAgVGhpcy0+bExhc3RGcmFtZSAgICA9IC0xOwogIFRoaXMtPnBhZiA9IE5VTEw7CiAgaWYgKFRoaXMtPmlkeEZyYW1lcyAhPSBOVUxMKSB7CiAgICBHbG9iYWxGcmVlUHRyKFRoaXMtPmlkeEZyYW1lcyk7CiAgICBUaGlzLT5pZHhGcmFtZXMgID0gTlVMTDsKICAgIFRoaXMtPm5JZHhGcmFtZXMgPSAwOwogIH0KICBpZiAoVGhpcy0+aWR4Rm10Q2hhbmdlcyAhPSBOVUxMKSB7CiAgICBHbG9iYWxGcmVlUHRyKFRoaXMtPmlkeEZtdENoYW5nZXMpOwogICAgVGhpcy0+aWR4Rm10Q2hhbmdlcyA9IE5VTEw7CiAgfQogIGlmIChUaGlzLT5scEJ1ZmZlciAhPSBOVUxMKSB7CiAgICBHbG9iYWxGcmVlUHRyKFRoaXMtPmxwQnVmZmVyKTsKICAgIFRoaXMtPmxwQnVmZmVyID0gTlVMTDsKICAgIFRoaXMtPmNiQnVmZmVyID0gMDsKICB9CiAgaWYgKFRoaXMtPmxwSGFuZGxlckRhdGEgIT0gTlVMTCkgewogICAgR2xvYmFsRnJlZVB0cihUaGlzLT5scEhhbmRsZXJEYXRhKTsKICAgIFRoaXMtPmxwSGFuZGxlckRhdGEgPSBOVUxMOwogICAgVGhpcy0+Y2JIYW5kbGVyRGF0YSA9IDA7CiAgfQogIGlmIChUaGlzLT5leHRyYS5scCAhPSBOVUxMKSB7CiAgICBHbG9iYWxGcmVlUHRyKFRoaXMtPmV4dHJhLmxwKTsKICAgIFRoaXMtPmV4dHJhLmxwID0gTlVMTDsKICAgIFRoaXMtPmV4dHJhLmNiID0gMDsKICB9CiAgaWYgKFRoaXMtPmxwRm9ybWF0ICE9IE5VTEwpIHsKICAgIEdsb2JhbEZyZWVQdHIoVGhpcy0+bHBGb3JtYXQpOwogICAgVGhpcy0+bHBGb3JtYXQgPSBOVUxMOwogICAgVGhpcy0+Y2JGb3JtYXQgPSAwOwogIH0KfQoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9Mb2FkRmlsZShJQVZJRmlsZUltcGwgKlRoaXMpCnsKICBNYWluQVZJSGVhZGVyICAgTWFpbkFWSUhkcjsKICBNTUNLSU5GTyAgICAgICAgY2tSSUZGOwogIE1NQ0tJTkZPICAgICAgICBja0xJU1QxOwogIE1NQ0tJTkZPICAgICAgICBja0xJU1QyOwogIE1NQ0tJTkZPICAgICAgICBjazsKICBJQVZJU3RyZWFtSW1wbCAqcFN0cmVhbTsKICBEV09SRCAgICAgICAgICAgblN0cmVhbTsKICBIUkVTVUxUICAgICAgICAgaHI7CgogIGlmIChUaGlzLT5obW1pbyA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFT1BFTjsKCiAgLyogaW5pdGlhbGl6ZSBzdHJlYW0gcHRyJ3MgKi8KICBtZW1zZXQoVGhpcy0+cHBTdHJlYW1zLCAwLCBzaXplb2YoVGhpcy0+cHBTdHJlYW1zKSk7CgogIC8qIHRyeSB0byBnZXQgIlJJRkYiIGNodW5rIC0tIG11c3Qgbm90IGJlIGF0IGJlZ2lubmluZyBvZiBmaWxlISAqLwogIGNrUklGRi5mY2NUeXBlID0gZm9ybXR5cGVBVkk7CiAgaWYgKG1taW9EZXNjZW5kKFRoaXMtPmhtbWlvLCAmY2tSSUZGLCBOVUxMLCBNTUlPX0ZJTkRSSUZGKSAhPSBTX09LKSB7CiAgICBFUlIoIjogbm90IGFuIEFWSSFcbiIpOwogICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKICB9CgogIC8qIGdldCAiTElTVCIgImhkcmwiICovCiAgY2tMSVNUMS5mY2NUeXBlID0gbGlzdHR5cGVBVklIRUFERVI7CiAgaHIgPSBGaW5kQ2h1bmtBbmRLZWVwRXh0cmFzKCZUaGlzLT5maWxlZXh0cmEsIFRoaXMtPmhtbWlvLCAmY2tMSVNUMSwgJmNrUklGRiwgTU1JT19GSU5ETElTVCk7CiAgaWYgKEZBSUxFRChocikpCiAgICByZXR1cm4gaHI7CgogIC8qIGdldCAiYXZpaCIgY2h1bmsgKi8KICBjay5ja2lkID0gY2tpZEFWSU1BSU5IRFI7CiAgaHIgPSBGaW5kQ2h1bmtBbmRLZWVwRXh0cmFzKCZUaGlzLT5maWxlZXh0cmEsIFRoaXMtPmhtbWlvLCAmY2ssICZja0xJU1QxLCBNTUlPX0ZJTkRDSFVOSyk7CiAgaWYgKEZBSUxFRChocikpCiAgICByZXR1cm4gaHI7CgogIGlmIChjay5ja3NpemUgIT0gc2l6ZW9mKE1haW5BVklIZHIpKSB7CiAgICBFUlIoIjogaW52YWxpZCBzaXplIG9mICVsZCBmb3IgTWFpbkFWSUhlYWRlciFcbiIsIGNrLmNrc2l6ZSk7CiAgICByZXR1cm4gQVZJRVJSX0JBREZPUk1BVDsKICB9CiAgaWYgKG1taW9SZWFkKFRoaXMtPmhtbWlvLCAoSFBTVFIpJk1haW5BVklIZHIsIGNrLmNrc2l6ZSkgIT0gY2suY2tzaXplKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCiAgLyogY2hlY2sgZm9yIE1BWF9BVklTVFJFQU1TIGxpbWl0ICovCiAgaWYgKE1haW5BVklIZHIuZHdTdHJlYW1zID4gTUFYX0FWSVNUUkVBTVMpIHsKICAgIFdBUk4oImZpbGUgY29udGFpbnMgJWx1IHN0cmVhbXMsIGJ1dCBvbmx5IHN1cHBvcnRzICVkIC0tIGNoYW5nZSBNQVhfQVZJU1RSRUFNUyFcbiIsIE1haW5BVklIZHIuZHdTdHJlYW1zLCBNQVhfQVZJU1RSRUFNUyk7CiAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwogIH0KCiAgLyogYWRqdXN0IHBlcm1pc3Npb25zIGlmIGNvcHlyaWdodGVkIG1hdGVyaWFsIGluIGZpbGUgKi8KICBpZiAoTWFpbkFWSUhkci5kd0ZsYWdzICYgQVZJRklMRUlORk9fQ09QWVJJR0hURUQpIHsKICAgIFRoaXMtPnVNb2RlICY9IH5NTUlPX1JXTU9ERTsKICAgIFRoaXMtPnVNb2RlIHw9IE1NSU9fUkVBRDsKICB9CgogIC8qIGNvbnZlcnQgTWFpbkFWSUhlYWRlciBpbnRvIEFWSUZJTElORk9XICovCiAgbWVtc2V0KCZUaGlzLT5mSW5mbywgMCwgc2l6ZW9mKFRoaXMtPmZJbmZvKSk7CiAgVGhpcy0+ZkluZm8uZHdSYXRlICAgICAgICAgICAgICAgID0gTWFpbkFWSUhkci5kd01pY3JvU2VjUGVyRnJhbWU7CiAgVGhpcy0+ZkluZm8uZHdTY2FsZSAgICAgICAgICAgICAgID0gMTAwMDAwMDsKICBUaGlzLT5mSW5mby5kd01heEJ5dGVzUGVyU2VjICAgICAgPSBNYWluQVZJSGRyLmR3TWF4Qnl0ZXNQZXJTZWM7CiAgVGhpcy0+ZkluZm8uZHdGbGFncyAgICAgICAgICAgICAgID0gTWFpbkFWSUhkci5kd0ZsYWdzOwogIFRoaXMtPmZJbmZvLmR3Q2FwcyAgICAgICAgICAgICAgICA9IEFWSUZJTEVDQVBTX0NBTlJFQUR8QVZJRklMRUNBUFNfQ0FOV1JJVEU7CiAgVGhpcy0+ZkluZm8uZHdMZW5ndGggICAgICAgICAgICAgID0gTWFpbkFWSUhkci5kd1RvdGFsRnJhbWVzOwogIFRoaXMtPmZJbmZvLmR3U3RyZWFtcyAgICAgICAgICAgICA9IE1haW5BVklIZHIuZHdTdHJlYW1zOwogIFRoaXMtPmZJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA9IE1haW5BVklIZHIuZHdTdWdnZXN0ZWRCdWZmZXJTaXplOwogIFRoaXMtPmZJbmZvLmR3V2lkdGggICAgICAgICAgICAgICA9IE1haW5BVklIZHIuZHdXaWR0aDsKICBUaGlzLT5mSW5mby5kd0hlaWdodCAgICAgICAgICAgICAgPSBNYWluQVZJSGRyLmR3SGVpZ2h0OwogIExvYWRTdHJpbmdXKEFWSUZJTEVfaE1vZHVsZSwgSURTX0FWSUZJTEVUWVBFLCBUaGlzLT5mSW5mby5zekZpbGVUeXBlLAoJICAgICAgc2l6ZW9mKFRoaXMtPmZJbmZvLnN6RmlsZVR5cGUpKTsKCiAgLyogZ28gYmFjayB0byBpbnRvIGhlYWRlciBsaXN0ICovCiAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CgogIC8qIGZvcmVhY2ggc3RyZWFtIGV4aXN0cyBhICJMSVNUIiwic3RybCIgY2h1bmsgKi8KICBmb3IgKG5TdHJlYW0gPSAwOyBuU3RyZWFtIDwgVGhpcy0+ZkluZm8uZHdTdHJlYW1zOyBuU3RyZWFtKyspIHsKICAgIC8qIGdldCBuZXh0IG5lc3RlZCBjaHVuayBpbiB0aGlzICJMSVNUIiwic3RybCIgKi8KICAgIGlmIChtbWlvRGVzY2VuZChUaGlzLT5obW1pbywgJmNrTElTVDIsICZja0xJU1QxLCAwKSAhPSBTX09LKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwoKICAgIC8qIG5lc3RlZCBjaHVuayBtdXN0IGJlIG9mIHR5cGUgIkxJU1QiLCJzdHJsIiAtLSB3aGVuIG5vdCBub3JtYWxseSBKVU5LICovCiAgICBpZiAoY2tMSVNUMi5ja2lkID09IEZPVVJDQ19MSVNUICYmCglja0xJU1QyLmZjY1R5cGUgPT0gbGlzdHR5cGVTVFJFQU1IRUFERVIpIHsKICAgICAgcFN0cmVhbSA9IFRoaXMtPnBwU3RyZWFtc1tuU3RyZWFtXSA9CgkoSUFWSVN0cmVhbUltcGwqKUxvY2FsQWxsb2MoTFBUUiwgc2l6ZW9mKElBVklTdHJlYW1JbXBsKSk7CiAgICAgIGlmIChwU3RyZWFtID09IE5VTEwpCglyZXR1cm4gQVZJRVJSX01FTU9SWTsKICAgICAgQVZJRklMRV9Db25zdHJ1Y3RBVklTdHJlYW0oVGhpcywgblN0cmVhbSwgTlVMTCk7CgogICAgICBjay5ja2lkID0gMDsKICAgICAgd2hpbGUgKG1taW9EZXNjZW5kKFRoaXMtPmhtbWlvLCAmY2ssICZja0xJU1QyLCAwKSA9PSBTX09LKSB7Cglzd2l0Y2ggKGNrLmNraWQpIHsKCWNhc2UgY2tpZFNUUkVBTUhBTkRMRVJEQVRBOgoJICBpZiAocFN0cmVhbS0+bHBIYW5kbGVyRGF0YSAhPSBOVUxMKQoJICAgIHJldHVybiBBVklFUlJfQkFERk9STUFUOwoJICBwU3RyZWFtLT5scEhhbmRsZXJEYXRhID0gR2xvYmFsQWxsb2NQdHIoR01FTV9EREVTSEFSRXxHTUVNX01PVkVBQkxFLAoJCQkJCQkgIGNrLmNrc2l6ZSk7CgkgIGlmIChwU3RyZWFtLT5scEhhbmRsZXJEYXRhID09IE5VTEwpCgkgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgkgIHBTdHJlYW0tPmNiSGFuZGxlckRhdGEgPSBjay5ja3NpemU7CgoJICBpZiAobW1pb1JlYWQoVGhpcy0+aG1taW8sIChIUFNUUilwU3RyZWFtLT5scEhhbmRsZXJEYXRhLCBjay5ja3NpemUpICE9IGNrLmNrc2l6ZSkKCSAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwoJICBicmVhazsKCWNhc2UgY2tpZFNUUkVBTUZPUk1BVDoKCSAgaWYgKHBTdHJlYW0tPmxwRm9ybWF0ICE9IE5VTEwpCgkgICAgcmV0dXJuIEFWSUVSUl9CQURGT1JNQVQ7CiAgICAgICAgICBpZiAoY2suY2tzaXplID09IDApCiAgICAgICAgICAgIGJyZWFrOwoKCSAgcFN0cmVhbS0+bHBGb3JtYXQgPSBHbG9iYWxBbGxvY1B0cihHTUVNX0RERVNIQVJFfEdNRU1fTU9WRUFCTEUsCgkJCQkJICAgICBjay5ja3NpemUpOwoJICBpZiAocFN0cmVhbS0+bHBGb3JtYXQgPT0gTlVMTCkKCSAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCSAgcFN0cmVhbS0+Y2JGb3JtYXQgPSBjay5ja3NpemU7CgoJICBpZiAobW1pb1JlYWQoVGhpcy0+aG1taW8sIChIUFNUUilwU3RyZWFtLT5scEZvcm1hdCwgY2suY2tzaXplKSAhPSBjay5ja3NpemUpCgkgICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCgkgIGlmIChwU3RyZWFtLT5zSW5mby5mY2NUeXBlID09IHN0cmVhbXR5cGVWSURFTykgewoJICAgIExQQklUTUFQSU5GT0hFQURFUiBscGJpID0gKExQQklUTUFQSU5GT0hFQURFUilwU3RyZWFtLT5scEZvcm1hdDsKCgkgICAgLyogc29tZSBjb3JyZWN0aW9ucyB0byB0aGUgdmlkZW8gZm9ybWF0ICovCgkgICAgaWYgKGxwYmktPmJpQ2xyVXNlZCA9PSAwICYmIGxwYmktPmJpQml0Q291bnQgPD0gOCkKCSAgICAgIGxwYmktPmJpQ2xyVXNlZCA9IDF1IDw8IGxwYmktPmJpQml0Q291bnQ7CgkgICAgaWYgKGxwYmktPmJpQ29tcHJlc3Npb24gPT0gQklfUkdCICYmIGxwYmktPmJpU2l6ZUltYWdlID09IDApCgkgICAgICBscGJpLT5iaVNpemVJbWFnZSA9IERJQldJRFRIQllURVMoKmxwYmkpICogbHBiaS0+YmlIZWlnaHQ7CgkgICAgaWYgKGxwYmktPmJpQ29tcHJlc3Npb24gIT0gQklfUkdCICYmIGxwYmktPmJpQml0Q291bnQgPT0gOCkgewoJICAgICAgaWYgKHBTdHJlYW0tPnNJbmZvLmZjY0hhbmRsZXIgPT0gbW1pb0ZPVVJDQygnUicsJ0wnLCdFJywnMCcpIHx8CgkJICBwU3RyZWFtLT5zSW5mby5mY2NIYW5kbGVyID09IG1taW9GT1VSQ0MoJ1InLCdMJywnRScsJyAnKSkKCQlscGJpLT5iaUNvbXByZXNzaW9uID0gQklfUkxFODsKCSAgICB9CgkgICAgaWYgKGxwYmktPmJpQ29tcHJlc3Npb24gPT0gQklfUkdCICYmCgkJKHBTdHJlYW0tPnNJbmZvLmZjY0hhbmRsZXIgPT0gMCB8fAoJCSBwU3RyZWFtLT5zSW5mby5mY2NIYW5kbGVyID09IG1taW9GT1VSQ0MoJ04nLCdPJywnTicsJ0UnKSkpCgkgICAgICBwU3RyZWFtLT5zSW5mby5mY2NIYW5kbGVyID0gY29tcHR5cGVESUI7CgoJICAgIC8qIGluaXQgcmNGcmFtZSBpZiBpdCdzIGVtcHR5ICovCgkgICAgaWYgKElzUmVjdEVtcHR5KCZwU3RyZWFtLT5zSW5mby5yY0ZyYW1lKSkKCSAgICAgIFNldFJlY3QoJnBTdHJlYW0tPnNJbmZvLnJjRnJhbWUsIDAsIDAsIGxwYmktPmJpV2lkdGgsIGxwYmktPmJpSGVpZ2h0KTsKCSAgfQoJICBicmVhazsKCWNhc2UgY2tpZFNUUkVBTUhFQURFUjoKCSAgewoJICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzdHJlYW1UeXBlRm10W10gPSB7JyUnLCc0JywnLicsJzQnLCdoJywncycsMH07CgoJICAgIEFWSVN0cmVhbUhlYWRlciBzdHJlYW1IZHI7CgkgICAgV0NIQVIgICAgICAgICAgIHN6VHlwZVsyNV07CgkgICAgV0NIQVIgICAgICAgICAgIHN0cmVhbU5hbWVGbXRbMjVdOwoJICAgIFVJTlQgICAgICAgICAgICBjb3VudDsKCSAgICBMT05HICAgICAgICAgICAgbiA9IGNrLmNrc2l6ZTsKCgkgICAgaWYgKGNrLmNrc2l6ZSA+IHNpemVvZihzdHJlYW1IZHIpKQoJICAgICAgbiA9IHNpemVvZihzdHJlYW1IZHIpOwoKCSAgICBpZiAobW1pb1JlYWQoVGhpcy0+aG1taW8sIChIUFNUUikmc3RyZWFtSGRyLCBuKSAhPSBuKQoJICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCgkgICAgcFN0cmVhbS0+c0luZm8uZmNjVHlwZSAgICAgICAgICAgICAgID0gc3RyZWFtSGRyLmZjY1R5cGU7CgkgICAgcFN0cmVhbS0+c0luZm8uZmNjSGFuZGxlciAgICAgICAgICAgID0gc3RyZWFtSGRyLmZjY0hhbmRsZXI7CgkgICAgcFN0cmVhbS0+c0luZm8uZHdGbGFncyAgICAgICAgICAgICAgID0gc3RyZWFtSGRyLmR3RmxhZ3M7CgkgICAgcFN0cmVhbS0+c0luZm8ud1ByaW9yaXR5ICAgICAgICAgICAgID0gc3RyZWFtSGRyLndQcmlvcml0eTsKCSAgICBwU3RyZWFtLT5zSW5mby53TGFuZ3VhZ2UgICAgICAgICAgICAgPSBzdHJlYW1IZHIud0xhbmd1YWdlOwoJICAgIHBTdHJlYW0tPnNJbmZvLmR3SW5pdGlhbEZyYW1lcyAgICAgICA9IHN0cmVhbUhkci5kd0luaXRpYWxGcmFtZXM7CgkgICAgcFN0cmVhbS0+c0luZm8uZHdTY2FsZSAgICAgICAgICAgICAgID0gc3RyZWFtSGRyLmR3U2NhbGU7CgkgICAgcFN0cmVhbS0+c0luZm8uZHdSYXRlICAgICAgICAgICAgICAgID0gc3RyZWFtSGRyLmR3UmF0ZTsKCSAgICBwU3RyZWFtLT5zSW5mby5kd1N0YXJ0ICAgICAgICAgICAgICAgPSBzdHJlYW1IZHIuZHdTdGFydDsKCSAgICBwU3RyZWFtLT5zSW5mby5kd0xlbmd0aCAgICAgICAgICAgICAgPSBzdHJlYW1IZHIuZHdMZW5ndGg7CgkgICAgcFN0cmVhbS0+c0luZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplID0KCSAgICAgIHN0cmVhbUhkci5kd1N1Z2dlc3RlZEJ1ZmZlclNpemU7CgkgICAgcFN0cmVhbS0+c0luZm8uZHdRdWFsaXR5ICAgICAgICAgICAgID0gc3RyZWFtSGRyLmR3UXVhbGl0eTsKCSAgICBwU3RyZWFtLT5zSW5mby5kd1NhbXBsZVNpemUgICAgICAgICAgPSBzdHJlYW1IZHIuZHdTYW1wbGVTaXplOwoJICAgIHBTdHJlYW0tPnNJbmZvLnJjRnJhbWUubGVmdCAgICAgICAgICA9IHN0cmVhbUhkci5yY0ZyYW1lLmxlZnQ7CgkgICAgcFN0cmVhbS0+c0luZm8ucmNGcmFtZS50b3AgICAgICAgICAgID0gc3RyZWFtSGRyLnJjRnJhbWUudG9wOwoJICAgIHBTdHJlYW0tPnNJbmZvLnJjRnJhbWUucmlnaHQgICAgICAgICA9IHN0cmVhbUhkci5yY0ZyYW1lLnJpZ2h0OwoJICAgIHBTdHJlYW0tPnNJbmZvLnJjRnJhbWUuYm90dG9tICAgICAgICA9IHN0cmVhbUhkci5yY0ZyYW1lLmJvdHRvbTsKCSAgICBwU3RyZWFtLT5zSW5mby5kd0VkaXRDb3VudCAgICAgICAgICAgPSAwOwoJICAgIHBTdHJlYW0tPnNJbmZvLmR3Rm9ybWF0Q2hhbmdlQ291bnQgICA9IDA7CgoJICAgIC8qIGdlbmVyYXRlIGRlc2NyaXB0aW9uIGZvciBzdHJlYW0gbGlrZSAiZmlsZW5hbWUuYXZpIFR5cGUgI24iICovCgkgICAgaWYgKHN0cmVhbUhkci5mY2NUeXBlID09IHN0cmVhbXR5cGVWSURFTykKCSAgICAgIExvYWRTdHJpbmdXKEFWSUZJTEVfaE1vZHVsZSwgSURTX1ZJREVPLCBzelR5cGUsIHNpemVvZihzelR5cGUpKTsKCSAgICBlbHNlIGlmIChzdHJlYW1IZHIuZmNjVHlwZSA9PSBzdHJlYW10eXBlQVVESU8pCgkgICAgICBMb2FkU3RyaW5nVyhBVklGSUxFX2hNb2R1bGUsIElEU19BVURJTywgc3pUeXBlLCBzaXplb2Yoc3pUeXBlKSk7CgkgICAgZWxzZQoJICAgICAgd3NwcmludGZXKHN6VHlwZSwgc3RyZWFtVHlwZUZtdCwgKGNoYXIqKSZzdHJlYW1IZHIuZmNjVHlwZSk7CgoJICAgIC8qIGdldCBjb3VudCBvZiB0aGlzIHN0cmVhbXR5cGUgdXAgdG8gdGhpcyBzdHJlYW0gKi8KCSAgICBjb3VudCA9IDA7CgkgICAgZm9yIChuID0gblN0cmVhbTsgMCA8PSBuOyBuLS0pIHsKCSAgICAgIGlmIChUaGlzLT5wcFN0cmVhbXNbbl0tPnNJbmZvLmZjY0hhbmRsZXIgPT0gc3RyZWFtSGRyLmZjY1R5cGUpCgkJY291bnQrKzsKCSAgICB9CgoJICAgIG1lbXNldChwU3RyZWFtLT5zSW5mby5zek5hbWUsIDAsIHNpemVvZihwU3RyZWFtLT5zSW5mby5zek5hbWUpKTsKCgkgICAgTG9hZFN0cmluZ1coQVZJRklMRV9oTW9kdWxlLCBJRFNfQVZJU1RSRUFNRk9STUFULCBzdHJlYW1OYW1lRm10LCBzaXplb2Yoc3RyZWFtTmFtZUZtdCkpOwoKCSAgICAvKiBGSVhNRTogYXZvaWQgb3ZlcmZsb3cgLS0gYmV0dGVyIHVzZSB3c25wcmludGZXLCB3aGljaCBkb2Vzbid0IGV4aXN0cyAhICovCgkgICAgd3NwcmludGZXKHBTdHJlYW0tPnNJbmZvLnN6TmFtZSwgc3RyZWFtTmFtZUZtdCwKCQkgICAgICBBVklGSUxFX0Jhc2VuYW1lVyhUaGlzLT5zekZpbGVOYW1lKSwgc3pUeXBlLCBjb3VudCk7CgkgIH0KCSAgYnJlYWs7CgljYXNlIGNraWRTVFJFQU1OQU1FOgoJICB7IC8qIHN0cmVhbW5hbWUgd2lsbCBiZSBzYXZlZCBhcyBBU0NJSSBzdHJpbmcgKi8KCSAgICBMUFNUUiBzdHIgPSAoTFBTVFIpTG9jYWxBbGxvYyhMTUVNX0ZJWEVELCBjay5ja3NpemUpOwoJICAgIGlmIChzdHIgPT0gTlVMTCkKCSAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKCSAgICBpZiAobW1pb1JlYWQoVGhpcy0+aG1taW8sIChIUFNUUilzdHIsIGNrLmNrc2l6ZSkgIT0gY2suY2tzaXplKQoJICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCgkgICAgTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIHN0ciwgLTEsIHBTdHJlYW0tPnNJbmZvLnN6TmFtZSwKCQkJCXNpemVvZihwU3RyZWFtLT5zSW5mby5zek5hbWUpL3NpemVvZihwU3RyZWFtLT5zSW5mby5zek5hbWVbMF0pKTsKCgkgICAgTG9jYWxGcmVlKChITE9DQUwpc3RyKTsKCSAgfQoJICBicmVhazsKCWNhc2UgY2tpZEFWSVBBRERJTkc6CgljYXNlIG1taW9GT1VSQ0MoJ3AnLCdhJywnZCcsJ2QnKToKCSAgYnJlYWs7CglkZWZhdWx0OgoJICBXQVJOKCI6IGZvdW5kIGV4dHJhIGNodW5rIDB4JTA4bFhcbiIsIGNrLmNraWQpOwoJICBociA9IFJlYWRDaHVua0ludG9FeHRyYSgmcFN0cmVhbS0+ZXh0cmEsIFRoaXMtPmhtbWlvLCAmY2spOwoJICBpZiAoRkFJTEVEKGhyKSkKCSAgICByZXR1cm4gaHI7Cgl9OwoKCWlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCgkgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIC8qIG5lc3RlZCBjaHVua3MgaW4gIkxJU1QiLCJoZHJsIiB3aGljaCBhcmUgbm90IG9mIHR5cGUgIkxJU1QiLCJzdHJsIiAqLwogICAgICBociA9IFJlYWRDaHVua0ludG9FeHRyYSgmVGhpcy0+ZmlsZWV4dHJhLCBUaGlzLT5obW1pbywgJmNrTElTVDIpOwogICAgICBpZiAoRkFJTEVEKGhyKSkKCXJldHVybiBocjsKICAgIH0KICAgIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2tMSVNUMiwgMCkgIT0gU19PSykKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKICB9CgogIC8qIHJlYWQgYW55IGV4dHJhIGhlYWRlcnMgaW4gIkxJU1QiLCJoZHJsIiAqLwogIEZpbmRDaHVua0FuZEtlZXBFeHRyYXMoJlRoaXMtPmZpbGVleHRyYSwgVGhpcy0+aG1taW8sICZjaywgJmNrTElTVDEsIDApOwogIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2tMSVNUMSwgMCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CgogIC8qIHNlYXJjaCAiTElTVCIsIm1vdmkiIGNodW5rIGluICJSSUZGIiwiQVZJICIgKi8KICBja0xJU1QxLmZjY1R5cGUgPSBsaXN0dHlwZUFWSU1PVklFOwogIGhyID0gRmluZENodW5rQW5kS2VlcEV4dHJhcygmVGhpcy0+ZmlsZWV4dHJhLCBUaGlzLT5obW1pbywgJmNrTElTVDEsICZja1JJRkYsCgkJCSAgICAgIE1NSU9fRklORExJU1QpOwogIGlmIChGQUlMRUQoaHIpKQogICAgcmV0dXJuIGhyOwoKICBUaGlzLT5kd01vdmlDaHVua1BvcyA9IGNrTElTVDEuZHdEYXRhT2Zmc2V0OwogIFRoaXMtPmR3SWR4Q2h1bmtQb3MgID0gY2tMSVNUMS5ja3NpemUgKyBja0xJU1QxLmR3RGF0YU9mZnNldDsKICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrTElTVDEsIDApICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwoKICAvKiB0cnkgdG8gZmluZCBhbiBpbmRleCAqLwogIGNrLmNraWQgPSBja2lkQVZJTkVXSU5ERVg7CiAgaHIgPSBGaW5kQ2h1bmtBbmRLZWVwRXh0cmFzKCZUaGlzLT5maWxlZXh0cmEsIFRoaXMtPmhtbWlvLAoJCQkgICAgICAmY2ssICZja1JJRkYsIE1NSU9fRklORENIVU5LKTsKICBpZiAoU1VDQ0VFREVEKGhyKSAmJiBjay5ja3NpemUgPiAwKSB7CiAgICBpZiAoRkFJTEVEKEFWSUZJTEVfTG9hZEluZGV4KFRoaXMsIGNrLmNrc2l6ZSwgY2tMSVNUMS5kd0RhdGFPZmZzZXQpKSkKICAgICAgVGhpcy0+ZkluZm8uZHdGbGFncyAmPSB+QVZJRklMRUlORk9fSEFTSU5ERVg7CiAgfQoKICAvKiB3aGVuIHdlIGhhdmVuJ3QgZm91bmQgYW4gaW5kZXggb3IgaXQncyBiYWQsIHRoZW4gYnVpbGQgb25lCiAgICogYnkgcGFyc2luZyAnbW92aScgY2h1bmsgKi8KICBpZiAoKFRoaXMtPmZJbmZvLmR3RmxhZ3MgJiBBVklGSUxFSU5GT19IQVNJTkRFWCkgPT0gMCkgewogICAgZm9yIChuU3RyZWFtID0gMDsgblN0cmVhbSA8IFRoaXMtPmZJbmZvLmR3U3RyZWFtczsgblN0cmVhbSsrKQogICAgICBUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV0tPmxMYXN0RnJhbWUgPSAtMTsKCiAgICBpZiAobW1pb1NlZWsoVGhpcy0+aG1taW8sIGNrTElTVDEuZHdEYXRhT2Zmc2V0ICsgc2l6ZW9mKERXT1JEKSwgU0VFS19TRVQpID09IC0xKSB7CiAgICAgIEVSUigiOiBPb3BzLCBjYW4ndCBzZWVrIGJhY2sgdG8gJ21vdmknIGNodW5rIVxuIik7CiAgICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CiAgICB9CgogICAgLyogc2VlayB0aHJvdWdoIHRoZSAnbW92aScgbGlzdCB1bnRpbCBlbmQgKi8KICAgIHdoaWxlIChtbWlvRGVzY2VuZChUaGlzLT5obW1pbywgJmNrLCAmY2tMSVNUMSwgMCkgPT0gU19PSykgewogICAgICBpZiAoY2suY2tpZCAhPSBGT1VSQ0NfTElTVCkgewoJaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZjaywgMCkgPT0gU19PSykgewoJICBuU3RyZWFtID0gU3RyZWFtRnJvbUZPVVJDQyhjay5ja2lkKTsKCgkgIGlmIChuU3RyZWFtID4gVGhpcy0+ZkluZm8uZHdTdHJlYW1zKQoJICAgIHJldHVybiBBVklFUlJfQkFERk9STUFUOwoKCSAgQVZJRklMRV9BZGRGcmFtZShUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV0sIGNrLmNraWQsIGNrLmNrc2l6ZSwKCQkJICAgY2suZHdEYXRhT2Zmc2V0IC0gMiAqIHNpemVvZihEV09SRCksIDApOwoJfSBlbHNlIHsKCSAgblN0cmVhbSA9IFN0cmVhbUZyb21GT1VSQ0MoY2suY2tpZCk7CgkgIFdBUk4oIjogZmlsZSBzZWVtcyB0byBiZSB0cnVuY2F0ZWQhXG4iKTsKCSAgaWYgKG5TdHJlYW0gPD0gVGhpcy0+ZkluZm8uZHdTdHJlYW1zICYmCgkgICAgICBUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV0tPnNJbmZvLmR3U2FtcGxlU2l6ZSA+IDApIHsKCSAgICBjay5ja3NpemUgPSBtbWlvU2VlayhUaGlzLT5obW1pbywgMCwgU0VFS19FTkQpOwoJICAgIGlmIChjay5ja3NpemUgIT0gLTEpIHsKCSAgICAgIGNrLmNrc2l6ZSAtPSBjay5kd0RhdGFPZmZzZXQ7CgkgICAgICBjay5ja3NpemUgJj0gfihUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV0tPnNJbmZvLmR3U2FtcGxlU2l6ZSAtIDEpOwoKCSAgICAgIEFWSUZJTEVfQWRkRnJhbWUoVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dLCBjay5ja2lkLCBjay5ja3NpemUsCgkJCSAgICAgICBjay5kd0RhdGFPZmZzZXQgLSAyICogc2l6ZW9mKERXT1JEKSwgMCk7CgkgICAgfQoJICB9Cgl9CiAgICAgIH0KICAgIH0KICB9CgogIC8qIGZpbmQgb3RoZXIgY2h1bmtzICovCiAgRmluZENodW5rQW5kS2VlcEV4dHJhcygmVGhpcy0+ZmlsZWV4dHJhLCBUaGlzLT5obW1pbywgJmNrLCAmY2tSSUZGLCAwKTsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9Mb2FkSW5kZXgoSUFWSUZpbGVJbXBsICpUaGlzLCBEV09SRCBzaXplLCBEV09SRCBvZmZzZXQpCnsKICBBVklJTkRFWEVOVFJZICpscDsKICBEV09SRCAgICAgICAgICBwb3MsIG47CiAgSFJFU1VMVCAgICAgICAgaHIgPSBBVklFUlJfT0s7CiAgQk9PTCAgICAgICAgICAgYkFic29sdXRlID0gVFJVRTsKCiAgbHAgPSAoQVZJSU5ERVhFTlRSWSopR2xvYmFsQWxsb2NQdHIoR01FTV9NT1ZFQUJMRSwKCQkJCSAgICAgIElEWF9QRVJfQkxPQ0sgKiBzaXplb2YoQVZJSU5ERVhFTlRSWSkpOwogIGlmIChscCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogIC8qIGFkanVzdCBsaW1pdHMgZm9yIGluZGV4IHRhYmxlcywgc28gdGhhdCBpbnNlcnRpbmcgd2lsbCBiZSBmYXN0ZXIgKi8KICBmb3IgKG4gPSAwOyBuIDwgVGhpcy0+ZkluZm8uZHdTdHJlYW1zOyBuKyspIHsKICAgIElBVklTdHJlYW1JbXBsICpwU3RyZWFtID0gVGhpcy0+cHBTdHJlYW1zW25dOwoKICAgIHBTdHJlYW0tPmxMYXN0RnJhbWUgPSAtMTsKCiAgICBpZiAocFN0cmVhbS0+aWR4RnJhbWVzICE9IE5VTEwpIHsKICAgICAgR2xvYmFsRnJlZVB0cihwU3RyZWFtLT5pZHhGcmFtZXMpOwogICAgICBwU3RyZWFtLT5pZHhGcmFtZXMgID0gTlVMTDsKICAgICAgcFN0cmVhbS0+bklkeEZyYW1lcyA9IDA7CiAgICB9CgogICAgaWYgKHBTdHJlYW0tPnNJbmZvLmR3U2FtcGxlU2l6ZSAhPSAwKSB7CiAgICAgIGlmIChuID4gMCAmJiBUaGlzLT5mSW5mby5kd0ZsYWdzICYgQVZJRklMRUlORk9fSVNJTlRFUkxFQVZFRCkgewoJcFN0cmVhbS0+bklkeEZyYW1lcyA9IFRoaXMtPnBwU3RyZWFtc1swXS0+bklkeEZyYW1lczsKICAgICAgfSBlbHNlIGlmIChwU3RyZWFtLT5zSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUpIHsKCXBTdHJlYW0tPm5JZHhGcmFtZXMgPQoJICBwU3RyZWFtLT5zSW5mby5kd0xlbmd0aCAvIHBTdHJlYW0tPnNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZTsKICAgICAgfQogICAgfSBlbHNlCiAgICAgIHBTdHJlYW0tPm5JZHhGcmFtZXMgPSBwU3RyZWFtLT5zSW5mby5kd0xlbmd0aDsKCiAgICBwU3RyZWFtLT5pZHhGcmFtZXMgPQogICAgICAoQVZJSU5ERVhFTlRSWSopR2xvYmFsQWxsb2NQdHIoR0hORCwgcFN0cmVhbS0+bklkeEZyYW1lcyAqIHNpemVvZihBVklJTkRFWEVOVFJZKSk7CiAgICBpZiAocFN0cmVhbS0+aWR4RnJhbWVzID09IE5VTEwgJiYgcFN0cmVhbS0+bklkeEZyYW1lcyA+IDApIHsKICAgICAgcFN0cmVhbS0+bklkeEZyYW1lcyA9IDA7CiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogICAgfQogIH0KCiAgcG9zID0gKERXT1JEKS0xOwogIHdoaWxlIChzaXplICE9IDApIHsKICAgIExPTkcgcmVhZCA9IG1pbihJRFhfUEVSX0JMT0NLICogc2l6ZW9mKEFWSUlOREVYRU5UUlkpLCBzaXplKTsKCiAgICBpZiAobW1pb1JlYWQoVGhpcy0+aG1taW8sIChIUFNUUilscCwgcmVhZCkgIT0gcmVhZCkgewogICAgICBociA9IEFWSUVSUl9GSUxFUkVBRDsKICAgICAgYnJlYWs7CiAgICB9CiAgICBzaXplIC09IHJlYWQ7CgogICAgaWYgKHBvcyA9PSAoRFdPUkQpLTEpCiAgICAgIHBvcyA9IG9mZnNldCAtIGxwLT5kd0NodW5rT2Zmc2V0ICsgc2l6ZW9mKERXT1JEKTsKCiAgICBBVklGSUxFX1BhcnNlSW5kZXgoVGhpcywgbHAsIHJlYWQgLyBzaXplb2YoQVZJSU5ERVhFTlRSWSksCgkJICAgICAgIHBvcywgJmJBYnNvbHV0ZSk7CiAgfQoKICBpZiAobHAgIT0gTlVMTCkKICAgIEdsb2JhbEZyZWVQdHIobHApOwoKICAvKiBjaGVja2luZyAuLi4gKi8KICBmb3IgKG4gPSAwOyBuIDwgVGhpcy0+ZkluZm8uZHdTdHJlYW1zOyBuKyspIHsKICAgIElBVklTdHJlYW1JbXBsICpwU3RyZWFtID0gVGhpcy0+cHBTdHJlYW1zW25dOwoKICAgIGlmIChwU3RyZWFtLT5zSW5mby5kd1NhbXBsZVNpemUgPT0gMCAmJgoJcFN0cmVhbS0+c0luZm8uZHdMZW5ndGggIT0gcFN0cmVhbS0+bExhc3RGcmFtZSsxKQogICAgICBFUlIoInN0cmVhbSAlbHUgbGVuZ3RoIG1pc21hdGNoOiBkd0xlbmd0aD0lbHUgZm91bmQ9JWxkXG4iLAoJICAgbiwgcFN0cmVhbS0+c0luZm8uZHdMZW5ndGgsIHBTdHJlYW0tPmxMYXN0RnJhbWUpOwogIH0KCiAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX1BhcnNlSW5kZXgoSUFWSUZpbGVJbXBsICpUaGlzLCBBVklJTkRFWEVOVFJZICpscCwKCQkJCSAgTE9ORyBjb3VudCwgRFdPUkQgcG9zLCBCT09MICpiQWJzb2x1dGUpCnsKICBpZiAobHAgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIGZvciAoOyBjb3VudCA+IDA7IGNvdW50LS0sIGxwKyspIHsKICAgIFdPUkQgblN0cmVhbSA9IFN0cmVhbUZyb21GT1VSQ0MobHAtPmNraWQpOwoKICAgIGlmIChscC0+Y2tpZCA9PSBsaXN0dHlwZUFWSVJFQ09SRCB8fCBuU3RyZWFtID09IDB4N0YpCiAgICAgIGNvbnRpbnVlOyAvKiBza2lwIHRoZXNlICovCgogICAgaWYgKG5TdHJlYW0gPiBUaGlzLT5mSW5mby5kd1N0cmVhbXMpCiAgICAgIHJldHVybiBBVklFUlJfQkFERk9STUFUOwoKICAgIGlmICgqYkFic29sdXRlID09IFRSVUUgJiYgbHAtPmR3Q2h1bmtPZmZzZXQgPCBUaGlzLT5kd01vdmlDaHVua1BvcykKICAgICAgKmJBYnNvbHV0ZSA9IEZBTFNFOwoKICAgIGlmICgqYkFic29sdXRlKQogICAgICBscC0+ZHdDaHVua09mZnNldCArPSBzaXplb2YoRFdPUkQpOwogICAgZWxzZQogICAgICBscC0+ZHdDaHVua09mZnNldCArPSBwb3M7CgogICAgaWYgKEZBSUxFRChBVklGSUxFX0FkZEZyYW1lKFRoaXMtPnBwU3RyZWFtc1tuU3RyZWFtXSwgbHAtPmNraWQsIGxwLT5kd0NodW5rTGVuZ3RoLCBscC0+ZHdDaHVua09mZnNldCwgbHAtPmR3RmxhZ3MpKSkKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgfQoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX1JlYWRCbG9jayhJQVZJU3RyZWFtSW1wbCAqVGhpcywgRFdPUkQgcG9zLAoJCQkJIExQVk9JRCBidWZmZXIsIExPTkcgc2l6ZSkKewogIC8qIHByZS1jb25kaXRpb25zICovCiAgYXNzZXJ0KFRoaXMgIT0gTlVMTCk7CiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKICBhc3NlcnQoVGhpcy0+cGFmLT5obW1pbyAhPSBOVUxMKTsKICBhc3NlcnQoVGhpcy0+c0luZm8uZHdTdGFydCA8PSBwb3MgJiYgcG9zIDwgVGhpcy0+c0luZm8uZHdMZW5ndGgpOwogIGFzc2VydChwb3MgPD0gVGhpcy0+bExhc3RGcmFtZSk7CgogIC8qIHNob3VsZCB3ZSByZWFkIGFzIG11Y2ggYXMgYmxvY2sgZ2l2ZXMgdXM/ICovCiAgaWYgKHNpemUgPT0gMCB8fCBzaXplID4gVGhpcy0+aWR4RnJhbWVzW3Bvc10uZHdDaHVua0xlbmd0aCkKICAgIHNpemUgPSBUaGlzLT5pZHhGcmFtZXNbcG9zXS5kd0NodW5rTGVuZ3RoOwoKICAvKiByZWFkIGludG8gb3V0IG93biBidWZmZXIgb3IgZ2l2ZW4gb25lPyAqLwogIGlmIChidWZmZXIgPT0gTlVMTCkgewogICAgLyogd2UgYWxzbyByZWFkIHRoZSBjaHVuayAqLwogICAgc2l6ZSArPSAyICogc2l6ZW9mKERXT1JEKTsKCiAgICAvKiBjaGVjayB0aGF0IGJ1ZmZlciBpcyBiaWcgZW5vdWdoIC0tIGRvbid0IHRydXN0IGR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSAqLwogICAgaWYgKFRoaXMtPmxwQnVmZmVyID09IE5VTEwgfHwgc2l6ZSA8IFRoaXMtPmNiQnVmZmVyKSB7CiAgICAgIERXT1JEIG1heFNpemUgPSBtYXgoc2l6ZSwgVGhpcy0+c0luZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplKTsKCiAgICAgIGlmIChUaGlzLT5scEJ1ZmZlciA9PSBOVUxMKQoJVGhpcy0+bHBCdWZmZXIgPSAoTFBEV09SRClHbG9iYWxBbGxvY1B0cihHTUVNX01PVkVBQkxFLCBtYXhTaXplKTsKICAgICAgZWxzZQoJVGhpcy0+bHBCdWZmZXIgPQoJICAoTFBEV09SRClHbG9iYWxSZUFsbG9jUHRyKFRoaXMtPmxwQnVmZmVyLCBtYXhTaXplLCBHTUVNX01PVkVBQkxFKTsKICAgICAgaWYgKFRoaXMtPmxwQnVmZmVyID09IE5VTEwpCglyZXR1cm4gQVZJRVJSX01FTU9SWTsKICAgICAgVGhpcy0+Y2JCdWZmZXIgPSBtYXgoc2l6ZSwgVGhpcy0+c0luZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplKTsKICAgIH0KCiAgICAvKiBub3cgcmVhZCB0aGUgY29tcGxldGUgY2h1bmsgaW50byBvdXIgYnVmZmVyICovCiAgICBpZiAobW1pb1NlZWsoVGhpcy0+cGFmLT5obW1pbywgVGhpcy0+aWR4RnJhbWVzW3Bvc10uZHdDaHVua09mZnNldCwgU0VFS19TRVQpID09IC0xKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwogICAgaWYgKG1taW9SZWFkKFRoaXMtPnBhZi0+aG1taW8sIChIUFNUUilUaGlzLT5scEJ1ZmZlciwgc2l6ZSkgIT0gc2l6ZSkKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCiAgICAvKiBjaGVjayBpZiBpdCB3YXMgdGhlIGNvcnJlY3QgYmxvY2sgd2hpY2ggd2UgaGF2ZSByZWFkICovCiAgICBpZiAoVGhpcy0+bHBCdWZmZXJbMF0gIT0gVGhpcy0+aWR4RnJhbWVzW3Bvc10uY2tpZCB8fAoJVGhpcy0+bHBCdWZmZXJbMV0gIT0gVGhpcy0+aWR4RnJhbWVzW3Bvc10uZHdDaHVua0xlbmd0aCkgewogICAgICBFUlIoIjogYmxvY2sgJWxkIG5vdCBmb3VuZCBhdCAweCUwOGxYXG4iLCBwb3MsIFRoaXMtPmlkeEZyYW1lc1twb3NdLmR3Q2h1bmtPZmZzZXQpOwogICAgICBFUlIoIjogSW5kZXggc2F5czogJyU0LjRzJygweCUwOGxYKSBzaXplIDB4JTA4bFhcbiIsCgkgIChjaGFyKikmVGhpcy0+aWR4RnJhbWVzW3Bvc10uY2tpZCwgVGhpcy0+aWR4RnJhbWVzW3Bvc10uY2tpZCwKCSAgVGhpcy0+aWR4RnJhbWVzW3Bvc10uZHdDaHVua0xlbmd0aCk7CiAgICAgIEVSUigiOiBEYXRhICBzYXlzOiAnJTQuNHMnKDB4JTA4bFgpIHNpemUgMHglMDhsWFxuIiwKCSAgKGNoYXIqKSZUaGlzLT5scEJ1ZmZlclswXSwgVGhpcy0+bHBCdWZmZXJbMF0sIFRoaXMtPmxwQnVmZmVyWzFdKTsKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKICAgIH0KICB9IGVsc2UgewogICAgaWYgKG1taW9TZWVrKFRoaXMtPnBhZi0+aG1taW8sIFRoaXMtPmlkeEZyYW1lc1twb3NdLmR3Q2h1bmtPZmZzZXQgKyAyICogc2l6ZW9mKERXT1JEKSwgU0VFS19TRVQpID09IC0xKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwogICAgaWYgKG1taW9SZWFkKFRoaXMtPnBhZi0+aG1taW8sIChIUFNUUilidWZmZXIsIHNpemUpICE9IHNpemUpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CiAgfQoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgdm9pZCAgICBBVklGSUxFX1NhbXBsZXNUb0Jsb2NrKElBVklTdHJlYW1JbXBsICpUaGlzLCBMUExPTkcgcG9zLAoJCQkJICAgICAgTFBMT05HIG9mZnNldCkKewogIExPTkcgYmxvY2s7CgogIC8qIHByZS1jb25kaXRpb25zICovCiAgYXNzZXJ0KFRoaXMgIT0gTlVMTCk7CiAgYXNzZXJ0KHBvcyAhPSBOVUxMKTsKICBhc3NlcnQob2Zmc2V0ICE9IE5VTEwpOwogIGFzc2VydChUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUgIT0gMCk7CiAgYXNzZXJ0KCpwb3MgPj0gVGhpcy0+c0luZm8uZHdTdGFydCk7CgogIC8qIGNvbnZlcnQgc3RhcnQgc2FtcGxlIHRvIHN0YXJ0IGJ5dGVzICovCiAgKCpvZmZzZXQpICA9ICgqcG9zKSAtIFRoaXMtPnNJbmZvLmR3U3RhcnQ7CiAgKCpvZmZzZXQpICo9IFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZTsKCiAgLyogY29udmVydCBieXRlcyB0byBibG9jayBudW1iZXIgKi8KICBmb3IgKGJsb2NrID0gMDsgYmxvY2sgPD0gVGhpcy0+bExhc3RGcmFtZTsgYmxvY2srKykgewogICAgaWYgKFRoaXMtPmlkeEZyYW1lc1tibG9ja10uZHdDaHVua0xlbmd0aCA8PSAqb2Zmc2V0KQogICAgICAoKm9mZnNldCkgLT0gVGhpcy0+aWR4RnJhbWVzW2Jsb2NrXS5kd0NodW5rTGVuZ3RoOwogICAgZWxzZQogICAgICBicmVhazsKICB9CgogICpwb3MgPSBibG9jazsKfQoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9TYXZlRmlsZShJQVZJRmlsZUltcGwgKlRoaXMpCnsKICBNYWluQVZJSGVhZGVyICAgTWFpbkFWSUhkcjsKICBJQVZJU3RyZWFtSW1wbCogcFN0cmVhbTsKICBNTUNLSU5GTyAgICAgICAgY2tSSUZGOwogIE1NQ0tJTkZPICAgICAgICBja0xJU1QxOwogIE1NQ0tJTkZPICAgICAgICBja0xJU1QyOwogIE1NQ0tJTkZPICAgICAgICBjazsKICBEV09SRCAgICAgICAgICAgblN0cmVhbTsKICBEV09SRCAgICAgICAgICAgZHdQb3M7CiAgSFJFU1VMVCAgICAgICAgIGhyOwoKICAvKiBpbml0aWFsaXplIHNvbWUgdGhpbmdzICovCiAgaWYgKFRoaXMtPmR3TW92aUNodW5rUG9zID09IDApCiAgICBBVklGSUxFX0NvbXB1dGVNb3ZpU3RhcnQoVGhpcyk7CgogIC8qIHdyaXR0ZW4gb25lIHJlY29yZCB0byBtdWNoPyAqLwogIGlmIChUaGlzLT5ja0xhc3RSZWNvcmQuZHdGbGFncyAmIE1NSU9fRElSVFkpIHsKICAgIFRoaXMtPmR3TmV4dEZyYW1lUG9zIC09IDMgKiBzaXplb2YoRFdPUkQpOwogICAgaWYgKFRoaXMtPm5JZHhSZWNvcmRzID4gMCkKICAgICAgVGhpcy0+bklkeFJlY29yZHMtLTsKICB9CgogIEFWSUZJTEVfVXBkYXRlSW5mbyhUaGlzKTsKCiAgYXNzZXJ0KFRoaXMtPmZJbmZvLmR3U2NhbGUgIT0gMCk7CgogIG1lbXNldCgmTWFpbkFWSUhkciwgMCwgc2l6ZW9mKE1haW5BVklIZHIpKTsKICBNYWluQVZJSGRyLmR3TWljcm9TZWNQZXJGcmFtZSAgICA9IE11bERpdihUaGlzLT5mSW5mby5kd1JhdGUsIDEwMDAwMDAsCgkJCQkJICAgIFRoaXMtPmZJbmZvLmR3U2NhbGUpOwogIE1haW5BVklIZHIuZHdNYXhCeXRlc1BlclNlYyAgICAgID0gVGhpcy0+ZkluZm8uZHdNYXhCeXRlc1BlclNlYzsKICBNYWluQVZJSGRyLmR3UGFkZGluZ0dyYW51bGFyaXR5ICA9IEFWSV9IRUFERVJTSVpFOwogIE1haW5BVklIZHIuZHdGbGFncyAgICAgICAgICAgICAgID0gVGhpcy0+ZkluZm8uZHdGbGFnczsKICBNYWluQVZJSGRyLmR3VG90YWxGcmFtZXMgICAgICAgICA9IFRoaXMtPmZJbmZvLmR3TGVuZ3RoOwogIE1haW5BVklIZHIuZHdJbml0aWFsRnJhbWVzICAgICAgID0gMDsKICBNYWluQVZJSGRyLmR3U3RyZWFtcyAgICAgICAgICAgICA9IFRoaXMtPmZJbmZvLmR3U3RyZWFtczsKICBNYWluQVZJSGRyLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA9IFRoaXMtPmZJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZTsKICBNYWluQVZJSGRyLmR3V2lkdGggICAgICAgICAgICAgICA9IFRoaXMtPmZJbmZvLmR3V2lkdGg7CiAgTWFpbkFWSUhkci5kd0hlaWdodCAgICAgICAgICAgICAgPSBUaGlzLT5mSW5mby5kd0hlaWdodDsKICBNYWluQVZJSGRyLmR3SW5pdGlhbEZyYW1lcyAgICAgICA9IFRoaXMtPmR3SW5pdGlhbEZyYW1lczsKCiAgLyogbm93IGJlZ2luIHdyaXRpbmcgLi4uICovCiAgbW1pb1NlZWsoVGhpcy0+aG1taW8sIDAsIFNFRUtfU0VUKTsKCiAgLyogUklGRiBjaHVuayAqLwogIGNrUklGRi5ja3NpemUgID0gMDsKICBja1JJRkYuZmNjVHlwZSA9IGZvcm10eXBlQVZJOwogIGlmIChtbWlvQ3JlYXRlQ2h1bmsoVGhpcy0+aG1taW8sICZja1JJRkYsIE1NSU9fQ1JFQVRFUklGRikgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAvKiBBVkkgaGVhZGVybGlzdCAqLwogIGNrTElTVDEuY2tzaXplICA9IDA7CiAgY2tMSVNUMS5mY2NUeXBlID0gbGlzdHR5cGVBVklIRUFERVI7CiAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJmNrTElTVDEsIE1NSU9fQ1JFQVRFTElTVCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAvKiBNYWluQVZJSGVhZGVyICovCiAgY2suY2tpZCAgICA9IGNraWRBVklNQUlOSERSOwogIGNrLmNrc2l6ZSAgPSBzaXplb2YoTWFpbkFWSUhkcik7CiAgY2suZmNjVHlwZSA9IDA7CiAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgaWYgKG1taW9Xcml0ZShUaGlzLT5obW1pbywgKEhQU1RSKSZNYWluQVZJSGRyLCBjay5ja3NpemUpICE9IGNrLmNrc2l6ZSkKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgLyogd3JpdGUgdGhlIGhlYWRlcnMgb2YgZWFjaCBzdHJlYW0gaW50byBhIHNlcGFyYXRlIHN0cmVhbWhlYWRlciBsaXN0ICovCiAgZm9yIChuU3RyZWFtID0gMDsgblN0cmVhbSA8IFRoaXMtPmZJbmZvLmR3U3RyZWFtczsgblN0cmVhbSsrKSB7CiAgICBBVklTdHJlYW1IZWFkZXIgc3RySGRyOwoKICAgIHBTdHJlYW0gPSBUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV07CgogICAgLyogYmVnaW4gdGhlIG5ldyBzdHJlYW1oZWFkZXIgbGlzdCAqLwogICAgY2tMSVNUMi5ja3NpemUgID0gMDsKICAgIGNrTElTVDIuZmNjVHlwZSA9IGxpc3R0eXBlU1RSRUFNSEVBREVSOwogICAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJmNrTElTVDIsIE1NSU9fQ1JFQVRFTElTVCkgIT0gU19PSykKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogICAgLyogY3JlYXRlIGFuIEFWSVN0cmVhbUhlYWRlciBmcm9tIHRoZSBBVlNUUkVBTUlORk8gKi8KICAgIHN0ckhkci5mY2NUeXBlICAgICAgICAgICAgICAgPSBwU3RyZWFtLT5zSW5mby5mY2NUeXBlOwogICAgc3RySGRyLmZjY0hhbmRsZXIgICAgICAgICAgICA9IHBTdHJlYW0tPnNJbmZvLmZjY0hhbmRsZXI7CiAgICBzdHJIZHIuZHdGbGFncyAgICAgICAgICAgICAgID0gcFN0cmVhbS0+c0luZm8uZHdGbGFnczsKICAgIHN0ckhkci53UHJpb3JpdHkgICAgICAgICAgICAgPSBwU3RyZWFtLT5zSW5mby53UHJpb3JpdHk7CiAgICBzdHJIZHIud0xhbmd1YWdlICAgICAgICAgICAgID0gcFN0cmVhbS0+c0luZm8ud0xhbmd1YWdlOwogICAgc3RySGRyLmR3SW5pdGlhbEZyYW1lcyAgICAgICA9IHBTdHJlYW0tPnNJbmZvLmR3SW5pdGlhbEZyYW1lczsKICAgIHN0ckhkci5kd1NjYWxlICAgICAgICAgICAgICAgPSBwU3RyZWFtLT5zSW5mby5kd1NjYWxlOwogICAgc3RySGRyLmR3UmF0ZSAgICAgICAgICAgICAgICA9IHBTdHJlYW0tPnNJbmZvLmR3UmF0ZTsKICAgIHN0ckhkci5kd1N0YXJ0ICAgICAgICAgICAgICAgPSBwU3RyZWFtLT5zSW5mby5kd1N0YXJ0OwogICAgc3RySGRyLmR3TGVuZ3RoICAgICAgICAgICAgICA9IHBTdHJlYW0tPnNJbmZvLmR3TGVuZ3RoOwogICAgc3RySGRyLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA9IHBTdHJlYW0tPnNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZTsKICAgIHN0ckhkci5kd1F1YWxpdHkgICAgICAgICAgICAgPSBwU3RyZWFtLT5zSW5mby5kd1F1YWxpdHk7CiAgICBzdHJIZHIuZHdTYW1wbGVTaXplICAgICAgICAgID0gcFN0cmVhbS0+c0luZm8uZHdTYW1wbGVTaXplOwogICAgc3RySGRyLnJjRnJhbWUubGVmdCAgICAgICAgICA9IHBTdHJlYW0tPnNJbmZvLnJjRnJhbWUubGVmdDsKICAgIHN0ckhkci5yY0ZyYW1lLnRvcCAgICAgICAgICAgPSBwU3RyZWFtLT5zSW5mby5yY0ZyYW1lLnRvcDsKICAgIHN0ckhkci5yY0ZyYW1lLnJpZ2h0ICAgICAgICAgPSBwU3RyZWFtLT5zSW5mby5yY0ZyYW1lLnJpZ2h0OwogICAgc3RySGRyLnJjRnJhbWUuYm90dG9tICAgICAgICA9IHBTdHJlYW0tPnNJbmZvLnJjRnJhbWUuYm90dG9tOwoKICAgIC8qIG5vdyB3cml0ZSB0aGUgQVZJU3RyZWFtSGVhZGVyICovCiAgICBjay5ja2lkICAgPSBja2lkU1RSRUFNSEVBREVSOwogICAgY2suY2tzaXplID0gc2l6ZW9mKHN0ckhkcik7CiAgICBpZiAobW1pb0NyZWF0ZUNodW5rKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgaWYgKG1taW9Xcml0ZShUaGlzLT5obW1pbywgKEhQU1RSKSZzdHJIZHIsIGNrLmNrc2l6ZSkgIT0gY2suY2tzaXplKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAgIC8qIC4uLiB0aGUgaG9wZWZ1bGx5IGV2ZXIgcHJlc2VudCBzdHJlYW1mb3JtYXQgLi4uICovCiAgICBjay5ja2lkICAgPSBja2lkU1RSRUFNRk9STUFUOwogICAgY2suY2tzaXplID0gcFN0cmVhbS0+Y2JGb3JtYXQ7CiAgICBpZiAobW1pb0NyZWF0ZUNodW5rKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgaWYgKHBTdHJlYW0tPmxwRm9ybWF0ICE9IE5VTEwgJiYgY2suY2tzaXplID4gMCkgewogICAgICBpZiAobW1pb1dyaXRlKFRoaXMtPmhtbWlvLCAoSFBTVFIpcFN0cmVhbS0+bHBGb3JtYXQsIGNrLmNrc2l6ZSkgIT0gY2suY2tzaXplKQoJcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICB9CiAgICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgICAvKiAuLi4gc29tZSBvcHRpb25hbCBleGlzdGluZyBoYW5kbGVyIGRhdGEgLi4uICovCiAgICBpZiAocFN0cmVhbS0+bHBIYW5kbGVyRGF0YSAhPSBOVUxMICYmIHBTdHJlYW0tPmNiSGFuZGxlckRhdGEgPiAwKSB7CiAgICAgIGNrLmNraWQgICA9IGNraWRTVFJFQU1IQU5ETEVSREFUQTsKICAgICAgY2suY2tzaXplID0gcFN0cmVhbS0+Y2JIYW5kbGVyRGF0YTsKICAgICAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQoJcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICAgIGlmIChtbWlvV3JpdGUoVGhpcy0+aG1taW8sIChIUFNUUilwU3RyZWFtLT5scEhhbmRsZXJEYXRhLCBjay5ja3NpemUpICE9IGNrLmNrc2l6ZSkKCXJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQoJcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICB9CgogICAgLyogLi4uIHNvbWUgb3B0aW9uYWwgYWRkaXRpb25hbCBleHRyYSBjaHVuayBmb3IgdGhpcyBzdHJlYW0gLi4uICovCiAgICBpZiAocFN0cmVhbS0+ZXh0cmEubHAgIT0gTlVMTCAmJiBwU3RyZWFtLT5leHRyYS5jYiA+IDApIHsKICAgICAgLyogdGhlIGNodW5rIGhlYWRlcihzKSBhcmUgYWxyZWFkeSBpbiB0aGUgc3RydWN1dHVyZSAqLwogICAgICBpZiAobW1pb1dyaXRlKFRoaXMtPmhtbWlvLCAoSFBTVFIpcFN0cmVhbS0+ZXh0cmEubHAsIHBTdHJlYW0tPmV4dHJhLmNiKSAhPSBwU3RyZWFtLT5leHRyYS5jYikKCXJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgfQoKICAgIC8qIC4uLiBhbiBvcHRpb25hbCBuYW1lIGZvciB0aGlzIHN0cmVhbSAuLi4gKi8KICAgIGlmIChsc3RybGVuVyhwU3RyZWFtLT5zSW5mby5zek5hbWUpID4gMCkgewogICAgICBMUFNUUiBzdHI7CgogICAgICBjay5ja2lkICAgPSBja2lkU1RSRUFNTkFNRTsKICAgICAgY2suY2tzaXplID0gbHN0cmxlblcocFN0cmVhbS0+c0luZm8uc3pOYW1lKSArIDE7CiAgICAgIGlmIChjay5ja3NpemUgJiAxKSAvKiBhbGlnbiAqLwoJY2suY2tzaXplKys7CiAgICAgIGlmIChtbWlvQ3JlYXRlQ2h1bmsoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKCXJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAgICAgLyogdGhlIHN0cmVhbW5hbWUgbXVzdCBiZSBzYXZlZCBpbiBBU0NJSSBub3QgVW5pY29kZSAqLwogICAgICBzdHIgPSAoTFBTVFIpTG9jYWxBbGxvYyhMUFRSLCBjay5ja3NpemUpOwogICAgICBpZiAoc3RyID09IE5VTEwpCglyZXR1cm4gQVZJRVJSX01FTU9SWTsKICAgICAgV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIHBTdHJlYW0tPnNJbmZvLnN6TmFtZSwgLTEsIHN0ciwKCQkJICBjay5ja3NpemUsIE5VTEwsIE5VTEwpOwoKICAgICAgaWYgKG1taW9Xcml0ZShUaGlzLT5obW1pbywgKEhQU1RSKXN0ciwgY2suY2tzaXplKSAhPSBjay5ja3NpemUpIHsKCUxvY2FsRnJlZSgoSExPQ0FMKXN0cik7CQoJcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICAgIH0KCiAgICAgIExvY2FsRnJlZSgoSExPQ0FMKXN0cik7CiAgICAgIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCglyZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgIH0KCiAgICAvKiBjbG9zZSBzdHJlYW1oZWFkZXIgbGlzdCBmb3IgdGhpcyBzdHJlYW0gKi8KICAgIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2tMSVNUMiwgMCkgIT0gU19PSykKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgfSAvKiBmb3IgKDAgPD0gblN0cmVhbSA8IE1haW5BVklIZHIuZHdTdHJlYW1zKSAqLwoKICAvKiBjbG9zZSB0aGUgYXZpaGVhZGVyIGxpc3QgKi8KICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrTElTVDEsIDApICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgLyogY2hlY2sgZm9yIHBhZGRpbmcgdG8gcHJlLWd1ZXNzZWQgJ21vdmknLWNodW5rIHBvc2l0aW9uICovCiAgZHdQb3MgPSBja0xJU1QxLmR3RGF0YU9mZnNldCArIGNrTElTVDEuY2tzaXplOwogIGlmIChUaGlzLT5kd01vdmlDaHVua1BvcyAtIDIgKiBzaXplb2YoRFdPUkQpID4gZHdQb3MpIHsKICAgIGNrLmNraWQgICA9IGNraWRBVklQQURESU5HOwogICAgY2suY2tzaXplID0gVGhpcy0+ZHdNb3ZpQ2h1bmtQb3MgLSBkd1BvcyAtIDQgKiBzaXplb2YoRFdPUkQpOwogICAgYXNzZXJ0KChMT05HKWNrLmNrc2l6ZSA+PSAwKTsKCiAgICBpZiAobW1pb0NyZWF0ZUNodW5rKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgaWYgKG1taW9TZWVrKFRoaXMtPmhtbWlvLCBjay5ja3NpemUsIFNFRUtfQ1VSKSA9PSAtMSkKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICB9CgogIC8qIG5vdyB3cml0ZSB0aGUgJ21vdmknIGNodW5rICovCiAgbW1pb1NlZWsoVGhpcy0+aG1taW8sIFRoaXMtPmR3TW92aUNodW5rUG9zIC0gMiAqIHNpemVvZihEV09SRCksIFNFRUtfU0VUKTsKICBja0xJU1QxLmNrc2l6ZSAgPSAwOwogIGNrTElTVDEuZmNjVHlwZSA9IGxpc3R0eXBlQVZJTU9WSUU7CiAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJmNrTElTVDEsIE1NSU9fQ1JFQVRFTElTVCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogIGlmIChtbWlvU2VlayhUaGlzLT5obW1pbywgVGhpcy0+ZHdOZXh0RnJhbWVQb3MsIFNFRUtfU0VUKSA9PSAtMSkKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2tMSVNUMSwgMCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAvKiB3cml0ZSAnaWR4MScgY2h1bmsgKi8KICBociA9IEFWSUZJTEVfU2F2ZUluZGV4KFRoaXMpOwogIGlmIChGQUlMRUQoaHIpKQogICAgcmV0dXJuIGhyOwoKICAvKiB3cml0ZSBvcHRpb25hbCBleHRyYSBmaWxlIGNodW5rcyAqLwogIGlmIChUaGlzLT5maWxlZXh0cmEubHAgIT0gTlVMTCAmJiBUaGlzLT5maWxlZXh0cmEuY2IgPiAwKSB7CiAgICAvKiBhcyBmb3IgdGhlIHN0cmVhbXMsIGFyZSB0aGUgY2h1bmsgaGVhZGVyKHMpIGluIHRoZSBzdHJ1Y3R1cmUgKi8KICAgIGlmIChtbWlvV3JpdGUoVGhpcy0+aG1taW8sIChIUFNUUilUaGlzLT5maWxlZXh0cmEubHAsIFRoaXMtPmZpbGVleHRyYS5jYikgIT0gVGhpcy0+ZmlsZWV4dHJhLmNiKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICB9CgogIC8qIGNsb3NlIFJJRkYgY2h1bmsgKi8KICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrUklGRiwgMCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAvKiBhZGQgc29tZSBKVU5LIGF0IGVuZCBmb3IgYmFkIHBhcnNlcnMgKi8KICBtZW1zZXQoJmNrUklGRiwgMCwgc2l6ZW9mKGNrUklGRikpOwogIG1taW9Xcml0ZShUaGlzLT5obW1pbywgKEhQU1RSKSZja1JJRkYsIHNpemVvZihja1JJRkYpKTsKICBtbWlvRmx1c2goVGhpcy0+aG1taW8sIDApOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX1NhdmVJbmRleChJQVZJRmlsZUltcGwgKlRoaXMpCnsKICBJQVZJU3RyZWFtSW1wbCAqcFN0cmVhbTsKICBBVklJTkRFWEVOVFJZICAgaWR4OwogIE1NQ0tJTkZPICAgICAgICBjazsKICBEV09SRCAgICAgICAgICAgblN0cmVhbTsKICBMT05HICAgICAgICAgICAgbjsKCiAgY2suY2tpZCAgID0gY2tpZEFWSU5FV0lOREVYOwogIGNrLmNrc2l6ZSA9IDA7CiAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogIGlmIChUaGlzLT5mSW5mby5kd0ZsYWdzICYgQVZJRklMRUlORk9fSVNJTlRFUkxFQVZFRCkgewogICAgLyogaXMgaW50ZXJsZWF2ZWQgLS0gd3JpdGUgYmxvY2sgb2YgY29yZXNwb25kaW5nIGZyYW1lcyAqLwogICAgTE9ORyBsSW5pdGlhbEZyYW1lcyA9IDA7CiAgICBMT05HIHN0ZXBzaXplOwogICAgTE9ORyBpOwoKICAgIGlmIChUaGlzLT5wcFN0cmVhbXNbMF0tPnNJbmZvLmR3U2FtcGxlU2l6ZSA9PSAwKQogICAgICBzdGVwc2l6ZSA9IDE7CiAgICBlbHNlCiAgICAgIHN0ZXBzaXplID0gQVZJU3RyZWFtVGltZVRvU2FtcGxlKChQQVZJU1RSRUFNKVRoaXMtPnBwU3RyZWFtc1swXSwgMTAwMDAwMCk7CgogICAgYXNzZXJ0KHN0ZXBzaXplID4gMCk7CgogICAgZm9yIChuU3RyZWFtID0gMDsgblN0cmVhbSA8IFRoaXMtPmZJbmZvLmR3U3RyZWFtczsgblN0cmVhbSsrKSB7CiAgICAgIGlmIChsSW5pdGlhbEZyYW1lcyA8IFRoaXMtPnBwU3RyZWFtc1tuU3RyZWFtXS0+c0luZm8uZHdJbml0aWFsRnJhbWVzKQoJbEluaXRpYWxGcmFtZXMgPSBUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV0tPnNJbmZvLmR3SW5pdGlhbEZyYW1lczsKICAgIH0KCiAgICBmb3IgKGkgPSAtbEluaXRpYWxGcmFtZXM7IGkgPCAoTE9ORylUaGlzLT5mSW5mby5kd0xlbmd0aCAtIGxJbml0aWFsRnJhbWVzOwoJIGkgKz0gc3RlcHNpemUpIHsKICAgICAgRFdPUkQgbkZyYW1lID0gbEluaXRpYWxGcmFtZXMgKyBpOwoKICAgICAgYXNzZXJ0KG5GcmFtZSA8IFRoaXMtPm5JZHhSZWNvcmRzKTsKCiAgICAgIGlkeC5ja2lkICAgICAgICAgID0gbGlzdHR5cGVBVklSRUNPUkQ7CiAgICAgIGlkeC5kd0ZsYWdzICAgICAgID0gQVZJSUZfTElTVDsKICAgICAgaWR4LmR3Q2h1bmtMZW5ndGggPSBUaGlzLT5pZHhSZWNvcmRzW25GcmFtZV0uZHdDaHVua0xlbmd0aDsKICAgICAgaWR4LmR3Q2h1bmtPZmZzZXQgPSBUaGlzLT5pZHhSZWNvcmRzW25GcmFtZV0uZHdDaHVua09mZnNldAoJLSBUaGlzLT5kd01vdmlDaHVua1BvczsKICAgICAgaWYgKG1taW9Xcml0ZShUaGlzLT5obW1pbywgKEhQU1RSKSZpZHgsIHNpemVvZihpZHgpKSAhPSBzaXplb2YoaWR4KSkKCXJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAgICAgZm9yIChuU3RyZWFtID0gMDsgblN0cmVhbSA8IFRoaXMtPmZJbmZvLmR3U3RyZWFtczsgblN0cmVhbSsrKSB7CglwU3RyZWFtID0gVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dOwoKCS8qIGhlYXZlIHdlIHJlYWNoZWQgc3RhcnQgb2YgdGhpcyBzdHJlYW0/ICovCglpZiAoLShMT05HKXBTdHJlYW0tPnNJbmZvLmR3SW5pdGlhbEZyYW1lcyA+IGkpCgkgIGNvbnRpbnVlOwoKCWlmIChwU3RyZWFtLT5zSW5mby5kd0luaXRpYWxGcmFtZXMgPCBsSW5pdGlhbEZyYW1lcykKCSAgbkZyYW1lIC09IChsSW5pdGlhbEZyYW1lcyAtIHBTdHJlYW0tPnNJbmZvLmR3SW5pdGlhbEZyYW1lcyk7CgoJLyogcmVhY2hlZCBlbmQgb2YgdGhpcyBzdHJlYW0/ICovCglpZiAocFN0cmVhbS0+bExhc3RGcmFtZSA8PSBuRnJhbWUpCgkgIGNvbnRpbnVlOwoKCWlmICgocFN0cmVhbS0+c0luZm8uZHdGbGFncyAmIEFWSVNUUkVBTUlORk9fRk9STUFUQ0hBTkdFUykgJiYKCSAgICBwU3RyZWFtLT5zSW5mby5kd0Zvcm1hdENoYW5nZUNvdW50ICE9IDAgJiYKCSAgICBwU3RyZWFtLT5pZHhGbXRDaGFuZ2VzICE9IE5VTEwpIHsKCSAgRFdPUkQgcG9zOwoKCSAgZm9yIChwb3MgPSAwOyBwb3MgPCBwU3RyZWFtLT5zSW5mby5kd0Zvcm1hdENoYW5nZUNvdW50OyBwb3MrKykgewoJICAgIGlmIChwU3RyZWFtLT5pZHhGbXRDaGFuZ2VzW3Bvc10uY2tpZCA9PSBuRnJhbWUpIHsKCSAgICAgIGlkeC5kd0ZsYWdzID0gQVZJSUZfTk9USU1FOwoJICAgICAgaWR4LmNraWQgICAgPSBNQUtFQVZJQ0tJRChja3R5cGVQQUxjaGFuZ2UsIHBTdHJlYW0tPm5TdHJlYW0pOwoJICAgICAgaWR4LmR3Q2h1bmtMZW5ndGggPSBwU3RyZWFtLT5pZHhGbXRDaGFuZ2VzW3Bvc10uZHdDaHVua0xlbmd0aDsKCSAgICAgIGlkeC5kd0NodW5rT2Zmc2V0ID0gcFN0cmVhbS0+aWR4Rm10Q2hhbmdlc1twb3NdLmR3Q2h1bmtPZmZzZXQKCQktIFRoaXMtPmR3TW92aUNodW5rUG9zOwoKCSAgICAgIGlmIChtbWlvV3JpdGUoVGhpcy0+aG1taW8sIChIUFNUUikmaWR4LCBzaXplb2YoaWR4KSkgIT0gc2l6ZW9mKGlkeCkpCgkJcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgkgICAgICBicmVhazsKCSAgICB9CgkgIH0KCX0gLyogaWYgaGF2ZSBmb3JtYXRjaGFuZ2VzICovCgoJaWR4LmNraWQgICAgICAgICAgPSBwU3RyZWFtLT5pZHhGcmFtZXNbbkZyYW1lXS5ja2lkOwoJaWR4LmR3RmxhZ3MgICAgICAgPSBwU3RyZWFtLT5pZHhGcmFtZXNbbkZyYW1lXS5kd0ZsYWdzOwoJaWR4LmR3Q2h1bmtMZW5ndGggPSBwU3RyZWFtLT5pZHhGcmFtZXNbbkZyYW1lXS5kd0NodW5rTGVuZ3RoOwoJaWR4LmR3Q2h1bmtPZmZzZXQgPSBwU3RyZWFtLT5pZHhGcmFtZXNbbkZyYW1lXS5kd0NodW5rT2Zmc2V0CgkgIC0gVGhpcy0+ZHdNb3ZpQ2h1bmtQb3M7CglpZiAobW1pb1dyaXRlKFRoaXMtPmhtbWlvLCAoSFBTVFIpJmlkeCwgc2l6ZW9mKGlkeCkpICE9IHNpemVvZihpZHgpKQoJICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgICAgfQogICAgfQogIH0gZWxzZSB7CiAgICAvKiBub3QgaW50ZXJsZWF2ZWQgLS0gd3JpdGUgaW5kZXggZm9yIGVhY2ggc3RyZWFtIGF0IG9uY2UgKi8KICAgIGZvciAoblN0cmVhbSA9IDA7IG5TdHJlYW0gPCBUaGlzLT5mSW5mby5kd1N0cmVhbXM7IG5TdHJlYW0rKykgewogICAgICBwU3RyZWFtID0gVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dOwoKICAgICAgZm9yIChuID0gMDsgbiA8PSBwU3RyZWFtLT5sTGFzdEZyYW1lOyBuKyspIHsKCWlmICgocFN0cmVhbS0+c0luZm8uZHdGbGFncyAmIEFWSVNUUkVBTUlORk9fRk9STUFUQ0hBTkdFUykgJiYKCSAgICAocFN0cmVhbS0+c0luZm8uZHdGb3JtYXRDaGFuZ2VDb3VudCAhPSAwKSkgewoJICBEV09SRCBwb3M7CgoJICBmb3IgKHBvcyA9IDA7IHBvcyA8IHBTdHJlYW0tPnNJbmZvLmR3Rm9ybWF0Q2hhbmdlQ291bnQ7IHBvcysrKSB7CgkgICAgaWYgKHBTdHJlYW0tPmlkeEZtdENoYW5nZXNbcG9zXS5ja2lkID09IG4pIHsKCSAgICAgIGlkeC5kd0ZsYWdzID0gQVZJSUZfTk9USU1FOwoJICAgICAgaWR4LmNraWQgICAgPSBNQUtFQVZJQ0tJRChja3R5cGVQQUxjaGFuZ2UsIHBTdHJlYW0tPm5TdHJlYW0pOwoJICAgICAgaWR4LmR3Q2h1bmtMZW5ndGggPSBwU3RyZWFtLT5pZHhGbXRDaGFuZ2VzW3Bvc10uZHdDaHVua0xlbmd0aDsKCSAgICAgIGlkeC5kd0NodW5rT2Zmc2V0ID0KCQlwU3RyZWFtLT5pZHhGbXRDaGFuZ2VzW3Bvc10uZHdDaHVua09mZnNldCAtIFRoaXMtPmR3TW92aUNodW5rUG9zOwoJICAgICAgaWYgKG1taW9Xcml0ZShUaGlzLT5obW1pbywgKEhQU1RSKSZpZHgsIHNpemVvZihpZHgpKSAhPSBzaXplb2YoaWR4KSkKCQlyZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCSAgICAgIGJyZWFrOwoJICAgIH0KCSAgfQoJfSAvKiBpZiBoYXZlIGZvcm1hdGNoYW5nZXMgKi8KCglpZHguY2tpZCAgICAgICAgICA9IHBTdHJlYW0tPmlkeEZyYW1lc1tuXS5ja2lkOwoJaWR4LmR3RmxhZ3MgICAgICAgPSBwU3RyZWFtLT5pZHhGcmFtZXNbbl0uZHdGbGFnczsKCWlkeC5kd0NodW5rTGVuZ3RoID0gcFN0cmVhbS0+aWR4RnJhbWVzW25dLmR3Q2h1bmtMZW5ndGg7CglpZHguZHdDaHVua09mZnNldCA9IHBTdHJlYW0tPmlkeEZyYW1lc1tuXS5kd0NodW5rT2Zmc2V0CgkgIC0gVGhpcy0+ZHdNb3ZpQ2h1bmtQb3M7CgoJaWYgKG1taW9Xcml0ZShUaGlzLT5obW1pbywgKEhQU1RSKSZpZHgsIHNpemVvZihpZHgpKSAhPSBzaXplb2YoaWR4KSkKCSAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICAgIH0KICAgIH0KICB9IC8qIGlmIG5vdCBpbnRlcmxlYXZlZCAqLwoKICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBVTE9ORyAgQVZJRklMRV9TZWFyY2hTdHJlYW0oSUFWSUZpbGVJbXBsICpUaGlzLCBEV09SRCBmY2MsIExPTkcgbFNraXApCnsKICBVSU5UIGk7CiAgVUlOVCBuU3RyZWFtOwoKICAvKiBwcmUtY29uZGl0aW9uICovCiAgYXNzZXJ0KGxTa2lwID49IDApOwoKICBpZiAoZmNjICE9IDApIHsKICAgIC8qIHNlYXJjaCB0aGUgbnVtYmVyIG9mIHRoZSBzcGVjaWZpZWQgc3RyZWFtICovCiAgICBuU3RyZWFtID0gKFVMT05HKS0xOwogICAgZm9yIChpID0gMDsgaSA8IFRoaXMtPmZJbmZvLmR3U3RyZWFtczsgaSsrKSB7CiAgICAgIGFzc2VydChUaGlzLT5wcFN0cmVhbXNbaV0gIT0gTlVMTCk7CgogICAgICBpZiAoVGhpcy0+cHBTdHJlYW1zW2ldLT5zSW5mby5mY2NUeXBlID09IGZjYykgewoJaWYgKGxTa2lwID09IDApIHsKCSAgblN0cmVhbSA9IGk7CgkgIGJyZWFrOwoJfSBlbHNlCgkgIGxTa2lwLS07CiAgICAgIH0KICAgIH0KICB9IGVsc2UKICAgIG5TdHJlYW0gPSBsU2tpcDsKCiAgcmV0dXJuIG5TdHJlYW07Cn0KCnN0YXRpYyB2b2lkICAgIEFWSUZJTEVfVXBkYXRlSW5mbyhJQVZJRmlsZUltcGwgKlRoaXMpCnsKICBVSU5UIGk7CgogIC8qIHByZS1jb25kaXRpb25zICovCiAgYXNzZXJ0KFRoaXMgIT0gTlVMTCk7CgogIFRoaXMtPmZJbmZvLmR3TWF4Qnl0ZXNQZXJTZWMgICAgICA9IDA7CiAgVGhpcy0+ZkluZm8uZHdDYXBzICAgICAgICAgICAgICAgID0gQVZJRklMRUNBUFNfQ0FOUkVBRHxBVklGSUxFQ0FQU19DQU5XUklURTsKICBUaGlzLT5mSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPSAwOwogIFRoaXMtPmZJbmZvLmR3V2lkdGggICAgICAgICAgICAgICA9IDA7CiAgVGhpcy0+ZkluZm8uZHdIZWlnaHQgICAgICAgICAgICAgID0gMDsKICBUaGlzLT5mSW5mby5kd1NjYWxlICAgICAgICAgICAgICAgPSAwOwogIFRoaXMtPmZJbmZvLmR3UmF0ZSAgICAgICAgICAgICAgICA9IDA7CiAgVGhpcy0+ZkluZm8uZHdMZW5ndGggICAgICAgICAgICAgID0gMDsKICBUaGlzLT5kd0luaXRpYWxGcmFtZXMgICAgICAgICAgICAgPSAwOwoKICBmb3IgKGkgPSAwOyBpIDwgVGhpcy0+ZkluZm8uZHdTdHJlYW1zOyBpKyspIHsKICAgIEFWSVNUUkVBTUlORk9XICpwc2k7CiAgICBEV09SRCAgICAgICAgICAgbjsKCiAgICAvKiBwcmUtY29uZGl0aW9ucyAqLwogICAgYXNzZXJ0KFRoaXMtPnBwU3RyZWFtc1tpXSAhPSBOVUxMKTsKCiAgICBwc2kgPSAmVGhpcy0+cHBTdHJlYW1zW2ldLT5zSW5mbzsKICAgIGFzc2VydChwc2ktPmR3U2NhbGUgIT0gMCk7CiAgICBhc3NlcnQocHNpLT5kd1JhdGUgIT0gMCk7CgogICAgaWYgKGkgPT0gMCkgewogICAgICAvKiB1c2UgZmlyc3Qgc3RyZWFtIHRpbWluZ3MgYXMgYmFzZSAqLwogICAgICBUaGlzLT5mSW5mby5kd1NjYWxlICA9IHBzaS0+ZHdTY2FsZTsKICAgICAgVGhpcy0+ZkluZm8uZHdSYXRlICAgPSBwc2ktPmR3UmF0ZTsKICAgICAgVGhpcy0+ZkluZm8uZHdMZW5ndGggPSBwc2ktPmR3TGVuZ3RoOwogICAgfSBlbHNlIHsKICAgICAgbiA9IEFWSVN0cmVhbVNhbXBsZVRvU2FtcGxlKChQQVZJU1RSRUFNKVRoaXMtPnBwU3RyZWFtc1swXSwKCQkJCSAgKFBBVklTVFJFQU0pVGhpcy0+cHBTdHJlYW1zW2ldLHBzaS0+ZHdMZW5ndGgpOwogICAgICBpZiAoVGhpcy0+ZkluZm8uZHdMZW5ndGggPCBuKQoJVGhpcy0+ZkluZm8uZHdMZW5ndGggPSBuOwogICAgfQoKICAgIGlmIChUaGlzLT5kd0luaXRpYWxGcmFtZXMgPCBwc2ktPmR3SW5pdGlhbEZyYW1lcykKICAgICAgVGhpcy0+ZHdJbml0aWFsRnJhbWVzID0gcHNpLT5kd0luaXRpYWxGcmFtZXM7CgogICAgaWYgKFRoaXMtPmZJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA8IHBzaS0+ZHdTdWdnZXN0ZWRCdWZmZXJTaXplKQogICAgICBUaGlzLT5mSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPSBwc2ktPmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZTsKCiAgICBpZiAocHNpLT5kd1NhbXBsZVNpemUgIT0gMCkgewogICAgICAvKiBmaXhlZCBzYW1wbGUgc2l6ZSAtLSBleGFjdCBjb21wdXRhdGlvbiAqLwogICAgICBUaGlzLT5mSW5mby5kd01heEJ5dGVzUGVyU2VjICs9IE11bERpdihwc2ktPmR3U2FtcGxlU2l6ZSwgcHNpLT5kd1JhdGUsCgkJCQkJICAgICBwc2ktPmR3U2NhbGUpOwogICAgfSBlbHNlIHsKICAgICAgLyogdmFyaWFibGUgc2FtcGxlIHNpemUgLS0gb25seSB1cHBlciBsaW1pdCAqLwogICAgICBUaGlzLT5mSW5mby5kd01heEJ5dGVzUGVyU2VjICs9IE11bERpdihwc2ktPmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSwKCQkJCQkgICAgIHBzaS0+ZHdSYXRlLCBwc2ktPmR3U2NhbGUpOwoKICAgICAgLyogdXBkYXRlIGRpbWVuc2lvbnMgKi8KICAgICAgbiA9IHBzaS0+cmNGcmFtZS5yaWdodCAtIHBzaS0+cmNGcmFtZS5sZWZ0OwogICAgICBpZiAoVGhpcy0+ZkluZm8uZHdXaWR0aCA8IG4pCglUaGlzLT5mSW5mby5kd1dpZHRoID0gbjsKICAgICAgbiA9IHBzaS0+cmNGcmFtZS5ib3R0b20gLSBwc2ktPnJjRnJhbWUudG9wOwogICAgICBpZiAoVGhpcy0+ZkluZm8uZHdIZWlnaHQgPCBuKQoJVGhpcy0+ZkluZm8uZHdIZWlnaHQgPSBuOwogICAgfQogIH0KfQoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9Xcml0ZUJsb2NrKElBVklTdHJlYW1JbXBsICpUaGlzLCBEV09SRCBibG9jaywKCQkJCSAgRk9VUkNDIGNraWQsIERXT1JEIGZsYWdzLCBMUFZPSUQgYnVmZmVyLAoJCQkJICBMT05HIHNpemUpCnsKICBNTUNLSU5GTyBjazsKCiAgY2suY2tpZCAgICA9IGNraWQ7CiAgY2suY2tzaXplICA9IHNpemU7CiAgY2suZmNjVHlwZSA9IDA7CgogIC8qIGlmIG5vIGZyYW1lL2Jsb2NrIGlzIGFscmVhZHkgd3JpdHRlbiwgd2UgbXVzdCBjb21wdXRlIHN0YXJ0IG9mIG1vdmkgY2h1bmsgKi8KICBpZiAoVGhpcy0+cGFmLT5kd01vdmlDaHVua1BvcyA9PSAwKQogICAgQVZJRklMRV9Db21wdXRlTW92aVN0YXJ0KFRoaXMtPnBhZik7CgogIGlmIChtbWlvU2VlayhUaGlzLT5wYWYtPmhtbWlvLCBUaGlzLT5wYWYtPmR3TmV4dEZyYW1lUG9zLCBTRUVLX1NFVCkgPT0gLTEpCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5wYWYtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICBpZiAoYnVmZmVyICE9IE5VTEwgJiYgc2l6ZSA+IDApIHsKICAgIGlmIChtbWlvV3JpdGUoVGhpcy0+cGFmLT5obW1pbywgKEhQU1RSKWJ1ZmZlciwgc2l6ZSkgIT0gc2l6ZSkKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgfQogIGlmIChtbWlvQXNjZW5kKFRoaXMtPnBhZi0+aG1taW8sICZjaywgMCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICBUaGlzLT5wYWYtPmZEaXJ0eSAgICAgICAgID0gVFJVRTsKICBUaGlzLT5wYWYtPmR3TmV4dEZyYW1lUG9zID0gbW1pb1NlZWsoVGhpcy0+cGFmLT5obW1pbywgMCwgU0VFS19DVVIpOwoKICByZXR1cm4gQVZJRklMRV9BZGRGcmFtZShUaGlzLCBja2lkLCBzaXplLAoJCQkgIGNrLmR3RGF0YU9mZnNldCAtIDIgKiBzaXplb2YoRFdPUkQpLCBmbGFncyk7Cn0K