LyogJFhGcmVlODYkICovIC8qIC0qLSBtb2RlOiBjOyBjLWJhc2ljLW9mZnNldDogMyAtKi0gKi8KLyoKICogQ29weXJpZ2h0IDIwMDAgR2FyZXRoIEh1Z2hlcwogKiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYQogKiBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlICJTb2Z0d2FyZSIpLAogKiB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uCiAqIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLAogKiBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUKICogU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKICoKICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgKGluY2x1ZGluZyB0aGUgbmV4dAogKiBwYXJhZ3JhcGgpIHNoYWxsIGJlIGluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlCiAqIFNvZnR3YXJlLgogKgogKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgogKiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gIElOIE5PIEVWRU5UIFNIQUxMCiAqIEdBUkVUSCBIVUdIRVMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSCiAqIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOCiAqIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuCiAqLwoKLyoKICogQXV0aG9yczoKICoJR2FyZXRoIEh1Z2hlcyA8Z2FyZXRoQHZhbGludXguY29tPgogKglMZWlmIERlbGdhc3MgPGxkZWxnYXNzQHJldGluYWxidXJuLm5ldD4KICoJSm9z6SBGb25zZWNhIDxqX3JfZm9uc2VjYUB5YWhvby5jby51az4KICovCgojaW5jbHVkZSAibWFjaDY0X2NvbnRleHQuaCIKI2luY2x1ZGUgIm1hY2g2NF9pb2N0bC5oIgojaW5jbHVkZSAibWFjaDY0X3N0YXRlLmgiCiNpbmNsdWRlICJtYWNoNjRfdmIuaCIKI2luY2x1ZGUgIm1hY2g2NF90cmlzLmgiCiNpbmNsdWRlICJtYWNoNjRfdGV4LmgiCgojaW5jbHVkZSAiY29udGV4dC5oIgojaW5jbHVkZSAibWFjcm9zLmgiCiNpbmNsdWRlICJzaW1wbGVfbGlzdC5oIgojaW5jbHVkZSAiZW51bXMuaCIKI2luY2x1ZGUgInRleHN0b3JlLmgiCiNpbmNsdWRlICJ0ZXhmb3JtYXQuaCIKI2luY2x1ZGUgInRleGltYWdlLmgiCiNpbmNsdWRlICJ0ZXhvYmouaCIKI2luY2x1ZGUgImltcG9ydHMuaCIKCgpzdGF0aWMgdm9pZCBtYWNoNjRTZXRUZXhXcmFwKCBtYWNoNjRUZXhPYmpQdHIgdCwKCQkJICAgICAgR0xlbnVtIHN3cmFwLCBHTGVudW0gdHdyYXAgKQp7CiAgIHN3aXRjaCAoIHN3cmFwICkgewogICBjYXNlIEdMX0NMQU1QOgogICBjYXNlIEdMX0NMQU1QX1RPX0VER0U6CiAgIGNhc2UgR0xfQ0xBTVBfVE9fQk9SREVSOgogICAgICB0LT5DbGFtcFMgPSBHTF9UUlVFOwogICAgICBicmVhazsKICAgY2FzZSBHTF9SRVBFQVQ6CiAgICAgIHQtPkNsYW1wUyA9IEdMX0ZBTFNFOwogICAgICBicmVhazsKICAgfQoKICAgc3dpdGNoICggdHdyYXAgKSB7CiAgIGNhc2UgR0xfQ0xBTVA6CiAgIGNhc2UgR0xfQ0xBTVBfVE9fRURHRToKICAgY2FzZSBHTF9DTEFNUF9UT19CT1JERVI6CiAgICAgIHQtPkNsYW1wVCA9IEdMX1RSVUU7CiAgICAgIGJyZWFrOwogICBjYXNlIEdMX1JFUEVBVDoKICAgICAgdC0+Q2xhbXBUID0gR0xfRkFMU0U7CiAgICAgIGJyZWFrOwogICB9Cn0KCnN0YXRpYyB2b2lkIG1hY2g2NFNldFRleEZpbHRlciggbWFjaDY0VGV4T2JqUHRyIHQsCgkJCQlHTGVudW0gbWluZiwgR0xlbnVtIG1hZ2YgKQp7CiAgIHN3aXRjaCAoIG1pbmYgKSB7CiAgIGNhc2UgR0xfTkVBUkVTVDoKICAgY2FzZSBHTF9ORUFSRVNUX01JUE1BUF9ORUFSRVNUOgogICBjYXNlIEdMX05FQVJFU1RfTUlQTUFQX0xJTkVBUjoKICAgICAgdC0+QmlsaW5lYXJNaW4gPSBHTF9GQUxTRTsKICAgICAgYnJlYWs7CiAgIGNhc2UgR0xfTElORUFSOgogICBjYXNlIEdMX0xJTkVBUl9NSVBNQVBfTkVBUkVTVDoKICAgY2FzZSBHTF9MSU5FQVJfTUlQTUFQX0xJTkVBUjoKICAgICAgdC0+QmlsaW5lYXJNaW4gPSBHTF9UUlVFOwogICAgICBicmVhazsKICAgfQoKICAgc3dpdGNoICggbWFnZiApIHsKICAgY2FzZSBHTF9ORUFSRVNUOgogICAgICB0LT5CaWxpbmVhck1hZyA9IEdMX0ZBTFNFOwogICAgICBicmVhazsKICAgY2FzZSBHTF9MSU5FQVI6CiAgICAgIHQtPkJpbGluZWFyTWFnID0gR0xfVFJVRTsKICAgICAgYnJlYWs7CiAgIH0KfQoKc3RhdGljIHZvaWQgbWFjaDY0U2V0VGV4Qm9yZGVyQ29sb3IoIG1hY2g2NFRleE9ialB0ciB0LCBHTHVieXRlIGNbNF0gKQp7CiNpZiAwCiAgIEdMdWludCBib3JkZXIgPSBtYWNoNjRQYWNrQ29sb3IoIDQsIGNbMF0sIGNbMV0sIGNbMl0sIGNbM10gKTsKI2VuZGlmCn0KCgpzdGF0aWMgbWFjaDY0VGV4T2JqUHRyCm1hY2g2NEFsbG9jVGV4T2JqKCBzdHJ1Y3QgZ2xfdGV4dHVyZV9vYmplY3QgKnRleE9iaiApCnsKICAgbWFjaDY0VGV4T2JqUHRyIHQ7CgogICBpZiAoIE1BQ0g2NF9ERUJVRyAmIERFQlVHX1ZFUkJPU0VfQVBJICkKICAgICAgZnByaW50Ziggc3RkZXJyLCAiJXMoICVwIClcbiIsIF9fRlVOQ1RJT05fXywgdGV4T2JqICk7CgogICB0ID0gKG1hY2g2NFRleE9ialB0cikgQ0FMTE9DX1NUUlVDVCggbWFjaDY0X3RleHR1cmVfb2JqZWN0ICk7CiAgIHRleE9iai0+RHJpdmVyRGF0YSA9IHQ7CiAgIGlmICggIXQgKQogICAgICByZXR1cm4gTlVMTDsKCiAgIC8qIEluaXRpYWxpemUgbm9uLWltYWdlLWRlcGVuZGVudCBwYXJ0cyBvZiB0aGUgc3RhdGU6CiAgICAqLwogICB0LT5iYXNlLnRPYmogPSB0ZXhPYmo7CiAgIHQtPmJhc2UuZGlydHlfaW1hZ2VzWzBdID0gKDEgPDwgMCk7CgogICB0LT5idWZBZGRyID0gMDsKCiAgIG1ha2VfZW1wdHlfbGlzdCggKGRyaVRleHR1cmVPYmplY3QgKikgdCApOwoKICAgbWFjaDY0U2V0VGV4V3JhcCggdCwgdGV4T2JqLT5XcmFwUywgdGV4T2JqLT5XcmFwVCApOwogICBtYWNoNjRTZXRUZXhGaWx0ZXIoIHQsIHRleE9iai0+TWluRmlsdGVyLCB0ZXhPYmotPk1hZ0ZpbHRlciApOwogICBtYWNoNjRTZXRUZXhCb3JkZXJDb2xvciggdCwgdGV4T2JqLT5fQm9yZGVyQ2hhbiApOwoKICAgcmV0dXJuIHQ7Cn0KCgovKiBDYWxsZWQgYnkgdGhlIF9tZXNhX3N0b3JlX3RleGltYWdlWzEyM11kKCkgZnVuY3Rpb25zLiAqLwpzdGF0aWMgY29uc3Qgc3RydWN0IGdsX3RleHR1cmVfZm9ybWF0ICoKbWFjaDY0Q2hvb3NlVGV4dHVyZUZvcm1hdCggR0xjb250ZXh0ICpjdHgsIEdMaW50IGludGVybmFsRm9ybWF0LAoJCQkgICBHTGVudW0gZm9ybWF0LCBHTGVudW0gdHlwZSApCnsKICAgbWFjaDY0Q29udGV4dFB0ciBtbWVzYSA9IE1BQ0g2NF9DT05URVhUKGN0eCk7CiAgICh2b2lkKSBmb3JtYXQ7CiAgICh2b2lkKSB0eXBlOwoKICAgc3dpdGNoICggaW50ZXJuYWxGb3JtYXQgKSB7CiAgIGNhc2UgR0xfQUxQSEE6CiAgIGNhc2UgR0xfQUxQSEE0OgogICBjYXNlIEdMX0FMUEhBODoKICAgY2FzZSBHTF9BTFBIQTEyOgogICBjYXNlIEdMX0FMUEhBMTY6CiAgIGNhc2UgMjoKICAgY2FzZSBHTF9MVU1JTkFOQ0VfQUxQSEE6CiAgIGNhc2UgR0xfTFVNSU5BTkNFNF9BTFBIQTQ6CiAgIGNhc2UgR0xfTFVNSU5BTkNFNl9BTFBIQTI6CiAgIGNhc2UgR0xfTFVNSU5BTkNFOF9BTFBIQTg6CiAgIGNhc2UgR0xfTFVNSU5BTkNFMTJfQUxQSEE0OgogICBjYXNlIEdMX0xVTUlOQU5DRTEyX0FMUEhBMTI6CiAgIGNhc2UgR0xfTFVNSU5BTkNFMTZfQUxQSEExNjoKICAgY2FzZSA0OgogICBjYXNlIEdMX1JHQkE6CiAgIGNhc2UgR0xfUkdCQTI6CiAgICAgIGlmIChtbWVzYS0+bWFjaDY0U2NyZWVuLT5jcHAgPT0gNCkKICAgICAgICAgcmV0dXJuICZfbWVzYV90ZXhmb3JtYXRfYXJnYjg4ODg7CiAgICAgIGVsc2UKICAgICAgICAgcmV0dXJuICZfbWVzYV90ZXhmb3JtYXRfYXJnYjQ0NDQ7CgogICBjYXNlIEdMX1JHQjVfQTE6CiAgICAgIGlmIChtbWVzYS0+bWFjaDY0U2NyZWVuLT5jcHAgPT0gNCkKICAgICAgICAgcmV0dXJuICZfbWVzYV90ZXhmb3JtYXRfYXJnYjg4ODg7CiAgICAgIGVsc2UKICAgICAgICAgcmV0dXJuICZfbWVzYV90ZXhmb3JtYXRfYXJnYjE1NTU7CgogICBjYXNlIEdMX1JHQkE4OgogICBjYXNlIEdMX1JHQjEwX0EyOgogICBjYXNlIEdMX1JHQkExMjoKICAgY2FzZSBHTF9SR0JBMTY6CiAgIGNhc2UgR0xfUkdCQTQ6CiAgICAgIGlmIChtbWVzYS0+bWFjaDY0U2NyZWVuLT5jcHAgPT0gNCkKICAgICAgICAgcmV0dXJuICZfbWVzYV90ZXhmb3JtYXRfYXJnYjg4ODg7CiAgICAgIGVsc2UKICAgICAgICAgcmV0dXJuICZfbWVzYV90ZXhmb3JtYXRfYXJnYjQ0NDQ7CgogICBjYXNlIDM6CiAgIGNhc2UgR0xfUkdCOgogICBjYXNlIEdMX1IzX0czX0IyOgogICBjYXNlIEdMX1JHQjQ6CiAgIGNhc2UgR0xfUkdCNToKICAgY2FzZSBHTF9SR0I4OgogICBjYXNlIEdMX1JHQjEwOgogICBjYXNlIEdMX1JHQjEyOgogICBjYXNlIEdMX1JHQjE2OgogICAgICBpZiAobW1lc2EtPm1hY2g2NFNjcmVlbi0+Y3BwID09IDQpCiAgICAgICAgIHJldHVybiAmX21lc2FfdGV4Zm9ybWF0X2FyZ2I4ODg4OwogICAgICBlbHNlCiAgICAgICAgIHJldHVybiAmX21lc2FfdGV4Zm9ybWF0X3JnYjU2NTsKCiAgIGNhc2UgMToKICAgY2FzZSBHTF9MVU1JTkFOQ0U6CiAgIGNhc2UgR0xfTFVNSU5BTkNFNDoKICAgY2FzZSBHTF9MVU1JTkFOQ0U4OgogICBjYXNlIEdMX0xVTUlOQU5DRTEyOgogICBjYXNlIEdMX0xVTUlOQU5DRTE2OgogICAgICBpZiAobW1lc2EtPm1hY2g2NFNjcmVlbi0+Y3BwID09IDQpCiAgICAgICAgIHJldHVybiAmX21lc2FfdGV4Zm9ybWF0X2FyZ2I4ODg4OyAvKiBpbmVmZmljaWVudCBidXQgYWNjdXJhdGUgKi8KICAgICAgZWxzZQogICAgICAgICByZXR1cm4gJl9tZXNhX3RleGZvcm1hdF9hcmdiMTU1NTsKCiAgIGNhc2UgR0xfSU5URU5TSVRZNDoKICAgY2FzZSBHTF9JTlRFTlNJVFk6CiAgIGNhc2UgR0xfSU5URU5TSVRZODoKICAgY2FzZSBHTF9JTlRFTlNJVFkxMjoKICAgY2FzZSBHTF9JTlRFTlNJVFkxNjoKICAgICAgaWYgKG1tZXNhLT5tYWNoNjRTY3JlZW4tPmNwcCA9PSA0KQogICAgICAgICByZXR1cm4gJl9tZXNhX3RleGZvcm1hdF9hcmdiODg4ODsgLyogaW5lZmZpY2llbnQgYnV0IGFjY3VyYXRlICovCiAgICAgIGVsc2UKICAgICAgICAgcmV0dXJuICZfbWVzYV90ZXhmb3JtYXRfYXJnYjQ0NDQ7CgogICBjYXNlIEdMX0NPTE9SX0lOREVYOgogICBjYXNlIEdMX0NPTE9SX0lOREVYMV9FWFQ6CiAgIGNhc2UgR0xfQ09MT1JfSU5ERVgyX0VYVDoKICAgY2FzZSBHTF9DT0xPUl9JTkRFWDRfRVhUOgogICBjYXNlIEdMX0NPTE9SX0lOREVYOF9FWFQ6CiAgIGNhc2UgR0xfQ09MT1JfSU5ERVgxMl9FWFQ6CiAgIGNhc2UgR0xfQ09MT1JfSU5ERVgxNl9FWFQ6CiAgICAgIHJldHVybiAmX21lc2FfdGV4Zm9ybWF0X2NpODsKCiAgIGNhc2UgR0xfWUNCQ1JfTUVTQToKICAgICAgaWYgKHR5cGUgPT0gR0xfVU5TSUdORURfU0hPUlRfOF84X0FQUExFIHx8CiAgICAgICAgICB0eXBlID09IEdMX1VOU0lHTkVEX0JZVEUpCiAgICAgICAgIHJldHVybiAmX21lc2FfdGV4Zm9ybWF0X3ljYmNyOwogICAgICBlbHNlCiAgICAgICAgIHJldHVybiAmX21lc2FfdGV4Zm9ybWF0X3ljYmNyX3JldjsKCiAgIGRlZmF1bHQ6CiAgICAgIF9tZXNhX3Byb2JsZW0oIGN0eCwgInVuZXhwZWN0ZWQgZm9ybWF0IGluICVzIiwgX19GVU5DVElPTl9fICk7CiAgICAgIHJldHVybiBOVUxMOwogICB9Cn0KCnN0YXRpYyB2b2lkIG1hY2g2NFRleEltYWdlMUQoIEdMY29udGV4dCAqY3R4LCBHTGVudW0gdGFyZ2V0LCBHTGludCBsZXZlbCwKCQkJICAgIEdMaW50IGludGVybmFsRm9ybWF0LAoJCQkgICAgR0xpbnQgd2lkdGgsIEdMaW50IGJvcmRlciwKCQkJICAgIEdMZW51bSBmb3JtYXQsIEdMZW51bSB0eXBlLCBjb25zdCBHTHZvaWQgKnBpeGVscywKCQkJICAgIGNvbnN0IHN0cnVjdCBnbF9waXhlbHN0b3JlX2F0dHJpYiAqcGFja2luZywKCQkJICAgIHN0cnVjdCBnbF90ZXh0dXJlX29iamVjdCAqdGV4T2JqLAoJCQkgICAgc3RydWN0IGdsX3RleHR1cmVfaW1hZ2UgKnRleEltYWdlICkKewogICBtYWNoNjRDb250ZXh0UHRyIG1tZXNhID0gTUFDSDY0X0NPTlRFWFQoY3R4KTsKICAgZHJpVGV4dHVyZU9iamVjdCAqIHQgPSAoZHJpVGV4dHVyZU9iamVjdCAqKSB0ZXhPYmotPkRyaXZlckRhdGE7CgogICBpZiAoIHQgKSB7CiAgICAgIGRyaVN3YXBPdXRUZXh0dXJlT2JqZWN0KCB0ICk7CiAgIH0KICAgZWxzZSB7CiAgICAgIHQgPSAoZHJpVGV4dHVyZU9iamVjdCAqKSBtYWNoNjRBbGxvY1RleE9iaih0ZXhPYmopOwogICAgICBpZiAoIXQpIHsKICAgICAgICAgX21lc2FfZXJyb3IoY3R4LCBHTF9PVVRfT0ZfTUVNT1JZLCAiZ2xUZXhJbWFnZTFEIik7CiAgICAgICAgIHJldHVybjsKICAgICAgfQogICB9CgogICAvKiBOb3RlLCB0aGlzIHdpbGwgY2FsbCBtYWNoNjRDaG9vc2VUZXh0dXJlRm9ybWF0ICovCiAgIF9tZXNhX3N0b3JlX3RleGltYWdlMWQoIGN0eCwgdGFyZ2V0LCBsZXZlbCwgaW50ZXJuYWxGb3JtYXQsCgkJCSAgIHdpZHRoLCBib3JkZXIsIGZvcm1hdCwgdHlwZSwKCQkJICAgcGl4ZWxzLCBwYWNraW5nLCB0ZXhPYmosIHRleEltYWdlICk7CgogICBtbWVzYS0+bmV3X3N0YXRlIHw9IE1BQ0g2NF9ORVdfVEVYVFVSRTsKfQoKc3RhdGljIHZvaWQgbWFjaDY0VGV4U3ViSW1hZ2UxRCggR0xjb250ZXh0ICpjdHgsCgkJCQkgR0xlbnVtIHRhcmdldCwKCQkJCSBHTGludCBsZXZlbCwKCQkJCSBHTGludCB4b2Zmc2V0LAoJCQkJIEdMc2l6ZWkgd2lkdGgsCgkJCQkgR0xlbnVtIGZvcm1hdCwgR0xlbnVtIHR5cGUsCgkJCQkgY29uc3QgR0x2b2lkICpwaXhlbHMsCgkJCQkgY29uc3Qgc3RydWN0IGdsX3BpeGVsc3RvcmVfYXR0cmliICpwYWNraW5nLAoJCQkJIHN0cnVjdCBnbF90ZXh0dXJlX29iamVjdCAqdGV4T2JqLAoJCQkJIHN0cnVjdCBnbF90ZXh0dXJlX2ltYWdlICp0ZXhJbWFnZSApCnsKICAgbWFjaDY0Q29udGV4dFB0ciBtbWVzYSA9IE1BQ0g2NF9DT05URVhUKGN0eCk7CiAgIGRyaVRleHR1cmVPYmplY3QgKiB0ID0gKGRyaVRleHR1cmVPYmplY3QgKikgdGV4T2JqLT5Ecml2ZXJEYXRhOwoKICAgYXNzZXJ0KCB0ICk7IC8qIHRoaXMgX3Nob3VsZF8gYmUgdHJ1ZSAqLwogICBpZiAoIHQgKSB7CiAgICAgIGRyaVN3YXBPdXRUZXh0dXJlT2JqZWN0KCB0ICk7CiAgIH0KICAgZWxzZSB7CiAgICAgIHQgPSAoZHJpVGV4dHVyZU9iamVjdCAqKSBtYWNoNjRBbGxvY1RleE9iaih0ZXhPYmopOwogICAgICBpZiAoIXQpIHsKICAgICAgICAgX21lc2FfZXJyb3IoY3R4LCBHTF9PVVRfT0ZfTUVNT1JZLCAiZ2xUZXhTdWJJbWFnZTFEIik7CiAgICAgICAgIHJldHVybjsKICAgICAgfQogICB9CgogICBfbWVzYV9zdG9yZV90ZXhzdWJpbWFnZTFkKGN0eCwgdGFyZ2V0LCBsZXZlbCwgeG9mZnNldCwgd2lkdGgsCgkJCSAgICAgZm9ybWF0LCB0eXBlLCBwaXhlbHMsIHBhY2tpbmcsIHRleE9iaiwKCQkJICAgICB0ZXhJbWFnZSk7CgogICBtbWVzYS0+bmV3X3N0YXRlIHw9IE1BQ0g2NF9ORVdfVEVYVFVSRTsKfQoKc3RhdGljIHZvaWQgbWFjaDY0VGV4SW1hZ2UyRCggR0xjb250ZXh0ICpjdHgsIEdMZW51bSB0YXJnZXQsIEdMaW50IGxldmVsLAoJCQkgICAgICBHTGludCBpbnRlcm5hbEZvcm1hdCwKCQkJICAgICAgR0xpbnQgd2lkdGgsIEdMaW50IGhlaWdodCwgR0xpbnQgYm9yZGVyLAoJCQkgICAgICBHTGVudW0gZm9ybWF0LCBHTGVudW0gdHlwZSwgY29uc3QgR0x2b2lkICpwaXhlbHMsCgkJCSAgICAgIGNvbnN0IHN0cnVjdCBnbF9waXhlbHN0b3JlX2F0dHJpYiAqcGFja2luZywKCQkJICAgICAgc3RydWN0IGdsX3RleHR1cmVfb2JqZWN0ICp0ZXhPYmosCgkJCSAgICAgIHN0cnVjdCBnbF90ZXh0dXJlX2ltYWdlICp0ZXhJbWFnZSApCnsKICAgbWFjaDY0Q29udGV4dFB0ciBtbWVzYSA9IE1BQ0g2NF9DT05URVhUKGN0eCk7CiAgIGRyaVRleHR1cmVPYmplY3QgKiB0ID0gKGRyaVRleHR1cmVPYmplY3QgKikgdGV4T2JqLT5Ecml2ZXJEYXRhOwoKICAgaWYgKCB0ICkgewogICAgICBkcmlTd2FwT3V0VGV4dHVyZU9iamVjdCggdCApOwogICB9CiAgIGVsc2UgewogICAgICB0ID0gKGRyaVRleHR1cmVPYmplY3QgKikgbWFjaDY0QWxsb2NUZXhPYmoodGV4T2JqKTsKICAgICAgaWYgKCF0KSB7CiAgICAgICAgIF9tZXNhX2Vycm9yKGN0eCwgR0xfT1VUX09GX01FTU9SWSwgImdsVGV4SW1hZ2UyRCIpOwogICAgICAgICByZXR1cm47CiAgICAgIH0KICAgfQoKICAgLyogTm90ZSwgdGhpcyB3aWxsIGNhbGwgbWFjaDY0Q2hvb3NlVGV4dHVyZUZvcm1hdCAqLwogICBfbWVzYV9zdG9yZV90ZXhpbWFnZTJkKCBjdHgsIHRhcmdldCwgbGV2ZWwsIGludGVybmFsRm9ybWF0LAoJCQkgICB3aWR0aCwgaGVpZ2h0LCBib3JkZXIsIGZvcm1hdCwgdHlwZSwgcGl4ZWxzLAoJCQkgICAmY3R4LT5VbnBhY2ssIHRleE9iaiwgdGV4SW1hZ2UgKTsKCiAgIG1tZXNhLT5uZXdfc3RhdGUgfD0gTUFDSDY0X05FV19URVhUVVJFOwp9CgpzdGF0aWMgdm9pZCBtYWNoNjRUZXhTdWJJbWFnZTJEKCBHTGNvbnRleHQgKmN0eCwKCQkJCSBHTGVudW0gdGFyZ2V0LAoJCQkJIEdMaW50IGxldmVsLAoJCQkJIEdMaW50IHhvZmZzZXQsIEdMaW50IHlvZmZzZXQsCgkJCQkgR0xzaXplaSB3aWR0aCwgR0xzaXplaSBoZWlnaHQsCgkJCQkgR0xlbnVtIGZvcm1hdCwgR0xlbnVtIHR5cGUsCgkJCQkgY29uc3QgR0x2b2lkICpwaXhlbHMsCgkJCQkgY29uc3Qgc3RydWN0IGdsX3BpeGVsc3RvcmVfYXR0cmliICpwYWNraW5nLAoJCQkJIHN0cnVjdCBnbF90ZXh0dXJlX29iamVjdCAqdGV4T2JqLAoJCQkJIHN0cnVjdCBnbF90ZXh0dXJlX2ltYWdlICp0ZXhJbWFnZSApCnsKICAgbWFjaDY0Q29udGV4dFB0ciBtbWVzYSA9IE1BQ0g2NF9DT05URVhUKGN0eCk7CiAgIGRyaVRleHR1cmVPYmplY3QgKiB0ID0gKGRyaVRleHR1cmVPYmplY3QgKikgdGV4T2JqLT5Ecml2ZXJEYXRhOwoKICAgYXNzZXJ0KCB0ICk7IC8qIHRoaXMgX3Nob3VsZF8gYmUgdHJ1ZSAqLwogICBpZiAoIHQgKSB7CiAgICAgIGRyaVN3YXBPdXRUZXh0dXJlT2JqZWN0KCB0ICk7CiAgIH0KICAgZWxzZSB7CiAgICAgIHQgPSAoZHJpVGV4dHVyZU9iamVjdCAqKSBtYWNoNjRBbGxvY1RleE9iaih0ZXhPYmopOwogICAgICBpZiAoIXQpIHsKICAgICAgICAgX21lc2FfZXJyb3IoY3R4LCBHTF9PVVRfT0ZfTUVNT1JZLCAiZ2xUZXhTdWJJbWFnZTJEIik7CiAgICAgICAgIHJldHVybjsKICAgICAgfQogICB9CgogICBfbWVzYV9zdG9yZV90ZXhzdWJpbWFnZTJkKGN0eCwgdGFyZ2V0LCBsZXZlbCwgeG9mZnNldCwgeW9mZnNldCwgd2lkdGgsCgkJCSAgICAgaGVpZ2h0LCBmb3JtYXQsIHR5cGUsIHBpeGVscywgcGFja2luZywgdGV4T2JqLAoJCQkgICAgIHRleEltYWdlKTsKCiAgIG1tZXNhLT5uZXdfc3RhdGUgfD0gTUFDSDY0X05FV19URVhUVVJFOwp9CgovKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqIERldmljZSBEcml2ZXIgQVBJIHRleHR1cmUgZnVuY3Rpb25zCiAqLwoKc3RhdGljIHZvaWQgbWFjaDY0RERUZXhFbnYoIEdMY29udGV4dCAqY3R4LCBHTGVudW0gdGFyZ2V0LAoJCQkgICAgR0xlbnVtIHBuYW1lLCBjb25zdCBHTGZsb2F0ICpwYXJhbSApCnsKICAgbWFjaDY0Q29udGV4dFB0ciBtbWVzYSA9IE1BQ0g2NF9DT05URVhUKGN0eCk7CiNpZiAwCiAgIHN0cnVjdCBnbF90ZXh0dXJlX3VuaXQgKnRleFVuaXQ7CiAgIEdMdWJ5dGUgY1s0XTsKI2VuZGlmCgogICBpZiAoIE1BQ0g2NF9ERUJVRyAmIERFQlVHX1ZFUkJPU0VfQVBJICkgewogICAgICBmcHJpbnRmKCBzdGRlcnIsICIlcyggJXMgKVxuIiwKCSAgICAgICBfX0ZVTkNUSU9OX18sIF9tZXNhX2xvb2t1cF9lbnVtX2J5X25yKCBwbmFtZSApICk7CiAgIH0KCiAgIHN3aXRjaCAoIHBuYW1lICkgewogICBjYXNlIEdMX1RFWFRVUkVfRU5WX01PREU6CiAgICAgIEZMVVNIX0JBVENIKCBtbWVzYSApOwogICAgICBtbWVzYS0+bmV3X3N0YXRlIHw9IE1BQ0g2NF9ORVdfVEVYVFVSRSB8IE1BQ0g2NF9ORVdfQUxQSEE7CiAgICAgIGJyZWFrOwoKI2lmIDAKICAgY2FzZSBHTF9URVhUVVJFX0VOVl9DT0xPUjoKICAgICAgdGV4VW5pdCA9ICZjdHgtPlRleHR1cmUuVW5pdFtjdHgtPlRleHR1cmUuQ3VycmVudFVuaXRdOwogICAgICBDTEFNUEVEX0ZMT0FUX1RPX1VCWVRFKCBjWzBdLCB0ZXhVbml0LT5FbnZDb2xvclswXSApOwogICAgICBDTEFNUEVEX0ZMT0FUX1RPX1VCWVRFKCBjWzFdLCB0ZXhVbml0LT5FbnZDb2xvclsxXSApOwogICAgICBDTEFNUEVEX0ZMT0FUX1RPX1VCWVRFKCBjWzJdLCB0ZXhVbml0LT5FbnZDb2xvclsyXSApOwogICAgICBDTEFNUEVEX0ZMT0FUX1RPX1VCWVRFKCBjWzNdLCB0ZXhVbml0LT5FbnZDb2xvclszXSApOwogICAgICBtbWVzYS0+ZW52X2NvbG9yID0gbWFjaDY0UGFja0NvbG9yKCAzMiwgY1swXSwgY1sxXSwgY1syXSwgY1szXSApOwogICAgICBpZiAoIG1tZXNhLT5zZXR1cC5jb25zdGFudF9jb2xvcl9jICE9IG1tZXNhLT5lbnZfY29sb3IgKSB7CgkgRkxVU0hfQkFUQ0goIG1tZXNhICk7CgkgbW1lc2EtPnNldHVwLmNvbnN0YW50X2NvbG9yX2MgPSBtbWVzYS0+ZW52X2NvbG9yOwoKCSBtbWVzYS0+bmV3X3N0YXRlIHw9IE1BQ0g2NF9ORVdfVEVYVFVSRTsKCgkgLyogTW9yZSBjb21wbGV4IG11bHRpdGV4dHVyZS9tdWx0aXBhc3MgZmFsbGJhY2tzIGZvciBHTF9CTEVORAoJICAqIGNhbiBiZSBkb25lIGxhdGVyLCBidXQgdGhpcyBhbGxvd3MgYSBzaW5nbGUgcGFzcyBHTF9CTEVORAoJICAqIGluIHNvbWUgY2FzZXMgKGllLiBQZXJmb3JtZXIgdG93biBkZW1vKS4KCSAgKi8KCSBtbWVzYS0+YmxlbmRfZmxhZ3MgJj0gfk1BQ0g2NF9CTEVORF9FTlZfQ09MT1I7CgkgaWYgKCBtbWVzYS0+ZW52X2NvbG9yICE9IDB4MDAwMDAwMDAgJiYKCSAgICAgIG1tZXNhLT5lbnZfY29sb3IgIT0gMHhmZjAwMDAwMCAmJgoJICAgICAgbW1lc2EtPmVudl9jb2xvciAhPSAweDAwZmZmZmZmICYmCgkgICAgICBtbWVzYS0+ZW52X2NvbG9yICE9IDB4ZmZmZmZmZmYgKSkgewkKCSAgICBtbWVzYS0+YmxlbmRfZmxhZ3MgfD0gTUFDSDY0X0JMRU5EX0VOVl9DT0xPUjsKCSB9CiAgICAgIH0KICAgICAgYnJlYWs7CiNlbmRpZgoKICAgZGVmYXVsdDoKICAgICAgcmV0dXJuOwogICB9Cn0KCnN0YXRpYyB2b2lkIG1hY2g2NEREVGV4UGFyYW1ldGVyKCBHTGNvbnRleHQgKmN0eCwgR0xlbnVtIHRhcmdldCwKCQkJCSAgc3RydWN0IGdsX3RleHR1cmVfb2JqZWN0ICp0T2JqLAoJCQkJICBHTGVudW0gcG5hbWUsIGNvbnN0IEdMZmxvYXQgKnBhcmFtcyApCnsKICAgbWFjaDY0Q29udGV4dFB0ciBtbWVzYSA9IE1BQ0g2NF9DT05URVhUKGN0eCk7CiAgIG1hY2g2NFRleE9ialB0ciB0ID0gKG1hY2g2NFRleE9ialB0cil0T2JqLT5Ecml2ZXJEYXRhOwoKICAgaWYgKCBNQUNINjRfREVCVUcgJiBERUJVR19WRVJCT1NFX0FQSSApIHsKICAgICAgZnByaW50Ziggc3RkZXJyLCAiJXMoICVzIClcbiIsCgkgICAgICAgX19GVU5DVElPTl9fLCBfbWVzYV9sb29rdXBfZW51bV9ieV9uciggcG5hbWUgKSApOwogICB9CgogICBpZiAoICggdGFyZ2V0ICE9IEdMX1RFWFRVUkVfMkQgKSAmJgoJKCB0YXJnZXQgIT0gR0xfVEVYVFVSRV8xRCApICkgewogICAgICByZXR1cm47CiAgIH0KCiAgIGlmICghdCkgewogICAgICB0ID0gbWFjaDY0QWxsb2NUZXhPYmoodE9iaik7CiAgICAgIGlmICghdCkgewogICAgICAgICBfbWVzYV9lcnJvcihjdHgsIEdMX09VVF9PRl9NRU1PUlksICJnbFRleFBhcmFtZXRlciIpOwogICAgICAgICByZXR1cm47CiAgICAgIH0KICAgfQoKICAgc3dpdGNoICggcG5hbWUgKSB7CiAgIGNhc2UgR0xfVEVYVFVSRV9NSU5fRklMVEVSOgogICBjYXNlIEdMX1RFWFRVUkVfTUFHX0ZJTFRFUjoKICAgICAgaWYgKCB0LT5iYXNlLmJvdW5kICkgRkxVU0hfQkFUQ0goIG1tZXNhICk7CiAgICAgIG1hY2g2NFNldFRleEZpbHRlciggdCwgdE9iai0+TWluRmlsdGVyLCB0T2JqLT5NYWdGaWx0ZXIgKTsKICAgICAgYnJlYWs7CgogICBjYXNlIEdMX1RFWFRVUkVfV1JBUF9TOgogICBjYXNlIEdMX1RFWFRVUkVfV1JBUF9UOgogICAgICBpZiAoIHQtPmJhc2UuYm91bmQgKSBGTFVTSF9CQVRDSCggbW1lc2EgKTsKICAgICAgbWFjaDY0U2V0VGV4V3JhcCggdCwgdE9iai0+V3JhcFMsIHRPYmotPldyYXBUICk7CiAgICAgIGJyZWFrOwoKICAgY2FzZSBHTF9URVhUVVJFX0JPUkRFUl9DT0xPUjoKICAgICAgaWYgKCB0LT5iYXNlLmJvdW5kICkgRkxVU0hfQkFUQ0goIG1tZXNhICk7CiAgICAgIG1hY2g2NFNldFRleEJvcmRlckNvbG9yKCB0LCB0T2JqLT5fQm9yZGVyQ2hhbiApOwogICAgICBicmVhazsKCiAgIGNhc2UgR0xfVEVYVFVSRV9CQVNFX0xFVkVMOgogICAgICAvKiBGcm9tIFJhZGVvbi9SYWdlMTI4OgogICAgICAgKiBUaGlzIGlzbid0IHRoZSBtb3N0IGVmZmljaWVudCBzb2x1dGlvbiBidXQgdGhlcmUgZG9lc24ndCBhcHBlYXIgdG8KICAgICAgICogYmUgYSBuaWNlIGFsdGVybmF0aXZlLiAgU2luY2UgdGhlcmUncyBubyBMT0QgY2xhbXBpbmcsCiAgICAgICAqIHdlIGp1c3QgaGF2ZSB0byByZWx5IG9uIGxvYWRpbmcgdGhlIHJpZ2h0IHN1YnNldCBvZiBtaXBtYXAgbGV2ZWxzCiAgICAgICAqIHRvIHNpbXVsYXRlIGEgY2xhbXBlZCBMT0QuICAKICAgICAgICoKICAgICAgICogRm9yIG1hY2g2NCB3ZSdyZSBvbmx5IGNvbmNlcm5lZCB3aXRoIHRoZSBiYXNlIGxldmVsCiAgICAgICAqIHNpbmNlIHRoYXQncyB0aGUgb25seSB0ZXh0dXJlIHdlIHVwbG9hZC4KICAgICAgICovCiAgICAgIGlmICggdC0+YmFzZS5ib3VuZCApIEZMVVNIX0JBVENIKCBtbWVzYSApOwogICAgICBkcmlTd2FwT3V0VGV4dHVyZU9iamVjdCggKGRyaVRleHR1cmVPYmplY3QgKikgdCApOwogICAgICBicmVhazsKCiAgIGRlZmF1bHQ6CiAgICAgIHJldHVybjsKICAgfQoKICAgbW1lc2EtPm5ld19zdGF0ZSB8PSBNQUNINjRfTkVXX1RFWFRVUkU7Cn0KCnN0YXRpYyB2b2lkIG1hY2g2NEREQmluZFRleHR1cmUoIEdMY29udGV4dCAqY3R4LCBHTGVudW0gdGFyZ2V0LAoJCQkJIHN0cnVjdCBnbF90ZXh0dXJlX29iamVjdCAqdE9iaiApCnsKICAgbWFjaDY0Q29udGV4dFB0ciBtbWVzYSA9IE1BQ0g2NF9DT05URVhUKGN0eCk7CiAgIEdMaW50IHVuaXQgPSBjdHgtPlRleHR1cmUuQ3VycmVudFVuaXQ7CgogICBpZiAoIE1BQ0g2NF9ERUJVRyAmIERFQlVHX1ZFUkJPU0VfQVBJICkgewogICAgICBmcHJpbnRmKCBzdGRlcnIsICIlcyggJXAgKSB1bml0PSVkXG4iLAoJICAgICAgIF9fRlVOQ1RJT05fXywgdE9iaiwgdW5pdCApOwogICB9CgogICBGTFVTSF9CQVRDSCggbW1lc2EgKTsKCiAgIGlmICggbW1lc2EtPkN1cnJlbnRUZXhPYmpbdW5pdF0gKSB7CiAgICAgIG1tZXNhLT5DdXJyZW50VGV4T2JqW3VuaXRdLT5iYXNlLmJvdW5kICY9IH4oMSA8PCB1bml0KTsKICAgICAgbW1lc2EtPkN1cnJlbnRUZXhPYmpbdW5pdF0gPSBOVUxMOwogICB9CgogICBtbWVzYS0+bmV3X3N0YXRlIHw9IE1BQ0g2NF9ORVdfVEVYVFVSRTsKfQoKc3RhdGljIHZvaWQgbWFjaDY0REREZWxldGVUZXh0dXJlKCBHTGNvbnRleHQgKmN0eCwKCQkJCSAgIHN0cnVjdCBnbF90ZXh0dXJlX29iamVjdCAqdE9iaiApCnsKICAgbWFjaDY0Q29udGV4dFB0ciBtbWVzYSA9IE1BQ0g2NF9DT05URVhUKGN0eCk7CiAgIGRyaVRleHR1cmVPYmplY3QgKiB0ID0gKGRyaVRleHR1cmVPYmplY3QgKikgdE9iai0+RHJpdmVyRGF0YTsKCiAgIGlmICggdCApIHsKICAgICAgaWYgKCB0LT5ib3VuZCAmJiBtbWVzYSApIHsKCSBGTFVTSF9CQVRDSCggbW1lc2EgKTsKCgkgbW1lc2EtPm5ld19zdGF0ZSB8PSBNQUNINjRfTkVXX1RFWFRVUkU7CiAgICAgIH0KCiAgICAgIGRyaURlc3Ryb3lUZXh0dXJlT2JqZWN0KCB0ICk7CgogICAgICAvKiBGcmVlIG1pcG1hcCBpbWFnZXMgYW5kIHRoZSB0ZXh0dXJlIG9iamVjdCBpdHNlbGYgKi8KICAgICAgX21lc2FfZGVsZXRlX3RleHR1cmVfb2JqZWN0KGN0eCwgdE9iaik7CiAgIH0KfQoKLyoqCiAqIEFsbG9jYXRlIGEgbmV3IHRleHR1cmUgb2JqZWN0LgogKiBDYWxsZWQgdmlhIGN0eC0+RHJpdmVyLk5ld1RleHR1cmVPYmplY3QuCiAqIE5vdGU6IHdlIGNvdWxkIHVzZSBjb250YWlubWVudCBoZXJlIHRvICdkZXJpdmUnIHRoZSBkcml2ZXItc3BlY2lmaWMKICogdGV4dHVyZSBvYmplY3QgZnJvbSB0aGUgY29yZSBtZXNhIGdsX3RleHR1cmVfb2JqZWN0LiAgTm90IGRvbmUgYXQgdGhpcyB0aW1lLgogKi8Kc3RhdGljIHN0cnVjdCBnbF90ZXh0dXJlX29iamVjdCAqCm1hY2g2NE5ld1RleHR1cmVPYmplY3QoIEdMY29udGV4dCAqY3R4LCBHTHVpbnQgbmFtZSwgR0xlbnVtIHRhcmdldCApCnsKICAgc3RydWN0IGdsX3RleHR1cmVfb2JqZWN0ICpvYmo7CiAgIG9iaiA9IF9tZXNhX25ld190ZXh0dXJlX29iamVjdChjdHgsIG5hbWUsIHRhcmdldCk7CiAgIG1hY2g2NEFsbG9jVGV4T2JqKCBvYmogKTsKICAgcmV0dXJuIG9iajsKfQoKdm9pZCBtYWNoNjRJbml0VGV4dHVyZUZ1bmNzKCBzdHJ1Y3QgZGRfZnVuY3Rpb25fdGFibGUgKmZ1bmN0aW9ucyApCnsKICAgZnVuY3Rpb25zLT5UZXhFbnYJCQk9IG1hY2g2NEREVGV4RW52OwogICBmdW5jdGlvbnMtPkNob29zZVRleHR1cmVGb3JtYXQJPSBtYWNoNjRDaG9vc2VUZXh0dXJlRm9ybWF0OwogICBmdW5jdGlvbnMtPlRleEltYWdlMUQJCT0gbWFjaDY0VGV4SW1hZ2UxRDsKICAgZnVuY3Rpb25zLT5UZXhTdWJJbWFnZTFECQk9IG1hY2g2NFRleFN1YkltYWdlMUQ7CiAgIGZ1bmN0aW9ucy0+VGV4SW1hZ2UyRAkJPSBtYWNoNjRUZXhJbWFnZTJEOwogICBmdW5jdGlvbnMtPlRleFN1YkltYWdlMkQJCT0gbWFjaDY0VGV4U3ViSW1hZ2UyRDsKICAgZnVuY3Rpb25zLT5UZXhQYXJhbWV0ZXIJCT0gbWFjaDY0RERUZXhQYXJhbWV0ZXI7CiAgIGZ1bmN0aW9ucy0+QmluZFRleHR1cmUJCT0gbWFjaDY0RERCaW5kVGV4dHVyZTsKICAgZnVuY3Rpb25zLT5OZXdUZXh0dXJlT2JqZWN0CQk9IG1hY2g2NE5ld1RleHR1cmVPYmplY3Q7CiAgIGZ1bmN0aW9ucy0+RGVsZXRlVGV4dHVyZQkJPSBtYWNoNjRERERlbGV0ZVRleHR1cmU7CiAgIGZ1bmN0aW9ucy0+SXNUZXh0dXJlUmVzaWRlbnQJCT0gZHJpSXNUZXh0dXJlUmVzaWRlbnQ7CgogICBmdW5jdGlvbnMtPlVwZGF0ZVRleHR1cmVQYWxldHRlCT0gTlVMTDsKICAgZnVuY3Rpb25zLT5BY3RpdmVUZXh0dXJlCQk9IE5VTEw7CiAgIGZ1bmN0aW9ucy0+UHJpb3JpdGl6ZVRleHR1cmUJCT0gTlVMTDsKCiAgIGRyaUluaXRUZXh0dXJlRm9ybWF0cygpOwp9Cg==