LyoqDQogKiBAZmlsZSBhdHJlZ19jb21tb24uYw0KICogQGJyaWVmIEltcGxlbWVudGF0aW9uIG9mIHRoZSBpbnRlciBBUElzIG9mIGxpYmF0cmVnLg0KICoNCiAqIENvcHlyaWdodCAoQykgMjAyMSBTYW5lY2hpcHMgVGVjaG5vbG9neSBDby4sIEx0ZC4NCiAqIEBhdXRob3IgDQogKiANCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5DQogKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMiBhcw0KICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uIKOosdjRoaO6R1BMdjIgTGljZW5jZaOpDQogKg0KICovDQoNCg0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioNCiAqIAkJCQkJCSAgICAgICBJbmNsdWRlIGhlYWRlciBmaWxlcyAJCQkJCQkgICAqDQogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8NCiNpbmNsdWRlIDxzdGRpby5oPg0KI2luY2x1ZGUgPHN0cmluZy5oPg0KI2luY2x1ZGUgPHN0ZGxpYi5oPg0KDQojaW5jbHVkZSAiYXRyZWdfY29tbW9uLmgiDQojaW5jbHVkZSAiYXRfdXRpbHMuaCINCg0KDQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKg0KICogCQkJCQkJICAgIAlNYWNybyBkZWZpbml0aW9ucwkJCQkJCQkgICAqDQogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8JIA0KDQoNCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqDQogKiAJCQkJCQkgICAgICAgCVR5cGUgZGVmaW5pdGlvbnMJCQkJCQkJICAgKg0KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovDQoNCiANCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqDQogKiAJCQkJCSAgICAgICBMb2NhbCB2YXJpYWJsZSBkZWZpbml0aW9ucwkJCQkJCSAgICoNCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLw0KIA0KIA0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioNCiAqIAkJCQkJICAgICAgIEdsb2JhbCB2YXJpYWJsZSBkZWZpbml0aW9ucwkJCQkJICAgICAgICoNCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLw0KIA0Kc3RydWN0IGF0cmVnX3Nlcl9jb250ZXh0X3QgYXRyZWdfc2VyX2N0eDsNCnN0cnVjdCBhdHJlZ19pbmZvX2NvbnRleHRfdCBhdHJlZ19pbmZvX2N0eDsNCnN0cnVjdCBhdHJlZ19jb21tb25fY29udGV4dF90IGF0cmVnX2NvbW1vbl9jdHg7DQoNCi8qKiBzZXIgLSC2r8ysaWSz2CwJt7bOpzogMH41MTEgKi8NCnVuc2lnbmVkIGNoYXIgYXRyZWdfc2VyX2R5bmFtaWNfaWRwb29sW0FUUkVHX1NFUl9JRF9NQVhdOw0KLyoqIGluZm8gLSC2r8ysaWSz2CwJt7bOpzogNTEyfjc2OCAqLw0KdW5zaWduZWQgY2hhciBhdHJlZ19pbmZvX2R5bmFtaWNfaWRwb29sW0FUUkVHX0lORk9fSURfTUFYXTsNCg0KZXh0ZXJuIGludCBhdHJlZ19zZXJfY3h0X2lzX2luaXQ7DQpleHRlcm4gaW50IGF0cmVnX2luZm9fY3h0X2lzX2luaXQ7DQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKg0KICogCQkJCSAgICAgICAgICAgTG9jYWwgZnVuY3Rpb24gZGVjbGFyYXRpb25zCQkJCQkJICAgKg0KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovDQogDQogDQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKg0KICogCQkJCQkgICAgICBMb2NhbCBmdW5jdGlvbiBpbXBsZW1lbnRhdGlvbnMgCQkJCQkgICAqDQogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8NCnN0YXRpYyB2b2lkICphdHJlZ19zZXJfc2VhcmNoX2luc3RhbmNlX2J5X3ByZWZpeF9wcm9jKGNoYXIgKmF0X2NtZF9wcmVmaXgpDQp7DQoJc3RydWN0IGF0cmVnX3Nlcl9pbnN0YW5jZV90ICogZW50cnkgPSBOVUxMOw0KCQ0KCXB0aHJlYWRfbXV0ZXhfbG9jaygmYXRyZWdfc2VyX2N0eC5hdF9zZXJfbG9jayk7DQogICAgbGlzdF9mb3JfZWFjaF9lbnRyeShlbnRyeSwgJmF0cmVnX3Nlcl9jdHguYXRfc2VyX2xpc3QsIGxpc3QpIHsNCgkJaWYoMCA9PSBhdF9zdHJuY21wKGF0X2NtZF9wcmVmaXgsIGVudHJ5LT5hdF9jbWRfcHJlZml4LCBBVF9DTURfUFJFRklYKSkgew0KCQkJcHRocmVhZF9tdXRleF91bmxvY2soJmF0cmVnX3Nlcl9jdHguYXRfc2VyX2xvY2spOw0KCQkJDQoJCQlyZXR1cm4gKHZvaWQgKillbnRyeTsNCgkJfQ0KCX0NCglwdGhyZWFkX211dGV4X3VubG9jaygmYXRyZWdfc2VyX2N0eC5hdF9zZXJfbG9jayk7DQoJDQoJcmV0dXJuIE5VTEw7DQp9DQoNCg0Kc3RhdGljIHZvaWQgKmF0cmVnX2luZm9fc2VhcmNoX2luc3RhbmNlX2J5X3ByZWZpeF9wcm9jKGNoYXIgKmF0X2NtZF9wcmVmaXgpDQp7DQoJc3RydWN0IGF0cmVnX2luZm9faW5zdGFuY2VfdCAqIGVudHJ5ID0gTlVMTDsNCgkNCglwdGhyZWFkX211dGV4X2xvY2soJmF0cmVnX2luZm9fY3R4LmF0X2luZm9fbG9jayk7DQoJbGlzdF9mb3JfZWFjaF9lbnRyeShlbnRyeSwgJmF0cmVnX2luZm9fY3R4LmF0X2luZm9fbGlzdCwgbGlzdCkgew0KCQlpZigwID09IGF0X3N0cm5jbXAoYXRfY21kX3ByZWZpeCwgZW50cnktPmF0X2NtZF9wcmVmaXgsIEFUX0NNRF9QUkVGSVgpKSB7DQoJCQlwdGhyZWFkX211dGV4X3VubG9jaygmYXRyZWdfaW5mb19jdHguYXRfaW5mb19sb2NrKTsNCgkJCQ0KCQkJcmV0dXJuICh2b2lkICopZW50cnk7DQoJCX0NCgl9DQoJcHRocmVhZF9tdXRleF91bmxvY2soJmF0cmVnX2luZm9fY3R4LmF0X2luZm9fbG9jayk7DQoJDQoJcmV0dXJuIE5VTEw7DQp9DQoNCg0Kc3RhdGljIHZvaWQgKmF0cmVnX3Nlcl9zZWFyY2hfaW5zdGFuY2VfYnlfcmVxaWRfcHJvYyhpbnQgcmVxX21zZ19pZCkNCnsNCglzdHJ1Y3QgYXRyZWdfc2VyX2luc3RhbmNlX3QgKmVudHJ5ID0gTlVMTDsNCgkNCiAgICBwdGhyZWFkX211dGV4X2xvY2soJmF0cmVnX3Nlcl9jdHguYXRfc2VyX2xvY2spOw0KCWxpc3RfZm9yX2VhY2hfZW50cnkoZW50cnksICZhdHJlZ19zZXJfY3R4LmF0X3Nlcl9saXN0LCBsaXN0KSB7DQogICAgICAgIGlmKGVudHJ5LT5yZXFfbXNnX2lkID09IHJlcV9tc2dfaWQpIHsNCgkJICAgIHB0aHJlYWRfbXV0ZXhfdW5sb2NrKCZhdHJlZ19zZXJfY3R4LmF0X3Nlcl9sb2NrKTsNCgkJCQ0KCQkJcmV0dXJuICh2b2lkICopZW50cnk7DQoJCX0NCiAgICB9DQogICAgcHRocmVhZF9tdXRleF91bmxvY2soJmF0cmVnX3Nlcl9jdHguYXRfc2VyX2xvY2spOw0KCQ0KICAgIHJldHVybiBOVUxMOw0KfQ0KDQoNCnN0YXRpYyB2b2lkICphdHJlZ19pbmZvX3NlYXJjaF9pbnN0YW5jZV9ieV9yZXFpZF9wcm9jKGludCByZXFfbXNnX2lkKQ0Kew0KCXN0cnVjdCBhdHJlZ19pbmZvX2luc3RhbmNlX3QgKmVudHJ5ID0gTlVMTDsNCgkNCiAgICBwdGhyZWFkX211dGV4X2xvY2soJmF0cmVnX2luZm9fY3R4LmF0X2luZm9fbG9jayk7DQoJbGlzdF9mb3JfZWFjaF9lbnRyeShlbnRyeSwgJmF0cmVnX2luZm9fY3R4LmF0X2luZm9fbGlzdCwgbGlzdCkgew0KICAgICAgICBpZihlbnRyeS0+cmVxX21zZ19pZCA9PSByZXFfbXNnX2lkKSB7DQoJCSAgICBwdGhyZWFkX211dGV4X3VubG9jaygmYXRyZWdfaW5mb19jdHguYXRfaW5mb19sb2NrKTsNCgkJCQ0KCQkJcmV0dXJuICh2b2lkICopZW50cnk7DQoJCX0NCiAgICB9DQogICAgcHRocmVhZF9tdXRleF91bmxvY2soJmF0cmVnX2luZm9fY3R4LmF0X2luZm9fbG9jayk7DQoJDQogICAgcmV0dXJuIE5VTEw7DQp9DQoNCg0Kc3RhdGljIHZvaWQgKmF0cmVnX3Nlcl9zZWFyY2hfaW5zdGFuY2VfdG1wX2J5X3JlcWlkX3Byb2MoaW50IHJlcV9tc2dfaWQpDQp7DQoJc3RydWN0IGF0cmVnX3Nlcl9pbnN0YW5jZV90ICplbnRyeSA9IE5VTEw7DQoJDQogICAgcHRocmVhZF9tdXRleF9sb2NrKCZhdHJlZ19zZXJfY3R4LmF0X3Nlcl9sb2NrX3RtcCk7DQoJbGlzdF9mb3JfZWFjaF9lbnRyeShlbnRyeSwgJmF0cmVnX3Nlcl9jdHguYXRfc2VyX2xpc3RfdG1wLCBsaXN0KSB7DQogICAgICAgIGlmKGVudHJ5LT5yZXFfbXNnX2lkID09IHJlcV9tc2dfaWQpIHsNCgkJICAgIHB0aHJlYWRfbXV0ZXhfdW5sb2NrKCZhdHJlZ19zZXJfY3R4LmF0X3Nlcl9sb2NrX3RtcCk7DQoJCQkNCgkJCXJldHVybiAodm9pZCAqKWVudHJ5Ow0KCQl9DQogICAgfQ0KICAgIHB0aHJlYWRfbXV0ZXhfdW5sb2NrKCZhdHJlZ19zZXJfY3R4LmF0X3Nlcl9sb2NrX3RtcCk7DQoJDQogICAgcmV0dXJuIE5VTEw7DQp9DQoNCg0Kc3RhdGljIHZvaWQgKmF0cmVnX2luZm9fc2VhcmNoX2luc3RhbmNlX3RtcF9ieV9yZXFpZF9wcm9jKGludCByZXFfbXNnX2lkKQ0Kew0KCXN0cnVjdCBhdHJlZ19pbmZvX2luc3RhbmNlX3QgKmVudHJ5ID0gTlVMTDsNCgkNCiAgICBwdGhyZWFkX211dGV4X2xvY2soJmF0cmVnX2luZm9fY3R4LmF0X2luZm9fbG9ja190bXApOw0KCWxpc3RfZm9yX2VhY2hfZW50cnkoZW50cnksICZhdHJlZ19pbmZvX2N0eC5hdF9pbmZvX2xpc3RfdG1wLCBsaXN0KSB7DQogICAgICAgIGlmKGVudHJ5LT5yZXFfbXNnX2lkID09IHJlcV9tc2dfaWQpIHsNCgkJICAgIHB0aHJlYWRfbXV0ZXhfdW5sb2NrKCZhdHJlZ19pbmZvX2N0eC5hdF9pbmZvX2xvY2tfdG1wKTsNCgkJCQ0KCQkJcmV0dXJuICh2b2lkICopZW50cnk7DQoJCX0NCiAgICB9DQogICAgcHRocmVhZF9tdXRleF91bmxvY2soJmF0cmVnX2luZm9fY3R4LmF0X2luZm9fbG9ja190bXApOw0KCQ0KICAgIHJldHVybiBOVUxMOw0KfQ0KDQoNCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqDQogKiAJCQkJICAgICAgIAkgIEdsb2JhbCBmdW5jdGlvbiBpbXBsZW1lbnRhdGlvbnMJCQkJCSAgICoNCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLw0Kdm9pZCBhdHJlZ193YWl0X3JzcChpbnQgbXNnX2NtZCkNCnsNCglpbnQgcmV0ID0gLTE7DQoJDQoJaWYgKGNsb2NrX2dldHRpbWUoQ0xPQ0tfUkVBTFRJTUUsICZhdHJlZ19jb21tb25fY3R4LnRzKSA9PSAtMSkgew0KCQlzbG9nKEFUUkVHX1BSSU5ULCBTTE9HX05PUk1BTCwgImF0cmVnX3dhaXRfcnNwIGNsb2NrX2dldHRpbWUgZmFpbC5cbiIpOw0KCQlyZXR1cm47DQoJfQ0KCWF0cmVnX2NvbW1vbl9jdHgudHMudHZfc2VjICs9IFdBSVRfUlNQX1RJTUVPVVQ7DQoJDQoJd2hpbGUgKChyZXQgPSBzZW1fdGltZWR3YWl0KCZhdHJlZ19jb21tb25fY3R4LnNlbV9pZCwgJmF0cmVnX2NvbW1vbl9jdHgudHMpKSA9PSAtMSAmJiBlcnJubyA9PSBFSU5UUikNCgkJY29udGludWU7DQoJaWYoLTEgPT0gcmV0KSB7DQoJCXNsb2coQVRSRUdfUFJJTlQsIFNMT0dfRVJSLCAiRXJyOiBhdHJlZ193YWl0X3JzcCB3YWl0IG1zZygleCkgdGltZW91dC5cbiIsIG1zZ19jbWQpOyAJCQkJDQoJfQ0KCWVsc2Ugew0KCQlzbG9nKEFUUkVHX1BSSU5ULCBTTE9HX05PUk1BTCwgImF0cmVnX3dhaXRfcnNwIHBvc3QgbXNnKCV4KSByZXNwb25zZS5cbiIsIG1zZ19jbWQpOw0KCX0NCg0KCXJldHVybjsNCn0NCg0KDQp2b2lkICphdHJlZ19zZWFyY2hfaW5zdGFuY2VfYnlfcHJlZml4KGNoYXIgKmF0X2NtZF9wcmVmaXgsIGludCBhdHJlZ190eXBlKQ0Kew0KCXZvaWQqIHBhdHJlZyA9IE5VTEw7DQoNCglzd2l0Y2ggKGF0cmVnX3R5cGUpIHsNCgkJY2FzZSBBVF9SRUdfU0VSOg0KCQkJcGF0cmVnID0gYXRyZWdfc2VyX3NlYXJjaF9pbnN0YW5jZV9ieV9wcmVmaXhfcHJvYyhhdF9jbWRfcHJlZml4KTsNCgkJCWJyZWFrOw0KDQoJCWNhc2UgQVRfUkVHX0lORk86DQoJCQlwYXRyZWcgPSBhdHJlZ19pbmZvX3NlYXJjaF9pbnN0YW5jZV9ieV9wcmVmaXhfcHJvYyhhdF9jbWRfcHJlZml4KTsNCgkJCWJyZWFrOw0KDQoJCWRlZmF1bHQ6DQoJCQlicmVhazsNCgl9DQoNCglyZXR1cm4gcGF0cmVnOw0KfQ0KDQoNCnZvaWQgKmF0cmVnX3NlYXJjaF9pbnN0YW5jZV90bXBfYnlfcmVxaWQoaW50IHJlcV9tc2dfaWQsIGludCBhdHJlZ190eXBlKQ0Kew0KCXZvaWQqIHBhdHJlZyA9IE5VTEw7DQoNCglzd2l0Y2ggKGF0cmVnX3R5cGUpIHsNCgljYXNlIEFUX1JFR19TRVI6DQoJCXBhdHJlZyA9IGF0cmVnX3Nlcl9zZWFyY2hfaW5zdGFuY2VfdG1wX2J5X3JlcWlkX3Byb2MocmVxX21zZ19pZCk7DQoJCWJyZWFrOw0KDQoJY2FzZSBBVF9SRUdfSU5GTzoNCgkJcGF0cmVnID0gYXRyZWdfaW5mb19zZWFyY2hfaW5zdGFuY2VfdG1wX2J5X3JlcWlkX3Byb2MocmVxX21zZ19pZCk7DQoJCWJyZWFrOw0KDQoJZGVmYXVsdDoNCgkJYnJlYWs7DQoJfQ0KDQoJcmV0dXJuIHBhdHJlZzsNCn0NCg0KDQpzdHJ1Y3QgYXRyZWdfaW5zdGFuY2VfYW5kX3R5cGVfdCBhdHJlZ19zZWFyY2hfaW5zdGFuY2VfYW5kX3R5cGVfYnlfcmVxaWQoaW50IHJlcV9tc2dfaWQpDQp7DQogICAgdm9pZCogcGF0cmVnID0gTlVMTDsNCglzdHJ1Y3QgYXRyZWdfaW5zdGFuY2VfYW5kX3R5cGVfdCBhdHJlZ19pbnN0YW5jZV9hbmRfdHlwZSA9IHswfTsNCg0KCWlmKGF0cmVnX3Nlcl9jeHRfaXNfaW5pdCkNCglwYXRyZWcgPSBhdHJlZ19zZXJfc2VhcmNoX2luc3RhbmNlX2J5X3JlcWlkX3Byb2MocmVxX21zZ19pZCk7DQoJaWYgKE5VTEwgIT0gcGF0cmVnKSB7DQoJCWF0cmVnX2luc3RhbmNlX2FuZF90eXBlLnR5cGUgPSBBVF9SRUdfU0VSOw0KCQlhdHJlZ19pbnN0YW5jZV9hbmRfdHlwZS5pbnN0YW5jZSA9IHBhdHJlZzsNCg0KCQlyZXR1cm4gYXRyZWdfaW5zdGFuY2VfYW5kX3R5cGU7DQoJfQ0KCWlmKGF0cmVnX2luZm9fY3h0X2lzX2luaXQpDQoJcGF0cmVnID0gYXRyZWdfaW5mb19zZWFyY2hfaW5zdGFuY2VfYnlfcmVxaWRfcHJvYyhyZXFfbXNnX2lkKTsNCglpZiAoTlVMTCAhPSBwYXRyZWcpIHsNCgkJYXRyZWdfaW5zdGFuY2VfYW5kX3R5cGUudHlwZSA9IEFUX1JFR19JTkZPOw0KCQlhdHJlZ19pbnN0YW5jZV9hbmRfdHlwZS5pbnN0YW5jZSA9IHBhdHJlZzsNCg0KCQlyZXR1cm4gYXRyZWdfaW5zdGFuY2VfYW5kX3R5cGU7DQoJfQ0KCWF0cmVnX2luc3RhbmNlX2FuZF90eXBlLnR5cGUgPSAtMTsNCglyZXR1cm4gYXRyZWdfaW5zdGFuY2VfYW5kX3R5cGU7DQp9DQoNCg==