LyoKICogUlBDIHNlcnZlciBBUEkKICoKICogQ29weXJpZ2h0IDIwMDEgT3ZlIEvldmVuLCBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMKICogQ29weXJpZ2h0IDIwMDQgRmlsaXAgTmF2YXJhCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKgogKiBUT0RPOgogKiAgLSBhIHdob2xlIGxvdAogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgIndpbmUvcG9ydC5oIgoKI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8YXNzZXJ0Lmg+CgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAid2lucmVnLmgiCgojaW5jbHVkZSAicnBjLmgiCiNpbmNsdWRlICJycGNuZHIuaCIKI2luY2x1ZGUgImV4Y3B0LmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgojaW5jbHVkZSAid2luZS9leGNlcHRpb24uaCIKCiNpbmNsdWRlICJycGNfc2VydmVyLmgiCiNpbmNsdWRlICJycGNfbWlzYy5oIgojaW5jbHVkZSAicnBjX21lc3NhZ2UuaCIKI2luY2x1ZGUgInJwY19kZWZzLmgiCgojZGVmaW5lIE1BWF9USFJFQURTIDEyOAoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwocnBjKTsKCnR5cGVkZWYgc3RydWN0IF9ScGNQYWNrZXQKewogIHN0cnVjdCBfUnBjUGFja2V0KiBuZXh0OwogIHN0cnVjdCBfUnBjQ29ubmVjdGlvbiogY29ubjsKICBScGNQa3RIZHIqIGhkcjsKICBSUENfTUVTU0FHRSogbXNnOwp9IFJwY1BhY2tldDsKCnR5cGVkZWYgc3RydWN0IF9ScGNPYmpUeXBlTWFwCnsKICAvKiBGSVhNRTogYSBoYXNoIHRhYmxlIHdvdWxkIGJlIGJldHRlci4gKi8KICBzdHJ1Y3QgX1JwY09ialR5cGVNYXAgKm5leHQ7CiAgVVVJRCBPYmplY3Q7CiAgVVVJRCBUeXBlOwp9IFJwY09ialR5cGVNYXA7CgpzdGF0aWMgUnBjT2JqVHlwZU1hcCAqUnBjT2JqVHlwZU1hcHM7CgpzdGF0aWMgUnBjU2VydmVyUHJvdHNlcSogcHJvdHNlcXM7CnN0YXRpYyBScGNTZXJ2ZXJJbnRlcmZhY2UqIGlmczsKCnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OIHNlcnZlcl9jczsKc3RhdGljIENSSVRJQ0FMX1NFQ1RJT05fREVCVUcgc2VydmVyX2NzX2RlYnVnID0KewogICAgMCwgMCwgJnNlcnZlcl9jcywKICAgIHsgJnNlcnZlcl9jc19kZWJ1Zy5Qcm9jZXNzTG9ja3NMaXN0LCAmc2VydmVyX2NzX2RlYnVnLlByb2Nlc3NMb2Nrc0xpc3QgfSwKICAgICAgMCwgMCwgeyAoRFdPUkRfUFRSKShfX0ZJTEVfXyAiOiBzZXJ2ZXJfY3MiKSB9Cn07CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OIHNlcnZlcl9jcyA9IHsgJnNlcnZlcl9jc19kZWJ1ZywgLTEsIDAsIDAsIDAsIDAgfTsKCnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OIGxpc3Rlbl9jczsKc3RhdGljIENSSVRJQ0FMX1NFQ1RJT05fREVCVUcgbGlzdGVuX2NzX2RlYnVnID0KewogICAgMCwgMCwgJmxpc3Rlbl9jcywKICAgIHsgJmxpc3Rlbl9jc19kZWJ1Zy5Qcm9jZXNzTG9ja3NMaXN0LCAmbGlzdGVuX2NzX2RlYnVnLlByb2Nlc3NMb2Nrc0xpc3QgfSwKICAgICAgMCwgMCwgeyAoRFdPUkRfUFRSKShfX0ZJTEVfXyAiOiBsaXN0ZW5fY3MiKSB9Cn07CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OIGxpc3Rlbl9jcyA9IHsgJmxpc3Rlbl9jc19kZWJ1ZywgLTEsIDAsIDAsIDAsIDAgfTsKCi8qIHdoZXRoZXIgdGhlIHNlcnZlciBpcyBjdXJyZW50bHkgbGlzdGVuaW5nICovCnN0YXRpYyBCT09MIHN0ZF9saXN0ZW47Ci8qIG51bWJlciBvZiBtYW51YWwgbGlzdGVuZXJzIChjYWxscyB0byBScGNTZXJ2ZXJMaXN0ZW4pICovCnN0YXRpYyBMT05HIG1hbnVhbF9saXN0ZW5fY291bnQ7Ci8qIHRvdGFsIGxpc3RlbmVycyBpbmNsdWRpbmcgYXV0byBsaXN0ZW5lcnMgKi8Kc3RhdGljIExPTkcgbGlzdGVuX2NvdW50OwovKiBzZXQgb24gY2hhbmdlIG9mIGNvbmZpZ3VyYXRpb24gKGUuZy4gbGlzdGVuaW5nIG9uIG5ldyBwcm90c2VxKSAqLwpzdGF0aWMgSEFORExFIG1ncl9ldmVudDsKLyogbXV0ZXggZm9yIGVuc3VyaW5nIG9ubHkgb25lIHRocmVhZCBjYW4gY2hhbmdlIHN0YXRlIGF0IGEgdGltZSAqLwpzdGF0aWMgSEFORExFIG1ncl9tdXRleDsKLyogc2V0IHdoZW4gc2VydmVyIHRocmVhZCBoYXMgZmluaXNoZWQgb3BlbmluZyBjb25uZWN0aW9ucyAqLwpzdGF0aWMgSEFORExFIHNlcnZlcl9yZWFkeV9ldmVudDsKCnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OIHNwYWNrZXRfY3M7CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OX0RFQlVHIHNwYWNrZXRfY3NfZGVidWcgPQp7CiAgICAwLCAwLCAmc3BhY2tldF9jcywKICAgIHsgJnNwYWNrZXRfY3NfZGVidWcuUHJvY2Vzc0xvY2tzTGlzdCwgJnNwYWNrZXRfY3NfZGVidWcuUHJvY2Vzc0xvY2tzTGlzdCB9LAogICAgICAwLCAwLCB7IChEV09SRF9QVFIpKF9fRklMRV9fICI6IHNwYWNrZXRfY3MiKSB9Cn07CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OIHNwYWNrZXRfY3MgPSB7ICZzcGFja2V0X2NzX2RlYnVnLCAtMSwgMCwgMCwgMCwgMCB9OwoKc3RhdGljIFJwY1BhY2tldCogc3BhY2tldF9oZWFkOwpzdGF0aWMgUnBjUGFja2V0KiBzcGFja2V0X3RhaWw7CnN0YXRpYyBIQU5ETEUgc2VydmVyX3NlbTsKCnN0YXRpYyBMT05HIHdvcmtlcl9jb3VudCwgd29ya2VyX2ZyZWUsIHdvcmtlcl90bHM7CgpzdGF0aWMgVVVJRCB1dWlkX25pbDsKCmlubGluZSBzdGF0aWMgUnBjT2JqVHlwZU1hcCAqTG9va3VwT2JqVHlwZU1hcChVVUlEICpPYmpVdWlkKQp7CiAgUnBjT2JqVHlwZU1hcCAqcnNsdCA9IFJwY09ialR5cGVNYXBzOwogIFJQQ19TVEFUVVMgZHVtbXk7CgogIHdoaWxlIChyc2x0KSB7CiAgICBpZiAoISBVdWlkQ29tcGFyZShPYmpVdWlkLCAmcnNsdC0+T2JqZWN0LCAmZHVtbXkpKSBicmVhazsKICAgIHJzbHQgPSByc2x0LT5uZXh0OwogIH0KCiAgcmV0dXJuIHJzbHQ7Cn0KCmlubGluZSBzdGF0aWMgVVVJRCAqTG9va3VwT2JqVHlwZShVVUlEICpPYmpVdWlkKQp7CiAgUnBjT2JqVHlwZU1hcCAqbWFwID0gTG9va3VwT2JqVHlwZU1hcChPYmpVdWlkKTsKICBpZiAobWFwKQogICAgcmV0dXJuICZtYXAtPlR5cGU7CiAgZWxzZQogICAgcmV0dXJuICZ1dWlkX25pbDsKfQoKc3RhdGljIFJwY1NlcnZlckludGVyZmFjZSogUlBDUlQ0X2ZpbmRfaW50ZXJmYWNlKFVVSUQqIG9iamVjdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJQQ19TWU5UQVhfSURFTlRJRklFUiogaWZfaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCT09MIGNoZWNrX29iamVjdCkKewogIFVVSUQqIE1nclR5cGUgPSBOVUxMOwogIFJwY1NlcnZlckludGVyZmFjZSogY2lmID0gTlVMTDsKICBSUENfU1RBVFVTIHN0YXR1czsKCiAgaWYgKGNoZWNrX29iamVjdCkKICAgIE1nclR5cGUgPSBMb29rdXBPYmpUeXBlKG9iamVjdCk7CiAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnNlcnZlcl9jcyk7CiAgY2lmID0gaWZzOwogIHdoaWxlIChjaWYpIHsKICAgIGlmICghbWVtY21wKGlmX2lkLCAmY2lmLT5JZi0+SW50ZXJmYWNlSWQsIHNpemVvZihSUENfU1lOVEFYX0lERU5USUZJRVIpKSAmJgogICAgICAgIChjaGVja19vYmplY3QgPT0gRkFMU0UgfHwgVXVpZEVxdWFsKE1nclR5cGUsICZjaWYtPk1nclR5cGVVdWlkLCAmc3RhdHVzKSkgJiYKICAgICAgICBzdGRfbGlzdGVuKSBicmVhazsKICAgIGNpZiA9IGNpZi0+TmV4dDsKICB9CiAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnNlcnZlcl9jcyk7CiAgVFJBQ0UoInJldHVybmluZyAlcCBmb3IgJXNcbiIsIGNpZiwgZGVidWdzdHJfZ3VpZChvYmplY3QpKTsKICByZXR1cm4gY2lmOwp9CgpzdGF0aWMgdm9pZCBSUENSVDRfcHVzaF9wYWNrZXQoUnBjUGFja2V0KiBwYWNrZXQpCnsKICBwYWNrZXQtPm5leHQgPSBOVUxMOwogIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZzcGFja2V0X2NzKTsKICBpZiAoc3BhY2tldF90YWlsKSB7CiAgICBzcGFja2V0X3RhaWwtPm5leHQgPSBwYWNrZXQ7CiAgICBzcGFja2V0X3RhaWwgPSBwYWNrZXQ7CiAgfSBlbHNlIHsKICAgIHNwYWNrZXRfaGVhZCA9IHBhY2tldDsKICAgIHNwYWNrZXRfdGFpbCA9IHBhY2tldDsKICB9CiAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnNwYWNrZXRfY3MpOwp9CgpzdGF0aWMgUnBjUGFja2V0KiBSUENSVDRfcG9wX3BhY2tldCh2b2lkKQp7CiAgUnBjUGFja2V0KiBwYWNrZXQ7CiAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnNwYWNrZXRfY3MpOwogIHBhY2tldCA9IHNwYWNrZXRfaGVhZDsKICBpZiAocGFja2V0KSB7CiAgICBzcGFja2V0X2hlYWQgPSBwYWNrZXQtPm5leHQ7CiAgICBpZiAoIXNwYWNrZXRfaGVhZCkgc3BhY2tldF90YWlsID0gTlVMTDsKICB9CiAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnNwYWNrZXRfY3MpOwogIGlmIChwYWNrZXQpIHBhY2tldC0+bmV4dCA9IE5VTEw7CiAgcmV0dXJuIHBhY2tldDsKfQoKdHlwZWRlZiBzdHJ1Y3QgewogIFBSUENfTUVTU0FHRSBtc2c7CiAgdm9pZCogYnVmOwp9IHBhY2tldF9zdGF0ZTsKCnN0YXRpYyBXSU5FX0VYQ0VQVElPTl9GSUxURVIocnBjX2ZpbHRlcikKewogIHBhY2tldF9zdGF0ZSogc3RhdGU7CiAgUFJQQ19NRVNTQUdFIG1zZzsKICBzdGF0ZSA9IFRsc0dldFZhbHVlKHdvcmtlcl90bHMpOwogIG1zZyA9IHN0YXRlLT5tc2c7CiAgaWYgKG1zZy0+QnVmZmVyICE9IHN0YXRlLT5idWYpIElfUnBjRnJlZUJ1ZmZlcihtc2cpOwogIG1zZy0+UnBjRmxhZ3MgfD0gV0lORV9SUENGTEFHX0VYQ0VQVElPTjsKICBtc2ctPkJ1ZmZlckxlbmd0aCA9IHNpemVvZihEV09SRCk7CiAgSV9ScGNHZXRCdWZmZXIobXNnKTsKICAqKERXT1JEKiltc2ctPkJ1ZmZlciA9IEdldEV4Y2VwdGlvbkNvZGUoKTsKICBXQVJOKCJleGNlcHRpb24gY2F1Z2h0IHdpdGggY29kZSAweCUwOGx4ID0gJWxkXG4iLCAqKERXT1JEKiltc2ctPkJ1ZmZlciwgKihEV09SRCopbXNnLT5CdWZmZXIpOwogIFRSQUNFKCJyZXR1cm5pbmcgZmFpbHVyZSBwYWNrZXRcbiIpOwogIHJldHVybiBFWENFUFRJT05fRVhFQ1VURV9IQU5ETEVSOwp9CgpzdGF0aWMgdm9pZCBSUENSVDRfcHJvY2Vzc19wYWNrZXQoUnBjQ29ubmVjdGlvbiogY29ubiwgUnBjUGt0SGRyKiBoZHIsIFJQQ19NRVNTQUdFKiBtc2cpCnsKICBScGNTZXJ2ZXJJbnRlcmZhY2UqIHNpZjsKICBSUENfRElTUEFUQ0hfRlVOQ1RJT04gZnVuYzsKICBwYWNrZXRfc3RhdGUgc3RhdGU7CiAgVVVJRCAqb2JqZWN0X3V1aWQ7CiAgUnBjUGt0SGRyICpyZXNwb25zZTsKICB2b2lkICpidWYgPSBtc2ctPkJ1ZmZlcjsKICBSUENfU1RBVFVTIHN0YXR1czsKCiAgc3RhdGUubXNnID0gbXNnOwogIHN0YXRlLmJ1ZiA9IGJ1ZjsKICBUbHNTZXRWYWx1ZSh3b3JrZXJfdGxzLCAmc3RhdGUpOwoKICBzd2l0Y2ggKGhkci0+Y29tbW9uLnB0eXBlKSB7CiAgICBjYXNlIFBLVF9CSU5EOgogICAgICBUUkFDRSgiZ290IGJpbmQgcGFja2V0XG4iKTsKCiAgICAgIC8qIEZJWE1FOiBkbyBtb3JlIGNoZWNrcyEgKi8KICAgICAgaWYgKGhkci0+YmluZC5tYXhfdHNpemUgPCBSUENfTUlOX1BBQ0tFVF9TSVpFIHx8CiAgICAgICAgICAhVXVpZElzTmlsKCZjb25uLT5BY3RpdmVJbnRlcmZhY2UuU3ludGF4R1VJRCwgJnN0YXR1cykpIHsKICAgICAgICBUUkFDRSgicGFja2V0IHNpemUgbGVzcyB0aGFuIG1pbiBzaXplLCBvciBhY3RpdmUgaW50ZXJmYWNlIHN5bnRheCBndWlkIG5vbi1udWxsXG4iKTsKICAgICAgICBzaWYgPSBOVUxMOwogICAgICB9IGVsc2UgewogICAgICAgIHNpZiA9IFJQQ1JUNF9maW5kX2ludGVyZmFjZShOVUxMLCAmaGRyLT5iaW5kLmFic3RyYWN0LCBGQUxTRSk7CiAgICAgIH0KICAgICAgaWYgKHNpZiA9PSBOVUxMKSB7CiAgICAgICAgVFJBQ0UoInJlamVjdGluZyBiaW5kIHJlcXVlc3Qgb24gY29ubmVjdGlvbiAlcFxuIiwgY29ubik7CiAgICAgICAgLyogUmVwb3J0IGZhaWx1cmUgdG8gY2xpZW50LiAqLwogICAgICAgIHJlc3BvbnNlID0gUlBDUlQ0X0J1aWxkQmluZE5hY2tIZWFkZXIoTkRSX0xPQ0FMX0RBVEFfUkVQUkVTRU5UQVRJT04sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSUENfVkVSX01BSk9SLCBSUENfVkVSX01JTk9SKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBUUkFDRSgiYWNjZXB0aW5nIGJpbmQgcmVxdWVzdCBvbiBjb25uZWN0aW9uICVwXG4iLCBjb25uKTsKCiAgICAgICAgLyogYWNjZXB0LiAqLwogICAgICAgIHJlc3BvbnNlID0gUlBDUlQ0X0J1aWxkQmluZEFja0hlYWRlcihORFJfTE9DQUxfREFUQV9SRVBSRVNFTlRBVElPTiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUlBDX01BWF9QQUNLRVRfU0laRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUlBDX01BWF9QQUNLRVRfU0laRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubi0+RW5kcG9pbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFU1VMVF9BQ0NFUFQsIE5PX1JFQVNPTiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnNpZi0+SWYtPlRyYW5zZmVyU3ludGF4KTsKCiAgICAgICAgLyogc2F2ZSB0aGUgaW50ZXJmYWNlIGZvciBsYXRlciB1c2UgKi8KICAgICAgICBjb25uLT5BY3RpdmVJbnRlcmZhY2UgPSBoZHItPmJpbmQuYWJzdHJhY3Q7CiAgICAgICAgY29ubi0+TWF4VHJhbnNtaXNzaW9uU2l6ZSA9IGhkci0+YmluZC5tYXhfdHNpemU7CiAgICAgIH0KCiAgICAgIGlmIChSUENSVDRfU2VuZChjb25uLCByZXNwb25zZSwgTlVMTCwgMCkgIT0gUlBDX1NfT0spCiAgICAgICAgZ290byBmYWlsOwoKICAgICAgYnJlYWs7CgogICAgY2FzZSBQS1RfUkVRVUVTVDoKICAgICAgVFJBQ0UoImdvdCByZXF1ZXN0IHBhY2tldFxuIik7CgogICAgICAvKiBmYWlsIGlmIHRoZSBjb25uZWN0aW9uIGlzbid0IGJvdW5kIHdpdGggYW4gaW50ZXJmYWNlICovCiAgICAgIGlmIChVdWlkSXNOaWwoJmNvbm4tPkFjdGl2ZUludGVyZmFjZS5TeW50YXhHVUlELCAmc3RhdHVzKSkgewogICAgICAgIHJlc3BvbnNlID0gUlBDUlQ0X0J1aWxkRmF1bHRIZWFkZXIoTkRSX0xPQ0FMX0RBVEFfUkVQUkVTRU5UQVRJT04sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXMpOwoKICAgICAgICBSUENSVDRfU2VuZChjb25uLCByZXNwb25zZSwgTlVMTCwgMCk7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KCiAgICAgIGlmIChoZHItPmNvbW1vbi5mbGFncyAmIFJQQ19GTEdfT0JKRUNUX1VVSUQpIHsKICAgICAgICBvYmplY3RfdXVpZCA9IChVVUlEKikoJmhkci0+cmVxdWVzdCArIDEpOwogICAgICB9IGVsc2UgewogICAgICAgIG9iamVjdF91dWlkID0gTlVMTDsKICAgICAgfQoKICAgICAgc2lmID0gUlBDUlQ0X2ZpbmRfaW50ZXJmYWNlKG9iamVjdF91dWlkLCAmY29ubi0+QWN0aXZlSW50ZXJmYWNlLCBUUlVFKTsKICAgICAgbXNnLT5ScGNJbnRlcmZhY2VJbmZvcm1hdGlvbiA9IHNpZi0+SWY7CiAgICAgIC8qIGNvcHkgdGhlIGVuZHBvaW50IHZlY3RvciBmcm9tIHNpZiB0byBtc2cgc28gdGhhdCBtaWRsLWdlbmVyYXRlZCBjb2RlIHdpbGwgdXNlIGl0ICovCiAgICAgIG1zZy0+TWFuYWdlckVwdiA9IHNpZi0+TWdyRXB2OwogICAgICBpZiAob2JqZWN0X3V1aWQgIT0gTlVMTCkgewogICAgICAgIFJQQ1JUNF9TZXRCaW5kaW5nT2JqZWN0KG1zZy0+SGFuZGxlLCBvYmplY3RfdXVpZCk7CiAgICAgIH0KCiAgICAgIC8qIGZpbmQgZGlzcGF0Y2ggZnVuY3Rpb24gKi8KICAgICAgbXNnLT5Qcm9jTnVtID0gaGRyLT5yZXF1ZXN0Lm9wbnVtOwogICAgICBpZiAoc2lmLT5GbGFncyAmIFJQQ19JRl9PTEUpIHsKICAgICAgICAvKiBuYXRpdmUgb2xlMzIgYWx3YXlzIGdpdmVzIHVzIGEgZGlzcGF0Y2ggdGFibGUgd2l0aCBhIHNpbmdsZSBlbnRyeQogICAgICAgICAqIChJIGFzc3VtZSB0aGF0J3MgYSB3cmFwcGVyIGZvciBJUnBjU3R1YkJ1ZmZlcjo6SW52b2tlKSAqLwogICAgICAgIGZ1bmMgPSAqc2lmLT5JZi0+RGlzcGF0Y2hUYWJsZS0+RGlzcGF0Y2hUYWJsZTsKICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAobXNnLT5Qcm9jTnVtID49IHNpZi0+SWYtPkRpc3BhdGNoVGFibGUtPkRpc3BhdGNoVGFibGVDb3VudCkgewogICAgICAgICAgRVJSKCJpbnZhbGlkIHByb2NudW1cbiIpOwogICAgICAgICAgZnVuYyA9IE5VTEw7CiAgICAgICAgfQogICAgICAgIGZ1bmMgPSBzaWYtPklmLT5EaXNwYXRjaFRhYmxlLT5EaXNwYXRjaFRhYmxlW21zZy0+UHJvY051bV07CiAgICAgIH0KCiAgICAgIC8qIHB1dCBpbiB0aGUgZHJlcC4gRklYTUU6IGlzIHRoaXMgbW9yZSB1bml2ZXJzYWxseSBhcHBsaWNhYmxlPwogICAgICAgICBwZXJoYXBzIHdlIHNob3VsZCBtb3ZlIHRoaXMgb3V0d2FyZC4uLiAqLwogICAgICBtc2ctPkRhdGFSZXByZXNlbnRhdGlvbiA9IAogICAgICAgIE1BS0VMT05HKCBNQUtFV09SRChoZHItPmNvbW1vbi5kcmVwWzBdLCBoZHItPmNvbW1vbi5kcmVwWzFdKSwKICAgICAgICAgICAgICAgICAgTUFLRVdPUkQoaGRyLT5jb21tb24uZHJlcFsyXSwgaGRyLT5jb21tb24uZHJlcFszXSkpOwoKICAgICAgLyogZGlzcGF0Y2ggKi8KICAgICAgX19UUlkgewogICAgICAgIGlmIChmdW5jKSBmdW5jKG1zZyk7CiAgICAgIH0gX19FWENFUFQocnBjX2ZpbHRlcikgewogICAgICAgIC8qIGZhaWx1cmUgcGFja2V0IHdhcyBjcmVhdGVkIGluIHJwY19maWx0ZXIgKi8KICAgICAgfSBfX0VORFRSWQoKICAgICAgLyogc2VuZCByZXNwb25zZSBwYWNrZXQgKi8KICAgICAgSV9ScGNTZW5kKG1zZyk7CgogICAgICBtc2ctPlJwY0ludGVyZmFjZUluZm9ybWF0aW9uID0gTlVMTDsKCiAgICAgIGJyZWFrOwoKICAgIGRlZmF1bHQ6CiAgICAgIEZJWE1FKCJ1bmhhbmRsZWQgcGFja2V0IHR5cGVcbiIpOwogICAgICBicmVhazsKICB9CgpmYWlsOgogIC8qIGNsZWFuIHVwICovCiAgaWYgKG1zZy0+QnVmZmVyID09IGJ1ZikgbXNnLT5CdWZmZXIgPSBOVUxMOwogIFRSQUNFKCJmcmVlaW5nIEJ1ZmZlcj0lcFxuIiwgYnVmKTsKICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBidWYpOwogIFJQQ1JUNF9EZXN0cm95QmluZGluZyhtc2ctPkhhbmRsZSk7CiAgbXNnLT5IYW5kbGUgPSAwOwogIElfUnBjRnJlZUJ1ZmZlcihtc2cpOwogIG1zZy0+QnVmZmVyID0gTlVMTDsKICBSUENSVDRfRnJlZUhlYWRlcihoZHIpOwogIFRsc1NldFZhbHVlKHdvcmtlcl90bHMsIE5VTEwpOwp9CgpzdGF0aWMgRFdPUkQgQ0FMTEJBQ0sgUlBDUlQ0X3dvcmtlcl90aHJlYWQoTFBWT0lEIHRoZV9hcmcpCnsKICBEV09SRCBvYmo7CiAgUnBjUGFja2V0KiBwa3Q7CgogIGZvciAoOzspIHsKICAgIC8qIGlkbGUgdGltZW91dCBhZnRlciA1cyAqLwogICAgb2JqID0gV2FpdEZvclNpbmdsZU9iamVjdChzZXJ2ZXJfc2VtLCA1MDAwKTsKICAgIGlmIChvYmogPT0gV0FJVF9USU1FT1VUKSB7CiAgICAgIC8qIGlmIGFub3RoZXIgaWRsZSB0aHJlYWQgZXhpc3QsIHNlbGYtZGVzdHJ1Y3QgKi8KICAgICAgaWYgKHdvcmtlcl9mcmVlID4gMSkgYnJlYWs7CiAgICAgIGNvbnRpbnVlOwogICAgfQogICAgcGt0ID0gUlBDUlQ0X3BvcF9wYWNrZXQoKTsKICAgIGlmICghcGt0KSBjb250aW51ZTsKICAgIEludGVybG9ja2VkRGVjcmVtZW50KCZ3b3JrZXJfZnJlZSk7CiAgICBmb3IgKDs7KSB7CiAgICAgIFJQQ1JUNF9wcm9jZXNzX3BhY2tldChwa3QtPmNvbm4sIHBrdC0+aGRyLCBwa3QtPm1zZyk7CiAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBrdCk7CiAgICAgIC8qIHRyeSB0byBncmFiIGFub3RoZXIgcGFja2V0IGhlcmUgd2l0aG91dCB3YWl0aW5nCiAgICAgICAqIG9uIHRoZSBzZW1hcGhvcmUsIGluIGNhc2UgaXQgaGl0cyBtYXggKi8KICAgICAgcGt0ID0gUlBDUlQ0X3BvcF9wYWNrZXQoKTsKICAgICAgaWYgKCFwa3QpIGJyZWFrOwogICAgICAvKiBkZWNyZW1lbnQgc2VtYXBob3JlICovCiAgICAgIFdhaXRGb3JTaW5nbGVPYmplY3Qoc2VydmVyX3NlbSwgMCk7CiAgICB9CiAgICBJbnRlcmxvY2tlZEluY3JlbWVudCgmd29ya2VyX2ZyZWUpOwogIH0KICBJbnRlcmxvY2tlZERlY3JlbWVudCgmd29ya2VyX2ZyZWUpOwogIEludGVybG9ja2VkRGVjcmVtZW50KCZ3b3JrZXJfY291bnQpOwogIHJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBSUENSVDRfY3JlYXRlX3dvcmtlcl9pZl9uZWVkZWQodm9pZCkKewogIGlmICghd29ya2VyX2ZyZWUgJiYgd29ya2VyX2NvdW50IDwgTUFYX1RIUkVBRFMpIHsKICAgIEhBTkRMRSB0aHJlYWQ7CiAgICBJbnRlcmxvY2tlZEluY3JlbWVudCgmd29ya2VyX2NvdW50KTsKICAgIEludGVybG9ja2VkSW5jcmVtZW50KCZ3b3JrZXJfZnJlZSk7CiAgICB0aHJlYWQgPSBDcmVhdGVUaHJlYWQoTlVMTCwgMCwgUlBDUlQ0X3dvcmtlcl90aHJlYWQsIE5VTEwsIDAsIE5VTEwpOwogICAgaWYgKHRocmVhZCkgQ2xvc2VIYW5kbGUodGhyZWFkKTsKICAgIGVsc2UgewogICAgICBJbnRlcmxvY2tlZERlY3JlbWVudCgmd29ya2VyX2ZyZWUpOwogICAgICBJbnRlcmxvY2tlZERlY3JlbWVudCgmd29ya2VyX2NvdW50KTsKICAgIH0KICB9Cn0KCnN0YXRpYyBEV09SRCBDQUxMQkFDSyBSUENSVDRfaW9fdGhyZWFkKExQVk9JRCB0aGVfYXJnKQp7CiAgUnBjQ29ubmVjdGlvbiogY29ubiA9IChScGNDb25uZWN0aW9uKil0aGVfYXJnOwogIFJwY1BrdEhkciAqaGRyOwogIFJwY0JpbmRpbmcgKnBiaW5kOwogIFJQQ19NRVNTQUdFICptc2c7CiAgUlBDX1NUQVRVUyBzdGF0dXM7CiAgUnBjUGFja2V0ICpwYWNrZXQ7CgogIFRSQUNFKCIoJXApXG4iLCBjb25uKTsKCiAgZm9yICg7OykgewogICAgbXNnID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihSUENfTUVTU0FHRSkpOwoKICAgIC8qIGNyZWF0ZSB0ZW1wb3JhcnkgYmluZGluZyBmb3IgZGlzcGF0Y2gsIGl0IHdpbGwgYmUgZnJlZWQgaW4KICAgICAqIFJQQ1JUNF9wcm9jZXNzX3BhY2tldCAqLwogICAgUlBDUlQ0X01ha2VCaW5kaW5nKCZwYmluZCwgY29ubik7CiAgICBtc2ctPkhhbmRsZSA9IChSUENfQklORElOR19IQU5ETEUpcGJpbmQ7CgogICAgc3RhdHVzID0gUlBDUlQ0X1JlY2VpdmUoY29ubiwgJmhkciwgbXNnKTsKICAgIGlmIChzdGF0dXMgIT0gUlBDX1NfT0spIHsKICAgICAgV0FSTigicmVjZWl2ZSBmYWlsZWQgd2l0aCBlcnJvciAlbHhcbiIsIHN0YXR1cyk7CiAgICAgIGJyZWFrOwogICAgfQoKI2lmIDAKICAgIFJQQ1JUNF9wcm9jZXNzX3BhY2tldChjb25uLCBoZHIsIG1zZyk7CiNlbHNlCiAgICBwYWNrZXQgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKFJwY1BhY2tldCkpOwogICAgcGFja2V0LT5jb25uID0gY29ubjsKICAgIHBhY2tldC0+aGRyID0gaGRyOwogICAgcGFja2V0LT5tc2cgPSBtc2c7CiAgICBSUENSVDRfY3JlYXRlX3dvcmtlcl9pZl9uZWVkZWQoKTsKICAgIFJQQ1JUNF9wdXNoX3BhY2tldChwYWNrZXQpOwogICAgUmVsZWFzZVNlbWFwaG9yZShzZXJ2ZXJfc2VtLCAxLCBOVUxMKTsKI2VuZGlmCiAgICBtc2cgPSBOVUxMOwogIH0KICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBtc2cpOwogIFJQQ1JUNF9EZXN0cm95Q29ubmVjdGlvbihjb25uKTsKICByZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgUlBDUlQ0X25ld19jbGllbnQoUnBjQ29ubmVjdGlvbiogY29ubikKewogIEhBTkRMRSB0aHJlYWQgPSBDcmVhdGVUaHJlYWQoTlVMTCwgMCwgUlBDUlQ0X2lvX3RocmVhZCwgY29ubiwgMCwgTlVMTCk7CiAgaWYgKCF0aHJlYWQpIHsKICAgIERXT1JEIGVyciA9IEdldExhc3RFcnJvcigpOwogICAgRVJSKCJmYWlsZWQgdG8gY3JlYXRlIHRocmVhZCwgZXJyb3I9JTA4bHhcbiIsIGVycik7CiAgICBSUENSVDRfRGVzdHJveUNvbm5lY3Rpb24oY29ubik7CiAgfQogIC8qIHdlIGNvdWxkIHNldCBjb25uLT50aHJlYWQsIGJ1dCB0aGVuIHdlJ2QgaGF2ZSB0byBtYWtlIHRoZSBpb190aHJlYWQgd2FpdAogICAqIGZvciB0aGF0LCBvdGhlcndpc2UgdGhlIHRocmVhZCBtaWdodCBmaW5pc2gsIGRlc3Ryb3kgdGhlIGNvbm5lY3Rpb24sIGFuZAogICAqIGZyZWUgdGhlIG1lbW9yeSB3ZSdkIHdyaXRlIHRvIGJlZm9yZSB3ZSBkaWQsIGNhdXNpbmcgY3Jhc2hlcyBhbmQgc3R1ZmYgLQogICAqIHNvIGxldCdzIGltcGxlbWVudCB0aGF0IGxhdGVyLCB3aGVuIHdlIHJlYWxseSBuZWVkIGNvbm4tPnRocmVhZCAqLwoKICBDbG9zZUhhbmRsZSggdGhyZWFkICk7Cn0KCnN0YXRpYyBEV09SRCBDQUxMQkFDSyBSUENSVDRfc2VydmVyX3RocmVhZChMUFZPSUQgdGhlX2FyZykKewogIEhBTkRMRSBtX2V2ZW50ID0gbWdyX2V2ZW50LCBiX2hhbmRsZTsKICBIQU5ETEUgKm9ianMgPSBOVUxMOwogIERXT1JEIGNvdW50LCByZXM7CiAgUnBjU2VydmVyUHJvdHNlcSogY3BzOwogIFJwY0Nvbm5lY3Rpb24qIGNvbm47CiAgUnBjQ29ubmVjdGlvbiogY2Nvbm47CiAgQk9PTCBzZXRfcmVhZHlfZXZlbnQgPSBGQUxTRTsKCiAgVFJBQ0UoIih0aGVfYXJnID09IF4lcClcbiIsIHRoZV9hcmcpOwoKICBmb3IgKDs7KSB7CiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmc2VydmVyX2NzKTsKICAgIC8qIG9wZW4gYW5kIGNvdW50IGNvbm5lY3Rpb25zICovCiAgICBjb3VudCA9IDE7CiAgICBjcHMgPSBwcm90c2VxczsKICAgIHdoaWxlIChjcHMpIHsKICAgICAgY29ubiA9IGNwcy0+Y29ubjsKICAgICAgd2hpbGUgKGNvbm4pIHsKICAgICAgICBSUENSVDRfT3BlbkNvbm5lY3Rpb24oY29ubik7CiAgICAgICAgaWYgKGNvbm4tPm92bC5oRXZlbnQpIGNvdW50Kys7CiAgICAgICAgY29ubiA9IGNvbm4tPk5leHQ7CiAgICAgIH0KICAgICAgY3BzID0gY3BzLT5OZXh0OwogICAgfQogICAgLyogbWFrZSBhcnJheSBvZiBjb25uZWN0aW9ucyAqLwogICAgaWYgKG9ianMpCglvYmpzID0gSGVhcFJlQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb2JqcywgY291bnQqc2l6ZW9mKEhBTkRMRSkpOwogICAgZWxzZQoJb2JqcyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBjb3VudCpzaXplb2YoSEFORExFKSk7CgogICAgb2Jqc1swXSA9IG1fZXZlbnQ7CiAgICBjb3VudCA9IDE7CiAgICBjcHMgPSBwcm90c2VxczsKICAgIHdoaWxlIChjcHMpIHsKICAgICAgY29ubiA9IGNwcy0+Y29ubjsKICAgICAgd2hpbGUgKGNvbm4pIHsKICAgICAgICBpZiAoY29ubi0+b3ZsLmhFdmVudCkgb2Jqc1tjb3VudCsrXSA9IGNvbm4tPm92bC5oRXZlbnQ7CiAgICAgICAgY29ubiA9IGNvbm4tPk5leHQ7CiAgICAgIH0KICAgICAgY3BzID0gY3BzLT5OZXh0OwogICAgfQogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnNlcnZlcl9jcyk7CgogICAgaWYgKHNldF9yZWFkeV9ldmVudCkKICAgIHsKICAgICAgICAvKiBzaWduYWwgdG8gZnVuY3Rpb24gdGhhdCBjaGFuZ2VkIHN0YXRlIHRoYXQgd2UgYXJlIG5vdyBzeW5jJ2VkICovCiAgICAgICAgU2V0RXZlbnQoc2VydmVyX3JlYWR5X2V2ZW50KTsKICAgICAgICBzZXRfcmVhZHlfZXZlbnQgPSBGQUxTRTsKICAgIH0KCiAgICAvKiBzdGFydCB3YWl0aW5nICovCiAgICByZXMgPSBXYWl0Rm9yTXVsdGlwbGVPYmplY3RzKGNvdW50LCBvYmpzLCBGQUxTRSwgSU5GSU5JVEUpOwogICAgaWYgKHJlcyA9PSBXQUlUX09CSkVDVF8wKSB7CiAgICAgIGlmICghc3RkX2xpc3RlbikKICAgICAgewogICAgICAgIFNldEV2ZW50KHNlcnZlcl9yZWFkeV9ldmVudCk7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgc2V0X3JlYWR5X2V2ZW50ID0gVFJVRTsKICAgIH0KICAgIGVsc2UgaWYgKHJlcyA9PSBXQUlUX0ZBSUxFRCkgewogICAgICBFUlIoIndhaXQgZmFpbGVkXG4iKTsKICAgIH0KICAgIGVsc2UgewogICAgICBiX2hhbmRsZSA9IG9ianNbcmVzIC0gV0FJVF9PQkpFQ1RfMF07CiAgICAgIC8qIGZpbmQgd2hpY2ggY29ubmVjdGlvbiBnb3QgYSBSUEMgKi8KICAgICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnNlcnZlcl9jcyk7CiAgICAgIGNvbm4gPSBOVUxMOwogICAgICBjcHMgPSBwcm90c2VxczsKICAgICAgd2hpbGUgKGNwcykgewogICAgICAgIGNvbm4gPSBjcHMtPmNvbm47CiAgICAgICAgd2hpbGUgKGNvbm4pIHsKICAgICAgICAgIGlmIChjb25uLT5vdmwuaEV2ZW50ID09IGJfaGFuZGxlKSBicmVhazsKICAgICAgICAgIGNvbm4gPSBjb25uLT5OZXh0OwogICAgICAgIH0KICAgICAgICBpZiAoY29ubikgYnJlYWs7CiAgICAgICAgY3BzID0gY3BzLT5OZXh0OwogICAgICB9CiAgICAgIGNjb25uID0gTlVMTDsKICAgICAgaWYgKGNvbm4pIFJQQ1JUNF9TcGF3bkNvbm5lY3Rpb24oJmNjb25uLCBjb25uKTsKICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnNlcnZlcl9jcyk7CiAgICAgIGlmICghY29ubikgewogICAgICAgIEVSUigiZmFpbGVkIHRvIGxvY2F0ZSBjb25uZWN0aW9uIGZvciBoYW5kbGUgJXBcbiIsIGJfaGFuZGxlKTsKICAgICAgfQogICAgICBpZiAoY2Nvbm4pIFJQQ1JUNF9uZXdfY2xpZW50KGNjb25uKTsKICAgIH0KICB9CiAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb2Jqcyk7CiAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnNlcnZlcl9jcyk7CiAgLyogY2xvc2UgY29ubmVjdGlvbnMgKi8KICBjcHMgPSBwcm90c2VxczsKICB3aGlsZSAoY3BzKSB7CiAgICBjb25uID0gY3BzLT5jb25uOwogICAgd2hpbGUgKGNvbm4pIHsKICAgICAgUlBDUlQ0X0Nsb3NlQ29ubmVjdGlvbihjb25uKTsKICAgICAgY29ubiA9IGNvbm4tPk5leHQ7CiAgICB9CiAgICBjcHMgPSBjcHMtPk5leHQ7CiAgfQogIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZzZXJ2ZXJfY3MpOwogIHJldHVybiAwOwp9CgovKiB0ZWxscyB0aGUgc2VydmVyIHRocmVhZCB0aGF0IHRoZSBzdGF0ZSBoYXMgY2hhbmdlZCBhbmQgd2FpdHMgZm9yIGl0IHRvCiAqIG1ha2UgdGhlIGNoYW5nZXMgKi8Kc3RhdGljIHZvaWQgUlBDUlQ0X3N5bmNfd2l0aF9zZXJ2ZXJfdGhyZWFkKHZvaWQpCnsKICAvKiBtYWtlIHN1cmUgd2UgYXJlIHRoZSBvbmx5IHRocmVhZCBzeW5jJ2luZyB0aGUgc2VydmVyIHN0YXRlLCBvdGhlcndpc2UKICAgKiB0aGVyZSBpcyBhIHJhY2Ugd2l0aCB0aGUgc2VydmVyIHRocmVhZCBzZXR0aW5nIGFuIG9sZGVyIHN0YXRlIGFuZCBzZXR0aW5nCiAgICogdGhlIHNlcnZlcl9yZWFkeV9ldmVudCB3aGVuIHRoZSBuZXcgc3RhdGUgaGFzbid0IHlldCBiZWVuIGFwcGxpZWQgKi8KICBXYWl0Rm9yU2luZ2xlT2JqZWN0KG1ncl9tdXRleCwgSU5GSU5JVEUpOwoKICBTZXRFdmVudChtZ3JfZXZlbnQpOwogIC8qIHdhaXQgZm9yIHNlcnZlciB0aHJlYWQgdG8gbWFrZSB0aGUgcmVxdWVzdGVkIGNoYW5nZXMgYmVmb3JlIHJldHVybmluZyAqLwogIFdhaXRGb3JTaW5nbGVPYmplY3Qoc2VydmVyX3JlYWR5X2V2ZW50LCBJTkZJTklURSk7CgogIFJlbGVhc2VNdXRleChtZ3JfbXV0ZXgpOwp9CgpzdGF0aWMgUlBDX1NUQVRVUyBSUENSVDRfc3RhcnRfbGlzdGVuKEJPT0wgYXV0b19saXN0ZW4pCnsKICBSUENfU1RBVFVTIHN0YXR1cyA9IFJQQ19TX0FMUkVBRFlfTElTVEVOSU5HOwoKICBUUkFDRSgiXG4iKTsKCiAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmxpc3Rlbl9jcyk7CiAgaWYgKGF1dG9fbGlzdGVuIHx8IChtYW51YWxfbGlzdGVuX2NvdW50KysgPT0gMCkpCiAgewogICAgc3RhdHVzID0gUlBDX1NfT0s7CiAgICBpZiAoKytsaXN0ZW5fY291bnQgPT0gMSkgewogICAgICBIQU5ETEUgc2VydmVyX3RocmVhZDsKICAgICAgLyogZmlyc3QgbGlzdGVuZXIgY3JlYXRlcyBzZXJ2ZXIgdGhyZWFkICovCiAgICAgIGlmICghbWdyX211dGV4KSBtZ3JfbXV0ZXggPSBDcmVhdGVNdXRleFcoTlVMTCwgRkFMU0UsIE5VTEwpOwogICAgICBpZiAoIW1ncl9ldmVudCkgbWdyX2V2ZW50ID0gQ3JlYXRlRXZlbnRXKE5VTEwsIEZBTFNFLCBGQUxTRSwgTlVMTCk7CiAgICAgIGlmICghc2VydmVyX3JlYWR5X2V2ZW50KSBzZXJ2ZXJfcmVhZHlfZXZlbnQgPSBDcmVhdGVFdmVudFcoTlVMTCwgRkFMU0UsIEZBTFNFLCBOVUxMKTsKICAgICAgaWYgKCFzZXJ2ZXJfc2VtKSBzZXJ2ZXJfc2VtID0gQ3JlYXRlU2VtYXBob3JlVyhOVUxMLCAwLCBNQVhfVEhSRUFEUywgTlVMTCk7CiAgICAgIGlmICghd29ya2VyX3Rscykgd29ya2VyX3RscyA9IFRsc0FsbG9jKCk7CiAgICAgIHN0ZF9saXN0ZW4gPSBUUlVFOwogICAgICBzZXJ2ZXJfdGhyZWFkID0gQ3JlYXRlVGhyZWFkKE5VTEwsIDAsIFJQQ1JUNF9zZXJ2ZXJfdGhyZWFkLCBOVUxMLCAwLCBOVUxMKTsKICAgICAgQ2xvc2VIYW5kbGUoc2VydmVyX3RocmVhZCk7CiAgICB9CiAgfQogIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZsaXN0ZW5fY3MpOwoKICByZXR1cm4gc3RhdHVzOwp9CgpzdGF0aWMgdm9pZCBSUENSVDRfc3RvcF9saXN0ZW4oQk9PTCBhdXRvX2xpc3RlbikKewogIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZsaXN0ZW5fY3MpOwogIGlmIChhdXRvX2xpc3RlbiB8fCAoLS1tYW51YWxfbGlzdGVuX2NvdW50ID09IDApKQogIHsKICAgIGlmIChsaXN0ZW5fY291bnQgIT0gMCAmJiAtLWxpc3Rlbl9jb3VudCA9PSAwKSB7CiAgICAgIHN0ZF9saXN0ZW4gPSBGQUxTRTsKICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmxpc3Rlbl9jcyk7CiAgICAgIFJQQ1JUNF9zeW5jX3dpdGhfc2VydmVyX3RocmVhZCgpOwogICAgICByZXR1cm47CiAgICB9CiAgICBhc3NlcnQobGlzdGVuX2NvdW50ID49IDApOwogIH0KICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmbGlzdGVuX2NzKTsKfQoKc3RhdGljIFJQQ19TVEFUVVMgUlBDUlQ0X3VzZV9wcm90c2VxKFJwY1NlcnZlclByb3RzZXEqIHBzKQp7CiAgUlBDUlQ0X0NyZWF0ZUNvbm5lY3Rpb24oJnBzLT5jb25uLCBUUlVFLCBwcy0+UHJvdHNlcSwgTlVMTCwgcHMtPkVuZHBvaW50LCBOVUxMLCBOVUxMKTsKCiAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnNlcnZlcl9jcyk7CiAgcHMtPk5leHQgPSBwcm90c2VxczsKICBwcm90c2VxcyA9IHBzOwogIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZzZXJ2ZXJfY3MpOwoKICBpZiAoc3RkX2xpc3RlbikgUlBDUlQ0X3N5bmNfd2l0aF9zZXJ2ZXJfdGhyZWFkKCk7CgogIHJldHVybiBSUENfU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1NlcnZlcklucUJpbmRpbmdzIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1NlcnZlcklucUJpbmRpbmdzKCBSUENfQklORElOR19WRUNUT1IqKiBCaW5kaW5nVmVjdG9yICkKewogIFJQQ19TVEFUVVMgc3RhdHVzOwogIERXT1JEIGNvdW50OwogIFJwY1NlcnZlclByb3RzZXEqIHBzOwogIFJwY0Nvbm5lY3Rpb24qIGNvbm47CgogIGlmIChCaW5kaW5nVmVjdG9yKQogICAgVFJBQ0UoIigqQmluZGluZ1ZlY3RvciA9PSBeJXApXG4iLCAqQmluZGluZ1ZlY3Rvcik7CiAgZWxzZQogICAgRVJSKCIoQmluZGluZ1ZlY3RvciA9PSBOVUxMISE/KVxuIik7CgogIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZzZXJ2ZXJfY3MpOwogIC8qIGNvdW50IGNvbm5lY3Rpb25zICovCiAgY291bnQgPSAwOwogIHBzID0gcHJvdHNlcXM7CiAgd2hpbGUgKHBzKSB7CiAgICBjb25uID0gcHMtPmNvbm47CiAgICB3aGlsZSAoY29ubikgewogICAgICBjb3VudCsrOwogICAgICBjb25uID0gY29ubi0+TmV4dDsKICAgIH0KICAgIHBzID0gcHMtPk5leHQ7CiAgfQogIGlmIChjb3VudCkgewogICAgLyogZXhwb3J0IGJpbmRpbmdzICovCiAgICAqQmluZGluZ1ZlY3RvciA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YoUlBDX0JJTkRJTkdfVkVDVE9SKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihSUENfQklORElOR19IQU5ETEUpKihjb3VudC0xKSk7CiAgICAoKkJpbmRpbmdWZWN0b3IpLT5Db3VudCA9IGNvdW50OwogICAgY291bnQgPSAwOwogICAgcHMgPSBwcm90c2VxczsKICAgIHdoaWxlIChwcykgewogICAgICBjb25uID0gcHMtPmNvbm47CiAgICAgIHdoaWxlIChjb25uKSB7CiAgICAgICBSUENSVDRfTWFrZUJpbmRpbmcoKFJwY0JpbmRpbmcqKikmKCpCaW5kaW5nVmVjdG9yKS0+QmluZGluZ0hbY291bnRdLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbm4pOwogICAgICAgY291bnQrKzsKICAgICAgIGNvbm4gPSBjb25uLT5OZXh0OwogICAgICB9CiAgICAgIHBzID0gcHMtPk5leHQ7CiAgICB9CiAgICBzdGF0dXMgPSBSUENfU19PSzsKICB9IGVsc2UgewogICAgKkJpbmRpbmdWZWN0b3IgPSBOVUxMOwogICAgc3RhdHVzID0gUlBDX1NfTk9fQklORElOR1M7CiAgfQogIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZzZXJ2ZXJfY3MpOwogIHJldHVybiBzdGF0dXM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTZXJ2ZXJVc2VQcm90c2VxRXBBIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1NlcnZlclVzZVByb3RzZXFFcEEoIHVuc2lnbmVkIGNoYXIgKlByb3RzZXEsIFVJTlQgTWF4Q2FsbHMsIHVuc2lnbmVkIGNoYXIgKkVuZHBvaW50LCBMUFZPSUQgU2VjdXJpdHlEZXNjcmlwdG9yICkKewogIFJQQ19QT0xJQ1kgcG9saWN5OwogIAogIFRSQUNFKCAiKCVzLCV1LCVzLCVwKVxuIiwgUHJvdHNlcSwgTWF4Q2FsbHMsIEVuZHBvaW50LCBTZWN1cml0eURlc2NyaXB0b3IgKTsKICAKICAvKiBUaGlzIHNob3VsZCBwcm92aWRlIHRoZSBkZWZhdWx0IGJlaGF2aW91ciAqLwogIHBvbGljeS5MZW5ndGggICAgICAgID0gc2l6ZW9mKCBwb2xpY3kgKTsKICBwb2xpY3kuRW5kcG9pbnRGbGFncyA9IDA7CiAgcG9saWN5Lk5JQ0ZsYWdzICAgICAgPSAwOwogIAogIHJldHVybiBScGNTZXJ2ZXJVc2VQcm90c2VxRXBFeEEoIFByb3RzZXEsIE1heENhbGxzLCBFbmRwb2ludCwgU2VjdXJpdHlEZXNjcmlwdG9yLCAmcG9saWN5ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTZXJ2ZXJVc2VQcm90c2VxRXBXIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1NlcnZlclVzZVByb3RzZXFFcFcoIExQV1NUUiBQcm90c2VxLCBVSU5UIE1heENhbGxzLCBMUFdTVFIgRW5kcG9pbnQsIExQVk9JRCBTZWN1cml0eURlc2NyaXB0b3IgKQp7CiAgUlBDX1BPTElDWSBwb2xpY3k7CiAgCiAgVFJBQ0UoICIoJXMsJXUsJXMsJXApXG4iLCBkZWJ1Z3N0cl93KCBQcm90c2VxICksIE1heENhbGxzLCBkZWJ1Z3N0cl93KCBFbmRwb2ludCApLCBTZWN1cml0eURlc2NyaXB0b3IgKTsKICAKICAvKiBUaGlzIHNob3VsZCBwcm92aWRlIHRoZSBkZWZhdWx0IGJlaGF2aW91ciAqLwogIHBvbGljeS5MZW5ndGggICAgICAgID0gc2l6ZW9mKCBwb2xpY3kgKTsKICBwb2xpY3kuRW5kcG9pbnRGbGFncyA9IDA7CiAgcG9saWN5Lk5JQ0ZsYWdzICAgICAgPSAwOwogIAogIHJldHVybiBScGNTZXJ2ZXJVc2VQcm90c2VxRXBFeFcoIFByb3RzZXEsIE1heENhbGxzLCBFbmRwb2ludCwgU2VjdXJpdHlEZXNjcmlwdG9yLCAmcG9saWN5ICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTZXJ2ZXJVc2VQcm90c2VxRXBFeEEgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU2VydmVyVXNlUHJvdHNlcUVwRXhBKCB1bnNpZ25lZCBjaGFyICpQcm90c2VxLCBVSU5UIE1heENhbGxzLCB1bnNpZ25lZCBjaGFyICpFbmRwb2ludCwgTFBWT0lEIFNlY3VyaXR5RGVzY3JpcHRvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQUlBDX1BPTElDWSBscFBvbGljeSApCnsKICBScGNTZXJ2ZXJQcm90c2VxKiBwczsKCiAgVFJBQ0UoIiglcywldSwlcywlcCx7JXUsJWx1LCVsdX0pXG4iLCBkZWJ1Z3N0cl9hKCAoY2hhciopUHJvdHNlcSApLCBNYXhDYWxscywKICAgICAgIGRlYnVnc3RyX2EoIChjaGFyKilFbmRwb2ludCApLCBTZWN1cml0eURlc2NyaXB0b3IsCiAgICAgICBscFBvbGljeS0+TGVuZ3RoLCBscFBvbGljeS0+RW5kcG9pbnRGbGFncywgbHBQb2xpY3ktPk5JQ0ZsYWdzICk7CgogIHBzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihScGNTZXJ2ZXJQcm90c2VxKSk7CiAgcHMtPk1heENhbGxzID0gTWF4Q2FsbHM7CiAgcHMtPlByb3RzZXEgPSBSUENSVDRfc3RyZHVwQSgoY2hhciopUHJvdHNlcSk7CiAgcHMtPkVuZHBvaW50ID0gUlBDUlQ0X3N0cmR1cEEoKGNoYXIqKUVuZHBvaW50KTsKCiAgcmV0dXJuIFJQQ1JUNF91c2VfcHJvdHNlcShwcyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTZXJ2ZXJVc2VQcm90c2VxRXBFeFcgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU2VydmVyVXNlUHJvdHNlcUVwRXhXKCBMUFdTVFIgUHJvdHNlcSwgVUlOVCBNYXhDYWxscywgTFBXU1RSIEVuZHBvaW50LCBMUFZPSUQgU2VjdXJpdHlEZXNjcmlwdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBSUENfUE9MSUNZIGxwUG9saWN5ICkKewogIFJwY1NlcnZlclByb3RzZXEqIHBzOwoKICBUUkFDRSgiKCVzLCV1LCVzLCVwLHsldSwlbHUsJWx1fSlcbiIsIGRlYnVnc3RyX3coIFByb3RzZXEgKSwgTWF4Q2FsbHMsCiAgICAgICBkZWJ1Z3N0cl93KCBFbmRwb2ludCApLCBTZWN1cml0eURlc2NyaXB0b3IsCiAgICAgICBscFBvbGljeS0+TGVuZ3RoLCBscFBvbGljeS0+RW5kcG9pbnRGbGFncywgbHBQb2xpY3ktPk5JQ0ZsYWdzICk7CgogIHBzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihScGNTZXJ2ZXJQcm90c2VxKSk7CiAgcHMtPk1heENhbGxzID0gTWF4Q2FsbHM7CiAgcHMtPlByb3RzZXEgPSBSUENSVDRfc3RyZHVwV3RvQShQcm90c2VxKTsKICBwcy0+RW5kcG9pbnQgPSBSUENSVDRfc3RyZHVwV3RvQShFbmRwb2ludCk7CgogIHJldHVybiBSUENSVDRfdXNlX3Byb3RzZXEocHMpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjU2VydmVyVXNlUHJvdHNlcUEgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU2VydmVyVXNlUHJvdHNlcUEodW5zaWduZWQgY2hhciAqUHJvdHNlcSwgdW5zaWduZWQgaW50IE1heENhbGxzLCB2b2lkICpTZWN1cml0eURlc2NyaXB0b3IpCnsKICBUUkFDRSgiKFByb3RzZXEgPT0gJXMsIE1heENhbGxzID09ICVkLCBTZWN1cml0eURlc2NyaXB0b3IgPT0gXiVwKVxuIiwgZGVidWdzdHJfYSgoY2hhciopUHJvdHNlcSksIE1heENhbGxzLCBTZWN1cml0eURlc2NyaXB0b3IpOwogIHJldHVybiBScGNTZXJ2ZXJVc2VQcm90c2VxRXBBKFByb3RzZXEsIE1heENhbGxzLCBOVUxMLCBTZWN1cml0eURlc2NyaXB0b3IpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjU2VydmVyVXNlUHJvdHNlcVcgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU2VydmVyVXNlUHJvdHNlcVcoTFBXU1RSIFByb3RzZXEsIHVuc2lnbmVkIGludCBNYXhDYWxscywgdm9pZCAqU2VjdXJpdHlEZXNjcmlwdG9yKQp7CiAgVFJBQ0UoIlByb3RzZXEgPT0gJXMsIE1heENhbGxzID09ICVkLCBTZWN1cml0eURlc2NyaXB0b3IgPT0gXiVwKVxuIiwgZGVidWdzdHJfdyhQcm90c2VxKSwgTWF4Q2FsbHMsIFNlY3VyaXR5RGVzY3JpcHRvcik7CiAgcmV0dXJuIFJwY1NlcnZlclVzZVByb3RzZXFFcFcoUHJvdHNlcSwgTWF4Q2FsbHMsIE5VTEwsIFNlY3VyaXR5RGVzY3JpcHRvcik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTZXJ2ZXJSZWdpc3RlcklmIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1NlcnZlclJlZ2lzdGVySWYoIFJQQ19JRl9IQU5ETEUgSWZTcGVjLCBVVUlEKiBNZ3JUeXBlVXVpZCwgUlBDX01HUl9FUFYqIE1nckVwdiApCnsKICBUUkFDRSgiKCVwLCVzLCVwKVxuIiwgSWZTcGVjLCBkZWJ1Z3N0cl9ndWlkKE1nclR5cGVVdWlkKSwgTWdyRXB2KTsKICByZXR1cm4gUnBjU2VydmVyUmVnaXN0ZXJJZjIoIElmU3BlYywgTWdyVHlwZVV1aWQsIE1nckVwdiwgMCwgUlBDX0NfTElTVEVOX01BWF9DQUxMU19ERUZBVUxULCAoVUlOVCktMSwgTlVMTCApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjU2VydmVyUmVnaXN0ZXJJZkV4IChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1NlcnZlclJlZ2lzdGVySWZFeCggUlBDX0lGX0hBTkRMRSBJZlNwZWMsIFVVSUQqIE1nclR5cGVVdWlkLCBSUENfTUdSX0VQViogTWdyRXB2LAogICAgICAgICAgICAgICAgICAgICAgIFVJTlQgRmxhZ3MsIFVJTlQgTWF4Q2FsbHMsIFJQQ19JRl9DQUxMQkFDS19GTiogSWZDYWxsYmFja0ZuICkKewogIFRSQUNFKCIoJXAsJXMsJXAsJXUsJXUsJXApXG4iLCBJZlNwZWMsIGRlYnVnc3RyX2d1aWQoTWdyVHlwZVV1aWQpLCBNZ3JFcHYsIEZsYWdzLCBNYXhDYWxscywgSWZDYWxsYmFja0ZuKTsKICByZXR1cm4gUnBjU2VydmVyUmVnaXN0ZXJJZjIoIElmU3BlYywgTWdyVHlwZVV1aWQsIE1nckVwdiwgRmxhZ3MsIE1heENhbGxzLCAoVUlOVCktMSwgSWZDYWxsYmFja0ZuICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTZXJ2ZXJSZWdpc3RlcklmMiAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNTZXJ2ZXJSZWdpc3RlcklmMiggUlBDX0lGX0hBTkRMRSBJZlNwZWMsIFVVSUQqIE1nclR5cGVVdWlkLCBSUENfTUdSX0VQViogTWdyRXB2LAogICAgICAgICAgICAgICAgICAgICAgVUlOVCBGbGFncywgVUlOVCBNYXhDYWxscywgVUlOVCBNYXhScGNTaXplLCBSUENfSUZfQ0FMTEJBQ0tfRk4qIElmQ2FsbGJhY2tGbiApCnsKICBQUlBDX1NFUlZFUl9JTlRFUkZBQ0UgSWYgPSAoUFJQQ19TRVJWRVJfSU5URVJGQUNFKUlmU3BlYzsKICBScGNTZXJ2ZXJJbnRlcmZhY2UqIHNpZjsKICB1bnNpZ25lZCBpbnQgaTsKCiAgVFJBQ0UoIiglcCwlcywlcCwldSwldSwldSwlcClcbiIsIElmU3BlYywgZGVidWdzdHJfZ3VpZChNZ3JUeXBlVXVpZCksIE1nckVwdiwgRmxhZ3MsIE1heENhbGxzLAogICAgICAgICBNYXhScGNTaXplLCBJZkNhbGxiYWNrRm4pOwogIFRSQUNFKCIgaW50ZXJmYWNlIGlkOiAlcyAlZC4lZFxuIiwgZGVidWdzdHJfZ3VpZCgmSWYtPkludGVyZmFjZUlkLlN5bnRheEdVSUQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSWYtPkludGVyZmFjZUlkLlN5bnRheFZlcnNpb24uTWFqb3JWZXJzaW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSWYtPkludGVyZmFjZUlkLlN5bnRheFZlcnNpb24uTWlub3JWZXJzaW9uKTsKICBUUkFDRSgiIHRyYW5zZmVyIHN5bnRheDogJXMgJWQuJWRcbiIsIGRlYnVnc3RyX2d1aWQoJklmLT5UcmFuc2ZlclN5bnRheC5TeW50YXhHVUlEKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElmLT5UcmFuc2ZlclN5bnRheC5TeW50YXhWZXJzaW9uLk1ham9yVmVyc2lvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElmLT5UcmFuc2ZlclN5bnRheC5TeW50YXhWZXJzaW9uLk1pbm9yVmVyc2lvbik7CiAgVFJBQ0UoIiBkaXNwYXRjaCB0YWJsZTogJXBcbiIsIElmLT5EaXNwYXRjaFRhYmxlKTsKICBpZiAoSWYtPkRpc3BhdGNoVGFibGUpIHsKICAgIFRSQUNFKCIgIGRpc3BhdGNoIHRhYmxlIGNvdW50OiAlZFxuIiwgSWYtPkRpc3BhdGNoVGFibGUtPkRpc3BhdGNoVGFibGVDb3VudCk7CiAgICBmb3IgKGk9MDsgaTxJZi0+RGlzcGF0Y2hUYWJsZS0+RGlzcGF0Y2hUYWJsZUNvdW50OyBpKyspIHsKICAgICAgVFJBQ0UoIiAgIGVudHJ5ICVkOiAlcFxuIiwgaSwgSWYtPkRpc3BhdGNoVGFibGUtPkRpc3BhdGNoVGFibGVbaV0pOwogICAgfQogICAgVFJBQ0UoIiAgcmVzZXJ2ZWQ6ICVsZFxuIiwgSWYtPkRpc3BhdGNoVGFibGUtPlJlc2VydmVkKTsKICB9CiAgVFJBQ0UoIiBwcm90c2VxIGVuZHBvaW50IGNvdW50OiAlZFxuIiwgSWYtPlJwY1Byb3RzZXFFbmRwb2ludENvdW50KTsKICBUUkFDRSgiIGRlZmF1bHQgbWFuYWdlciBlcHY6ICVwXG4iLCBJZi0+RGVmYXVsdE1hbmFnZXJFcHYpOwogIFRSQUNFKCIgaW50ZXJwcmV0ZXIgaW5mbzogJXBcbiIsIElmLT5JbnRlcnByZXRlckluZm8pOwoKICBzaWYgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKFJwY1NlcnZlckludGVyZmFjZSkpOwogIHNpZi0+SWYgICAgICAgICAgID0gSWY7CiAgaWYgKE1nclR5cGVVdWlkKSB7CiAgICBtZW1jcHkoJnNpZi0+TWdyVHlwZVV1aWQsIE1nclR5cGVVdWlkLCBzaXplb2YoVVVJRCkpOwogICAgc2lmLT5NZ3JFcHYgICAgICAgPSBNZ3JFcHY7CiAgfSBlbHNlIHsKICAgIG1lbXNldCgmc2lmLT5NZ3JUeXBlVXVpZCwgMCwgc2l6ZW9mKFVVSUQpKTsKICAgIHNpZi0+TWdyRXB2ICAgICAgID0gSWYtPkRlZmF1bHRNYW5hZ2VyRXB2OwogIH0KICBzaWYtPkZsYWdzICAgICAgICA9IEZsYWdzOwogIHNpZi0+TWF4Q2FsbHMgICAgID0gTWF4Q2FsbHM7CiAgc2lmLT5NYXhScGNTaXplICAgPSBNYXhScGNTaXplOwogIHNpZi0+SWZDYWxsYmFja0ZuID0gSWZDYWxsYmFja0ZuOwoKICBFbnRlckNyaXRpY2FsU2VjdGlvbigmc2VydmVyX2NzKTsKICBzaWYtPk5leHQgPSBpZnM7CiAgaWZzID0gc2lmOwogIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZzZXJ2ZXJfY3MpOwoKICBpZiAoc2lmLT5GbGFncyAmIFJQQ19JRl9BVVRPTElTVEVOKSB7CiAgICBSUENSVDRfc3RhcnRfbGlzdGVuKFRSVUUpOwoKICAgIC8qIG1ha2Ugc3VyZSBzZXJ2ZXIgaXMgYWN0dWFsbHkgbGlzdGVuaW5nIG9uIHRoZSBpbnRlcmZhY2UgYmVmb3JlCiAgICAgKiByZXR1cm5pbmcgKi8KICAgIFJQQ1JUNF9zeW5jX3dpdGhfc2VydmVyX3RocmVhZCgpOwogIH0KCiAgcmV0dXJuIFJQQ19TX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjU2VydmVyVW5yZWdpc3RlcklmIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1NlcnZlclVucmVnaXN0ZXJJZiggUlBDX0lGX0hBTkRMRSBJZlNwZWMsIFVVSUQqIE1nclR5cGVVdWlkLCBVSU5UIFdhaXRGb3JDYWxsc1RvQ29tcGxldGUgKQp7CiAgRklYTUUoIihJZlNwZWMgPT0gKFJQQ19JRl9IQU5ETEUpXiVwLCBNZ3JUeXBlVXVpZCA9PSAlcywgV2FpdEZvckNhbGxzVG9Db21wbGV0ZSA9PSAldSk6IHN0dWJcbiIsCiAgICBJZlNwZWMsIGRlYnVnc3RyX2d1aWQoTWdyVHlwZVV1aWQpLCBXYWl0Rm9yQ2FsbHNUb0NvbXBsZXRlKTsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjU2VydmVyVW5yZWdpc3RlcklmRXggKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU2VydmVyVW5yZWdpc3RlcklmRXgoIFJQQ19JRl9IQU5ETEUgSWZTcGVjLCBVVUlEKiBNZ3JUeXBlVXVpZCwgaW50IFJ1bmRvd25Db250ZXh0SGFuZGxlcyApCnsKICBGSVhNRSgiKElmU3BlYyA9PSAoUlBDX0lGX0hBTkRMRSleJXAsIE1nclR5cGVVdWlkID09ICVzLCBSdW5kb3duQ29udGV4dEhhbmRsZXMgPT0gJWQpOiBzdHViXG4iLAogICAgSWZTcGVjLCBkZWJ1Z3N0cl9ndWlkKE1nclR5cGVVdWlkKSwgUnVuZG93bkNvbnRleHRIYW5kbGVzKTsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjT2JqZWN0U2V0VHlwZSAoUlBDUlQ0LkApCiAqCiAqIFBBUkFNUwogKiAgIE9ialV1aWQgIFtJXSAiT2JqZWN0IiBVVUlECiAqICAgVHlwZVV1aWQgW0ldICJUeXBlIiBVVUlECiAqCiAqIFJFVFVSTlMKICogICBSUENfU19PSyAgICAgICAgICAgICAgICAgVGhlIGNhbGwgc3VjY2VlZGVkCiAqICAgUlBDX1NfSU5WQUxJRF9PQkpFQ1QgICAgIFRoZSBwcm92aWRlZCBvYmplY3QgKG5pbCkgaXMgbm90IHZhbGlkCiAqICAgUlBDX1NfQUxSRUFEWV9SRUdJU1RFUkVEIFRoZSBwcm92aWRlZCBvYmplY3QgaXMgYWxyZWFkeSByZWdpc3RlcmVkCiAqCiAqIE1hcHMgIk9iamVjdCIgVVVJRHMgdG8gIlR5cGUiIFVVSUQncy4gIFBhc3NpbmcgdGhlIG5pbCBVVUlEIGFzIHRoZSB0eXBlCiAqIHJlc2V0cyB0aGUgbWFwcGluZyBmb3IgdGhlIHNwZWNpZmllZCBvYmplY3QgVVVJRCB0byBuaWwgKHRoZSBkZWZhdWx0KS4KICogVGhlIG5pbCBvYmplY3QgaXMgYWx3YXlzIGFzc29jaWF0ZWQgd2l0aCB0aGUgbmlsIHR5cGUgYW5kIGNhbm5vdCBiZQogKiByZWFzc2lnbmVkLiAgU2VydmVycyBjYW4gc3VwcG9ydCBtdWx0aXBsZSBpbXBsZW1lbnRhdGlvbnMgb24gdGhlIHNhbWUKICogaW50ZXJmYWNlIGJ5IHJlZ2lzdGVyaW5nIGRpZmZlcmVudCBlbmQtcG9pbnQgdmVjdG9ycyBmb3IgdGhlIGRpZmZlcmVudAogKiB0eXBlcy4gIFRoZXJlJ3Mgbm8gbmVlZCB0byBjYWxsIHRoaXMgaWYgYSBzZXJ2ZXIgb25seSBzdXBwb3J0cyB0aGUgbmlsCiAqIHR5cGUsIGFzIGlzIHR5cGljYWwuCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNPYmplY3RTZXRUeXBlKCBVVUlEKiBPYmpVdWlkLCBVVUlEKiBUeXBlVXVpZCApCnsKICBScGNPYmpUeXBlTWFwICptYXAgPSBScGNPYmpUeXBlTWFwcywgKnByZXYgPSBOVUxMOwogIFJQQ19TVEFUVVMgZHVtbXk7CgogIFRSQUNFKCIoT2JqVVVJRCA9PSAlcywgVHlwZVV1aWQgPT0gJXMpLlxuIiwgZGVidWdzdHJfZ3VpZChPYmpVdWlkKSwgZGVidWdzdHJfZ3VpZChUeXBlVXVpZCkpOwogIGlmICgoISBPYmpVdWlkKSB8fCBVdWlkSXNOaWwoT2JqVXVpZCwgJmR1bW15KSkgewogICAgLyogbmlsIHV1aWQgY2Fubm90IGJlIHJlbWFwcGVkICovCiAgICByZXR1cm4gUlBDX1NfSU5WQUxJRF9PQkpFQ1Q7CiAgfQoKICAvKiBmaW5kIHRoZSBtYXBwaW5nIGZvciB0aGlzIG9iamVjdCBpZiB0aGVyZSBpcyBvbmUgLi4uICovCiAgd2hpbGUgKG1hcCkgewogICAgaWYgKCEgVXVpZENvbXBhcmUoT2JqVXVpZCwgJm1hcC0+T2JqZWN0LCAmZHVtbXkpKSBicmVhazsKICAgIHByZXYgPSBtYXA7CiAgICBtYXAgPSBtYXAtPm5leHQ7CiAgfQogIGlmICgoISBUeXBlVXVpZCkgfHwgVXVpZElzTmlsKFR5cGVVdWlkLCAmZHVtbXkpKSB7CiAgICAvKiAuLi4gYW5kIGRyb3AgaXQgZnJvbSB0aGUgbGlzdCAqLwogICAgaWYgKG1hcCkgewogICAgICBpZiAocHJldikgCiAgICAgICAgcHJldi0+bmV4dCA9IG1hcC0+bmV4dDsKICAgICAgZWxzZQogICAgICAgIFJwY09ialR5cGVNYXBzID0gbWFwLT5uZXh0OwogICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBtYXApOwogICAgfQogIH0gZWxzZSB7CiAgICAvKiAuLi4gLCBmYWlsIGlmIHdlIGZvdW5kIGl0IC4uLiAqLwogICAgaWYgKG1hcCkKICAgICAgcmV0dXJuIFJQQ19TX0FMUkVBRFlfUkVHSVNURVJFRDsKICAgIC8qIC4uLiBvdGhlcndpc2UgY3JlYXRlIGEgbmV3IG9uZSBhbmQgYWRkIGl0IGluLiAqLwogICAgbWFwID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZihScGNPYmpUeXBlTWFwKSk7CiAgICBtZW1jcHkoJm1hcC0+T2JqZWN0LCBPYmpVdWlkLCBzaXplb2YoVVVJRCkpOwogICAgbWVtY3B5KCZtYXAtPlR5cGUsIFR5cGVVdWlkLCBzaXplb2YoVVVJRCkpOwogICAgbWFwLT5uZXh0ID0gTlVMTDsKICAgIGlmIChwcmV2KQogICAgICBwcmV2LT5uZXh0ID0gbWFwOyAvKiBwcmV2IGlzIHRoZSBsYXN0IG1hcCBpbiB0aGUgbGlua2xpc3QgKi8KICAgIGVsc2UKICAgICAgUnBjT2JqVHlwZU1hcHMgPSBtYXA7CiAgfQoKICByZXR1cm4gUlBDX1NfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTZXJ2ZXJSZWdpc3RlckF1dGhJbmZvQSAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNTZXJ2ZXJSZWdpc3RlckF1dGhJbmZvQSggdW5zaWduZWQgY2hhciAqU2VydmVyUHJpbmNOYW1lLCB1bnNpZ25lZCBsb25nIEF1dGhuU3ZjLCBSUENfQVVUSF9LRVlfUkVUUklFVkFMX0ZOIEdldEtleUZuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBWT0lEIEFyZyApCnsKICBGSVhNRSggIiglcywlbHUsJXAsJXApOiBzdHViXG4iLCBTZXJ2ZXJQcmluY05hbWUsIEF1dGhuU3ZjLCBHZXRLZXlGbiwgQXJnICk7CiAgCiAgcmV0dXJuIFJQQ19TX1VOS05PV05fQVVUSE5fU0VSVklDRTsgLyogV2UgZG9uJ3Qga25vdyBhbnkgYXV0aGVudGljYXRpb24gc2VydmljZXMgKi8KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1NlcnZlclJlZ2lzdGVyQXV0aEluZm9XIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1NlcnZlclJlZ2lzdGVyQXV0aEluZm9XKCBMUFdTVFIgU2VydmVyUHJpbmNOYW1lLCB1bnNpZ25lZCBsb25nIEF1dGhuU3ZjLCBSUENfQVVUSF9LRVlfUkVUUklFVkFMX0ZOIEdldEtleUZuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBWT0lEIEFyZyApCnsKICBGSVhNRSggIiglcywlbHUsJXAsJXApOiBzdHViXG4iLCBkZWJ1Z3N0cl93KCBTZXJ2ZXJQcmluY05hbWUgKSwgQXV0aG5TdmMsIEdldEtleUZuLCBBcmcgKTsKICAKICByZXR1cm4gUlBDX1NfVU5LTk9XTl9BVVRITl9TRVJWSUNFOyAvKiBXZSBkb24ndCBrbm93IGFueSBhdXRoZW50aWNhdGlvbiBzZXJ2aWNlcyAqLwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjU2VydmVyTGlzdGVuIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1NlcnZlckxpc3RlbiggVUlOVCBNaW5pbXVtQ2FsbFRocmVhZHMsIFVJTlQgTWF4Q2FsbHMsIFVJTlQgRG9udFdhaXQgKQp7CiAgUlBDX1NUQVRVUyBzdGF0dXM7CgogIFRSQUNFKCIoJXUsJXUsJXUpXG4iLCBNaW5pbXVtQ2FsbFRocmVhZHMsIE1heENhbGxzLCBEb250V2FpdCk7CgogIGlmICghcHJvdHNlcXMpCiAgICByZXR1cm4gUlBDX1NfTk9fUFJPVFNFUVNfUkVHSVNURVJFRDsKCiAgc3RhdHVzID0gUlBDUlQ0X3N0YXJ0X2xpc3RlbihGQUxTRSk7CgogIGlmIChEb250V2FpdCB8fCAoc3RhdHVzICE9IFJQQ19TX09LKSkgcmV0dXJuIHN0YXR1czsKCiAgcmV0dXJuIFJwY01nbXRXYWl0U2VydmVyTGlzdGVuKCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNNZ210U2VydmVyV2FpdExpc3RlbiAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNNZ210V2FpdFNlcnZlckxpc3Rlbiggdm9pZCApCnsKICBUUkFDRSgiKClcbiIpOwoKICBFbnRlckNyaXRpY2FsU2VjdGlvbigmbGlzdGVuX2NzKTsKCiAgaWYgKCFzdGRfbGlzdGVuKSB7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmbGlzdGVuX2NzKTsKICAgIHJldHVybiBSUENfU19OT1RfTElTVEVOSU5HOwogIH0KICAKICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmbGlzdGVuX2NzKTsKCiAgUlBDUlQ0X3N5bmNfd2l0aF9zZXJ2ZXJfdGhyZWFkKCk7CgogIHJldHVybiBSUENfU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY01nbXRTdG9wU2VydmVyTGlzdGVuaW5nIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY01nbXRTdG9wU2VydmVyTGlzdGVuaW5nICggUlBDX0JJTkRJTkdfSEFORExFIEJpbmRpbmcgKQp7CiAgVFJBQ0UoIihCaW5kaW5nID09IChSUENfQklORElOR19IQU5ETEUpXiVwKVxuIiwgQmluZGluZyk7CgogIGlmIChCaW5kaW5nKSB7CiAgICBGSVhNRSgiY2xpZW50LXNpZGUgaW52b2NhdGlvbiBub3QgaW1wbGVtZW50ZWQuXG4iKTsKICAgIHJldHVybiBSUENfU19XUk9OR19LSU5EX09GX0JJTkRJTkc7CiAgfQogIAogIFJQQ1JUNF9zdG9wX2xpc3RlbihGQUxTRSk7CgogIHJldHVybiBSUENfU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIElfUnBjU2VydmVyU3RhcnRMaXN0ZW5pbmcgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgSV9ScGNTZXJ2ZXJTdGFydExpc3RlbmluZyggSFdORCBoV25kICkKewogIEZJWE1FKCAiKCVwKTogc3R1YlxuIiwgaFduZCApOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBJX1JwY1NlcnZlclN0b3BMaXN0ZW5pbmcgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgSV9ScGNTZXJ2ZXJTdG9wTGlzdGVuaW5nKCB2b2lkICkKewogIEZJWE1FKCAiKCk6IHN0dWJcbiIgKTsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgSV9ScGNXaW5kb3dQcm9jIChSUENSVDQuQCkKICovClVJTlQgV0lOQVBJIElfUnBjV2luZG93UHJvYyggdm9pZCAqaFduZCwgVUlOVCBNZXNzYWdlLCBVSU5UIHdQYXJhbSwgVUxPTkcgbFBhcmFtICkKewogIEZJWE1FKCAiKCVwLCUwOHgsJTA4eCwlMDhseCk6IHN0dWJcbiIsIGhXbmQsIE1lc3NhZ2UsIHdQYXJhbSwgbFBhcmFtICk7CgogIHJldHVybiAwOwp9Cg==