LyoKICogUlBDIHNlcnZlciBBUEkKICoKICogQ29weXJpZ2h0IDIwMDEgT3ZlIEvldmVuLCBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMKICogQ29weXJpZ2h0IDIwMDQgRmlsaXAgTmF2YXJhCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKgogKiBUT0RPOgogKiAgLSBhIHdob2xlIGxvdAogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgIndpbmUvcG9ydC5oIgoKI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8YXNzZXJ0Lmg+CgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAid2lucmVnLmgiCiNpbmNsdWRlICJudHN0YXR1cy5oIgoKI2luY2x1ZGUgInJwYy5oIgojaW5jbHVkZSAicnBjbmRyLmgiCiNpbmNsdWRlICJleGNwdC5oIgoKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKI2luY2x1ZGUgIndpbmUvZXhjZXB0aW9uLmgiCgojaW5jbHVkZSAicnBjX3NlcnZlci5oIgojaW5jbHVkZSAicnBjX21pc2MuaCIKI2luY2x1ZGUgInJwY19tZXNzYWdlLmgiCiNpbmNsdWRlICJycGNfZGVmcy5oIgoKI2RlZmluZSBNQVhfVEhSRUFEUyAxMjgKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKHJwYyk7Cgp0eXBlZGVmIHN0cnVjdCBfUnBjUGFja2V0CnsKICBzdHJ1Y3QgX1JwY1BhY2tldCogbmV4dDsKICBzdHJ1Y3QgX1JwY0Nvbm5lY3Rpb24qIGNvbm47CiAgUnBjUGt0SGRyKiBoZHI7CiAgUlBDX01FU1NBR0UqIG1zZzsKfSBScGNQYWNrZXQ7Cgp0eXBlZGVmIHN0cnVjdCBfUnBjT2JqVHlwZU1hcAp7CiAgLyogRklYTUU6IGEgaGFzaCB0YWJsZSB3b3VsZCBiZSBiZXR0ZXIuICovCiAgc3RydWN0IF9ScGNPYmpUeXBlTWFwICpuZXh0OwogIFVVSUQgT2JqZWN0OwogIFVVSUQgVHlwZTsKfSBScGNPYmpUeXBlTWFwOwoKc3RhdGljIFJwY09ialR5cGVNYXAgKlJwY09ialR5cGVNYXBzOwoKc3RhdGljIFJwY1NlcnZlclByb3RzZXEqIHByb3RzZXFzOwpzdGF0aWMgUnBjU2VydmVySW50ZXJmYWNlKiBpZnM7CgpzdGF0aWMgQ1JJVElDQUxfU0VDVElPTiBzZXJ2ZXJfY3M7CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OX0RFQlVHIHNlcnZlcl9jc19kZWJ1ZyA9CnsKICAgIDAsIDAsICZzZXJ2ZXJfY3MsCiAgICB7ICZzZXJ2ZXJfY3NfZGVidWcuUHJvY2Vzc0xvY2tzTGlzdCwgJnNlcnZlcl9jc19kZWJ1Zy5Qcm9jZXNzTG9ja3NMaXN0IH0sCiAgICAgIDAsIDAsIHsgMCwgKERXT1JEKShfX0ZJTEVfXyAiOiBzZXJ2ZXJfY3MiKSB9Cn07CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OIHNlcnZlcl9jcyA9IHsgJnNlcnZlcl9jc19kZWJ1ZywgLTEsIDAsIDAsIDAsIDAgfTsKCnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OIGxpc3Rlbl9jczsKc3RhdGljIENSSVRJQ0FMX1NFQ1RJT05fREVCVUcgbGlzdGVuX2NzX2RlYnVnID0KewogICAgMCwgMCwgJmxpc3Rlbl9jcywKICAgIHsgJmxpc3Rlbl9jc19kZWJ1Zy5Qcm9jZXNzTG9ja3NMaXN0LCAmbGlzdGVuX2NzX2RlYnVnLlByb2Nlc3NMb2Nrc0xpc3QgfSwKICAgICAgMCwgMCwgeyAwLCAoRFdPUkQpKF9fRklMRV9fICI6IGxpc3Rlbl9jcyIpIH0KfTsKc3RhdGljIENSSVRJQ0FMX1NFQ1RJT04gbGlzdGVuX2NzID0geyAmbGlzdGVuX2NzX2RlYnVnLCAtMSwgMCwgMCwgMCwgMCB9OwoKLyogd2hldGhlciB0aGUgc2VydmVyIGlzIGN1cnJlbnRseSBsaXN0ZW5pbmcgKi8Kc3RhdGljIEJPT0wgc3RkX2xpc3RlbjsKLyogbnVtYmVyIG9mIG1hbnVhbCBsaXN0ZW5lcnMgKGNhbGxzIHRvIFJwY1NlcnZlckxpc3RlbikgKi8Kc3RhdGljIExPTkcgbWFudWFsX2xpc3Rlbl9jb3VudDsKLyogdG90YWwgbGlzdGVuZXJzIGluY2x1ZGluZyBhdXRvIGxpc3RlbmVycyAqLwpzdGF0aWMgTE9ORyBsaXN0ZW5fY291bnQ7Ci8qIHNldCBvbiBjaGFuZ2Ugb2YgY29uZmlndXJhdGlvbiAoZS5nLiBsaXN0ZW5pbmcgb24gbmV3IHByb3RzZXEpICovCnN0YXRpYyBIQU5ETEUgbWdyX2V2ZW50OwovKiBtdXRleCBmb3IgZW5zdXJpbmcgb25seSBvbmUgdGhyZWFkIGNhbiBjaGFuZ2Ugc3RhdGUgYXQgYSB0aW1lICovCnN0YXRpYyBIQU5ETEUgbWdyX211dGV4OwovKiBzZXQgd2hlbiBzZXJ2ZXIgdGhyZWFkIGhhcyBmaW5pc2hlZCBvcGVuaW5nIGNvbm5lY3Rpb25zICovCnN0YXRpYyBIQU5ETEUgc2VydmVyX3JlYWR5X2V2ZW50OwovKiB0aHJlYWQgdGhhdCB3YWl0cyBmb3IgY29ubmVjdGlvbnMgKi8Kc3RhdGljIEhBTkRMRSBzZXJ2ZXJfdGhyZWFkOwoKc3RhdGljIENSSVRJQ0FMX1NFQ1RJT04gc3BhY2tldF9jczsKc3RhdGljIENSSVRJQ0FMX1NFQ1RJT05fREVCVUcgc3BhY2tldF9jc19kZWJ1ZyA9CnsKICAgIDAsIDAsICZzcGFja2V0X2NzLAogICAgeyAmc3BhY2tldF9jc19kZWJ1Zy5Qcm9jZXNzTG9ja3NMaXN0LCAmc3BhY2tldF9jc19kZWJ1Zy5Qcm9jZXNzTG9ja3NMaXN0IH0sCiAgICAgIDAsIDAsIHsgMCwgKERXT1JEKShfX0ZJTEVfXyAiOiBzcGFja2V0X2NzIikgfQp9OwpzdGF0aWMgQ1JJVElDQUxfU0VDVElPTiBzcGFja2V0X2NzID0geyAmc3BhY2tldF9jc19kZWJ1ZywgLTEsIDAsIDAsIDAsIDAgfTsKCnN0YXRpYyBScGNQYWNrZXQqIHNwYWNrZXRfaGVhZDsKc3RhdGljIFJwY1BhY2tldCogc3BhY2tldF90YWlsOwpzdGF0aWMgSEFORExFIHNlcnZlcl9zZW07CgpzdGF0aWMgRFdPUkQgd29ya2VyX2NvdW50LCB3b3JrZXJfZnJlZSwgd29ya2VyX3RsczsKCnN0YXRpYyBVVUlEIHV1aWRfbmlsOwoKaW5saW5lIHN0YXRpYyBScGNPYmpUeXBlTWFwICpMb29rdXBPYmpUeXBlTWFwKFVVSUQgKk9ialV1aWQpCnsKICBScGNPYmpUeXBlTWFwICpyc2x0ID0gUnBjT2JqVHlwZU1hcHM7CiAgUlBDX1NUQVRVUyBkdW1teTsKCiAgd2hpbGUgKHJzbHQpIHsKICAgIGlmICghIFV1aWRDb21wYXJlKE9ialV1aWQsICZyc2x0LT5PYmplY3QsICZkdW1teSkpIGJyZWFrOwogICAgcnNsdCA9IHJzbHQtPm5leHQ7CiAgfQoKICByZXR1cm4gcnNsdDsKfQoKaW5saW5lIHN0YXRpYyBVVUlEICpMb29rdXBPYmpUeXBlKFVVSUQgKk9ialV1aWQpCnsKICBScGNPYmpUeXBlTWFwICptYXAgPSBMb29rdXBPYmpUeXBlTWFwKE9ialV1aWQpOwogIGlmIChtYXApCiAgICByZXR1cm4gJm1hcC0+VHlwZTsKICBlbHNlCiAgICByZXR1cm4gJnV1aWRfbmlsOwp9CgpzdGF0aWMgUnBjU2VydmVySW50ZXJmYWNlKiBSUENSVDRfZmluZF9pbnRlcmZhY2UoVVVJRCogb2JqZWN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUlBDX1NZTlRBWF9JREVOVElGSUVSKiBpZl9pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJPT0wgY2hlY2tfb2JqZWN0KQp7CiAgVVVJRCogTWdyVHlwZSA9IE5VTEw7CiAgUnBjU2VydmVySW50ZXJmYWNlKiBjaWYgPSBOVUxMOwogIFJQQ19TVEFUVVMgc3RhdHVzOwoKICBpZiAoY2hlY2tfb2JqZWN0KQogICAgTWdyVHlwZSA9IExvb2t1cE9ialR5cGUob2JqZWN0KTsKICBFbnRlckNyaXRpY2FsU2VjdGlvbigmc2VydmVyX2NzKTsKICBjaWYgPSBpZnM7CiAgd2hpbGUgKGNpZikgewogICAgaWYgKCFtZW1jbXAoaWZfaWQsICZjaWYtPklmLT5JbnRlcmZhY2VJZCwgc2l6ZW9mKFJQQ19TWU5UQVhfSURFTlRJRklFUikpICYmCiAgICAgICAgKGNoZWNrX29iamVjdCA9PSBGQUxTRSB8fCBVdWlkRXF1YWwoTWdyVHlwZSwgJmNpZi0+TWdyVHlwZVV1aWQsICZzdGF0dXMpKSAmJgogICAgICAgIHN0ZF9saXN0ZW4pIGJyZWFrOwogICAgY2lmID0gY2lmLT5OZXh0OwogIH0KICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmc2VydmVyX2NzKTsKICBUUkFDRSgicmV0dXJuaW5nICVwIGZvciAlc1xuIiwgY2lmLCBkZWJ1Z3N0cl9ndWlkKG9iamVjdCkpOwogIHJldHVybiBjaWY7Cn0KCnN0YXRpYyB2b2lkIFJQQ1JUNF9wdXNoX3BhY2tldChScGNQYWNrZXQqIHBhY2tldCkKewogIHBhY2tldC0+bmV4dCA9IE5VTEw7CiAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnNwYWNrZXRfY3MpOwogIGlmIChzcGFja2V0X3RhaWwpIHsKICAgIHNwYWNrZXRfdGFpbC0+bmV4dCA9IHBhY2tldDsKICAgIHNwYWNrZXRfdGFpbCA9IHBhY2tldDsKICB9IGVsc2UgewogICAgc3BhY2tldF9oZWFkID0gcGFja2V0OwogICAgc3BhY2tldF90YWlsID0gcGFja2V0OwogIH0KICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmc3BhY2tldF9jcyk7Cn0KCnN0YXRpYyBScGNQYWNrZXQqIFJQQ1JUNF9wb3BfcGFja2V0KHZvaWQpCnsKICBScGNQYWNrZXQqIHBhY2tldDsKICBFbnRlckNyaXRpY2FsU2VjdGlvbigmc3BhY2tldF9jcyk7CiAgcGFja2V0ID0gc3BhY2tldF9oZWFkOwogIGlmIChwYWNrZXQpIHsKICAgIHNwYWNrZXRfaGVhZCA9IHBhY2tldC0+bmV4dDsKICAgIGlmICghc3BhY2tldF9oZWFkKSBzcGFja2V0X3RhaWwgPSBOVUxMOwogIH0KICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmc3BhY2tldF9jcyk7CiAgaWYgKHBhY2tldCkgcGFja2V0LT5uZXh0ID0gTlVMTDsKICByZXR1cm4gcGFja2V0Owp9Cgp0eXBlZGVmIHN0cnVjdCB7CiAgUFJQQ19NRVNTQUdFIG1zZzsKICB2b2lkKiBidWY7Cn0gcGFja2V0X3N0YXRlOwoKc3RhdGljIFdJTkVfRVhDRVBUSU9OX0ZJTFRFUihycGNfZmlsdGVyKQp7CiAgcGFja2V0X3N0YXRlKiBzdGF0ZTsKICBQUlBDX01FU1NBR0UgbXNnOwogIHN0YXRlID0gVGxzR2V0VmFsdWUod29ya2VyX3Rscyk7CiAgbXNnID0gc3RhdGUtPm1zZzsKICBpZiAobXNnLT5CdWZmZXIgIT0gc3RhdGUtPmJ1ZikgSV9ScGNGcmVlQnVmZmVyKG1zZyk7CiAgbXNnLT5ScGNGbGFncyB8PSBXSU5FX1JQQ0ZMQUdfRVhDRVBUSU9OOwogIG1zZy0+QnVmZmVyTGVuZ3RoID0gc2l6ZW9mKERXT1JEKTsKICBJX1JwY0dldEJ1ZmZlcihtc2cpOwogICooRFdPUkQqKW1zZy0+QnVmZmVyID0gR2V0RXhjZXB0aW9uQ29kZSgpOwogIFdBUk4oImV4Y2VwdGlvbiBjYXVnaHQgd2l0aCBjb2RlIDB4JTA4bHggPSAlbGRcbiIsICooRFdPUkQqKW1zZy0+QnVmZmVyLCAqKERXT1JEKiltc2ctPkJ1ZmZlcik7CiAgVFJBQ0UoInJldHVybmluZyBmYWlsdXJlIHBhY2tldFxuIik7CiAgcmV0dXJuIEVYQ0VQVElPTl9FWEVDVVRFX0hBTkRMRVI7Cn0KCnN0YXRpYyB2b2lkIFJQQ1JUNF9wcm9jZXNzX3BhY2tldChScGNDb25uZWN0aW9uKiBjb25uLCBScGNQa3RIZHIqIGhkciwgUlBDX01FU1NBR0UqIG1zZykKewogIFJwY1NlcnZlckludGVyZmFjZSogc2lmOwogIFJQQ19ESVNQQVRDSF9GVU5DVElPTiBmdW5jOwogIHBhY2tldF9zdGF0ZSBzdGF0ZTsKICBVVUlEICpvYmplY3RfdXVpZDsKICBScGNQa3RIZHIgKnJlc3BvbnNlOwogIHZvaWQgKmJ1ZiA9IG1zZy0+QnVmZmVyOwogIFJQQ19TVEFUVVMgc3RhdHVzOwoKICBzdGF0ZS5tc2cgPSBtc2c7CiAgc3RhdGUuYnVmID0gYnVmOwogIFRsc1NldFZhbHVlKHdvcmtlcl90bHMsICZzdGF0ZSk7CgogIHN3aXRjaCAoaGRyLT5jb21tb24ucHR5cGUpIHsKICAgIGNhc2UgUEtUX0JJTkQ6CiAgICAgIFRSQUNFKCJnb3QgYmluZCBwYWNrZXRcbiIpOwoKICAgICAgLyogRklYTUU6IGRvIG1vcmUgY2hlY2tzISAqLwogICAgICBpZiAoaGRyLT5iaW5kLm1heF90c2l6ZSA8IFJQQ19NSU5fUEFDS0VUX1NJWkUgfHwKICAgICAgICAgICFVdWlkSXNOaWwoJmNvbm4tPkFjdGl2ZUludGVyZmFjZS5TeW50YXhHVUlELCAmc3RhdHVzKSkgewogICAgICAgIFRSQUNFKCJwYWNrZXQgc2l6ZSBsZXNzIHRoYW4gbWluIHNpemUsIG9yIGFjdGl2ZSBpbnRlcmZhY2Ugc3ludGF4IGd1aWQgbm9uLW51bGxcbiIpOwogICAgICAgIHNpZiA9IE5VTEw7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgc2lmID0gUlBDUlQ0X2ZpbmRfaW50ZXJmYWNlKE5VTEwsICZoZHItPmJpbmQuYWJzdHJhY3QsIEZBTFNFKTsKICAgICAgfQogICAgICBpZiAoc2lmID09IE5VTEwpIHsKICAgICAgICBUUkFDRSgicmVqZWN0aW5nIGJpbmQgcmVxdWVzdCBvbiBjb25uZWN0aW9uICVwXG4iLCBjb25uKTsKICAgICAgICAvKiBSZXBvcnQgZmFpbHVyZSB0byBjbGllbnQuICovCiAgICAgICAgcmVzcG9uc2UgPSBSUENSVDRfQnVpbGRCaW5kTmFja0hlYWRlcihORFJfTE9DQUxfREFUQV9SRVBSRVNFTlRBVElPTiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJQQ19WRVJfTUFKT1IsIFJQQ19WRVJfTUlOT1IpOwogICAgICB9IGVsc2UgewogICAgICAgIFRSQUNFKCJhY2NlcHRpbmcgYmluZCByZXF1ZXN0IG9uIGNvbm5lY3Rpb24gJXBcbiIsIGNvbm4pOwoKICAgICAgICAvKiBhY2NlcHQuICovCiAgICAgICAgcmVzcG9uc2UgPSBSUENSVDRfQnVpbGRCaW5kQWNrSGVhZGVyKE5EUl9MT0NBTF9EQVRBX1JFUFJFU0VOVEFUSU9OLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSUENfTUFYX1BBQ0tFVF9TSVpFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSUENfTUFYX1BBQ0tFVF9TSVpFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uLT5FbmRwb2ludCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVTVUxUX0FDQ0VQVCwgTk9fUkVBU09OLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc2lmLT5JZi0+VHJhbnNmZXJTeW50YXgpOwoKICAgICAgICAvKiBzYXZlIHRoZSBpbnRlcmZhY2UgZm9yIGxhdGVyIHVzZSAqLwogICAgICAgIGNvbm4tPkFjdGl2ZUludGVyZmFjZSA9IGhkci0+YmluZC5hYnN0cmFjdDsKICAgICAgICBjb25uLT5NYXhUcmFuc21pc3Npb25TaXplID0gaGRyLT5iaW5kLm1heF90c2l6ZTsKICAgICAgfQoKICAgICAgaWYgKFJQQ1JUNF9TZW5kKGNvbm4sIHJlc3BvbnNlLCBOVUxMLCAwKSAhPSBSUENfU19PSykKICAgICAgICBnb3RvIGZhaWw7CgogICAgICBicmVhazsKCiAgICBjYXNlIFBLVF9SRVFVRVNUOgogICAgICBUUkFDRSgiZ290IHJlcXVlc3QgcGFja2V0XG4iKTsKCiAgICAgIC8qIGZhaWwgaWYgdGhlIGNvbm5lY3Rpb24gaXNuJ3QgYm91bmQgd2l0aCBhbiBpbnRlcmZhY2UgKi8KICAgICAgaWYgKFV1aWRJc05pbCgmY29ubi0+QWN0aXZlSW50ZXJmYWNlLlN5bnRheEdVSUQsICZzdGF0dXMpKSB7CiAgICAgICAgcmVzcG9uc2UgPSBSUENSVDRfQnVpbGRGYXVsdEhlYWRlcihORFJfTE9DQUxfREFUQV9SRVBSRVNFTlRBVElPTiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1cyk7CgogICAgICAgIFJQQ1JUNF9TZW5kKGNvbm4sIHJlc3BvbnNlLCBOVUxMLCAwKTsKICAgICAgICBicmVhazsKICAgICAgfQoKICAgICAgaWYgKGhkci0+Y29tbW9uLmZsYWdzICYgUlBDX0ZMR19PQkpFQ1RfVVVJRCkgewogICAgICAgIG9iamVjdF91dWlkID0gKFVVSUQqKSgmaGRyLT5yZXF1ZXN0ICsgMSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgb2JqZWN0X3V1aWQgPSBOVUxMOwogICAgICB9CgogICAgICBzaWYgPSBSUENSVDRfZmluZF9pbnRlcmZhY2Uob2JqZWN0X3V1aWQsICZjb25uLT5BY3RpdmVJbnRlcmZhY2UsIFRSVUUpOwogICAgICBtc2ctPlJwY0ludGVyZmFjZUluZm9ybWF0aW9uID0gc2lmLT5JZjsKICAgICAgLyogY29weSB0aGUgZW5kcG9pbnQgdmVjdG9yIGZyb20gc2lmIHRvIG1zZyBzbyB0aGF0IG1pZGwtZ2VuZXJhdGVkIGNvZGUgd2lsbCB1c2UgaXQgKi8KICAgICAgbXNnLT5NYW5hZ2VyRXB2ID0gc2lmLT5NZ3JFcHY7CiAgICAgIGlmIChvYmplY3RfdXVpZCAhPSBOVUxMKSB7CiAgICAgICAgUlBDUlQ0X1NldEJpbmRpbmdPYmplY3QobXNnLT5IYW5kbGUsIG9iamVjdF91dWlkKTsKICAgICAgfQoKICAgICAgLyogZmluZCBkaXNwYXRjaCBmdW5jdGlvbiAqLwogICAgICBtc2ctPlByb2NOdW0gPSBoZHItPnJlcXVlc3Qub3BudW07CiAgICAgIGlmIChzaWYtPkZsYWdzICYgUlBDX0lGX09MRSkgewogICAgICAgIC8qIG5hdGl2ZSBvbGUzMiBhbHdheXMgZ2l2ZXMgdXMgYSBkaXNwYXRjaCB0YWJsZSB3aXRoIGEgc2luZ2xlIGVudHJ5CiAgICAgICAgICogKEkgYXNzdW1lIHRoYXQncyBhIHdyYXBwZXIgZm9yIElScGNTdHViQnVmZmVyOjpJbnZva2UpICovCiAgICAgICAgZnVuYyA9ICpzaWYtPklmLT5EaXNwYXRjaFRhYmxlLT5EaXNwYXRjaFRhYmxlOwogICAgICB9IGVsc2UgewogICAgICAgIGlmIChtc2ctPlByb2NOdW0gPj0gc2lmLT5JZi0+RGlzcGF0Y2hUYWJsZS0+RGlzcGF0Y2hUYWJsZUNvdW50KSB7CiAgICAgICAgICBFUlIoImludmFsaWQgcHJvY251bVxuIik7CiAgICAgICAgICBmdW5jID0gTlVMTDsKICAgICAgICB9CiAgICAgICAgZnVuYyA9IHNpZi0+SWYtPkRpc3BhdGNoVGFibGUtPkRpc3BhdGNoVGFibGVbbXNnLT5Qcm9jTnVtXTsKICAgICAgfQoKICAgICAgLyogcHV0IGluIHRoZSBkcmVwLiBGSVhNRTogaXMgdGhpcyBtb3JlIHVuaXZlcnNhbGx5IGFwcGxpY2FibGU/CiAgICAgICAgIHBlcmhhcHMgd2Ugc2hvdWxkIG1vdmUgdGhpcyBvdXR3YXJkLi4uICovCiAgICAgIG1zZy0+RGF0YVJlcHJlc2VudGF0aW9uID0gCiAgICAgICAgTUFLRUxPTkcoIE1BS0VXT1JEKGhkci0+Y29tbW9uLmRyZXBbMF0sIGhkci0+Y29tbW9uLmRyZXBbMV0pLAogICAgICAgICAgICAgICAgICBNQUtFV09SRChoZHItPmNvbW1vbi5kcmVwWzJdLCBoZHItPmNvbW1vbi5kcmVwWzNdKSk7CgogICAgICAvKiBkaXNwYXRjaCAqLwogICAgICBfX1RSWSB7CiAgICAgICAgaWYgKGZ1bmMpIGZ1bmMobXNnKTsKICAgICAgfSBfX0VYQ0VQVChycGNfZmlsdGVyKSB7CiAgICAgICAgLyogZmFpbHVyZSBwYWNrZXQgd2FzIGNyZWF0ZWQgaW4gcnBjX2ZpbHRlciAqLwogICAgICB9IF9fRU5EVFJZCgogICAgICAvKiBzZW5kIHJlc3BvbnNlIHBhY2tldCAqLwogICAgICBJX1JwY1NlbmQobXNnKTsKCiAgICAgIG1zZy0+UnBjSW50ZXJmYWNlSW5mb3JtYXRpb24gPSBOVUxMOwoKICAgICAgYnJlYWs7CgogICAgZGVmYXVsdDoKICAgICAgRklYTUUoInVuaGFuZGxlZCBwYWNrZXQgdHlwZVxuIik7CiAgICAgIGJyZWFrOwogIH0KCmZhaWw6CiAgLyogY2xlYW4gdXAgKi8KICBpZiAobXNnLT5CdWZmZXIgPT0gYnVmKSBtc2ctPkJ1ZmZlciA9IE5VTEw7CiAgVFJBQ0UoImZyZWVpbmcgQnVmZmVyPSVwXG4iLCBidWYpOwogIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGJ1Zik7CiAgUlBDUlQ0X0Rlc3Ryb3lCaW5kaW5nKG1zZy0+SGFuZGxlKTsKICBtc2ctPkhhbmRsZSA9IDA7CiAgSV9ScGNGcmVlQnVmZmVyKG1zZyk7CiAgbXNnLT5CdWZmZXIgPSBOVUxMOwogIFJQQ1JUNF9GcmVlSGVhZGVyKGhkcik7CiAgVGxzU2V0VmFsdWUod29ya2VyX3RscywgTlVMTCk7Cn0KCnN0YXRpYyBEV09SRCBDQUxMQkFDSyBSUENSVDRfd29ya2VyX3RocmVhZChMUFZPSUQgdGhlX2FyZykKewogIERXT1JEIG9iajsKICBScGNQYWNrZXQqIHBrdDsKCiAgZm9yICg7OykgewogICAgLyogaWRsZSB0aW1lb3V0IGFmdGVyIDVzICovCiAgICBvYmogPSBXYWl0Rm9yU2luZ2xlT2JqZWN0KHNlcnZlcl9zZW0sIDUwMDApOwogICAgaWYgKG9iaiA9PSBXQUlUX1RJTUVPVVQpIHsKICAgICAgLyogaWYgYW5vdGhlciBpZGxlIHRocmVhZCBleGlzdCwgc2VsZi1kZXN0cnVjdCAqLwogICAgICBpZiAod29ya2VyX2ZyZWUgPiAxKSBicmVhazsKICAgICAgY29udGludWU7CiAgICB9CiAgICBwa3QgPSBSUENSVDRfcG9wX3BhY2tldCgpOwogICAgaWYgKCFwa3QpIGNvbnRpbnVlOwogICAgSW50ZXJsb2NrZWREZWNyZW1lbnQoJndvcmtlcl9mcmVlKTsKICAgIGZvciAoOzspIHsKICAgICAgUlBDUlQ0X3Byb2Nlc3NfcGFja2V0KHBrdC0+Y29ubiwgcGt0LT5oZHIsIHBrdC0+bXNnKTsKICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcGt0KTsKICAgICAgLyogdHJ5IHRvIGdyYWIgYW5vdGhlciBwYWNrZXQgaGVyZSB3aXRob3V0IHdhaXRpbmcKICAgICAgICogb24gdGhlIHNlbWFwaG9yZSwgaW4gY2FzZSBpdCBoaXRzIG1heCAqLwogICAgICBwa3QgPSBSUENSVDRfcG9wX3BhY2tldCgpOwogICAgICBpZiAoIXBrdCkgYnJlYWs7CiAgICAgIC8qIGRlY3JlbWVudCBzZW1hcGhvcmUgKi8KICAgICAgV2FpdEZvclNpbmdsZU9iamVjdChzZXJ2ZXJfc2VtLCAwKTsKICAgIH0KICAgIEludGVybG9ja2VkSW5jcmVtZW50KCZ3b3JrZXJfZnJlZSk7CiAgfQogIEludGVybG9ja2VkRGVjcmVtZW50KCZ3b3JrZXJfZnJlZSk7CiAgSW50ZXJsb2NrZWREZWNyZW1lbnQoJndvcmtlcl9jb3VudCk7CiAgcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIFJQQ1JUNF9jcmVhdGVfd29ya2VyX2lmX25lZWRlZCh2b2lkKQp7CiAgaWYgKCF3b3JrZXJfZnJlZSAmJiB3b3JrZXJfY291bnQgPCBNQVhfVEhSRUFEUykgewogICAgSEFORExFIHRocmVhZDsKICAgIEludGVybG9ja2VkSW5jcmVtZW50KCZ3b3JrZXJfY291bnQpOwogICAgSW50ZXJsb2NrZWRJbmNyZW1lbnQoJndvcmtlcl9mcmVlKTsKICAgIHRocmVhZCA9IENyZWF0ZVRocmVhZChOVUxMLCAwLCBSUENSVDRfd29ya2VyX3RocmVhZCwgTlVMTCwgMCwgTlVMTCk7CiAgICBpZiAodGhyZWFkKSBDbG9zZUhhbmRsZSh0aHJlYWQpOwogICAgZWxzZSB7CiAgICAgIEludGVybG9ja2VkRGVjcmVtZW50KCZ3b3JrZXJfZnJlZSk7CiAgICAgIEludGVybG9ja2VkRGVjcmVtZW50KCZ3b3JrZXJfY291bnQpOwogICAgfQogIH0KfQoKc3RhdGljIERXT1JEIENBTExCQUNLIFJQQ1JUNF9pb190aHJlYWQoTFBWT0lEIHRoZV9hcmcpCnsKICBScGNDb25uZWN0aW9uKiBjb25uID0gKFJwY0Nvbm5lY3Rpb24qKXRoZV9hcmc7CiAgUnBjUGt0SGRyICpoZHI7CiAgUnBjQmluZGluZyAqcGJpbmQ7CiAgUlBDX01FU1NBR0UgKm1zZzsKICBSUENfU1RBVFVTIHN0YXR1czsKICBScGNQYWNrZXQgKnBhY2tldDsKCiAgVFJBQ0UoIiglcClcbiIsIGNvbm4pOwoKICBmb3IgKDs7KSB7CiAgICBtc2cgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKFJQQ19NRVNTQUdFKSk7CgogICAgLyogY3JlYXRlIHRlbXBvcmFyeSBiaW5kaW5nIGZvciBkaXNwYXRjaCwgaXQgd2lsbCBiZSBmcmVlZCBpbgogICAgICogUlBDUlQ0X3Byb2Nlc3NfcGFja2V0ICovCiAgICBSUENSVDRfTWFrZUJpbmRpbmcoJnBiaW5kLCBjb25uKTsKICAgIG1zZy0+SGFuZGxlID0gKFJQQ19CSU5ESU5HX0hBTkRMRSlwYmluZDsKCiAgICBzdGF0dXMgPSBSUENSVDRfUmVjZWl2ZShjb25uLCAmaGRyLCBtc2cpOwogICAgaWYgKHN0YXR1cyAhPSBSUENfU19PSykgewogICAgICBXQVJOKCJyZWNlaXZlIGZhaWxlZCB3aXRoIGVycm9yICVseFxuIiwgc3RhdHVzKTsKICAgICAgYnJlYWs7CiAgICB9CgojaWYgMAogICAgUlBDUlQ0X3Byb2Nlc3NfcGFja2V0KGNvbm4sIGhkciwgbXNnKTsKI2Vsc2UKICAgIHBhY2tldCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoUnBjUGFja2V0KSk7CiAgICBwYWNrZXQtPmNvbm4gPSBjb25uOwogICAgcGFja2V0LT5oZHIgPSBoZHI7CiAgICBwYWNrZXQtPm1zZyA9IG1zZzsKICAgIFJQQ1JUNF9jcmVhdGVfd29ya2VyX2lmX25lZWRlZCgpOwogICAgUlBDUlQ0X3B1c2hfcGFja2V0KHBhY2tldCk7CiAgICBSZWxlYXNlU2VtYXBob3JlKHNlcnZlcl9zZW0sIDEsIE5VTEwpOwojZW5kaWYKICAgIG1zZyA9IE5VTEw7CiAgfQogIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG1zZyk7CiAgUlBDUlQ0X0Rlc3Ryb3lDb25uZWN0aW9uKGNvbm4pOwogIHJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBSUENSVDRfbmV3X2NsaWVudChScGNDb25uZWN0aW9uKiBjb25uKQp7CiAgSEFORExFIHRocmVhZCA9IENyZWF0ZVRocmVhZChOVUxMLCAwLCBSUENSVDRfaW9fdGhyZWFkLCBjb25uLCAwLCBOVUxMKTsKICBpZiAoIXRocmVhZCkgewogICAgRFdPUkQgZXJyID0gR2V0TGFzdEVycm9yKCk7CiAgICBFUlIoImZhaWxlZCB0byBjcmVhdGUgdGhyZWFkLCBlcnJvcj0lMDhseFxuIiwgZXJyKTsKICAgIFJQQ1JUNF9EZXN0cm95Q29ubmVjdGlvbihjb25uKTsKICB9CiAgLyogd2UgY291bGQgc2V0IGNvbm4tPnRocmVhZCwgYnV0IHRoZW4gd2UnZCBoYXZlIHRvIG1ha2UgdGhlIGlvX3RocmVhZCB3YWl0CiAgICogZm9yIHRoYXQsIG90aGVyd2lzZSB0aGUgdGhyZWFkIG1pZ2h0IGZpbmlzaCwgZGVzdHJveSB0aGUgY29ubmVjdGlvbiwgYW5kCiAgICogZnJlZSB0aGUgbWVtb3J5IHdlJ2Qgd3JpdGUgdG8gYmVmb3JlIHdlIGRpZCwgY2F1c2luZyBjcmFzaGVzIGFuZCBzdHVmZiAtCiAgICogc28gbGV0J3MgaW1wbGVtZW50IHRoYXQgbGF0ZXIsIHdoZW4gd2UgcmVhbGx5IG5lZWQgY29ubi0+dGhyZWFkICovCgogIENsb3NlSGFuZGxlKCB0aHJlYWQgKTsKfQoKc3RhdGljIERXT1JEIENBTExCQUNLIFJQQ1JUNF9zZXJ2ZXJfdGhyZWFkKExQVk9JRCB0aGVfYXJnKQp7CiAgSEFORExFIG1fZXZlbnQgPSBtZ3JfZXZlbnQsIGJfaGFuZGxlOwogIEhBTkRMRSAqb2JqcyA9IE5VTEw7CiAgRFdPUkQgY291bnQsIHJlczsKICBScGNTZXJ2ZXJQcm90c2VxKiBjcHM7CiAgUnBjQ29ubmVjdGlvbiogY29ubjsKICBScGNDb25uZWN0aW9uKiBjY29ubjsKICBCT09MIHNldF9yZWFkeV9ldmVudCA9IEZBTFNFOwoKICBUUkFDRSgiKHRoZV9hcmcgPT0gXiVwKVxuIiwgdGhlX2FyZyk7CgogIGZvciAoOzspIHsKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZzZXJ2ZXJfY3MpOwogICAgLyogb3BlbiBhbmQgY291bnQgY29ubmVjdGlvbnMgKi8KICAgIGNvdW50ID0gMTsKICAgIGNwcyA9IHByb3RzZXFzOwogICAgd2hpbGUgKGNwcykgewogICAgICBjb25uID0gY3BzLT5jb25uOwogICAgICB3aGlsZSAoY29ubikgewogICAgICAgIFJQQ1JUNF9PcGVuQ29ubmVjdGlvbihjb25uKTsKICAgICAgICBpZiAoY29ubi0+b3ZsLmhFdmVudCkgY291bnQrKzsKICAgICAgICBjb25uID0gY29ubi0+TmV4dDsKICAgICAgfQogICAgICBjcHMgPSBjcHMtPk5leHQ7CiAgICB9CiAgICAvKiBtYWtlIGFycmF5IG9mIGNvbm5lY3Rpb25zICovCiAgICBpZiAob2JqcykKCW9ianMgPSBIZWFwUmVBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBvYmpzLCBjb3VudCpzaXplb2YoSEFORExFKSk7CiAgICBlbHNlCglvYmpzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGNvdW50KnNpemVvZihIQU5ETEUpKTsKCiAgICBvYmpzWzBdID0gbV9ldmVudDsKICAgIGNvdW50ID0gMTsKICAgIGNwcyA9IHByb3RzZXFzOwogICAgd2hpbGUgKGNwcykgewogICAgICBjb25uID0gY3BzLT5jb25uOwogICAgICB3aGlsZSAoY29ubikgewogICAgICAgIGlmIChjb25uLT5vdmwuaEV2ZW50KSBvYmpzW2NvdW50KytdID0gY29ubi0+b3ZsLmhFdmVudDsKICAgICAgICBjb25uID0gY29ubi0+TmV4dDsKICAgICAgfQogICAgICBjcHMgPSBjcHMtPk5leHQ7CiAgICB9CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmc2VydmVyX2NzKTsKCiAgICBpZiAoc2V0X3JlYWR5X2V2ZW50KQogICAgewogICAgICAgIC8qIHNpZ25hbCB0byBmdW5jdGlvbiB0aGF0IGNoYW5nZWQgc3RhdGUgdGhhdCB3ZSBhcmUgbm93IHN5bmMnZWQgKi8KICAgICAgICBTZXRFdmVudChzZXJ2ZXJfcmVhZHlfZXZlbnQpOwogICAgICAgIHNldF9yZWFkeV9ldmVudCA9IEZBTFNFOwogICAgfQoKICAgIC8qIHN0YXJ0IHdhaXRpbmcgKi8KICAgIHJlcyA9IFdhaXRGb3JNdWx0aXBsZU9iamVjdHMoY291bnQsIG9ianMsIEZBTFNFLCBJTkZJTklURSk7CiAgICBpZiAocmVzID09IFdBSVRfT0JKRUNUXzApIHsKICAgICAgaWYgKCFzdGRfbGlzdGVuKQogICAgICB7CiAgICAgICAgU2V0RXZlbnQoc2VydmVyX3JlYWR5X2V2ZW50KTsKICAgICAgICBicmVhazsKICAgICAgfQogICAgICBzZXRfcmVhZHlfZXZlbnQgPSBUUlVFOwogICAgfQogICAgZWxzZSBpZiAocmVzID09IFdBSVRfRkFJTEVEKSB7CiAgICAgIEVSUigid2FpdCBmYWlsZWRcbiIpOwogICAgfQogICAgZWxzZSB7CiAgICAgIGJfaGFuZGxlID0gb2Jqc1tyZXMgLSBXQUlUX09CSkVDVF8wXTsKICAgICAgLyogZmluZCB3aGljaCBjb25uZWN0aW9uIGdvdCBhIFJQQyAqLwogICAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmc2VydmVyX2NzKTsKICAgICAgY29ubiA9IE5VTEw7CiAgICAgIGNwcyA9IHByb3RzZXFzOwogICAgICB3aGlsZSAoY3BzKSB7CiAgICAgICAgY29ubiA9IGNwcy0+Y29ubjsKICAgICAgICB3aGlsZSAoY29ubikgewogICAgICAgICAgaWYgKGNvbm4tPm92bC5oRXZlbnQgPT0gYl9oYW5kbGUpIGJyZWFrOwogICAgICAgICAgY29ubiA9IGNvbm4tPk5leHQ7CiAgICAgICAgfQogICAgICAgIGlmIChjb25uKSBicmVhazsKICAgICAgICBjcHMgPSBjcHMtPk5leHQ7CiAgICAgIH0KICAgICAgY2Nvbm4gPSBOVUxMOwogICAgICBpZiAoY29ubikgUlBDUlQ0X1NwYXduQ29ubmVjdGlvbigmY2Nvbm4sIGNvbm4pOwogICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmc2VydmVyX2NzKTsKICAgICAgaWYgKCFjb25uKSB7CiAgICAgICAgRVJSKCJmYWlsZWQgdG8gbG9jYXRlIGNvbm5lY3Rpb24gZm9yIGhhbmRsZSAlcFxuIiwgYl9oYW5kbGUpOwogICAgICB9CiAgICAgIGlmIChjY29ubikgUlBDUlQ0X25ld19jbGllbnQoY2Nvbm4pOwogICAgfQogIH0KICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBvYmpzKTsKICBFbnRlckNyaXRpY2FsU2VjdGlvbigmc2VydmVyX2NzKTsKICAvKiBjbG9zZSBjb25uZWN0aW9ucyAqLwogIGNwcyA9IHByb3RzZXFzOwogIHdoaWxlIChjcHMpIHsKICAgIGNvbm4gPSBjcHMtPmNvbm47CiAgICB3aGlsZSAoY29ubikgewogICAgICBSUENSVDRfQ2xvc2VDb25uZWN0aW9uKGNvbm4pOwogICAgICBjb25uID0gY29ubi0+TmV4dDsKICAgIH0KICAgIGNwcyA9IGNwcy0+TmV4dDsKICB9CiAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnNlcnZlcl9jcyk7CiAgcmV0dXJuIDA7Cn0KCi8qIHRlbGxzIHRoZSBzZXJ2ZXIgdGhyZWFkIHRoYXQgdGhlIHN0YXRlIGhhcyBjaGFuZ2VkIGFuZCB3YWl0cyBmb3IgaXQgdG8KICogbWFrZSB0aGUgY2hhbmdlcyAqLwpzdGF0aWMgdm9pZCBSUENSVDRfc3luY193aXRoX3NlcnZlcl90aHJlYWQodm9pZCkKewogIC8qIG1ha2Ugc3VyZSB3ZSBhcmUgdGhlIG9ubHkgdGhyZWFkIHN5bmMnaW5nIHRoZSBzZXJ2ZXIgc3RhdGUsIG90aGVyd2lzZQogICAqIHRoZXJlIGlzIGEgcmFjZSB3aXRoIHRoZSBzZXJ2ZXIgdGhyZWFkIHNldHRpbmcgYW4gb2xkZXIgc3RhdGUgYW5kIHNldHRpbmcKICAgKiB0aGUgc2VydmVyX3JlYWR5X2V2ZW50IHdoZW4gdGhlIG5ldyBzdGF0ZSBoYXNuJ3QgeWV0IGJlZW4gYXBwbGllZCAqLwogIFdhaXRGb3JTaW5nbGVPYmplY3QobWdyX211dGV4LCBJTkZJTklURSk7CgogIFNldEV2ZW50KG1ncl9ldmVudCk7CiAgLyogd2FpdCBmb3Igc2VydmVyIHRocmVhZCB0byBtYWtlIHRoZSByZXF1ZXN0ZWQgY2hhbmdlcyBiZWZvcmUgcmV0dXJuaW5nICovCiAgV2FpdEZvclNpbmdsZU9iamVjdChzZXJ2ZXJfcmVhZHlfZXZlbnQsIElORklOSVRFKTsKCiAgUmVsZWFzZU11dGV4KG1ncl9tdXRleCk7Cn0KCnN0YXRpYyB2b2lkIFJQQ1JUNF9zdGFydF9saXN0ZW4oQk9PTCBhdXRvX2xpc3RlbikKewogIFRSQUNFKCJcbiIpOwoKICBFbnRlckNyaXRpY2FsU2VjdGlvbigmbGlzdGVuX2NzKTsKICBpZiAoYXV0b19saXN0ZW4gfHwgKG1hbnVhbF9saXN0ZW5fY291bnQrKyA9PSAwKSkKICB7CiAgICBpZiAoKytsaXN0ZW5fY291bnQgPT0gMSkgewogICAgICAvKiBmaXJzdCBsaXN0ZW5lciBjcmVhdGVzIHNlcnZlciB0aHJlYWQgKi8KICAgICAgaWYgKCFtZ3JfbXV0ZXgpIG1ncl9tdXRleCA9IENyZWF0ZU11dGV4VyhOVUxMLCBGQUxTRSwgTlVMTCk7CiAgICAgIGlmICghbWdyX2V2ZW50KSBtZ3JfZXZlbnQgPSBDcmVhdGVFdmVudFcoTlVMTCwgRkFMU0UsIEZBTFNFLCBOVUxMKTsKICAgICAgaWYgKCFzZXJ2ZXJfcmVhZHlfZXZlbnQpIHNlcnZlcl9yZWFkeV9ldmVudCA9IENyZWF0ZUV2ZW50VyhOVUxMLCBGQUxTRSwgRkFMU0UsIE5VTEwpOwogICAgICBpZiAoIXNlcnZlcl9zZW0pIHNlcnZlcl9zZW0gPSBDcmVhdGVTZW1hcGhvcmVXKE5VTEwsIDAsIE1BWF9USFJFQURTLCBOVUxMKTsKICAgICAgaWYgKCF3b3JrZXJfdGxzKSB3b3JrZXJfdGxzID0gVGxzQWxsb2MoKTsKICAgICAgc3RkX2xpc3RlbiA9IFRSVUU7CiAgICAgIHNlcnZlcl90aHJlYWQgPSBDcmVhdGVUaHJlYWQoTlVMTCwgMCwgUlBDUlQ0X3NlcnZlcl90aHJlYWQsIE5VTEwsIDAsIE5VTEwpOwogICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmbGlzdGVuX2NzKTsKICAgIH0gZWxzZSB7CiAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZsaXN0ZW5fY3MpOwogICAgICBSUENSVDRfc3luY193aXRoX3NlcnZlcl90aHJlYWQoKTsKICAgIH0KICB9Cn0KCnN0YXRpYyB2b2lkIFJQQ1JUNF9zdG9wX2xpc3RlbihCT09MIGF1dG9fbGlzdGVuKQp7CiAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmxpc3Rlbl9jcyk7CiAgaWYgKGF1dG9fbGlzdGVuIHx8ICgtLW1hbnVhbF9saXN0ZW5fY291bnQgPT0gMCkpCiAgewogICAgaWYgKGxpc3Rlbl9jb3VudCAhPSAwICYmIC0tbGlzdGVuX2NvdW50ID09IDApIHsKICAgICAgc3RkX2xpc3RlbiA9IEZBTFNFOwogICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmbGlzdGVuX2NzKTsKICAgICAgUlBDUlQ0X3N5bmNfd2l0aF9zZXJ2ZXJfdGhyZWFkKCk7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGFzc2VydChsaXN0ZW5fY291bnQgPj0gMCk7CiAgfQogIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZsaXN0ZW5fY3MpOwp9CgpzdGF0aWMgUlBDX1NUQVRVUyBSUENSVDRfdXNlX3Byb3RzZXEoUnBjU2VydmVyUHJvdHNlcSogcHMpCnsKICBSUENSVDRfQ3JlYXRlQ29ubmVjdGlvbigmcHMtPmNvbm4sIFRSVUUsIHBzLT5Qcm90c2VxLCBOVUxMLCBwcy0+RW5kcG9pbnQsIE5VTEwsIE5VTEwpOwoKICBFbnRlckNyaXRpY2FsU2VjdGlvbigmc2VydmVyX2NzKTsKICBwcy0+TmV4dCA9IHByb3RzZXFzOwogIHByb3RzZXFzID0gcHM7CiAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnNlcnZlcl9jcyk7CgogIGlmIChzdGRfbGlzdGVuKSBSUENSVDRfc3luY193aXRoX3NlcnZlcl90aHJlYWQoKTsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjU2VydmVySW5xQmluZGluZ3MgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU2VydmVySW5xQmluZGluZ3MoIFJQQ19CSU5ESU5HX1ZFQ1RPUioqIEJpbmRpbmdWZWN0b3IgKQp7CiAgUlBDX1NUQVRVUyBzdGF0dXM7CiAgRFdPUkQgY291bnQ7CiAgUnBjU2VydmVyUHJvdHNlcSogcHM7CiAgUnBjQ29ubmVjdGlvbiogY29ubjsKCiAgaWYgKEJpbmRpbmdWZWN0b3IpCiAgICBUUkFDRSgiKCpCaW5kaW5nVmVjdG9yID09IF4lcClcbiIsICpCaW5kaW5nVmVjdG9yKTsKICBlbHNlCiAgICBFUlIoIihCaW5kaW5nVmVjdG9yID09IE5VTEwhIT8pXG4iKTsKCiAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnNlcnZlcl9jcyk7CiAgLyogY291bnQgY29ubmVjdGlvbnMgKi8KICBjb3VudCA9IDA7CiAgcHMgPSBwcm90c2VxczsKICB3aGlsZSAocHMpIHsKICAgIGNvbm4gPSBwcy0+Y29ubjsKICAgIHdoaWxlIChjb25uKSB7CiAgICAgIGNvdW50Kys7CiAgICAgIGNvbm4gPSBjb25uLT5OZXh0OwogICAgfQogICAgcHMgPSBwcy0+TmV4dDsKICB9CiAgaWYgKGNvdW50KSB7CiAgICAvKiBleHBvcnQgYmluZGluZ3MgKi8KICAgICpCaW5kaW5nVmVjdG9yID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihSUENfQklORElOR19WRUNUT1IpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKFJQQ19CSU5ESU5HX0hBTkRMRSkqKGNvdW50LTEpKTsKICAgICgqQmluZGluZ1ZlY3RvciktPkNvdW50ID0gY291bnQ7CiAgICBjb3VudCA9IDA7CiAgICBwcyA9IHByb3RzZXFzOwogICAgd2hpbGUgKHBzKSB7CiAgICAgIGNvbm4gPSBwcy0+Y29ubjsKICAgICAgd2hpbGUgKGNvbm4pIHsKICAgICAgIFJQQ1JUNF9NYWtlQmluZGluZygoUnBjQmluZGluZyoqKSYoKkJpbmRpbmdWZWN0b3IpLT5CaW5kaW5nSFtjb3VudF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubik7CiAgICAgICBjb3VudCsrOwogICAgICAgY29ubiA9IGNvbm4tPk5leHQ7CiAgICAgIH0KICAgICAgcHMgPSBwcy0+TmV4dDsKICAgIH0KICAgIHN0YXR1cyA9IFJQQ19TX09LOwogIH0gZWxzZSB7CiAgICAqQmluZGluZ1ZlY3RvciA9IE5VTEw7CiAgICBzdGF0dXMgPSBSUENfU19OT19CSU5ESU5HUzsKICB9CiAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnNlcnZlcl9jcyk7CiAgcmV0dXJuIHN0YXR1czsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1NlcnZlclVzZVByb3RzZXFFcEEgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU2VydmVyVXNlUHJvdHNlcUVwQSggdW5zaWduZWQgY2hhciAqUHJvdHNlcSwgVUlOVCBNYXhDYWxscywgdW5zaWduZWQgY2hhciAqRW5kcG9pbnQsIExQVk9JRCBTZWN1cml0eURlc2NyaXB0b3IgKQp7CiAgUlBDX1BPTElDWSBwb2xpY3k7CiAgCiAgVFJBQ0UoICIoJXMsJXUsJXMsJXApXG4iLCBQcm90c2VxLCBNYXhDYWxscywgRW5kcG9pbnQsIFNlY3VyaXR5RGVzY3JpcHRvciApOwogIAogIC8qIFRoaXMgc2hvdWxkIHByb3ZpZGUgdGhlIGRlZmF1bHQgYmVoYXZpb3VyICovCiAgcG9saWN5Lkxlbmd0aCAgICAgICAgPSBzaXplb2YoIHBvbGljeSApOwogIHBvbGljeS5FbmRwb2ludEZsYWdzID0gMDsKICBwb2xpY3kuTklDRmxhZ3MgICAgICA9IDA7CiAgCiAgcmV0dXJuIFJwY1NlcnZlclVzZVByb3RzZXFFcEV4QSggUHJvdHNlcSwgTWF4Q2FsbHMsIEVuZHBvaW50LCBTZWN1cml0eURlc2NyaXB0b3IsICZwb2xpY3kgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1NlcnZlclVzZVByb3RzZXFFcFcgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU2VydmVyVXNlUHJvdHNlcUVwVyggTFBXU1RSIFByb3RzZXEsIFVJTlQgTWF4Q2FsbHMsIExQV1NUUiBFbmRwb2ludCwgTFBWT0lEIFNlY3VyaXR5RGVzY3JpcHRvciApCnsKICBSUENfUE9MSUNZIHBvbGljeTsKICAKICBUUkFDRSggIiglcywldSwlcywlcClcbiIsIGRlYnVnc3RyX3coIFByb3RzZXEgKSwgTWF4Q2FsbHMsIGRlYnVnc3RyX3coIEVuZHBvaW50ICksIFNlY3VyaXR5RGVzY3JpcHRvciApOwogIAogIC8qIFRoaXMgc2hvdWxkIHByb3ZpZGUgdGhlIGRlZmF1bHQgYmVoYXZpb3VyICovCiAgcG9saWN5Lkxlbmd0aCAgICAgICAgPSBzaXplb2YoIHBvbGljeSApOwogIHBvbGljeS5FbmRwb2ludEZsYWdzID0gMDsKICBwb2xpY3kuTklDRmxhZ3MgICAgICA9IDA7CiAgCiAgcmV0dXJuIFJwY1NlcnZlclVzZVByb3RzZXFFcEV4VyggUHJvdHNlcSwgTWF4Q2FsbHMsIEVuZHBvaW50LCBTZWN1cml0eURlc2NyaXB0b3IsICZwb2xpY3kgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1NlcnZlclVzZVByb3RzZXFFcEV4QSAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNTZXJ2ZXJVc2VQcm90c2VxRXBFeEEoIHVuc2lnbmVkIGNoYXIgKlByb3RzZXEsIFVJTlQgTWF4Q2FsbHMsIHVuc2lnbmVkIGNoYXIgKkVuZHBvaW50LCBMUFZPSUQgU2VjdXJpdHlEZXNjcmlwdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBSUENfUE9MSUNZIGxwUG9saWN5ICkKewogIFJwY1NlcnZlclByb3RzZXEqIHBzOwoKICBUUkFDRSgiKCVzLCV1LCVzLCVwLHsldSwlbHUsJWx1fSlcbiIsIGRlYnVnc3RyX2EoIFByb3RzZXEgKSwgTWF4Q2FsbHMsCiAgICAgICBkZWJ1Z3N0cl9hKCBFbmRwb2ludCApLCBTZWN1cml0eURlc2NyaXB0b3IsCiAgICAgICBscFBvbGljeS0+TGVuZ3RoLCBscFBvbGljeS0+RW5kcG9pbnRGbGFncywgbHBQb2xpY3ktPk5JQ0ZsYWdzICk7CgogIHBzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihScGNTZXJ2ZXJQcm90c2VxKSk7CiAgcHMtPk1heENhbGxzID0gTWF4Q2FsbHM7CiAgcHMtPlByb3RzZXEgPSBSUENSVDRfc3RyZHVwQShQcm90c2VxKTsKICBwcy0+RW5kcG9pbnQgPSBSUENSVDRfc3RyZHVwQShFbmRwb2ludCk7CgogIHJldHVybiBSUENSVDRfdXNlX3Byb3RzZXEocHMpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjU2VydmVyVXNlUHJvdHNlcUVwRXhXIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1NlcnZlclVzZVByb3RzZXFFcEV4VyggTFBXU1RSIFByb3RzZXEsIFVJTlQgTWF4Q2FsbHMsIExQV1NUUiBFbmRwb2ludCwgTFBWT0lEIFNlY3VyaXR5RGVzY3JpcHRvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQUlBDX1BPTElDWSBscFBvbGljeSApCnsKICBScGNTZXJ2ZXJQcm90c2VxKiBwczsKCiAgVFJBQ0UoIiglcywldSwlcywlcCx7JXUsJWx1LCVsdX0pXG4iLCBkZWJ1Z3N0cl93KCBQcm90c2VxICksIE1heENhbGxzLAogICAgICAgZGVidWdzdHJfdyggRW5kcG9pbnQgKSwgU2VjdXJpdHlEZXNjcmlwdG9yLAogICAgICAgbHBQb2xpY3ktPkxlbmd0aCwgbHBQb2xpY3ktPkVuZHBvaW50RmxhZ3MsIGxwUG9saWN5LT5OSUNGbGFncyApOwoKICBwcyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoUnBjU2VydmVyUHJvdHNlcSkpOwogIHBzLT5NYXhDYWxscyA9IE1heENhbGxzOwogIHBzLT5Qcm90c2VxID0gUlBDUlQ0X3N0cmR1cFd0b0EoUHJvdHNlcSk7CiAgcHMtPkVuZHBvaW50ID0gUlBDUlQ0X3N0cmR1cFd0b0EoRW5kcG9pbnQpOwoKICByZXR1cm4gUlBDUlQ0X3VzZV9wcm90c2VxKHBzKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1NlcnZlclVzZVByb3RzZXFBIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1NlcnZlclVzZVByb3RzZXFBKHVuc2lnbmVkIGNoYXIgKlByb3RzZXEsIHVuc2lnbmVkIGludCBNYXhDYWxscywgdm9pZCAqU2VjdXJpdHlEZXNjcmlwdG9yKQp7CiAgVFJBQ0UoIihQcm90c2VxID09ICVzLCBNYXhDYWxscyA9PSAlZCwgU2VjdXJpdHlEZXNjcmlwdG9yID09IF4lcClcbiIsIGRlYnVnc3RyX2EoUHJvdHNlcSksIE1heENhbGxzLCBTZWN1cml0eURlc2NyaXB0b3IpOwogIHJldHVybiBScGNTZXJ2ZXJVc2VQcm90c2VxRXBBKFByb3RzZXEsIE1heENhbGxzLCBOVUxMLCBTZWN1cml0eURlc2NyaXB0b3IpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjU2VydmVyVXNlUHJvdHNlcVcgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU2VydmVyVXNlUHJvdHNlcVcoTFBXU1RSIFByb3RzZXEsIHVuc2lnbmVkIGludCBNYXhDYWxscywgdm9pZCAqU2VjdXJpdHlEZXNjcmlwdG9yKQp7CiAgVFJBQ0UoIlByb3RzZXEgPT0gJXMsIE1heENhbGxzID09ICVkLCBTZWN1cml0eURlc2NyaXB0b3IgPT0gXiVwKVxuIiwgZGVidWdzdHJfdyhQcm90c2VxKSwgTWF4Q2FsbHMsIFNlY3VyaXR5RGVzY3JpcHRvcik7CiAgcmV0dXJuIFJwY1NlcnZlclVzZVByb3RzZXFFcFcoUHJvdHNlcSwgTWF4Q2FsbHMsIE5VTEwsIFNlY3VyaXR5RGVzY3JpcHRvcik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTZXJ2ZXJSZWdpc3RlcklmIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1NlcnZlclJlZ2lzdGVySWYoIFJQQ19JRl9IQU5ETEUgSWZTcGVjLCBVVUlEKiBNZ3JUeXBlVXVpZCwgUlBDX01HUl9FUFYqIE1nckVwdiApCnsKICBUUkFDRSgiKCVwLCVzLCVwKVxuIiwgSWZTcGVjLCBkZWJ1Z3N0cl9ndWlkKE1nclR5cGVVdWlkKSwgTWdyRXB2KTsKICByZXR1cm4gUnBjU2VydmVyUmVnaXN0ZXJJZjIoIElmU3BlYywgTWdyVHlwZVV1aWQsIE1nckVwdiwgMCwgUlBDX0NfTElTVEVOX01BWF9DQUxMU19ERUZBVUxULCAoVUlOVCktMSwgTlVMTCApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjU2VydmVyUmVnaXN0ZXJJZkV4IChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1NlcnZlclJlZ2lzdGVySWZFeCggUlBDX0lGX0hBTkRMRSBJZlNwZWMsIFVVSUQqIE1nclR5cGVVdWlkLCBSUENfTUdSX0VQViogTWdyRXB2LAogICAgICAgICAgICAgICAgICAgICAgIFVJTlQgRmxhZ3MsIFVJTlQgTWF4Q2FsbHMsIFJQQ19JRl9DQUxMQkFDS19GTiogSWZDYWxsYmFja0ZuICkKewogIFRSQUNFKCIoJXAsJXMsJXAsJXUsJXUsJXApXG4iLCBJZlNwZWMsIGRlYnVnc3RyX2d1aWQoTWdyVHlwZVV1aWQpLCBNZ3JFcHYsIEZsYWdzLCBNYXhDYWxscywgSWZDYWxsYmFja0ZuKTsKICByZXR1cm4gUnBjU2VydmVyUmVnaXN0ZXJJZjIoIElmU3BlYywgTWdyVHlwZVV1aWQsIE1nckVwdiwgRmxhZ3MsIE1heENhbGxzLCAoVUlOVCktMSwgSWZDYWxsYmFja0ZuICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTZXJ2ZXJSZWdpc3RlcklmMiAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNTZXJ2ZXJSZWdpc3RlcklmMiggUlBDX0lGX0hBTkRMRSBJZlNwZWMsIFVVSUQqIE1nclR5cGVVdWlkLCBSUENfTUdSX0VQViogTWdyRXB2LAogICAgICAgICAgICAgICAgICAgICAgVUlOVCBGbGFncywgVUlOVCBNYXhDYWxscywgVUlOVCBNYXhScGNTaXplLCBSUENfSUZfQ0FMTEJBQ0tfRk4qIElmQ2FsbGJhY2tGbiApCnsKICBQUlBDX1NFUlZFUl9JTlRFUkZBQ0UgSWYgPSAoUFJQQ19TRVJWRVJfSU5URVJGQUNFKUlmU3BlYzsKICBScGNTZXJ2ZXJJbnRlcmZhY2UqIHNpZjsKICB1bnNpZ25lZCBpbnQgaTsKCiAgVFJBQ0UoIiglcCwlcywlcCwldSwldSwldSwlcClcbiIsIElmU3BlYywgZGVidWdzdHJfZ3VpZChNZ3JUeXBlVXVpZCksIE1nckVwdiwgRmxhZ3MsIE1heENhbGxzLAogICAgICAgICBNYXhScGNTaXplLCBJZkNhbGxiYWNrRm4pOwogIFRSQUNFKCIgaW50ZXJmYWNlIGlkOiAlcyAlZC4lZFxuIiwgZGVidWdzdHJfZ3VpZCgmSWYtPkludGVyZmFjZUlkLlN5bnRheEdVSUQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSWYtPkludGVyZmFjZUlkLlN5bnRheFZlcnNpb24uTWFqb3JWZXJzaW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSWYtPkludGVyZmFjZUlkLlN5bnRheFZlcnNpb24uTWlub3JWZXJzaW9uKTsKICBUUkFDRSgiIHRyYW5zZmVyIHN5bnRheDogJXMgJWQuJWRcbiIsIGRlYnVnc3RyX2d1aWQoJklmLT5UcmFuc2ZlclN5bnRheC5TeW50YXhHVUlEKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElmLT5UcmFuc2ZlclN5bnRheC5TeW50YXhWZXJzaW9uLk1ham9yVmVyc2lvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElmLT5UcmFuc2ZlclN5bnRheC5TeW50YXhWZXJzaW9uLk1pbm9yVmVyc2lvbik7CiAgVFJBQ0UoIiBkaXNwYXRjaCB0YWJsZTogJXBcbiIsIElmLT5EaXNwYXRjaFRhYmxlKTsKICBpZiAoSWYtPkRpc3BhdGNoVGFibGUpIHsKICAgIFRSQUNFKCIgIGRpc3BhdGNoIHRhYmxlIGNvdW50OiAlZFxuIiwgSWYtPkRpc3BhdGNoVGFibGUtPkRpc3BhdGNoVGFibGVDb3VudCk7CiAgICBmb3IgKGk9MDsgaTxJZi0+RGlzcGF0Y2hUYWJsZS0+RGlzcGF0Y2hUYWJsZUNvdW50OyBpKyspIHsKICAgICAgVFJBQ0UoIiAgIGVudHJ5ICVkOiAlcFxuIiwgaSwgSWYtPkRpc3BhdGNoVGFibGUtPkRpc3BhdGNoVGFibGVbaV0pOwogICAgfQogICAgVFJBQ0UoIiAgcmVzZXJ2ZWQ6ICVsZFxuIiwgSWYtPkRpc3BhdGNoVGFibGUtPlJlc2VydmVkKTsKICB9CiAgVFJBQ0UoIiBwcm90c2VxIGVuZHBvaW50IGNvdW50OiAlZFxuIiwgSWYtPlJwY1Byb3RzZXFFbmRwb2ludENvdW50KTsKICBUUkFDRSgiIGRlZmF1bHQgbWFuYWdlciBlcHY6ICVwXG4iLCBJZi0+RGVmYXVsdE1hbmFnZXJFcHYpOwogIFRSQUNFKCIgaW50ZXJwcmV0ZXIgaW5mbzogJXBcbiIsIElmLT5JbnRlcnByZXRlckluZm8pOwoKICBzaWYgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKFJwY1NlcnZlckludGVyZmFjZSkpOwogIHNpZi0+SWYgICAgICAgICAgID0gSWY7CiAgaWYgKE1nclR5cGVVdWlkKSB7CiAgICBtZW1jcHkoJnNpZi0+TWdyVHlwZVV1aWQsIE1nclR5cGVVdWlkLCBzaXplb2YoVVVJRCkpOwogICAgc2lmLT5NZ3JFcHYgICAgICAgPSBNZ3JFcHY7CiAgfSBlbHNlIHsKICAgIG1lbXNldCgmc2lmLT5NZ3JUeXBlVXVpZCwgMCwgc2l6ZW9mKFVVSUQpKTsKICAgIHNpZi0+TWdyRXB2ICAgICAgID0gSWYtPkRlZmF1bHRNYW5hZ2VyRXB2OwogIH0KICBzaWYtPkZsYWdzICAgICAgICA9IEZsYWdzOwogIHNpZi0+TWF4Q2FsbHMgICAgID0gTWF4Q2FsbHM7CiAgc2lmLT5NYXhScGNTaXplICAgPSBNYXhScGNTaXplOwogIHNpZi0+SWZDYWxsYmFja0ZuID0gSWZDYWxsYmFja0ZuOwoKICBFbnRlckNyaXRpY2FsU2VjdGlvbigmc2VydmVyX2NzKTsKICBzaWYtPk5leHQgPSBpZnM7CiAgaWZzID0gc2lmOwogIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZzZXJ2ZXJfY3MpOwoKICBpZiAoc2lmLT5GbGFncyAmIFJQQ19JRl9BVVRPTElTVEVOKSB7CiAgICAvKiB3ZWxsLCBzdGFydCBsaXN0ZW5pbmcsIEkgdGhpbmsuLi4gKi8KICAgIFJQQ1JUNF9zdGFydF9saXN0ZW4oVFJVRSk7CiAgfQoKICByZXR1cm4gUlBDX1NfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTZXJ2ZXJVbnJlZ2lzdGVySWYgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU2VydmVyVW5yZWdpc3RlcklmKCBSUENfSUZfSEFORExFIElmU3BlYywgVVVJRCogTWdyVHlwZVV1aWQsIFVJTlQgV2FpdEZvckNhbGxzVG9Db21wbGV0ZSApCnsKICBGSVhNRSgiKElmU3BlYyA9PSAoUlBDX0lGX0hBTkRMRSleJXAsIE1nclR5cGVVdWlkID09ICVzLCBXYWl0Rm9yQ2FsbHNUb0NvbXBsZXRlID09ICV1KTogc3R1YlxuIiwKICAgIElmU3BlYywgZGVidWdzdHJfZ3VpZChNZ3JUeXBlVXVpZCksIFdhaXRGb3JDYWxsc1RvQ29tcGxldGUpOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTZXJ2ZXJVbnJlZ2lzdGVySWZFeCAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNTZXJ2ZXJVbnJlZ2lzdGVySWZFeCggUlBDX0lGX0hBTkRMRSBJZlNwZWMsIFVVSUQqIE1nclR5cGVVdWlkLCBpbnQgUnVuZG93bkNvbnRleHRIYW5kbGVzICkKewogIEZJWE1FKCIoSWZTcGVjID09IChSUENfSUZfSEFORExFKV4lcCwgTWdyVHlwZVV1aWQgPT0gJXMsIFJ1bmRvd25Db250ZXh0SGFuZGxlcyA9PSAlZCk6IHN0dWJcbiIsCiAgICBJZlNwZWMsIGRlYnVnc3RyX2d1aWQoTWdyVHlwZVV1aWQpLCBSdW5kb3duQ29udGV4dEhhbmRsZXMpOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNPYmplY3RTZXRUeXBlIChSUENSVDQuQCkKICoKICogUEFSQU1TCiAqICAgT2JqVXVpZCAgW0ldICJPYmplY3QiIFVVSUQKICogICBUeXBlVXVpZCBbSV0gIlR5cGUiIFVVSUQKICoKICogUkVUVVJOUwogKiAgIFJQQ19TX09LICAgICAgICAgICAgICAgICBUaGUgY2FsbCBzdWNjZWVkZWQKICogICBSUENfU19JTlZBTElEX09CSkVDVCAgICAgVGhlIHByb3ZpZGVkIG9iamVjdCAobmlsKSBpcyBub3QgdmFsaWQKICogICBSUENfU19BTFJFQURZX1JFR0lTVEVSRUQgVGhlIHByb3ZpZGVkIG9iamVjdCBpcyBhbHJlYWR5IHJlZ2lzdGVyZWQKICoKICogTWFwcyAiT2JqZWN0IiBVVUlEcyB0byAiVHlwZSIgVVVJRCdzLiAgUGFzc2luZyB0aGUgbmlsIFVVSUQgYXMgdGhlIHR5cGUKICogcmVzZXRzIHRoZSBtYXBwaW5nIGZvciB0aGUgc3BlY2lmaWVkIG9iamVjdCBVVUlEIHRvIG5pbCAodGhlIGRlZmF1bHQpLgogKiBUaGUgbmlsIG9iamVjdCBpcyBhbHdheXMgYXNzb2NpYXRlZCB3aXRoIHRoZSBuaWwgdHlwZSBhbmQgY2Fubm90IGJlCiAqIHJlYXNzaWduZWQuICBTZXJ2ZXJzIGNhbiBzdXBwb3J0IG11bHRpcGxlIGltcGxlbWVudGF0aW9ucyBvbiB0aGUgc2FtZQogKiBpbnRlcmZhY2UgYnkgcmVnaXN0ZXJpbmcgZGlmZmVyZW50IGVuZC1wb2ludCB2ZWN0b3JzIGZvciB0aGUgZGlmZmVyZW50CiAqIHR5cGVzLiAgVGhlcmUncyBubyBuZWVkIHRvIGNhbGwgdGhpcyBpZiBhIHNlcnZlciBvbmx5IHN1cHBvcnRzIHRoZSBuaWwKICogdHlwZSwgYXMgaXMgdHlwaWNhbC4KICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY09iamVjdFNldFR5cGUoIFVVSUQqIE9ialV1aWQsIFVVSUQqIFR5cGVVdWlkICkKewogIFJwY09ialR5cGVNYXAgKm1hcCA9IFJwY09ialR5cGVNYXBzLCAqcHJldiA9IE5VTEw7CiAgUlBDX1NUQVRVUyBkdW1teTsKCiAgVFJBQ0UoIihPYmpVVUlEID09ICVzLCBUeXBlVXVpZCA9PSAlcykuXG4iLCBkZWJ1Z3N0cl9ndWlkKE9ialV1aWQpLCBkZWJ1Z3N0cl9ndWlkKFR5cGVVdWlkKSk7CiAgaWYgKCghIE9ialV1aWQpIHx8IFV1aWRJc05pbChPYmpVdWlkLCAmZHVtbXkpKSB7CiAgICAvKiBuaWwgdXVpZCBjYW5ub3QgYmUgcmVtYXBwZWQgKi8KICAgIHJldHVybiBSUENfU19JTlZBTElEX09CSkVDVDsKICB9CgogIC8qIGZpbmQgdGhlIG1hcHBpbmcgZm9yIHRoaXMgb2JqZWN0IGlmIHRoZXJlIGlzIG9uZSAuLi4gKi8KICB3aGlsZSAobWFwKSB7CiAgICBpZiAoISBVdWlkQ29tcGFyZShPYmpVdWlkLCAmbWFwLT5PYmplY3QsICZkdW1teSkpIGJyZWFrOwogICAgcHJldiA9IG1hcDsKICAgIG1hcCA9IG1hcC0+bmV4dDsKICB9CiAgaWYgKCghIFR5cGVVdWlkKSB8fCBVdWlkSXNOaWwoVHlwZVV1aWQsICZkdW1teSkpIHsKICAgIC8qIC4uLiBhbmQgZHJvcCBpdCBmcm9tIHRoZSBsaXN0ICovCiAgICBpZiAobWFwKSB7CiAgICAgIGlmIChwcmV2KSAKICAgICAgICBwcmV2LT5uZXh0ID0gbWFwLT5uZXh0OwogICAgICBlbHNlCiAgICAgICAgUnBjT2JqVHlwZU1hcHMgPSBtYXAtPm5leHQ7CiAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG1hcCk7CiAgICB9CiAgfSBlbHNlIHsKICAgIC8qIC4uLiAsIGZhaWwgaWYgd2UgZm91bmQgaXQgLi4uICovCiAgICBpZiAobWFwKQogICAgICByZXR1cm4gUlBDX1NfQUxSRUFEWV9SRUdJU1RFUkVEOwogICAgLyogLi4uIG90aGVyd2lzZSBjcmVhdGUgYSBuZXcgb25lIGFuZCBhZGQgaXQgaW4uICovCiAgICBtYXAgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKFJwY09ialR5cGVNYXApKTsKICAgIG1lbWNweSgmbWFwLT5PYmplY3QsIE9ialV1aWQsIHNpemVvZihVVUlEKSk7CiAgICBtZW1jcHkoJm1hcC0+VHlwZSwgVHlwZVV1aWQsIHNpemVvZihVVUlEKSk7CiAgICBtYXAtPm5leHQgPSBOVUxMOwogICAgaWYgKHByZXYpCiAgICAgIHByZXYtPm5leHQgPSBtYXA7IC8qIHByZXYgaXMgdGhlIGxhc3QgbWFwIGluIHRoZSBsaW5rbGlzdCAqLwogICAgZWxzZQogICAgICBScGNPYmpUeXBlTWFwcyA9IG1hcDsKICB9CgogIHJldHVybiBSUENfU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1NlcnZlclJlZ2lzdGVyQXV0aEluZm9BIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1NlcnZlclJlZ2lzdGVyQXV0aEluZm9BKCB1bnNpZ25lZCBjaGFyICpTZXJ2ZXJQcmluY05hbWUsIHVuc2lnbmVkIGxvbmcgQXV0aG5TdmMsIFJQQ19BVVRIX0tFWV9SRVRSSUVWQUxfRk4gR2V0S2V5Rm4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFZPSUQgQXJnICkKewogIEZJWE1FKCAiKCVzLCVsdSwlcCwlcCk6IHN0dWJcbiIsIFNlcnZlclByaW5jTmFtZSwgQXV0aG5TdmMsIEdldEtleUZuLCBBcmcgKTsKICAKICByZXR1cm4gUlBDX1NfVU5LTk9XTl9BVVRITl9TRVJWSUNFOyAvKiBXZSBkb24ndCBrbm93IGFueSBhdXRoZW50aWNhdGlvbiBzZXJ2aWNlcyAqLwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjU2VydmVyUmVnaXN0ZXJBdXRoSW5mb1cgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU2VydmVyUmVnaXN0ZXJBdXRoSW5mb1coIExQV1NUUiBTZXJ2ZXJQcmluY05hbWUsIHVuc2lnbmVkIGxvbmcgQXV0aG5TdmMsIFJQQ19BVVRIX0tFWV9SRVRSSUVWQUxfRk4gR2V0S2V5Rm4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFZPSUQgQXJnICkKewogIEZJWE1FKCAiKCVzLCVsdSwlcCwlcCk6IHN0dWJcbiIsIGRlYnVnc3RyX3coIFNlcnZlclByaW5jTmFtZSApLCBBdXRoblN2YywgR2V0S2V5Rm4sIEFyZyApOwogIAogIHJldHVybiBSUENfU19VTktOT1dOX0FVVEhOX1NFUlZJQ0U7IC8qIFdlIGRvbid0IGtub3cgYW55IGF1dGhlbnRpY2F0aW9uIHNlcnZpY2VzICovCn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTZXJ2ZXJMaXN0ZW4gKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU2VydmVyTGlzdGVuKCBVSU5UIE1pbmltdW1DYWxsVGhyZWFkcywgVUlOVCBNYXhDYWxscywgVUlOVCBEb250V2FpdCApCnsKICBUUkFDRSgiKCV1LCV1LCV1KVxuIiwgTWluaW11bUNhbGxUaHJlYWRzLCBNYXhDYWxscywgRG9udFdhaXQpOwoKICBpZiAoIXByb3RzZXFzKQogICAgcmV0dXJuIFJQQ19TX05PX1BST1RTRVFTX1JFR0lTVEVSRUQ7CgogIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZsaXN0ZW5fY3MpOwoKICBpZiAoc3RkX2xpc3RlbikgewogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmxpc3Rlbl9jcyk7CiAgICByZXR1cm4gUlBDX1NfQUxSRUFEWV9MSVNURU5JTkc7CiAgfQoKICBSUENSVDRfc3RhcnRfbGlzdGVuKEZBTFNFKTsKCiAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmxpc3Rlbl9jcyk7CgogIGlmIChEb250V2FpdCkgcmV0dXJuIFJQQ19TX09LOwoKICByZXR1cm4gUnBjTWdtdFdhaXRTZXJ2ZXJMaXN0ZW4oKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY01nbXRTZXJ2ZXJXYWl0TGlzdGVuIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY01nbXRXYWl0U2VydmVyTGlzdGVuKCB2b2lkICkKewogIFJQQ19TVEFUVVMgcnNsdCA9IFJQQ19TX09LOwoKICBUUkFDRSgiXG4iKTsKCiAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmxpc3Rlbl9jcyk7CgogIGlmICghc3RkX2xpc3RlbikKICAgIGlmICggKHJzbHQgPSBScGNTZXJ2ZXJMaXN0ZW4oMSwgMCwgVFJVRSkpICE9IFJQQ19TX09LICkgewogICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmbGlzdGVuX2NzKTsKICAgICAgcmV0dXJuIHJzbHQ7CiAgICB9CiAgCiAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmxpc3Rlbl9jcyk7CgogIHdoaWxlIChzdGRfbGlzdGVuKSB7CiAgICBXYWl0Rm9yU2luZ2xlT2JqZWN0KG1ncl9ldmVudCwgSU5GSU5JVEUpOwogICAgaWYgKCFzdGRfbGlzdGVuKSB7CiAgICAgIFNsZWVwKDEwMCk7IC8qIGRvbid0IHNwaW4gdmlvbGVudGx5ICovCiAgICAgIFRSQUNFKCJzcGlubmluZy5cbiIpOwogICAgfQogIH0KCiAgcmV0dXJuIHJzbHQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNNZ210U3RvcFNlcnZlckxpc3RlbmluZyAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNNZ210U3RvcFNlcnZlckxpc3RlbmluZyAoIFJQQ19CSU5ESU5HX0hBTkRMRSBCaW5kaW5nICkKewogIFRSQUNFKCIoQmluZGluZyA9PSAoUlBDX0JJTkRJTkdfSEFORExFKV4lcClcbiIsIEJpbmRpbmcpOwoKICBpZiAoQmluZGluZykgewogICAgRklYTUUoImNsaWVudC1zaWRlIGludm9jYXRpb24gbm90IGltcGxlbWVudGVkLlxuIik7CiAgICByZXR1cm4gUlBDX1NfV1JPTkdfS0lORF9PRl9CSU5ESU5HOwogIH0KICAKICBSUENSVDRfc3RvcF9saXN0ZW4oRkFMU0UpOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBJX1JwY1NlcnZlclN0YXJ0TGlzdGVuaW5nIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIElfUnBjU2VydmVyU3RhcnRMaXN0ZW5pbmcoIEhXTkQgaFduZCApCnsKICBGSVhNRSggIiglcCk6IHN0dWJcbiIsIGhXbmQgKTsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgSV9ScGNTZXJ2ZXJTdG9wTGlzdGVuaW5nIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIElfUnBjU2VydmVyU3RvcExpc3RlbmluZyggdm9pZCApCnsKICBGSVhNRSggIigpOiBzdHViXG4iICk7CgogIHJldHVybiBSUENfU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIElfUnBjV2luZG93UHJvYyAoUlBDUlQ0LkApCiAqLwpVSU5UIFdJTkFQSSBJX1JwY1dpbmRvd1Byb2MoIHZvaWQgKmhXbmQsIFVJTlQgTWVzc2FnZSwgVUlOVCB3UGFyYW0sIFVMT05HIGxQYXJhbSApCnsKICBGSVhNRSggIiglcCwlMDh4LCUwOHgsJTA4bHgpOiBzdHViXG4iLCBoV25kLCBNZXNzYWdlLCB3UGFyYW0sIGxQYXJhbSApOwoKICByZXR1cm4gMDsKfQo=