LyoKICogQ29weXJpZ2h0IKkgMjAwOSBJbnRlbCBDb3Jwb3JhdGlvbgogKgogKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYQogKiBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlCiAqICJTb2Z0d2FyZSIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcKICogd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLAogKiBkaXN0cmlidXRlLCBzdWIgbGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvCiAqIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0bwogKiB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CiAqCiAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIChpbmNsdWRpbmcgdGhlCiAqIG5leHQgcGFyYWdyYXBoKSBzaGFsbCBiZSBpbmNsdWRlZCBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zCiAqIG9mIHRoZSBTb2Z0d2FyZS4KICoKICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MKICogT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRgogKiBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT04tSU5GUklOR0VNRU5ULgogKiBJTiBOTyBFVkVOVCBTSEFMTCBQUkVDSVNJT04gSU5TSUdIVCBBTkQvT1IgSVRTIFNVUFBMSUVSUyBCRSBMSUFCTEUgRk9SCiAqIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULAogKiBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRQogKiBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS4KICoKICogQXV0aG9yczoKICogICAgWGlhbmcgSGFpaGFvIDxoYWloYW8ueGlhbmdAaW50ZWwuY29tPgogKiAgICBab3UgTmFuIGhhaSA8bmFuaGFpLnpvdUBpbnRlbC5jb20+CiAqCiAqLwoKI2luY2x1ZGUgPGFzc2VydC5oPgoKI2luY2x1ZGUgInZhX2RyaWNvbW1vbi5oIgoKI2luY2x1ZGUgImludGVsX2JhdGNoYnVmZmVyLmgiCiNpbmNsdWRlICJpbnRlbF9tZW1tYW4uaCIKI2luY2x1ZGUgImludGVsX2RyaXZlci5oIgoKc3RhdGljIEJvb2wKaW50ZWxfZHJpdmVyX2dldF9wYXJhbShzdHJ1Y3QgaW50ZWxfZHJpdmVyX2RhdGEgKmludGVsLCBpbnQgcGFyYW0sIGludCAqdmFsdWUpCnsKICAgaW50IHJldDsKICAgc3RydWN0IGRybV9pOTE1X2dldHBhcmFtIGdwOwoKICAgZ3AucGFyYW0gPSBwYXJhbTsKICAgZ3AudmFsdWUgPSB2YWx1ZTsKCiAgIHJldCA9IGRybUNvbW1hbmRXcml0ZVJlYWQoaW50ZWwtPmZkLCBEUk1fSTkxNV9HRVRQQVJBTSwgJmdwLCBzaXplb2YoZ3ApKTsKICAgYXNzZXJ0KHJldCA9PSAwKTsKCiAgIHJldHVybiBUcnVlOwp9CgpCb29sIAppbnRlbF9kcml2ZXJfaW5pdChWQURyaXZlckNvbnRleHRQIGN0eCkKewogICAgc3RydWN0IGludGVsX2RyaXZlcl9kYXRhICppbnRlbCA9IGludGVsX2RyaXZlcl9kYXRhKGN0eCk7CiAgICBzdHJ1Y3QgZHJpX3N0YXRlICpkcmlfc3RhdGUgPSAoc3RydWN0IGRyaV9zdGF0ZSAqKWN0eC0+ZHJpX3N0YXRlOwoKICAgIGFzc2VydChkcmlfc3RhdGUpOwogICAgYXNzZXJ0KGRyaV9zdGF0ZS0+ZHJpQ29ubmVjdGVkRmxhZyA9PSBWQV9EUkkyIHx8IAogICAgICAgICAgIGRyaV9zdGF0ZS0+ZHJpQ29ubmVjdGVkRmxhZyA9PSBWQV9EUkkxKTsKCiAgICBpbnRlbC0+ZmQgPSBkcmlfc3RhdGUtPmZkOwogICAgaW50ZWwtPmRyaTJFbmFibGVkID0gKGRyaV9zdGF0ZS0+ZHJpQ29ubmVjdGVkRmxhZyA9PSBWQV9EUkkyKTsKCiAgICBpZiAoIWludGVsLT5kcmkyRW5hYmxlZCkgewogICAgICAgIGRybV9zYXJlYV90ICpwU0FSRUE7CgogICAgICAgIHBTQVJFQSA9IChkcm1fc2FyZWFfdCAqKWRyaV9zdGF0ZS0+cFNBUkVBOwogICAgICAgIGludGVsLT5oSFdDb250ZXh0ID0gZHJpX3N0YXRlLT5od0NvbnRleHQ7CiAgICAgICAgaW50ZWwtPmRyaUh3TG9jayA9IChkcm1Mb2NrICopKCZwU0FSRUEtPmxvY2spOwogICAgICAgIGludGVsLT5wUHJpdlNhcmVhID0gKHZvaWQgKilwU0FSRUEgKyBzaXplb2YoZHJtX3NhcmVhX3QpOwogICAgfQoKICAgIGludGVsLT5sb2NrZWQgPSAwOwogICAgcHRocmVhZF9tdXRleF9pbml0KCZpbnRlbC0+Y3R4bXV0ZXgsIE5VTEwpOwoKICAgIGludGVsX2RyaXZlcl9nZXRfcGFyYW0oaW50ZWwsIEk5MTVfUEFSQU1fQ0hJUFNFVF9JRCwgJmludGVsLT5kZXZpY2VfaWQpOwogICAgaW50ZWxfbWVtbWFuX2luaXQoaW50ZWwpOwogICAgaW50ZWxfYmF0Y2hidWZmZXJfaW5pdChpbnRlbCk7CgogICAgcmV0dXJuIFRydWU7Cn0KCkJvb2wgCmludGVsX2RyaXZlcl90ZXJtaW5hdGUoVkFEcml2ZXJDb250ZXh0UCBjdHgpCnsKICAgIHN0cnVjdCBpbnRlbF9kcml2ZXJfZGF0YSAqaW50ZWwgPSBpbnRlbF9kcml2ZXJfZGF0YShjdHgpOwoKICAgIGludGVsX21lbW1hbl90ZXJtaW5hdGUoaW50ZWwpOwogICAgaW50ZWxfYmF0Y2hidWZmZXJfdGVybWluYXRlKGludGVsKTsKCiAgICBwdGhyZWFkX211dGV4X2Rlc3Ryb3koJmludGVsLT5jdHhtdXRleCk7CgogICAgcmV0dXJuIFRydWU7Cn0KCnZvaWQgCmludGVsX2xvY2tfaGFyZHdhcmUoVkFEcml2ZXJDb250ZXh0UCBjdHgpCnsKICAgIHN0cnVjdCBpbnRlbF9kcml2ZXJfZGF0YSAqaW50ZWwgPSBpbnRlbF9kcml2ZXJfZGF0YShjdHgpOwogICAgY2hhciBfX3JldCA9IDA7CgogICAgUFBUSFJFQURfTVVURVhfTE9DSygpOwoKICAgIGFzc2VydCghaW50ZWwtPmxvY2tlZCk7CgogICAgaWYgKCFpbnRlbC0+ZHJpMkVuYWJsZWQpIHsKICAgICAgICBEUk1fQ0FTKGludGVsLT5kcmlId0xvY2ssIAogICAgICAgICAgICAgICAgaW50ZWwtPmhIV0NvbnRleHQsCiAgICAgICAgICAgICAgICAoRFJNX0xPQ0tfSEVMRHxpbnRlbC0+aEhXQ29udGV4dCksCiAgICAgICAgICAgICAgICBfX3JldCk7CgogICAgICAgIGlmIChfX3JldCkgewogICAgICAgICAgICBkcm1HZXRMb2NrKGludGVsLT5mZCwgaW50ZWwtPmhIV0NvbnRleHQsIDApOwogICAgICAgIH0JCiAgICB9CgogICAgaW50ZWwtPmxvY2tlZCA9IDE7Cn0KCnZvaWQgCmludGVsX3VubG9ja19oYXJkd2FyZShWQURyaXZlckNvbnRleHRQIGN0eCkKewogICAgc3RydWN0IGludGVsX2RyaXZlcl9kYXRhICppbnRlbCA9IGludGVsX2RyaXZlcl9kYXRhKGN0eCk7CgogICAgaWYgKCFpbnRlbC0+ZHJpMkVuYWJsZWQpIHsKICAgICAgICBEUk1fVU5MT0NLKGludGVsLT5mZCwgCiAgICAgICAgICAgICAgICAgICBpbnRlbC0+ZHJpSHdMb2NrLAogICAgICAgICAgICAgICAgICAgaW50ZWwtPmhIV0NvbnRleHQpOwogICAgfQoKICAgIGludGVsLT5sb2NrZWQgPSAwOwogICAgUFBUSFJFQURfTVVURVhfVU5MT0NLKCk7Cn0K