LyoKICogQ29weXJpZ2h0IDIwMDIgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojZGVmaW5lIENPTV9OT19XSU5ET1dTX0gKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbmRvd3N4LmgiCiNpbmNsdWRlICJtbXN5c3RlbS5oIgojaW5jbHVkZSAidmZ3LmgiCiNpbmNsdWRlICJtc2FjbS5oIgoKI2luY2x1ZGUgImF2aWZpbGVfcHJpdmF0ZS5oIgojaW5jbHVkZSAiZXh0cmFjaHVuay5oIgoKI2luY2x1ZGUgIndpbmUvdW5pY29kZS5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoYXZpZmlsZSk7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojZGVmaW5lIGZvcm10eXBlV0FWRSAgICBtbWlvRk9VUkNDKCdXJywnQScsJ1YnLCdFJykKI2RlZmluZSBja2lkV0FWRUZPUk1BVCAgbW1pb0ZPVVJDQygnZicsJ20nLCd0JywnICcpCiNkZWZpbmUgY2tpZFdBVkVGQUNUICAgIG1taW9GT1VSQ0MoJ2YnLCdhJywnYycsJ3QnKQojZGVmaW5lIGNraWRXQVZFREFUQSAgICBtbWlvRk9VUkNDKCdkJywnYScsJ3QnLCdhJykKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiNkZWZpbmUgRU5ESUFOX1NXQVBXT1JEKHgpICAoKCgoeCkgPj4gOCkgJiAweEZGKSB8ICgoKHgpICYgMHhGRikgPDwgOCkpCiNkZWZpbmUgRU5ESUFOX1NXQVBEV09SRCh4KSAoRU5ESUFOX1NXQVBXT1JEKCh4ID4+IDE2KSAmIDB4RkZGRikgfCBcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRU5ESUFOX1NXQVBXT1JEKHggJiAweEZGRkYpIDw8IDE2KQoKI2lmZGVmIFdPUkRTX0JJR0VORElBTgojZGVmaW5lIEJFMkhfV09SRCh4KSAgKHgpCiNkZWZpbmUgQkUySF9EV09SRCh4KSAoeCkKI2RlZmluZSBMRTJIX1dPUkQoeCkgIEVORElBTl9TV0FQV09SRCh4KQojZGVmaW5lIExFMkhfRFdPUkQoeCkgRU5ESUFOX1NXQVBEV09SRCh4KQojZWxzZQojZGVmaW5lIEJFMkhfV09SRCh4KSAgRU5ESUFOX1NXQVBXT1JEKHgpCiNkZWZpbmUgQkUySF9EV09SRCh4KSBFTkRJQU5fU1dBUERXT1JEKHgpCiNkZWZpbmUgTEUySF9XT1JEKHgpICAoeCkKI2RlZmluZSBMRTJIX0RXT1JEKHgpICh4KQojZW5kaWYKCnR5cGVkZWYgc3RydWN0IHsKICBGT1VSQ0MgIGZjY1R5cGU7CiAgRFdPUkQgICBvZmZzZXQ7CiAgRFdPUkQgICBzaXplOwogIElOVCAgICAgZW5jb2Rpbmc7CiAgRFdPUkQgICBzYW1wbGVSYXRlOwogIERXT1JEICAgY2hhbm5lbHM7Cn0gU1VOQVVESU9IRUFERVI7CgojZGVmaW5lIEFVX0VOQ09ESU5HX1VMQVdfOCAgICAgICAgICAgICAgICAgMQojZGVmaW5lIEFVX0VOQ09ESU5HX1BDTV84ICAgICAgICAgICAgICAgICAgMgojZGVmaW5lIEFVX0VOQ09ESU5HX1BDTV8xNiAgICAgICAgICAgICAgICAgMwojZGVmaW5lIEFVX0VOQ09ESU5HX1BDTV8yNCAgICAgICAgICAgICAgICAgNAojZGVmaW5lIEFVX0VOQ09ESU5HX1BDTV8zMiAgICAgICAgICAgICAgICAgNQojZGVmaW5lIEFVX0VOQ09ESU5HX0ZMT0FUICAgICAgICAgICAgICAgICAgNgojZGVmaW5lIEFVX0VOQ09ESU5HX0RPVUJMRSAgICAgICAgICAgICAgICAgNwojZGVmaW5lIEFVX0VOQ09ESU5HX0FEUENNX0c3MjFfMzIgICAgICAgICAyMwojZGVmaW5lIEFVX0VOQ09ESU5HX0FEUENNX0c3MjIgICAgICAgICAgICAyNAojZGVmaW5lIEFVX0VOQ09ESU5HX0FEUENNX0c3MjNfMjQgICAgICAgICAyNQojZGVmaW5lIEFVX0VOQ09ESU5HX0FEUENNX0c3MjNfNSAgICAgICAgICAyNgojZGVmaW5lIEFVX0VOQ09ESU5HX0FMQVdfOCAgICAgICAgICAgICAgICAyNwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuUXVlcnlJbnRlcmZhY2UoSUFWSUZpbGUqIGlmYWNlLFJFRklJRCByZWZpaWQsTFBWT0lEICpvYmopOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUFWSUZpbGVfZm5BZGRSZWYoSUFWSUZpbGUqIGlmYWNlKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElBVklGaWxlX2ZuUmVsZWFzZShJQVZJRmlsZSogaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5JbmZvKElBVklGaWxlKmlmYWNlLEFWSUZJTEVJTkZPVyphZmksTE9ORyBzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuR2V0U3RyZWFtKElBVklGaWxlKmlmYWNlLFBBVklTVFJFQU0qYXZpcyxEV09SRCBmY2NUeXBlLExPTkcgbFBhcmFtKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuQ3JlYXRlU3RyZWFtKElBVklGaWxlKmlmYWNlLFBBVklTVFJFQU0qYXZpcyxBVklTVFJFQU1JTkZPVyphc2kpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5Xcml0ZURhdGEoSUFWSUZpbGUqaWZhY2UsRFdPUkQgY2tpZCxMUFZPSUQgbHBEYXRhLExPTkcgc2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mblJlYWREYXRhKElBVklGaWxlKmlmYWNlLERXT1JEIGNraWQsTFBWT0lEIGxwRGF0YSxMT05HICpzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuRW5kUmVjb3JkKElBVklGaWxlKmlmYWNlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuRGVsZXRlU3RyZWFtKElBVklGaWxlKmlmYWNlLERXT1JEIGZjY1R5cGUsTE9ORyBsUGFyYW0pOwoKc3RhdGljIGNvbnN0IHN0cnVjdCBJQVZJRmlsZVZ0YmwgaXdhdmZ0ID0gewogIElBVklGaWxlX2ZuUXVlcnlJbnRlcmZhY2UsCiAgSUFWSUZpbGVfZm5BZGRSZWYsCiAgSUFWSUZpbGVfZm5SZWxlYXNlLAogIElBVklGaWxlX2ZuSW5mbywKICBJQVZJRmlsZV9mbkdldFN0cmVhbSwKICBJQVZJRmlsZV9mbkNyZWF0ZVN0cmVhbSwKICBJQVZJRmlsZV9mbldyaXRlRGF0YSwKICBJQVZJRmlsZV9mblJlYWREYXRhLAogIElBVklGaWxlX2ZuRW5kUmVjb3JkLAogIElBVklGaWxlX2ZuRGVsZXRlU3RyZWFtCn07CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuUXVlcnlJbnRlcmZhY2UoSVBlcnNpc3RGaWxlKmlmYWNlLFJFRklJRCByZWZpaWQsTFBWT0lEKm9iaik7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5BZGRSZWYoSVBlcnNpc3RGaWxlKmlmYWNlKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElQZXJzaXN0RmlsZV9mblJlbGVhc2UoSVBlcnNpc3RGaWxlKmlmYWNlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkdldENsYXNzSUQoSVBlcnNpc3RGaWxlKmlmYWNlLENMU0lEKnBDbGFzc0lEKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mbklzRGlydHkoSVBlcnNpc3RGaWxlKmlmYWNlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkxvYWQoSVBlcnNpc3RGaWxlKmlmYWNlLExQQ09MRVNUUiBwc3pGaWxlTmFtZSxEV09SRCBkd01vZGUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuU2F2ZShJUGVyc2lzdEZpbGUqaWZhY2UsTFBDT0xFU1RSIHBzekZpbGVOYW1lLEJPT0wgZlJlbWVtYmVyKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mblNhdmVDb21wbGV0ZWQoSVBlcnNpc3RGaWxlKmlmYWNlLExQQ09MRVNUUiBwc3pGaWxlTmFtZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5HZXRDdXJGaWxlKElQZXJzaXN0RmlsZSppZmFjZSxMUE9MRVNUUipwcHN6RmlsZU5hbWUpOwoKc3RhdGljIGNvbnN0IHN0cnVjdCBJUGVyc2lzdEZpbGVWdGJsIGl3YXZwZnQgPSB7CiAgSVBlcnNpc3RGaWxlX2ZuUXVlcnlJbnRlcmZhY2UsCiAgSVBlcnNpc3RGaWxlX2ZuQWRkUmVmLAogIElQZXJzaXN0RmlsZV9mblJlbGVhc2UsCiAgSVBlcnNpc3RGaWxlX2ZuR2V0Q2xhc3NJRCwKICBJUGVyc2lzdEZpbGVfZm5Jc0RpcnR5LAogIElQZXJzaXN0RmlsZV9mbkxvYWQsCiAgSVBlcnNpc3RGaWxlX2ZuU2F2ZSwKICBJUGVyc2lzdEZpbGVfZm5TYXZlQ29tcGxldGVkLAogIElQZXJzaXN0RmlsZV9mbkdldEN1ckZpbGUKfTsKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUXVlcnlJbnRlcmZhY2UoSUFWSVN0cmVhbSppZmFjZSxSRUZJSUQgcmVmaWlkLExQVk9JRCAqb2JqKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElBVklTdHJlYW1fZm5BZGRSZWYoSUFWSVN0cmVhbSppZmFjZSk7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUmVsZWFzZShJQVZJU3RyZWFtKiBpZmFjZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuQ3JlYXRlKElBVklTdHJlYW0qaWZhY2UsTFBBUkFNIGxQYXJhbTEsTFBBUkFNIGxQYXJhbTIpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbkluZm8oSUFWSVN0cmVhbSppZmFjZSxBVklTVFJFQU1JTkZPVyAqcHNpLExPTkcgc2l6ZSk7CnN0YXRpYyBMT05HICAgIFdJTkFQSSBJQVZJU3RyZWFtX2ZuRmluZFNhbXBsZShJQVZJU3RyZWFtKmlmYWNlLExPTkcgcG9zLExPTkcgZmxhZ3MpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblJlYWRGb3JtYXQoSUFWSVN0cmVhbSppZmFjZSxMT05HIHBvcyxMUFZPSUQgZm9ybWF0LExPTkcgKmZvcm1hdHNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblNldEZvcm1hdChJQVZJU3RyZWFtKmlmYWNlLExPTkcgcG9zLExQVk9JRCBmb3JtYXQsTE9ORyBmb3JtYXRzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5SZWFkKElBVklTdHJlYW0qaWZhY2UsTE9ORyBzdGFydCxMT05HIHNhbXBsZXMsTFBWT0lEIGJ1ZmZlcixMT05HIGJ1ZmZlcnNpemUsTE9ORyAqYnl0ZXNyZWFkLExPTkcgKnNhbXBsZXNyZWFkKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5Xcml0ZShJQVZJU3RyZWFtKmlmYWNlLExPTkcgc3RhcnQsTE9ORyBzYW1wbGVzLExQVk9JRCBidWZmZXIsTE9ORyBidWZmZXJzaXplLERXT1JEIGZsYWdzLExPTkcgKnNhbXB3cml0dGVuLExPTkcgKmJ5dGVzd3JpdHRlbik7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuRGVsZXRlKElBVklTdHJlYW0qaWZhY2UsTE9ORyBzdGFydCxMT05HIHNhbXBsZXMpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblJlYWREYXRhKElBVklTdHJlYW0qaWZhY2UsRFdPUkQgZmNjLExQVk9JRCBscCxMT05HICpscHJlYWQpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbldyaXRlRGF0YShJQVZJU3RyZWFtKmlmYWNlLERXT1JEIGZjYyxMUFZPSUQgbHAsTE9ORyBzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5TZXRJbmZvKElBVklTdHJlYW0qaWZhY2UsQVZJU1RSRUFNSU5GT1cqaW5mbyxMT05HIGluZm9sZW4pOwoKc3RhdGljIGNvbnN0IHN0cnVjdCBJQVZJU3RyZWFtVnRibCBpd2F2c3QgPSB7CiAgSUFWSVN0cmVhbV9mblF1ZXJ5SW50ZXJmYWNlLAogIElBVklTdHJlYW1fZm5BZGRSZWYsCiAgSUFWSVN0cmVhbV9mblJlbGVhc2UsCiAgSUFWSVN0cmVhbV9mbkNyZWF0ZSwKICBJQVZJU3RyZWFtX2ZuSW5mbywKICBJQVZJU3RyZWFtX2ZuRmluZFNhbXBsZSwKICBJQVZJU3RyZWFtX2ZuUmVhZEZvcm1hdCwKICBJQVZJU3RyZWFtX2ZuU2V0Rm9ybWF0LAogIElBVklTdHJlYW1fZm5SZWFkLAogIElBVklTdHJlYW1fZm5Xcml0ZSwKICBJQVZJU3RyZWFtX2ZuRGVsZXRlLAogIElBVklTdHJlYW1fZm5SZWFkRGF0YSwKICBJQVZJU3RyZWFtX2ZuV3JpdGVEYXRhLAogIElBVklTdHJlYW1fZm5TZXRJbmZvCn07Cgp0eXBlZGVmIHN0cnVjdCBfSUFWSUZpbGVJbXBsIElBVklGaWxlSW1wbDsKCnR5cGVkZWYgc3RydWN0IF9JUGVyc2lzdEZpbGVJbXBsIHsKICAvKiBJVW5rbm93biBzdHVmZiAqLwogIGNvbnN0IElQZXJzaXN0RmlsZVZ0YmwgKmxwVnRibDsKCiAgLyogSVBlcnNpc3RGaWxlIHN0dWZmICovCiAgSUFWSUZpbGVJbXBsICAgICAqcGFmOwp9IElQZXJzaXN0RmlsZUltcGw7Cgp0eXBlZGVmIHN0cnVjdCBfSUFWSVN0cmVhbUltcGwgewogIC8qIElVbmtub3duIHN0dWZmICovCiAgY29uc3QgSUFWSVN0cmVhbVZ0YmwgKmxwVnRibDsKCiAgLyogSUFWSVN0cmVhbSBzdHVmZiAqLwogIElBVklGaWxlSW1wbCAgICAgKnBhZjsKfSBJQVZJU3RyZWFtSW1wbDsKCnN0cnVjdCBfSUFWSUZpbGVJbXBsIHsKICAvKiBJVW5rbm93biBzdHVmZiAqLwogIGNvbnN0IElBVklGaWxlVnRibCAqbHBWdGJsOwogIExPTkcJCSAgICByZWY7CgogIC8qIElBVklGaWxlLCBJQVZJU3RyZWFtIHN0dWZmLi4uICovCiAgSVBlcnNpc3RGaWxlSW1wbCAgaVBlcnNpc3RGaWxlOwogIElBVklTdHJlYW1JbXBsICAgIGlBVklTdHJlYW07CgogIEFWSUZJTEVJTkZPVyAgICAgIGZJbmZvOwogIEFWSVNUUkVBTUlORk9XICAgIHNJbmZvOwoKICBMUFdBVkVGT1JNQVRFWCAgICBscEZvcm1hdDsKICBMT05HICAgICAgICAgICAgICBjYkZvcm1hdDsKCiAgTU1DS0lORk8gICAgICAgICAgY2tEYXRhOwoKICBFWFRSQUNIVU5LUyAgICAgICBleHRyYTsKCiAgLyogSVBlcnNpc3RGaWxlIHN0dWZmIC4uLiAqLwogIEhNTUlPICAgICAgICAgICAgIGhtbWlvOwogIExQV1NUUiAgICAgICAgICAgIHN6RmlsZU5hbWU7CiAgVUlOVCAgICAgICAgICAgICAgdU1vZGU7CiAgQk9PTCAgICAgICAgICAgICAgZkRpcnR5Owp9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9Mb2FkRmlsZShJQVZJRmlsZUltcGwgKlRoaXMpOwpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX0xvYWRTdW5GaWxlKElBVklGaWxlSW1wbCAqVGhpcyk7CnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfU2F2ZUZpbGUoSUFWSUZpbGVJbXBsICpUaGlzKTsKCkhSRVNVTFQgQVZJRklMRV9DcmVhdGVXQVZGaWxlKFJFRklJRCByaWlkLCBMUFZPSUQgKnBwdikKewogIElBVklGaWxlSW1wbCAqcGZpbGU7CiAgSFJFU1VMVCAgICAgICBocjsKCiAgYXNzZXJ0KHJpaWQgIT0gTlVMTCAmJiBwcHYgIT0gTlVMTCk7CgogICpwcHYgPSBOVUxMOwoKICBwZmlsZSA9IChJQVZJRmlsZUltcGwqKUxvY2FsQWxsb2MoTFBUUiwgc2l6ZW9mKElBVklGaWxlSW1wbCkpOwogIGlmIChwZmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogIHBmaWxlLT5scFZ0YmwgICAgICAgICAgICAgICAgPSAmaXdhdmZ0OwogIHBmaWxlLT5pUGVyc2lzdEZpbGUubHBWdGJsICAgPSAmaXdhdnBmdDsKICBwZmlsZS0+aUFWSVN0cmVhbS5scFZ0YmwgICAgID0gJml3YXZzdDsKICBwZmlsZS0+cmVmID0gMDsKICBwZmlsZS0+aVBlcnNpc3RGaWxlLnBhZiA9IHBmaWxlOwogIHBmaWxlLT5pQVZJU3RyZWFtLnBhZiAgID0gcGZpbGU7CgogIGhyID0gSUFWSUZpbGVfUXVlcnlJbnRlcmZhY2UoKElBVklGaWxlKilwZmlsZSwgcmlpZCwgcHB2KTsKICBpZiAoRkFJTEVEKGhyKSkKICAgIExvY2FsRnJlZSgoSExPQ0FMKXBmaWxlKTsKCiAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5RdWVyeUludGVyZmFjZShJQVZJRmlsZSAqaWZhY2UsIFJFRklJRCByZWZpaWQsCgkJCQkJCUxQVk9JRCAqb2JqKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKElBVklGaWxlSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVzLCVwKVxuIiwgVGhpcywgZGVidWdzdHJfZ3VpZChyZWZpaWQpLCBvYmopOwoKICBpZiAoSXNFcXVhbEdVSUQoJklJRF9JVW5rbm93biwgcmVmaWlkKSB8fAogICAgICBJc0VxdWFsR1VJRCgmSUlEX0lBVklGaWxlLCByZWZpaWQpKSB7CiAgICAqb2JqID0gaWZhY2U7CiAgICByZXR1cm4gU19PSzsKICB9IGVsc2UgaWYgKFRoaXMtPmZJbmZvLmR3U3RyZWFtcyA9PSAxICYmCgkgICAgIElzRXF1YWxHVUlEKCZJSURfSUFWSVN0cmVhbSwgcmVmaWlkKSkgewogICAgKm9iaiA9ICZUaGlzLT5pQVZJU3RyZWFtOwogICAgcmV0dXJuIFNfT0s7CiAgfSBlbHNlIGlmIChJc0VxdWFsR1VJRCgmSUlEX0lQZXJzaXN0RmlsZSwgcmVmaWlkKSkgewogICAgKm9iaiA9ICZUaGlzLT5pUGVyc2lzdEZpbGU7CiAgICByZXR1cm4gU19PSzsKICB9CgogIHJldHVybiBPTEVfRV9FTlVNX05PTU9SRTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBJQVZJRmlsZV9mbkFkZFJlZihJQVZJRmlsZSAqaWZhY2UpCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoSUFWSUZpbGVJbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXApXG4iLGlmYWNlKTsKCiAgcmV0dXJuIEludGVybG9ja2VkSW5jcmVtZW50KCZUaGlzLT5yZWYpOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIElBVklGaWxlX2ZuUmVsZWFzZShJQVZJRmlsZSAqaWZhY2UpCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoSUFWSUZpbGVJbXBsICopaWZhY2U7CiAgVUxPTkcgcmVmID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJlRoaXMtPnJlZik7CgogIFRSQUNFKCIoJXApXG4iLGlmYWNlKTsKCiAgaWYgKCFyZWYpIHsKICAgIGlmIChUaGlzLT5mRGlydHkpIHsKICAgICAgLyogbmVlZCB0byB3cml0ZSBoZWFkZXJzIHRvIGZpbGUgKi8KICAgICAgQVZJRklMRV9TYXZlRmlsZShUaGlzKTsKICAgIH0KCiAgICBpZiAoVGhpcy0+bHBGb3JtYXQgIT0gTlVMTCkgewogICAgICBHbG9iYWxGcmVlUHRyKFRoaXMtPmxwRm9ybWF0KTsKICAgICAgVGhpcy0+bHBGb3JtYXQgPSBOVUxMOwogICAgICBUaGlzLT5jYkZvcm1hdCA9IDA7CiAgICB9CiAgICBpZiAoVGhpcy0+ZXh0cmEubHAgIT0gTlVMTCkgewogICAgICBHbG9iYWxGcmVlUHRyKFRoaXMtPmV4dHJhLmxwKTsKICAgICAgVGhpcy0+ZXh0cmEubHAgPSBOVUxMOwogICAgICBUaGlzLT5leHRyYS5jYiA9IDA7CiAgICB9CiAgICBpZiAoVGhpcy0+c3pGaWxlTmFtZSAhPSBOVUxMKSB7CiAgICAgIExvY2FsRnJlZSgoSExPQ0FMKVRoaXMtPnN6RmlsZU5hbWUpOwogICAgICBUaGlzLT5zekZpbGVOYW1lID0gTlVMTDsKICAgIH0KICAgIGlmIChUaGlzLT5obW1pbyAhPSBOVUxMKSB7CiAgICAgIG1taW9DbG9zZShUaGlzLT5obW1pbywgMCk7CiAgICAgIFRoaXMtPmhtbWlvID0gTlVMTDsKICAgIH0KCiAgICBMb2NhbEZyZWUoKEhMT0NBTClUaGlzKTsKICAgIHJldHVybiAwOwogIH0KICByZXR1cm4gcmVmOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5JbmZvKElBVklGaWxlICppZmFjZSwgTFBBVklGSUxFSU5GT1cgYWZpLAoJCQkJICAgICAgTE9ORyBzaXplKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKElBVklGaWxlSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVwLCVsZClcbiIsaWZhY2UsYWZpLHNpemUpOwoKICBpZiAoYWZpID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIGlmIChzaXplIDwgMCkKICAgIHJldHVybiBBVklFUlJfQkFEU0laRTsKCiAgLyogdXBkYXRlIGZpbGUgaW5mbyAqLwogIFRoaXMtPmZJbmZvLmR3RmxhZ3MgPSAwOwogIFRoaXMtPmZJbmZvLmR3Q2FwcyAgPSBBVklGSUxFQ0FQU19DQU5SRUFEfEFWSUZJTEVDQVBTX0NBTldSSVRFOwogIGlmIChUaGlzLT5scEZvcm1hdCAhPSBOVUxMKSB7CiAgICBhc3NlcnQoVGhpcy0+c0luZm8uZHdTY2FsZSAhPSAwKTsKCiAgICBUaGlzLT5mSW5mby5kd1N0cmVhbXMgICAgICAgICAgICAgPSAxOwogICAgVGhpcy0+ZkluZm8uZHdTY2FsZSAgICAgICAgICAgICAgID0gVGhpcy0+c0luZm8uZHdTY2FsZTsKICAgIFRoaXMtPmZJbmZvLmR3UmF0ZSAgICAgICAgICAgICAgICA9IFRoaXMtPnNJbmZvLmR3UmF0ZTsKICAgIFRoaXMtPmZJbmZvLmR3TGVuZ3RoICAgICAgICAgICAgICA9IFRoaXMtPnNJbmZvLmR3TGVuZ3RoOwogICAgVGhpcy0+ZkluZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplID0gVGhpcy0+Y2tEYXRhLmNrc2l6ZTsKICAgIFRoaXMtPmZJbmZvLmR3TWF4Qnl0ZXNQZXJTZWMgPQogICAgICBNdWxEaXYoVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplLFRoaXMtPnNJbmZvLmR3UmF0ZSxUaGlzLT5zSW5mby5kd1NjYWxlKTsKICB9CgogIG1lbWNweShhZmksICZUaGlzLT5mSW5mbywgbWluKChEV09SRClzaXplLCBzaXplb2YoVGhpcy0+ZkluZm8pKSk7CgogIGlmICgoRFdPUkQpc2l6ZSA8IHNpemVvZihUaGlzLT5mSW5mbykpCiAgICByZXR1cm4gQVZJRVJSX0JVRkZFUlRPT1NNQUxMOwogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkdldFN0cmVhbShJQVZJRmlsZSAqaWZhY2UsIFBBVklTVFJFQU0gKmF2aXMsCgkJCQkJICAgRFdPUkQgZmNjVHlwZSwgTE9ORyBsUGFyYW0pCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoSUFWSUZpbGVJbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJXAsMHglMDhsWCwlbGQpXG4iLCBpZmFjZSwgYXZpcywgZmNjVHlwZSwgbFBhcmFtKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVyICovCiAgaWYgKGF2aXMgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICphdmlzID0gTlVMTDsKCiAgLyogRG9lcyBvdXIgc3RyZWFtIGV4aXN0cz8gKi8KICBpZiAobFBhcmFtICE9IDAgfHwgVGhpcy0+ZkluZm8uZHdTdHJlYW1zID09IDApCiAgICByZXR1cm4gQVZJRVJSX05PREFUQTsKICBpZiAoZmNjVHlwZSAhPSAwICYmIGZjY1R5cGUgIT0gc3RyZWFtdHlwZUFVRElPKQogICAgcmV0dXJuIEFWSUVSUl9OT0RBVEE7CgogICphdmlzID0gKFBBVklTVFJFQU0pJlRoaXMtPmlBVklTdHJlYW07CiAgSUFWSUZpbGVfQWRkUmVmKGlmYWNlKTsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuQ3JlYXRlU3RyZWFtKElBVklGaWxlICppZmFjZSxQQVZJU1RSRUFNICphdmlzLAoJCQkJCSAgICAgIExQQVZJU1RSRUFNSU5GT1cgYXNpKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKElBVklGaWxlSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVwLCVwKVxuIiwgaWZhY2UsIGF2aXMsIGFzaSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoYXZpcyA9PSBOVUxMIHx8IGFzaSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgKmF2aXMgPSBOVUxMOwoKICAvKiBXZSBvbmx5IHN1cHBvcnQgb25lIGF1ZGlvIHN0cmVhbSAqLwogIGlmIChUaGlzLT5mSW5mby5kd1N0cmVhbXMgIT0gMCB8fCBUaGlzLT5scEZvcm1hdCAhPSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKICBpZiAoYXNpLT5mY2NUeXBlICE9IHN0cmVhbXR5cGVBVURJTykKICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CgogIC8qIERvZXMgdGhlIHVzZXIgaGF2ZSB3cml0ZSBwZXJtaXNzaW9uPyAqLwogIGlmICgoVGhpcy0+dU1vZGUgJiBNTUlPX1JXTU9ERSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIFRoaXMtPmNiRm9ybWF0ID0gMDsKICBUaGlzLT5scEZvcm1hdCA9IE5VTEw7CgogIG1lbWNweSgmVGhpcy0+c0luZm8sIGFzaSwgc2l6ZW9mKFRoaXMtPnNJbmZvKSk7CgogIC8qIG1ha2Ugc3VyZSBzdHJlYW1pbmZvIGlmIG9rYXkgZm9yIHVzICovCiAgVGhpcy0+c0luZm8uZmNjSGFuZGxlciAgICAgICAgICA9IDA7CiAgVGhpcy0+c0luZm8uZHdGbGFncyAgICAgICAgICAgICA9IDA7CiAgVGhpcy0+c0luZm8uZHdDYXBzICAgICAgICAgICAgICA9IEFWSUZJTEVDQVBTX0NBTlJFQUR8QVZJRklMRUNBUFNfQ0FOV1JJVEU7CiAgVGhpcy0+c0luZm8uZHdTdGFydCAgICAgICAgICAgICA9IDA7CiAgVGhpcy0+c0luZm8uZHdJbml0aWFsRnJhbWVzICAgICA9IDA7CiAgVGhpcy0+c0luZm8uZHdGb3JtYXRDaGFuZ2VDb3VudCA9IDA7CiAgbWVtc2V0KCZUaGlzLT5zSW5mby5yY0ZyYW1lLCAwLCBzaXplb2YoVGhpcy0+c0luZm8ucmNGcmFtZSkpOwoKICBUaGlzLT5mSW5mby5kd1N0cmVhbXMgPSAxOwogIFRoaXMtPmZJbmZvLmR3U2NhbGUgICA9IFRoaXMtPnNJbmZvLmR3U2NhbGU7CiAgVGhpcy0+ZkluZm8uZHdSYXRlICAgID0gVGhpcy0+c0luZm8uZHdSYXRlOwogIFRoaXMtPmZJbmZvLmR3TGVuZ3RoICA9IFRoaXMtPnNJbmZvLmR3TGVuZ3RoOwoKICBUaGlzLT5ja0RhdGEuZHdEYXRhT2Zmc2V0ID0gMDsKICBUaGlzLT5ja0RhdGEuY2tzaXplICAgICAgID0gMDsKCiAgKmF2aXMgPSAoUEFWSVNUUkVBTSkmVGhpcy0+aUFWSVN0cmVhbTsKICBJQVZJRmlsZV9BZGRSZWYoaWZhY2UpOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5Xcml0ZURhdGEoSUFWSUZpbGUgKmlmYWNlLCBEV09SRCBja2lkLAoJCQkJCSAgIExQVk9JRCBscERhdGEsIExPTkcgc2l6ZSkKewogIElBVklGaWxlSW1wbCAqVGhpcyA9IChJQVZJRmlsZUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwweCUwOGxYLCVwLCVsZClcbiIsIGlmYWNlLCBja2lkLCBscERhdGEsIHNpemUpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKGxwRGF0YSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICBpZiAoc2l6ZSA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CgogIC8qIERvIHdlIGhhdmUgd3JpdGUgcGVybWlzc2lvbj8gKi8KICBpZiAoKFRoaXMtPnVNb2RlICYgTU1JT19SV01PREUpID09IDApCiAgICByZXR1cm4gQVZJRVJSX1JFQURPTkxZOwoKICBUaGlzLT5mRGlydHkgPSBUUlVFOwoKICByZXR1cm4gV3JpdGVFeHRyYUNodW5rKCZUaGlzLT5leHRyYSwgY2tpZCwgbHBEYXRhLCBzaXplKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuUmVhZERhdGEoSUFWSUZpbGUgKmlmYWNlLCBEV09SRCBja2lkLAoJCQkJCSAgTFBWT0lEIGxwRGF0YSwgTE9ORyAqc2l6ZSkKewogIElBVklGaWxlSW1wbCAqVGhpcyA9IChJQVZJRmlsZUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwweCUwOGxYLCVwLCVwKVxuIiwgaWZhY2UsIGNraWQsIGxwRGF0YSwgc2l6ZSk7CgogIHJldHVybiBSZWFkRXh0cmFDaHVuaygmVGhpcy0+ZXh0cmEsIGNraWQsIGxwRGF0YSwgc2l6ZSk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkVuZFJlY29yZChJQVZJRmlsZSAqaWZhY2UpCnsKICBUUkFDRSgiKCVwKVxuIixpZmFjZSk7CgogIC8qIFRoaXMgaXMgb25seSBuZWVkZWQgZm9yIGludGVybGVhdmVkIGZpbGVzLgogICAqIFdlIGhhdmUgb25seSBvbmUgc3RyZWFtLCB3aGljaCBjYW4ndCBiZSBpbnRlcmxlYXZlZC4KICAgKi8KICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5EZWxldGVTdHJlYW0oSUFWSUZpbGUgKmlmYWNlLCBEV09SRCBmY2NUeXBlLAoJCQkJCSAgICAgIExPTkcgbFBhcmFtKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKElBVklGaWxlSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLDB4JTA4bFgsJWxkKVxuIiwgaWZhY2UsIGZjY1R5cGUsIGxQYXJhbSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlciAqLwogIGlmIChsUGFyYW0gPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogRG8gd2UgaGF2ZSBvdXIgYXVkaW8gc3RyZWFtPyAqLwogIGlmIChsUGFyYW0gIT0gMCB8fCBUaGlzLT5mSW5mby5kd1N0cmVhbXMgPT0gMCB8fAogICAgICAoZmNjVHlwZSAhPSAwICYmIGZjY1R5cGUgIT0gc3RyZWFtdHlwZUFVRElPKSkKICAgIHJldHVybiBBVklFUlJfTk9EQVRBOwoKICAvKiBIYXZlIHVzZXIgd3JpdGUgcGVybWlzc2lvbnM/ICovCiAgaWYgKChUaGlzLT51TW9kZSAmIE1NSU9fUldNT0RFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgR2xvYmFsRnJlZVB0cihUaGlzLT5scEZvcm1hdCk7CiAgVGhpcy0+bHBGb3JtYXQgPSBOVUxMOwogIFRoaXMtPmNiRm9ybWF0ID0gMDsKCiAgLyogdXBkYXRlIGluZm9zICovCiAgVGhpcy0+Y2tEYXRhLmR3RGF0YU9mZnNldCA9IDA7CiAgVGhpcy0+Y2tEYXRhLmNrc2l6ZSAgICAgICA9IDA7CgogIFRoaXMtPnNJbmZvLmR3U2NhbGUgICA9IDA7CiAgVGhpcy0+c0luZm8uZHdSYXRlICAgID0gMDsKICBUaGlzLT5zSW5mby5kd0xlbmd0aCAgPSAwOwogIFRoaXMtPnNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA9IDA7CgogIFRoaXMtPmZJbmZvLmR3U3RyZWFtcyA9IDA7CiAgVGhpcy0+ZkluZm8uZHdFZGl0Q291bnQrKzsKCiAgVGhpcy0+ZkRpcnR5ID0gVFJVRTsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mblF1ZXJ5SW50ZXJmYWNlKElQZXJzaXN0RmlsZSAqaWZhY2UsCgkJCQkJCSAgICBSRUZJSUQgcmVmaWlkLCBMUFZPSUQgKm9iaikKewogIElQZXJzaXN0RmlsZUltcGwgKlRoaXMgPSAoSVBlcnNpc3RGaWxlSW1wbCAqKWlmYWNlOwoKICBhc3NlcnQoVGhpcy0+cGFmICE9IE5VTEwpOwoKICByZXR1cm4gSUFWSUZpbGVfUXVlcnlJbnRlcmZhY2UoKFBBVklGSUxFKVRoaXMtPnBhZiwgcmVmaWlkLCBvYmopOwp9CgpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuQWRkUmVmKElQZXJzaXN0RmlsZSAqaWZhY2UpCnsKICBJUGVyc2lzdEZpbGVJbXBsICpUaGlzID0gKElQZXJzaXN0RmlsZUltcGwgKilpZmFjZTsKCiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklGaWxlX0FkZFJlZigoUEFWSUZJTEUpVGhpcy0+cGFmKTsKfQoKc3RhdGljIFVMT05HICAgV0lOQVBJIElQZXJzaXN0RmlsZV9mblJlbGVhc2UoSVBlcnNpc3RGaWxlICppZmFjZSkKewogIElQZXJzaXN0RmlsZUltcGwgKlRoaXMgPSAoSVBlcnNpc3RGaWxlSW1wbCAqKWlmYWNlOwoKICBhc3NlcnQoVGhpcy0+cGFmICE9IE5VTEwpOwoKICByZXR1cm4gSUFWSUZpbGVfUmVsZWFzZSgoUEFWSUZJTEUpVGhpcy0+cGFmKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkdldENsYXNzSUQoSVBlcnNpc3RGaWxlICppZmFjZSwKCQkJCQkJTFBDTFNJRCBwQ2xhc3NJRCkKewogIFRSQUNFKCIoJXAsJXApXG4iLCBpZmFjZSwgcENsYXNzSUQpOwoKICBpZiAocENsYXNzSUQgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIG1lbWNweShwQ2xhc3NJRCwgJkNMU0lEX1dBVkZpbGUsIHNpemVvZihDTFNJRF9XQVZGaWxlKSk7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5Jc0RpcnR5KElQZXJzaXN0RmlsZSAqaWZhY2UpCnsKICBJUGVyc2lzdEZpbGVJbXBsICpUaGlzID0gKElQZXJzaXN0RmlsZUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcClcbiIsIGlmYWNlKTsKCiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKCiAgcmV0dXJuIChUaGlzLT5wYWYtPmZEaXJ0eSA/IFNfT0sgOiBTX0ZBTFNFKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkxvYWQoSVBlcnNpc3RGaWxlICppZmFjZSwKCQkJCQkgIExQQ09MRVNUUiBwc3pGaWxlTmFtZSwgRFdPUkQgZHdNb2RlKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKChJUGVyc2lzdEZpbGVJbXBsKilpZmFjZSktPnBhZjsKCiAgV0NIQVIgd3N6U3RyZWFtRm10WzUwXTsKICBJTlQgICBsZW47CgogIFRSQUNFKCIoJXAsJXMsMHglMDhsWClcbiIsIGlmYWNlLCBkZWJ1Z3N0cl93KHBzekZpbGVOYW1lKSwgZHdNb2RlKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVyICovCiAgaWYgKHBzekZpbGVOYW1lID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICBhc3NlcnQoVGhpcyAhPSBOVUxMKTsKICBpZiAoVGhpcy0+aG1taW8gIT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfRVJST1I7IC8qIE5vIHJldXNlIG9mIHRoaXMgb2JqZWN0IGZvciBhbm90aGVyIGZpbGUhICovCgogIC8qIHJlbWViZXIgbW9kZSBhbmQgbmFtZSAqLwogIFRoaXMtPnVNb2RlID0gZHdNb2RlOwoKICBsZW4gPSBsc3RybGVuVyhwc3pGaWxlTmFtZSkgKyAxOwogIFRoaXMtPnN6RmlsZU5hbWUgPSBMb2NhbEFsbG9jKExQVFIsIGxlbiAqIHNpemVvZihXQ0hBUikpOwogIGlmIChUaGlzLT5zekZpbGVOYW1lID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKICBsc3RyY3B5VyhUaGlzLT5zekZpbGVOYW1lLCBwc3pGaWxlTmFtZSk7CgogIC8qIHRyeSB0byBvcGVuIHRoZSBmaWxlICovCiAgVGhpcy0+aG1taW8gPSBtbWlvT3BlblcoVGhpcy0+c3pGaWxlTmFtZSwgTlVMTCwgTU1JT19BTExPQ0JVRiB8IGR3TW9kZSk7CiAgaWYgKFRoaXMtPmhtbWlvID09IE5VTEwpIHsKICAgIC8qIG1taW9PcGVuVyBub3QgaW4gbmF0aXZlIERMTHMgb2YgV2luOXggLS0gdHJ5IG1taW9PcGVuQSAqLwogICAgTFBTVFIgc3pGaWxlTmFtZTsKICAgIGxlbiA9IFdpZGVDaGFyVG9NdWx0aUJ5dGUoQ1BfQUNQLCAwLCBUaGlzLT5zekZpbGVOYW1lLCAtMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgMCwgTlVMTCwgTlVMTCk7CiAgICBzekZpbGVOYW1lID0gTG9jYWxBbGxvYyhMUFRSLCBsZW4gKiBzaXplb2YoQ0hBUikpOwogICAgaWYgKHN6RmlsZU5hbWUgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogICAgV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIFRoaXMtPnN6RmlsZU5hbWUsIC0xLCBzekZpbGVOYW1lLAoJCQlsZW4sIE5VTEwsIE5VTEwpOwoKICAgIFRoaXMtPmhtbWlvID0gbW1pb09wZW5BKHN6RmlsZU5hbWUsIE5VTEwsIE1NSU9fQUxMT0NCVUYgfCBkd01vZGUpOwogICAgTG9jYWxGcmVlKChITE9DQUwpc3pGaWxlTmFtZSk7CiAgICBpZiAoVGhpcy0+aG1taW8gPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFT1BFTjsKICB9CgogIG1lbXNldCgmIFRoaXMtPmZJbmZvLCAwLCBzaXplb2YoVGhpcy0+ZkluZm8pKTsKICBtZW1zZXQoJiBUaGlzLT5zSW5mbywgMCwgc2l6ZW9mKFRoaXMtPnNJbmZvKSk7CgogIExvYWRTdHJpbmdXKEFWSUZJTEVfaE1vZHVsZSwgSURTX1dBVkVGSUxFVFlQRSwgVGhpcy0+ZkluZm8uc3pGaWxlVHlwZSwKCSAgICAgIHNpemVvZihUaGlzLT5mSW5mby5zekZpbGVUeXBlKSk7CiAgaWYgKExvYWRTdHJpbmdXKEFWSUZJTEVfaE1vZHVsZSwgSURTX1dBVkVTVFJFQU1GT1JNQVQsCgkJICB3c3pTdHJlYW1GbXQsIHNpemVvZih3c3pTdHJlYW1GbXQpKSA+IDApIHsKICAgIHdzcHJpbnRmVyhUaGlzLT5zSW5mby5zek5hbWUsIHdzelN0cmVhbUZtdCwKCSAgICAgIEFWSUZJTEVfQmFzZW5hbWVXKFRoaXMtPnN6RmlsZU5hbWUpKTsKICB9CgogIC8qIHNob3VsZCB3ZSBjcmVhdGUgYSBuZXcgZmlsZT8gKi8KICBpZiAoZHdNb2RlICYgT0ZfQ1JFQVRFKSB7CiAgICAvKiBub3RoaW5nIG1vcmUgdG8gZG8gKi8KICAgIHJldHVybiBBVklFUlJfT0s7CiAgfSBlbHNlCiAgICByZXR1cm4gQVZJRklMRV9Mb2FkRmlsZShUaGlzKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mblNhdmUoSVBlcnNpc3RGaWxlICppZmFjZSwKCQkJCQkgIExQQ09MRVNUUiBwc3pGaWxlTmFtZSxCT09MIGZSZW1lbWJlcikKewogIFRSQUNFKCIoJXAsJXMsJWQpXG4iLCBpZmFjZSwgZGVidWdzdHJfdyhwc3pGaWxlTmFtZSksIGZSZW1lbWJlcik7CgogIC8qIFdlIHdyaXRlIGRpcmVjdGx5IHRvIGRpc2ssIHNvIG5vdGhpbmcgdG8gZG8uICovCgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5TYXZlQ29tcGxldGVkKElQZXJzaXN0RmlsZSAqaWZhY2UsCgkJCQkJCSAgIExQQ09MRVNUUiBwc3pGaWxlTmFtZSkKewogIFRSQUNFKCIoJXAsJXMpXG4iLCBpZmFjZSwgZGVidWdzdHJfdyhwc3pGaWxlTmFtZSkpOwoKICAvKiBXZSB3cml0ZSBkaXJlY3RseSB0byBkaXNrLCBzbyBub3RoaW5nIHRvIGRvLiAqLwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuR2V0Q3VyRmlsZShJUGVyc2lzdEZpbGUgKmlmYWNlLAoJCQkJCQlMUE9MRVNUUiAqcHBzekZpbGVOYW1lKQp7CiAgSVBlcnNpc3RGaWxlSW1wbCAqVGhpcyA9IChJUGVyc2lzdEZpbGVJbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJXApXG4iLCBpZmFjZSwgcHBzekZpbGVOYW1lKTsKCiAgaWYgKHBwc3pGaWxlTmFtZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgKnBwc3pGaWxlTmFtZSA9IE5VTEw7CgogIGFzc2VydChUaGlzLT5wYWYgIT0gTlVMTCk7CgogIGlmIChUaGlzLT5wYWYtPnN6RmlsZU5hbWUgIT0gTlVMTCkgewogICAgaW50IGxlbiA9IGxzdHJsZW5XKFRoaXMtPnBhZi0+c3pGaWxlTmFtZSkgKyAxOwoKICAgICpwcHN6RmlsZU5hbWUgPSBHbG9iYWxBbGxvY1B0cihHSE5ELCBsZW4gKiBzaXplb2YoV0NIQVIpKTsKICAgIGlmICgqcHBzekZpbGVOYW1lID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICAgIHN0cmNweVcoKnBwc3pGaWxlTmFtZSwgVGhpcy0+cGFmLT5zekZpbGVOYW1lKTsKICB9CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUXVlcnlJbnRlcmZhY2UoSUFWSVN0cmVhbSAqaWZhY2UsCgkJCQkJCSAgUkVGSUlEIHJlZmlpZCwgTFBWT0lEICpvYmopCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBhc3NlcnQoVGhpcy0+cGFmICE9IE5VTEwpOwoKICByZXR1cm4gSUFWSUZpbGVfUXVlcnlJbnRlcmZhY2UoKFBBVklGSUxFKVRoaXMtPnBhZiwgcmVmaWlkLCBvYmopOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIElBVklTdHJlYW1fZm5BZGRSZWYoSUFWSVN0cmVhbSAqaWZhY2UpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBhc3NlcnQoVGhpcy0+cGFmICE9IE5VTEwpOwoKICByZXR1cm4gSUFWSUZpbGVfQWRkUmVmKChQQVZJRklMRSlUaGlzLT5wYWYpOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIElBVklTdHJlYW1fZm5SZWxlYXNlKElBVklTdHJlYW0qIGlmYWNlKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklGaWxlX1JlbGVhc2UoKFBBVklGSUxFKVRoaXMtPnBhZik7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuQ3JlYXRlKElBVklTdHJlYW0gKmlmYWNlLCBMUEFSQU0gbFBhcmFtMSwKCQkJCQkgIExQQVJBTSBsUGFyYW0yKQp7CiAgVFJBQ0UoIiglcCwweCUwOGxYLDB4JTA4bFgpXG4iLCBpZmFjZSwgbFBhcmFtMSwgbFBhcmFtMik7CgogIC8qIFRoaXMgSUFWSVN0cmVhbSBpbnRlcmZhY2UgbmVlZHMgYW4gV0FWRmlsZSAqLwogIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuSW5mbyhJQVZJU3RyZWFtICppZmFjZSxMUEFWSVNUUkVBTUlORk9XIHBzaSwKCQkJCQlMT05HIHNpemUpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVwLCVsZClcbiIsIGlmYWNlLCBwc2ksIHNpemUpOwoKICBpZiAocHNpID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIGlmIChzaXplIDwgMCkKICAgIHJldHVybiBBVklFUlJfQkFEU0laRTsKCiAgbWVtY3B5KHBzaSwgJlRoaXMtPnBhZi0+c0luZm8sIG1pbigoRFdPUkQpc2l6ZSwgc2l6ZW9mKFRoaXMtPnBhZi0+c0luZm8pKSk7CgogIGlmICgoRFdPUkQpc2l6ZSA8IHNpemVvZihUaGlzLT5wYWYtPnNJbmZvKSkKICAgIHJldHVybiBBVklFUlJfQlVGRkVSVE9PU01BTEw7CiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIExPTkcgV0lOQVBJIElBVklTdHJlYW1fZm5GaW5kU2FtcGxlKElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHBvcywKCQkJCQkgICBMT05HIGZsYWdzKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKChJQVZJU3RyZWFtSW1wbCopaWZhY2UpLT5wYWY7CgogIFRSQUNFKCIoJXAsJWxkLDB4JTA4bFgpXG4iLGlmYWNlLHBvcyxmbGFncyk7CgogIC8qIERvIHdlIGhhdmUgZGF0YT8gKi8KICBpZiAoVGhpcy0+bHBGb3JtYXQgPT0gTlVMTCkKICAgIHJldHVybiAtMTsKCiAgLyogV2UgZG9uJ3QgaGF2ZSBhbiBpbmRleCAqLwogIGlmIChmbGFncyAmIEZJTkRfSU5ERVgpCiAgICByZXR1cm4gLTE7CgogIGlmIChmbGFncyAmIEZJTkRfRlJPTV9TVEFSVCkgewogICAgcG9zID0gVGhpcy0+c0luZm8uZHdTdGFydDsKICAgIGZsYWdzICY9IH4oRklORF9GUk9NX1NUQVJUfEZJTkRfUFJFVik7CiAgICBmbGFncyB8PSBGSU5EX05FWFQ7CiAgfQoKICBpZiAoZmxhZ3MgJiBGSU5EX0ZPUk1BVCkgewogICAgaWYgKChmbGFncyAmIEZJTkRfTkVYVCkgJiYgcG9zID4gMCkKICAgICAgcG9zID0gLTE7CiAgICBlbHNlCiAgICAgIHBvcyA9IDA7CiAgfQoKICBpZiAoKGZsYWdzICYgRklORF9SRVQpID09IEZJTkRfTEVOR1RIIHx8CiAgICAgIChmbGFncyAmIEZJTkRfUkVUKSA9PSBGSU5EX1NJWkUpCiAgICByZXR1cm4gVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplOwogIGlmICgoZmxhZ3MgJiBGSU5EX1JFVCkgPT0gRklORF9PRkZTRVQpCiAgICByZXR1cm4gVGhpcy0+Y2tEYXRhLmR3RGF0YU9mZnNldCArIHBvcyAqIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZTsKCiAgcmV0dXJuIHBvczsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5SZWFkRm9ybWF0KElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHBvcywKCQkJCQkgICAgICBMUFZPSUQgZm9ybWF0LCBMT05HICpmb3JtYXRzaXplKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlbGQsJXAsJXApXG4iLCBpZmFjZSwgcG9zLCBmb3JtYXQsIGZvcm1hdHNpemUpOwoKICBpZiAoZm9ybWF0c2l6ZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogb25seSBpbnRlcmVzdGVkIGluIG5lZWRlZCBidWZmZXJzaXplPyAqLwogIGlmIChmb3JtYXQgPT0gTlVMTCB8fCAqZm9ybWF0c2l6ZSA8PSAwKSB7CiAgICAqZm9ybWF0c2l6ZSA9IFRoaXMtPnBhZi0+Y2JGb3JtYXQ7CgogICAgcmV0dXJuIEFWSUVSUl9PSzsKICB9CgogIC8qIGNvcHkgaW5pdGlhbCBmb3JtYXQgKG9ubHkgYXMgbXVjaCBhcyB3aWxsIGZpdCkgKi8KICBtZW1jcHkoZm9ybWF0LCBUaGlzLT5wYWYtPmxwRm9ybWF0LCBtaW4oKmZvcm1hdHNpemUsIFRoaXMtPnBhZi0+Y2JGb3JtYXQpKTsKICBpZiAoKmZvcm1hdHNpemUgPCBUaGlzLT5wYWYtPmNiRm9ybWF0KSB7CiAgICAqZm9ybWF0c2l6ZSA9IFRoaXMtPnBhZi0+Y2JGb3JtYXQ7CiAgICByZXR1cm4gQVZJRVJSX0JVRkZFUlRPT1NNQUxMOwogIH0KCiAgKmZvcm1hdHNpemUgPSBUaGlzLT5wYWYtPmNiRm9ybWF0OwogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuU2V0Rm9ybWF0KElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHBvcywKCQkJCQkgICAgIExQVk9JRCBmb3JtYXQsIExPTkcgZm9ybWF0c2l6ZSkKewogIElBVklGaWxlSW1wbCAqVGhpcyA9ICgoSUFWSVN0cmVhbUltcGwqKWlmYWNlKS0+cGFmOwoKICBUUkFDRSgiKCVwLCVsZCwlcCwlbGQpXG4iLCBpZmFjZSwgcG9zLCBmb3JtYXQsIGZvcm1hdHNpemUpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKGZvcm1hdCA9PSBOVUxMIHx8IGZvcm1hdHNpemUgPD0gc2l6ZW9mKFBDTVdBVkVGT1JNQVQpKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogV2UgY2FuIG9ubHkgZG8gdGhpcyB0byBhbiBlbXB0eSB3YXZlIGZpbGUsIGJ1dCBpZ25vcmUgY2FsbAogICAqIGlmIHN0aWxsIHNhbWUgZm9ybWF0ICovCiAgaWYgKFRoaXMtPmxwRm9ybWF0ICE9IE5VTEwpIHsKICAgIGlmIChmb3JtYXRzaXplICE9IFRoaXMtPmNiRm9ybWF0IHx8CgltZW1jbXAoZm9ybWF0LCBUaGlzLT5scEZvcm1hdCwgZm9ybWF0c2l6ZSkgIT0gMCkKICAgICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKCiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0KCiAgLyogb25seSBzdXBwb3J0IHN0YXJ0IGF0IHBvc2l0aW9uIDAgKi8KICBpZiAocG9zICE9IDApCiAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICAvKiBEbyB3ZSBoYXZlIHdyaXRlIHBlcm1pc3Npb24/ICovCiAgaWYgKChUaGlzLT51TW9kZSAmIE1NSU9fUldNT0RFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgLyogZ2V0IG1lbW9yeSBmb3IgZm9ybWF0IGFuZCBjb3B5IGl0ICovCiAgVGhpcy0+bHBGb3JtYXQgPSAoTFBXQVZFRk9STUFURVgpR2xvYmFsQWxsb2NQdHIoR01FTV9NT1ZFQUJMRSwgZm9ybWF0c2l6ZSk7CiAgaWYgKFRoaXMtPmxwRm9ybWF0ID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgVGhpcy0+Y2JGb3JtYXQgPSBmb3JtYXRzaXplOwogIG1lbWNweShUaGlzLT5scEZvcm1hdCwgZm9ybWF0LCBmb3JtYXRzaXplKTsKCiAgLyogdXBkYXRlIGluZm8ncyBhYm91dCAnZGF0YScgY2h1bmsgKi8KICBUaGlzLT5ja0RhdGEuZHdEYXRhT2Zmc2V0ID0gZm9ybWF0c2l6ZSArIDcgKiBzaXplb2YoRFdPUkQpOwogIFRoaXMtPmNrRGF0YS5ja3NpemUgICAgICAgPSAwOwoKICAvKiBmb3Igbm9uLXBjbSBmb3JtYXQgd2UgbmVlZCBhbHNvIGEgJ2ZhY3QnIGNodW5rICovCiAgaWYgKFRoaXMtPmxwRm9ybWF0LT53Rm9ybWF0VGFnICE9IFdBVkVfRk9STUFUX1BDTSkKICAgIFRoaXMtPmNrRGF0YS5kd0RhdGFPZmZzZXQgKz0gMyAqIHNpemVvZihEV09SRCk7CgogIC8qIHVwZGF0ZSBzdHJlYW0gYW5kIGZpbGUgaW5mbyAqLwogIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSA9IFRoaXMtPmxwRm9ybWF0LT5uQmxvY2tBbGlnbjsKICBUaGlzLT5zSW5mby5kd1NjYWxlICAgICAgPSBUaGlzLT5scEZvcm1hdC0+bkJsb2NrQWxpZ247CiAgVGhpcy0+c0luZm8uZHdSYXRlICAgICAgID0gVGhpcy0+bHBGb3JtYXQtPm5BdmdCeXRlc1BlclNlYzsKICBUaGlzLT5zSW5mby5kd0xlbmd0aCAgICAgPSAwOwogIFRoaXMtPnNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA9IDA7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUmVhZChJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBzdGFydCwKCQkJCQlMT05HIHNhbXBsZXMsIExQVk9JRCBidWZmZXIsCgkJCQkJTE9ORyBidWZmZXJzaXplLCBMUExPTkcgYnl0ZXNyZWFkLAoJCQkJCUxQTE9ORyBzYW1wbGVzcmVhZCkKewogIElBVklGaWxlSW1wbCAqVGhpcyA9ICgoSUFWSVN0cmVhbUltcGwqKWlmYWNlKS0+cGFmOwoKICBUUkFDRSgiKCVwLCVsZCwlbGQsJXAsJWxkLCVwLCVwKVxuIiwgaWZhY2UsIHN0YXJ0LCBzYW1wbGVzLCBidWZmZXIsCglidWZmZXJzaXplLCBieXRlc3JlYWQsIHNhbXBsZXNyZWFkKTsKCiAgLyogY2xlYXIgcmV0dXJuIHBhcmFtZXRlcnMgaWYgZ2l2ZW4gKi8KICBpZiAoYnl0ZXNyZWFkICE9IE5VTEwpCiAgICAqYnl0ZXNyZWFkID0gMDsKICBpZiAoc2FtcGxlc3JlYWQgIT0gTlVMTCkKICAgICpzYW1wbGVzcmVhZCA9IDA7CgogIC8qIHBvc2l0aW9ucyB3aXRob3V0IGRhdGEgKi8KICBpZiAoc3RhcnQgPCAwIHx8IChEV09SRClzdGFydCA+IFRoaXMtPnNJbmZvLmR3TGVuZ3RoKQogICAgcmV0dXJuIEFWSUVSUl9PSzsKCiAgLyogY2hlY2sgc2FtcGxlcyAqLwogIGlmIChzYW1wbGVzIDwgMCkKICAgIHNhbXBsZXMgPSAwOwogIGlmIChidWZmZXJzaXplID4gMCkgewogICAgaWYgKHNhbXBsZXMgPiAwKQogICAgICBzYW1wbGVzID0gbWluKChEV09SRClzYW1wbGVzLCBidWZmZXJzaXplIC8gVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplKTsKICAgIGVsc2UKICAgICAgc2FtcGxlcyA9IGJ1ZmZlcnNpemUgLyBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemU7CiAgfQoKICAvKiBsaW1pdCB0byBlbmQgb2Ygc3RyZWFtICovCiAgaWYgKChEV09SRCkoc3RhcnQgKyBzYW1wbGVzKSA+IFRoaXMtPnNJbmZvLmR3TGVuZ3RoKQogICAgc2FtcGxlcyA9IFRoaXMtPnNJbmZvLmR3TGVuZ3RoIC0gc3RhcnQ7CgogIC8qIHJlcXVlc3Qgb25seSB0aGUgc2l6ZXM/ICovCiAgaWYgKGJ1ZmZlciA9PSBOVUxMIHx8IGJ1ZmZlcnNpemUgPD0gMCkgewogICAgLyogdGhlbiBJIG5lZWQgYXQgbGVhc3Qgb25lIHBhcmFtZXRlciBmb3IgaXQgKi8KICAgIGlmIChieXRlc3JlYWQgPT0gTlVMTCAmJiBzYW1wbGVzcmVhZCA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAgIGlmIChieXRlc3JlYWQgIT0gTlVMTCkKICAgICAgKmJ5dGVzcmVhZCA9IHNhbXBsZXMgKiBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemU7CiAgICBpZiAoc2FtcGxlc3JlYWQgIT0gTlVMTCkKICAgICAgKnNhbXBsZXNyZWFkID0gc2FtcGxlczsKCiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0KCiAgLyogbm90aGluZyB0byByZWFkPyAqLwogIGlmIChzYW1wbGVzID09IDApCiAgICByZXR1cm4gQVZJRVJSX09LOwoKICAvKiBDYW4gSSByZWFkIGF0IGxlYXN0IG9uZSBzYW1wbGU/ICovCiAgaWYgKChEV09SRClidWZmZXJzaXplIDwgVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplKQogICAgcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKCiAgYnVmZmVyc2l6ZSA9IHNhbXBsZXMgKiBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemU7CgogIGlmIChtbWlvU2VlayhUaGlzLT5obW1pbywgVGhpcy0+Y2tEYXRhLmR3RGF0YU9mZnNldAoJICAgICAgICsgc3RhcnQgKiBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUsIFNFRUtfU0VUKSA9PSAtMSkKICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CiAgaWYgKG1taW9SZWFkKFRoaXMtPmhtbWlvLCAoSFBTVFIpYnVmZmVyLCBidWZmZXJzaXplKSAhPSBidWZmZXJzaXplKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCiAgLyogZmlsbCBvdXQgcmV0dXJuIHBhcmFtZXRlcnMgaWYgZ2l2ZW4gKi8KICBpZiAoYnl0ZXNyZWFkICE9IE5VTEwpCiAgICAqYnl0ZXNyZWFkID0gYnVmZmVyc2l6ZTsKICBpZiAoc2FtcGxlc3JlYWQgIT0gTlVMTCkKICAgICpzYW1wbGVzcmVhZCA9IHNhbXBsZXM7ICAKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5Xcml0ZShJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBzdGFydCwKCQkJCQkgTE9ORyBzYW1wbGVzLCBMUFZPSUQgYnVmZmVyLAoJCQkJCSBMT05HIGJ1ZmZlcnNpemUsIERXT1JEIGZsYWdzLAoJCQkJCSBMUExPTkcgc2FtcHdyaXR0ZW4sCgkJCQkJIExQTE9ORyBieXRlc3dyaXR0ZW4pCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoKElBVklTdHJlYW1JbXBsKilpZmFjZSktPnBhZjsKCiAgVFJBQ0UoIiglcCwlbGQsJWxkLCVwLCVsZCwweCUwOGxYLCVwLCVwKVxuIiwgaWZhY2UsIHN0YXJ0LCBzYW1wbGVzLAoJYnVmZmVyLCBidWZmZXJzaXplLCBmbGFncywgc2FtcHdyaXR0ZW4sIGJ5dGVzd3JpdHRlbik7CgogIC8qIGNsZWFyIHJldHVybiBwYXJhbWV0ZXJzIGlmIGdpdmVuICovCiAgaWYgKHNhbXB3cml0dGVuICE9IE5VTEwpCiAgICAqc2FtcHdyaXR0ZW4gPSAwOwogIGlmIChieXRlc3dyaXR0ZW4gIT0gTlVMTCkKICAgICpieXRlc3dyaXR0ZW4gPSAwOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKGJ1ZmZlciA9PSBOVUxMICYmIChidWZmZXJzaXplID4gMCB8fCBzYW1wbGVzID4gMCkpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBEbyB3ZSBoYXZlIHdyaXRlIHBlcm1pc3Npb24/ICovCiAgaWYgKChUaGlzLT51TW9kZSAmIE1NSU9fUldNT0RFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgLyogPCAwIG1lYW5zICJhcHBlbmQiICovCiAgaWYgKHN0YXJ0IDwgMCkKICAgIHN0YXJ0ID0gVGhpcy0+c0luZm8uZHdTdGFydCArIFRoaXMtPnNJbmZvLmR3TGVuZ3RoOwoKICAvKiBjaGVjayBidWZmZXJzaXplIC0tIG11c3QgbXVsdGlwbGUgb2Ygc2FtcGxlc2l6ZSAqLwogIGlmIChidWZmZXJzaXplICYgfihUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUgLSAxKSkKICAgIHJldHVybiBBVklFUlJfQkFEU0laRTsKCiAgLyogZG8gd2UgaGF2ZSBhbnl0aGluZyB0byB3cml0ZT8gKi8KICBpZiAoYnVmZmVyICE9IE5VTEwgJiYgYnVmZmVyc2l6ZSA+IDApIHsKICAgIFRoaXMtPmZEaXJ0eSA9IDE7CgogICAgaWYgKG1taW9TZWVrKFRoaXMtPmhtbWlvLCBUaGlzLT5ja0RhdGEuZHdEYXRhT2Zmc2V0ICsKCQkgc3RhcnQgKiBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUsIFNFRUtfU0VUKSA9PSAtMSkKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICBpZiAobW1pb1dyaXRlKFRoaXMtPmhtbWlvLCAoSFBTVFIpYnVmZmVyLCBidWZmZXJzaXplKSAhPSBidWZmZXJzaXplKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgICBUaGlzLT5zSW5mby5kd0xlbmd0aCA9IG1heChUaGlzLT5zSW5mby5kd0xlbmd0aCwgKERXT1JEKXN0YXJ0ICsgc2FtcGxlcyk7CiAgICBUaGlzLT5ja0RhdGEuY2tzaXplICA9IG1heChUaGlzLT5ja0RhdGEuY2tzaXplLAoJCQkgICAgICAgc3RhcnQgKiBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUgKyBidWZmZXJzaXplKTsKCiAgICAvKiBmaWxsIG91dCByZXR1cm4gcGFyYW1ldGVycyBpZiBnaXZlbiAqLwogICAgaWYgKHNhbXB3cml0dGVuICE9IE5VTEwpCiAgICAgICpzYW1wd3JpdHRlbiA9IHNhbXBsZXM7CiAgICBpZiAoYnl0ZXN3cml0dGVuICE9IE5VTEwpCiAgICAgICpieXRlc3dyaXR0ZW4gPSBidWZmZXJzaXplOwogIH0KCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5EZWxldGUoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgc3RhcnQsCgkJCQkJICBMT05HIHNhbXBsZXMpCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoKElBVklTdHJlYW1JbXBsKilpZmFjZSktPnBhZjsKCiAgVFJBQ0UoIiglcCwlbGQsJWxkKVxuIiwgaWZhY2UsIHN0YXJ0LCBzYW1wbGVzKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChzdGFydCA8IDAgfHwgc2FtcGxlcyA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBEZWxldGUgYmVmb3JlIHN0YXJ0IG9mIHN0cmVhbT8gKi8KICBpZiAoKERXT1JEKShzdGFydCArIHNhbXBsZXMpIDwgVGhpcy0+c0luZm8uZHdTdGFydCkKICAgIHJldHVybiBBVklFUlJfT0s7CgogIC8qIERlbGV0ZSBhZnRlciBlbmQgb2Ygc3RyZWFtPyAqLwogIGlmICgoRFdPUkQpc3RhcnQgPiBUaGlzLT5zSW5mby5kd0xlbmd0aCkKICAgIHJldHVybiBBVklFUlJfT0s7CgogIC8qIEZvciB0aGUgcmVzdCB3ZSBuZWVkIHdyaXRlIHBlcm1pc3Npb25zICovCiAgaWYgKChUaGlzLT51TW9kZSAmIE1NSU9fUldNT0RFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgaWYgKChEV09SRCkoc3RhcnQgKyBzYW1wbGVzKSA+PSBUaGlzLT5zSW5mby5kd0xlbmd0aCkgewogICAgLyogZGVsZXRpb24gYXQgZW5kICovCiAgICBzYW1wbGVzID0gVGhpcy0+c0luZm8uZHdMZW5ndGggLSBzdGFydDsKICAgIFRoaXMtPnNJbmZvLmR3TGVuZ3RoIC09IHNhbXBsZXM7CiAgICBUaGlzLT5ja0RhdGEuY2tzaXplICAtPSBzYW1wbGVzICogVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplOwogIH0gZWxzZSBpZiAoKERXT1JEKXN0YXJ0IDw9IFRoaXMtPnNJbmZvLmR3U3RhcnQpIHsKICAgIC8qIGRlbGV0aW9uIGF0IHN0YXJ0ICovCiAgICBzYW1wbGVzID0gVGhpcy0+c0luZm8uZHdTdGFydCAtIHN0YXJ0OwogICAgc3RhcnQgICA9IFRoaXMtPnNJbmZvLmR3U3RhcnQ7CiAgICBUaGlzLT5ja0RhdGEuZHdEYXRhT2Zmc2V0ICs9IHNhbXBsZXMgKiBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemU7CiAgICBUaGlzLT5ja0RhdGEuY2tzaXplICAgICAgIC09IHNhbXBsZXMgKiBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemU7CiAgfSBlbHNlIHsKICAgIC8qIGRlbGV0aW9uIGluc2lkZSBzdHJlYW0gLS0gbmVlZHMgcGxheWxpc3QgYW5kIGN1ZSdzICovCiAgICBGSVhNRSgiOiBkZWxldGlvbiBpbnNpZGUgb2Ygc3RyZWFtIG5vdCBzdXBwb3J0ZWQhXG4iKTsKCiAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwogIH0KCiAgVGhpcy0+ZkRpcnR5ID0gMTsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5SZWFkRGF0YShJQVZJU3RyZWFtICppZmFjZSwgRFdPUkQgZmNjLAoJCQkJCSAgICBMUFZPSUQgbHAsIExQTE9ORyBscHJlYWQpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBhc3NlcnQoVGhpcy0+cGFmICE9IE5VTEwpOwoKICByZXR1cm4gSUFWSUZpbGVfUmVhZERhdGEoKFBBVklGSUxFKVRoaXMtPnBhZiwgZmNjLCBscCwgbHByZWFkKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5Xcml0ZURhdGEoSUFWSVN0cmVhbSAqaWZhY2UsIERXT1JEIGZjYywKCQkJCQkgICAgIExQVk9JRCBscCwgTE9ORyBzaXplKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgcmV0dXJuIElBVklGaWxlX1dyaXRlRGF0YSgoUEFWSUZJTEUpVGhpcy0+cGFmLCBmY2MsIGxwLCBzaXplKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5TZXRJbmZvKElBVklTdHJlYW0gKmlmYWNlLAoJCQkJCSAgIExQQVZJU1RSRUFNSU5GT1cgaW5mbywgTE9ORyBpbmZvbGVuKQp7CiAgRklYTUUoIiglcCwlcCwlbGQpOiBzdHViXG4iLCBpZmFjZSwgaW5mbywgaW5mb2xlbik7CgogIHJldHVybiBFX0ZBSUw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfTG9hZEZpbGUoSUFWSUZpbGVJbXBsICpUaGlzKQp7CiAgTU1DS0lORk8gY2tSSUZGOwogIE1NQ0tJTkZPIGNrOwoKICBUaGlzLT5zSW5mby5kd0xlbmd0aCA9IDA7IC8qIGp1c3QgdG8gYmUgc3VyZSAqLwogIFRoaXMtPmZEaXJ0eSA9IEZBTFNFOwoKICAvKiBzZWFyY2ggZm9yIFJJRkYgY2h1bmsgKi8KICBja1JJRkYuZmNjVHlwZSA9IDA7IC8qIGZpbmQgYW55ICovCiAgaWYgKG1taW9EZXNjZW5kKFRoaXMtPmhtbWlvLCAmY2tSSUZGLCBOVUxMLCBNTUlPX0ZJTkRSSUZGKSAhPSBTX09LKSB7CiAgICByZXR1cm4gQVZJRklMRV9Mb2FkU3VuRmlsZShUaGlzKTsKICB9CgogIGlmIChja1JJRkYuZmNjVHlwZSAhPSBmb3JtdHlwZVdBVkUpCiAgICByZXR1cm4gQVZJRVJSX0JBREZPUk1BVDsKCiAgLyogc2VhcmNoIFdBVkUgZm9ybWF0IGNodW5rICovCiAgY2suY2tpZCA9IGNraWRXQVZFRk9STUFUOwogIGlmIChGaW5kQ2h1bmtBbmRLZWVwRXh0cmFzKCZUaGlzLT5leHRyYSwgVGhpcy0+aG1taW8sICZjaywKCQkJICAgICAmY2tSSUZGLCBNTUlPX0ZJTkRDSFVOSykgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CgogIC8qIGdldCBtZW1vcnkgZm9yIGZvcm1hdCBhbmQgcmVhZCBpdCAqLwogIFRoaXMtPmxwRm9ybWF0ID0gKExQV0FWRUZPUk1BVEVYKUdsb2JhbEFsbG9jUHRyKEdNRU1fTU9WRUFCTEUsIGNrLmNrc2l6ZSk7CiAgaWYgKFRoaXMtPmxwRm9ybWF0ID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwogIFRoaXMtPmNiRm9ybWF0ID0gY2suY2tzaXplOwoKICBpZiAobW1pb1JlYWQoVGhpcy0+aG1taW8sIChIUFNUUilUaGlzLT5scEZvcm1hdCwgY2suY2tzaXplKSAhPSBjay5ja3NpemUpCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwogIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwoKICAvKiBOb24tcGNtIGZvcm1hdHMgaGF2ZSBhIGZhY3QgY2h1bmsuCiAgICogV2UgZG9uJ3QgbmVlZCBpdCwgc28gc2ltcGx5IGFkZCBpdCB0byB0aGUgZXh0cmEgY2h1bmtzLgogICAqLwoKICAvKiBmaW5kIHRoZSBiaWcgZGF0YSBjaHVuayAqLwogIFRoaXMtPmNrRGF0YS5ja2lkID0gY2tpZFdBVkVEQVRBOwogIGlmIChGaW5kQ2h1bmtBbmRLZWVwRXh0cmFzKCZUaGlzLT5leHRyYSwgVGhpcy0+aG1taW8sICZUaGlzLT5ja0RhdGEsCgkJCSAgICAgJmNrUklGRiwgTU1JT19GSU5EQ0hVTkspICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwoKICBtZW1zZXQoJlRoaXMtPnNJbmZvLCAwLCBzaXplb2YoVGhpcy0+c0luZm8pKTsKICBUaGlzLT5zSW5mby5mY2NUeXBlICAgICAgPSBzdHJlYW10eXBlQVVESU87CiAgVGhpcy0+c0luZm8uZHdSYXRlICAgICAgID0gVGhpcy0+bHBGb3JtYXQtPm5BdmdCeXRlc1BlclNlYzsKICBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUgPQogICAgVGhpcy0+c0luZm8uZHdTY2FsZSAgICA9IFRoaXMtPmxwRm9ybWF0LT5uQmxvY2tBbGlnbjsKICBUaGlzLT5zSW5mby5kd0xlbmd0aCAgICAgPSBUaGlzLT5ja0RhdGEuY2tzaXplIC8gVGhpcy0+bHBGb3JtYXQtPm5CbG9ja0FsaWduOwogIFRoaXMtPnNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA9IFRoaXMtPmNrRGF0YS5ja3NpemU7CgogIFRoaXMtPmZJbmZvLmR3U3RyZWFtcyA9IDE7CgogIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmVGhpcy0+Y2tEYXRhLCAwKSAhPSBTX09LKSB7CiAgICAvKiBzZWVtcyB0byBiZSB0cnVuY2F0ZWQgKi8KICAgIFdBUk4oIjogZmlsZSBzZWVtcyB0byBiZSB0cnVuY2F0ZWQhXG4iKTsKICAgIFRoaXMtPmNrRGF0YS5ja3NpemUgID0gbW1pb1NlZWsoVGhpcy0+aG1taW8sIDAsIFNFRUtfRU5EKSAtCiAgICAgIFRoaXMtPmNrRGF0YS5kd0RhdGFPZmZzZXQ7CiAgICBUaGlzLT5zSW5mby5kd0xlbmd0aCA9IFRoaXMtPmNrRGF0YS5ja3NpemUgLyBUaGlzLT5scEZvcm1hdC0+bkJsb2NrQWxpZ247CiAgICBUaGlzLT5zSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPSBUaGlzLT5ja0RhdGEuY2tzaXplOwogIH0KCiAgLyogaWdub3JlIGVycm9ycyAqLwogIEZpbmRDaHVua0FuZEtlZXBFeHRyYXMoJlRoaXMtPmV4dHJhLCBUaGlzLT5obW1pbywgJmNrLCAmY2tSSUZGLCAwKTsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9Mb2FkU3VuRmlsZShJQVZJRmlsZUltcGwgKlRoaXMpCnsKICBTVU5BVURJT0hFQURFUiBhdWhkcjsKCiAgbW1pb1NlZWsoVGhpcy0+aG1taW8sIDAsIFNFRUtfU0VUKTsKICBpZiAobW1pb1JlYWQoVGhpcy0+aG1taW8sIChIUFNUUikmYXVoZHIsIHNpemVvZihhdWhkcikpICE9IHNpemVvZihhdWhkcikpCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwoKICBpZiAoYXVoZHIuZmNjVHlwZSA9PSAweDAwNjQ3MzJFKSB7CiAgICAvKiBoZWFkZXIgaW4gbGl0dGxlIGVuZGlhbiAqLwogICAgVGhpcy0+Y2tEYXRhLmR3RGF0YU9mZnNldCA9IExFMkhfRFdPUkQoYXVoZHIub2Zmc2V0KTsKICAgIFRoaXMtPmNrRGF0YS5ja3NpemUgICAgICAgPSBMRTJIX0RXT1JEKGF1aGRyLnNpemUpOwoKICAgIGF1aGRyLmVuY29kaW5nICAgPSBMRTJIX0RXT1JEKGF1aGRyLmVuY29kaW5nKTsKICAgIGF1aGRyLnNhbXBsZVJhdGUgPSBMRTJIX0RXT1JEKGF1aGRyLnNhbXBsZVJhdGUpOwogICAgYXVoZHIuY2hhbm5lbHMgICA9IExFMkhfRFdPUkQoYXVoZHIuY2hhbm5lbHMpOwogIH0gZWxzZSBpZiAoYXVoZHIuZmNjVHlwZSA9PSBtbWlvRk9VUkNDKCcuJywncycsJ24nLCdkJykpIHsKICAgIC8qIGhlYWRlciBpbiBiaWcgZW5kaWFuICovCiAgICBUaGlzLT5ja0RhdGEuZHdEYXRhT2Zmc2V0ID0gQkUySF9EV09SRChhdWhkci5vZmZzZXQpOwogICAgVGhpcy0+Y2tEYXRhLmNrc2l6ZSAgICAgICA9IEJFMkhfRFdPUkQoYXVoZHIuc2l6ZSk7CgogICAgYXVoZHIuZW5jb2RpbmcgICA9IEJFMkhfRFdPUkQoYXVoZHIuZW5jb2RpbmcpOwogICAgYXVoZHIuc2FtcGxlUmF0ZSA9IEJFMkhfRFdPUkQoYXVoZHIuc2FtcGxlUmF0ZSk7CiAgICBhdWhkci5jaGFubmVscyAgID0gQkUySF9EV09SRChhdWhkci5jaGFubmVscyk7CiAgfSBlbHNlCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwoKICBpZiAoYXVoZHIuY2hhbm5lbHMgPCAxKQogICAgcmV0dXJuIEFWSUVSUl9CQURGT1JNQVQ7CgogIC8qIGdldCBzaXplIG9mIGhlYWRlciAqLwogIHN3aXRjaChhdWhkci5lbmNvZGluZykgewogIGNhc2UgQVVfRU5DT0RJTkdfQURQQ01fRzcyMV8zMjoKICAgIFRoaXMtPmNiRm9ybWF0ID0gc2l6ZW9mKEc3MjFfQURQQ01XQVZFRk9STUFUKTsgYnJlYWs7CiAgY2FzZSBBVV9FTkNPRElOR19BRFBDTV9HNzIzXzI0OgogICAgVGhpcy0+Y2JGb3JtYXQgPSBzaXplb2YoRzcyM19BRFBDTVdBVkVGT1JNQVQpOyBicmVhazsKICBjYXNlIEFVX0VOQ09ESU5HX0FEUENNX0c3MjI6CiAgY2FzZSBBVV9FTkNPRElOR19BRFBDTV9HNzIzXzU6CiAgICBXQVJOKCJ1bnN1cHBvcnRlZCBTdW4gYXVkaW8gZm9ybWF0ICVkXG4iLCBhdWhkci5lbmNvZGluZyk7CiAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOyAvKiBGSVhNRSAqLwogIGRlZmF1bHQ6CiAgICBUaGlzLT5jYkZvcm1hdCA9IHNpemVvZihXQVZFRk9STUFURVgpOyBicmVhazsKICB9OwoKICBUaGlzLT5scEZvcm1hdCA9CiAgICAoTFBXQVZFRk9STUFURVgpR2xvYmFsQWxsb2NQdHIoR01FTV9NT1ZFQUJMRSwgVGhpcy0+Y2JGb3JtYXQpOwogIGlmIChUaGlzLT5scEZvcm1hdCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogIFRoaXMtPmxwRm9ybWF0LT5uQ2hhbm5lbHMgICAgICA9IGF1aGRyLmNoYW5uZWxzOwogIFRoaXMtPmxwRm9ybWF0LT5uU2FtcGxlc1BlclNlYyA9IGF1aGRyLnNhbXBsZVJhdGU7CiAgc3dpdGNoKGF1aGRyLmVuY29kaW5nKSB7CiAgY2FzZSBBVV9FTkNPRElOR19VTEFXXzg6CiAgICBUaGlzLT5scEZvcm1hdC0+d0Zvcm1hdFRhZyAgICAgPSBXQVZFX0ZPUk1BVF9NVUxBVzsKICAgIFRoaXMtPmxwRm9ybWF0LT53Qml0c1BlclNhbXBsZSA9IDg7CiAgICBicmVhazsKICBjYXNlIEFVX0VOQ09ESU5HX1BDTV84OgogICAgVGhpcy0+bHBGb3JtYXQtPndGb3JtYXRUYWcgICAgID0gV0FWRV9GT1JNQVRfUENNOwogICAgVGhpcy0+bHBGb3JtYXQtPndCaXRzUGVyU2FtcGxlID0gODsKICAgIGJyZWFrOwogIGNhc2UgQVVfRU5DT0RJTkdfUENNXzE2OgogICAgVGhpcy0+bHBGb3JtYXQtPndGb3JtYXRUYWcgICAgID0gV0FWRV9GT1JNQVRfUENNOwogICAgVGhpcy0+bHBGb3JtYXQtPndCaXRzUGVyU2FtcGxlID0gMTY7CiAgICBicmVhazsKICBjYXNlIEFVX0VOQ09ESU5HX1BDTV8yNDoKICAgIFRoaXMtPmxwRm9ybWF0LT53Rm9ybWF0VGFnICAgICA9IFdBVkVfRk9STUFUX1BDTTsKICAgIFRoaXMtPmxwRm9ybWF0LT53Qml0c1BlclNhbXBsZSA9IDI0OwogICAgYnJlYWs7CiAgY2FzZSBBVV9FTkNPRElOR19QQ01fMzI6CiAgICBUaGlzLT5scEZvcm1hdC0+d0Zvcm1hdFRhZyAgICAgPSBXQVZFX0ZPUk1BVF9QQ007CiAgICBUaGlzLT5scEZvcm1hdC0+d0JpdHNQZXJTYW1wbGUgPSAzMjsKICAgIGJyZWFrOwogIGNhc2UgQVVfRU5DT0RJTkdfQUxBV184OgogICAgVGhpcy0+bHBGb3JtYXQtPndGb3JtYXRUYWcgICAgID0gV0FWRV9GT1JNQVRfQUxBVzsKICAgIFRoaXMtPmxwRm9ybWF0LT53Qml0c1BlclNhbXBsZSA9IDg7CiAgICBicmVhazsKICBjYXNlIEFVX0VOQ09ESU5HX0FEUENNX0c3MjFfMzI6CiAgICBUaGlzLT5scEZvcm1hdC0+d0Zvcm1hdFRhZyAgICAgPSBXQVZFX0ZPUk1BVF9HNzIxX0FEUENNOwogICAgVGhpcy0+bHBGb3JtYXQtPndCaXRzUGVyU2FtcGxlID0gKDMqNSo4KTsKICAgIFRoaXMtPmxwRm9ybWF0LT5uQmxvY2tBbGlnbiAgICA9IDE1KjE1Kjg7CiAgICBUaGlzLT5scEZvcm1hdC0+Y2JTaXplICAgICAgICAgPSBzaXplb2YoV09SRCk7CiAgICAoKExQRzcyMV9BRFBDTVdBVkVGT1JNQVQpVGhpcy0+bHBGb3JtYXQpLT5uQXV4QmxvY2tTaXplID0gMDsKICAgIGJyZWFrOwogIGNhc2UgQVVfRU5DT0RJTkdfQURQQ01fRzcyM18yNDoKICAgIFRoaXMtPmxwRm9ybWF0LT53Rm9ybWF0VGFnICAgICA9IFdBVkVfRk9STUFUX0c3MjNfQURQQ007CiAgICBUaGlzLT5scEZvcm1hdC0+d0JpdHNQZXJTYW1wbGUgPSAoMyo1KjgpOwogICAgVGhpcy0+bHBGb3JtYXQtPm5CbG9ja0FsaWduICAgID0gMTUqMTUqODsKICAgIFRoaXMtPmxwRm9ybWF0LT5jYlNpemUgICAgICAgICA9IDIqc2l6ZW9mKFdPUkQpOwogICAgKChMUEc3MjNfQURQQ01XQVZFRk9STUFUKVRoaXMtPmxwRm9ybWF0KS0+Y2JFeHRyYVNpemUgICA9IDA7CiAgICAoKExQRzcyM19BRFBDTVdBVkVGT1JNQVQpVGhpcy0+bHBGb3JtYXQpLT5uQXV4QmxvY2tTaXplID0gMDsKICAgIGJyZWFrOwogIGRlZmF1bHQ6CiAgICBXQVJOKCJ1bnN1cHBvcnRlZCBTdW4gYXVkaW8gZm9ybWF0ICVkXG4iLCBhdWhkci5lbmNvZGluZyk7CiAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwogIH07CgogIFRoaXMtPmxwRm9ybWF0LT5uQmxvY2tBbGlnbiA9CiAgICAoVGhpcy0+bHBGb3JtYXQtPm5DaGFubmVscyAqIFRoaXMtPmxwRm9ybWF0LT53Qml0c1BlclNhbXBsZSkgLyA4OwogIGlmIChUaGlzLT5scEZvcm1hdC0+bkJsb2NrQWxpZ24gPT0gMCAmJiBUaGlzLT5scEZvcm1hdC0+d0JpdHNQZXJTYW1wbGUgPCA4KQogICAgVGhpcy0+bHBGb3JtYXQtPm5CbG9ja0FsaWduKys7CiAgVGhpcy0+bHBGb3JtYXQtPm5BdmdCeXRlc1BlclNlYyA9CiAgICBUaGlzLT5scEZvcm1hdC0+bkJsb2NrQWxpZ24gKiBUaGlzLT5scEZvcm1hdC0+blNhbXBsZXNQZXJTZWM7CgogIFRoaXMtPmZEaXJ0eSA9IDA7CgogIFRoaXMtPnNJbmZvLmZjY1R5cGUgICAgICAgICAgICAgICA9IHN0cmVhbXR5cGVBVURJTzsKICBUaGlzLT5zSW5mby5mY2NIYW5kbGVyICAgICAgICAgICAgPSAwOwogIFRoaXMtPnNJbmZvLmR3RmxhZ3MgICAgICAgICAgICAgICA9IDA7CiAgVGhpcy0+c0luZm8ud1ByaW9yaXR5ICAgICAgICAgICAgID0gMDsKICBUaGlzLT5zSW5mby53TGFuZ3VhZ2UgICAgICAgICAgICAgPSAwOwogIFRoaXMtPnNJbmZvLmR3SW5pdGlhbEZyYW1lcyAgICAgICA9IDA7CiAgVGhpcy0+c0luZm8uZHdTY2FsZSAgICAgICAgICAgICAgID0gVGhpcy0+bHBGb3JtYXQtPm5CbG9ja0FsaWduOwogIFRoaXMtPnNJbmZvLmR3UmF0ZSAgICAgICAgICAgICAgICA9IFRoaXMtPmxwRm9ybWF0LT5uQXZnQnl0ZXNQZXJTZWM7CiAgVGhpcy0+c0luZm8uZHdTdGFydCAgICAgICAgICAgICAgID0gMDsKICBUaGlzLT5zSW5mby5kd0xlbmd0aCAgICAgICAgICAgICAgPQogICAgVGhpcy0+Y2tEYXRhLmNrc2l6ZSAvIFRoaXMtPmxwRm9ybWF0LT5uQmxvY2tBbGlnbjsKICBUaGlzLT5zSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPSBUaGlzLT5zSW5mby5kd0xlbmd0aDsKICBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUgICAgICAgICAgPSBUaGlzLT5scEZvcm1hdC0+bkJsb2NrQWxpZ247CgogIFRoaXMtPmZJbmZvLmR3U3RyZWFtcyA9IDE7CiAgVGhpcy0+ZkluZm8uZHdTY2FsZSAgID0gMTsKICBUaGlzLT5mSW5mby5kd1JhdGUgICAgPSBUaGlzLT5scEZvcm1hdC0+blNhbXBsZXNQZXJTZWM7CiAgVGhpcy0+ZkluZm8uZHdMZW5ndGggID0KICAgIE11bERpdihUaGlzLT5ja0RhdGEuY2tzaXplLCBUaGlzLT5scEZvcm1hdC0+blNhbXBsZXNQZXJTZWMsCgkgICBUaGlzLT5scEZvcm1hdC0+bkF2Z0J5dGVzUGVyU2VjKTsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9TYXZlRmlsZShJQVZJRmlsZUltcGwgKlRoaXMpCnsKICBNTUNLSU5GTyBja1JJRkY7CiAgTU1DS0lORk8gY2s7CgogIG1taW9TZWVrKFRoaXMtPmhtbWlvLCAwLCBTRUVLX1NFVCk7CgogIC8qIGNyZWF0ZSB0aGUgUklGRiBjaHVuayB3aXRoIGZvcm10eXBlIFdBVkUgKi8KICBja1JJRkYuZmNjVHlwZSA9IGZvcm10eXBlV0FWRTsKICBja1JJRkYuY2tzaXplICA9IDA7CiAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJmNrUklGRiwgTU1JT19DUkVBVEVSSUZGKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogIC8qIHRoZSBuZXh0IGNodW5rIGlzIHRoZSBmb3JtYXQgKi8KICBjay5ja2lkICAgPSBja2lkV0FWRUZPUk1BVDsKICBjay5ja3NpemUgPSBUaGlzLT5jYkZvcm1hdDsKICBpZiAobW1pb0NyZWF0ZUNodW5rKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICBpZiAoVGhpcy0+bHBGb3JtYXQgIT0gTlVMTCAmJiBUaGlzLT5jYkZvcm1hdCA+IDApIHsKICAgIGlmIChtbWlvV3JpdGUoVGhpcy0+aG1taW8sIChIUFNUUilUaGlzLT5scEZvcm1hdCwgY2suY2tzaXplKSAhPSBjay5ja3NpemUpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogIH0KICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogIC8qIGZhY3QgY2h1bmsgaXMgbmVlZGVkIGZvciBub24tcGNtIHdhdmVmb3JtcyAqLwogIGlmIChUaGlzLT5scEZvcm1hdCAhPSBOVUxMICYmIFRoaXMtPmNiRm9ybWF0ID4gc2l6ZW9mKFBDTVdBVkVGT1JNQVQpICYmCiAgICAgIFRoaXMtPmxwRm9ybWF0LT53Rm9ybWF0VGFnICE9IFdBVkVfRk9STUFUX1BDTSkgewogICAgV0FWRUZPUk1BVEVYIHdmeDsKICAgIERXT1JEICAgICAgICBkd0ZhY3RMZW5ndGg7CiAgICBIQUNNU1RSRUFNICAgaGFzOwoKICAgIC8qIHRyeSB0byBvcGVuIGFuIGFwcHJvcHJpYXRlIGF1ZGlvIGNvZGVjIHRvIGZpZ3VyZSBvdXQKICAgICAqIGRhdGEgZm9yIGZhY3QtY2h1bmsgKi8KICAgIHdmeC53Rm9ybWF0VGFnID0gV0FWRV9GT1JNQVRfUENNOwogICAgaWYgKGFjbUZvcm1hdFN1Z2dlc3QoTlVMTCwgVGhpcy0+bHBGb3JtYXQsICZ3ZngsCgkJCSBzaXplb2Yod2Z4KSwgQUNNX0ZPUk1BVFNVR0dFU1RGX1dGT1JNQVRUQUcpKSB7CiAgICAgIGFjbVN0cmVhbU9wZW4oJmhhcywgTlVMTCwgVGhpcy0+bHBGb3JtYXQsICZ3ZngsIE5VTEwsCgkJICAgIDAsIDAsIEFDTV9TVFJFQU1PUEVORl9OT05SRUFMVElNRSk7CiAgICAgIGFjbVN0cmVhbVNpemUoaGFzLCBUaGlzLT5ja0RhdGEuY2tzaXplLCAmZHdGYWN0TGVuZ3RoLAoJCSAgICBBQ01fU1RSRUFNU0laRUZfU09VUkNFKTsKICAgICAgZHdGYWN0TGVuZ3RoIC89IHdmeC5uQmxvY2tBbGlnbjsKICAgICAgYWNtU3RyZWFtQ2xvc2UoaGFzLCAwKTsKCiAgICAgIC8qIGNyZWF0ZSB0aGUgZmFjdCBjaHVuayAqLwogICAgICBjay5ja2lkICAgPSBja2lkV0FWRUZBQ1Q7CiAgICAgIGNrLmNrc2l6ZSA9IHNpemVvZihkd0ZhY3RMZW5ndGgpOwoKICAgICAgLyogdGVzdCBmb3IgZW5vdWdoIHNwYWNlIGJlZm9yZSBkYXRhIGNodW5rICovCiAgICAgIGlmIChtbWlvU2VlayhUaGlzLT5obW1pbywgMCwgU0VFS19DVVIpID4gVGhpcy0+Y2tEYXRhLmR3RGF0YU9mZnNldAoJICAtIGNrLmNrc2l6ZSAtIDQgKiBzaXplb2YoRFdPUkQpKQoJcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICAgIGlmIChtbWlvQ3JlYXRlQ2h1bmsoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKCXJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgICBpZiAobW1pb1dyaXRlKFRoaXMtPmhtbWlvLCAoSFBTVFIpJmR3RmFjdExlbmd0aCwgY2suY2tzaXplKSAhPSBjay5ja3NpemUpCglyZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgICAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKCXJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgfSBlbHNlCiAgICAgIEVSUigiOiBmYWN0IGNodW5rIGlzIG5lZWRlZCBmb3Igbm9uLXBjbSBmaWxlcyAtLSBjdXJyZW50bHkgbm8gY29kZWMgZm91bmQsIHNvIHNraXBwZWQhXG4iKTsKICB9CgogIC8qIGlmIHRoZXJlIHdhcyBleHRyYSBzdHVmZiwgd2UgbmVlZCB0byBmaWxsIGl0IHdpdGggSlVOSyAqLwogIGlmIChtbWlvU2VlayhUaGlzLT5obW1pbywgMCwgU0VFS19DVVIpICsgMiAqIHNpemVvZihEV09SRCkgPCBUaGlzLT5ja0RhdGEuZHdEYXRhT2Zmc2V0KSB7CiAgICBjay5ja2lkICAgPSBja2lkQVZJUEFERElORzsKICAgIGNrLmNrc2l6ZSA9IDA7CiAgICBpZiAobW1pb0NyZWF0ZUNodW5rKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAgIGlmIChtbWlvU2VlayhUaGlzLT5obW1pbywgVGhpcy0+Y2tEYXRhLmR3RGF0YU9mZnNldAoJCSAtIDIgKiBzaXplb2YoRFdPUkQpLCBTRUVLX1NFVCkgPT0gLTEpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgfQoKICAvKiBjcmVhdGUgdGhlIGRhdGEgY2h1bmsgKi8KICBjay5ja2lkICAgPSBja2lkV0FWRURBVEE7CiAgY2suY2tzaXplID0gVGhpcy0+Y2tEYXRhLmNrc2l6ZTsKICBpZiAobW1pb0NyZWF0ZUNodW5rKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICBpZiAobW1pb1NlZWsoVGhpcy0+aG1taW8sIFRoaXMtPmNrRGF0YS5ja3NpemUsIFNFRUtfQ1VSKSA9PSAtMSkKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgLyogc29tZSBvcHRpb25hbCBleHRyYSBjaHVua3M/ICovCiAgaWYgKFRoaXMtPmV4dHJhLmxwICE9IE5VTEwgJiYgVGhpcy0+ZXh0cmEuY2IgPiAwKSB7CiAgICAvKiBjaHVuayBoZWFkZXJzIGFyZSBhbHJlYWR5IGluIHN0cnVjdHVyZSAqLwogICAgaWYgKG1taW9Xcml0ZShUaGlzLT5obW1pbywgVGhpcy0+ZXh0cmEubHAsIFRoaXMtPmV4dHJhLmNiKSAhPSBUaGlzLT5leHRyYS5jYikKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgfQoKICAvKiBjbG9zZSBSSUZGIGNodW5rICovCiAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZja1JJRkYsIDApICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICBpZiAobW1pb0ZsdXNoKFRoaXMtPmhtbWlvLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogIHJldHVybiBBVklFUlJfT0s7Cn0K