From 32ba34fefb20b38deaa7cf154f2f826e2058af34 Mon Sep 17 00:00:00 2001 From: Chee Yee Date: Sun, 26 Feb 2023 00:17:19 -0800 Subject: [PATCH] initial gdrive client --- CMakeLists.txt | 21 +-- data/assets/certs/domain.crt | 22 +++ data/assets/certs/domain.csr | 17 +++ data/assets/certs/domain.ext | 7 + data/assets/certs/domain.key | 30 ++++ data/assets/certs/rootCA.crt | 22 +++ data/assets/certs/rootCA.key | 30 ++++ data/assets/certs/rootCA.srl | 1 + data/assets/langs/English.ini | 9 ++ source/actions.cpp | 26 ++-- source/{http => clients}/apache.cpp | 4 +- source/{http => clients}/apache.h | 4 +- source/{http => clients}/baseclient.cpp | 73 ++++++--- source/{http => clients}/baseclient.h | 4 +- source/{ => clients}/ftpclient.cpp | 4 +- source/{ => clients}/ftpclient.h | 2 +- source/clients/gdrive.cpp | 190 ++++++++++++++++++++++++ source/clients/gdrive.h | 27 ++++ source/{http => clients}/iis.cpp | 4 +- source/{http => clients}/iis.h | 4 +- source/{http => clients}/nginx.cpp | 4 +- source/{http => clients}/nginx.h | 4 +- source/{http => clients}/npxserve.cpp | 4 +- source/{http => clients}/npxserve.h | 4 +- source/{ => clients}/remote_client.h | 1 + source/{ => clients}/smbclient.cpp | 2 +- source/{ => clients}/smbclient.h | 2 +- source/{ => clients}/webdavclient.cpp | 4 +- source/{ => clients}/webdavclient.h | 2 +- source/config.cpp | 151 ++++++++++++------- source/config.h | 42 +++++- source/fs.cpp | 2 +- source/inifile.c | 45 ++++-- source/inifile.h | 4 +- source/installer.cpp | 4 +- source/lang.cpp | 25 +++- source/lang.h | 13 +- source/main.cpp | 10 +- source/server/http_server.cpp | 165 ++++++++++++++++++++ source/server/http_server.h | 19 +++ source/{sys_modules.cpp => system.cpp} | 17 ++- source/{sys_modules.h => system.h} | 2 + source/windows.cpp | 4 + source/zip_util.cpp | 2 +- 44 files changed, 886 insertions(+), 147 deletions(-) create mode 100644 data/assets/certs/domain.crt create mode 100644 data/assets/certs/domain.csr create mode 100644 data/assets/certs/domain.ext create mode 100644 data/assets/certs/domain.key create mode 100644 data/assets/certs/rootCA.crt create mode 100644 data/assets/certs/rootCA.key create mode 100644 data/assets/certs/rootCA.srl rename source/{http => clients}/apache.cpp (99%) rename source/{http => clients}/apache.h (77%) rename source/{http => clients}/baseclient.cpp (75%) rename source/{http => clients}/baseclient.h (90%) rename source/{ => clients}/ftpclient.cpp (99%) rename source/{ => clients}/ftpclient.h (99%) create mode 100644 source/clients/gdrive.cpp create mode 100644 source/clients/gdrive.h rename source/{http => clients}/iis.cpp (98%) rename source/{http => clients}/iis.h (77%) rename source/{http => clients}/nginx.cpp (98%) rename source/{http => clients}/nginx.h (77%) rename source/{http => clients}/npxserve.cpp (98%) rename source/{http => clients}/npxserve.h (78%) rename source/{ => clients}/remote_client.h (98%) rename source/{ => clients}/smbclient.cpp (99%) rename source/{ => clients}/smbclient.h (97%) rename source/{ => clients}/webdavclient.cpp (99%) rename source/{ => clients}/webdavclient.h (98%) create mode 100644 source/server/http_server.cpp create mode 100644 source/server/http_server.h rename source/{sys_modules.cpp => system.cpp} (84%) rename source/{sys_modules.h => system.h} (92%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 15c5477..8be5989 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,16 +28,20 @@ add_executable(ezremote_client source/web/urn.cpp source/webdav/client.cpp source/http/httplib.cpp - source/http/baseclient.cpp - source/http/apache.cpp - source/http/iis.cpp - source/http/nginx.cpp - source/http/npxserve.cpp + source/clients/baseclient.cpp + source/clients/apache.cpp + source/clients/ftpclient.cpp + source/clients/gdrive.cpp + source/clients/iis.cpp + source/clients/nginx.cpp + source/clients/npxserve.cpp + source/clients/smbclient.cpp + source/clients/webdavclient.cpp + source/server/http_server.cpp source/actions.cpp source/config.cpp source/crypt.c source/fs.cpp - source/ftpclient.cpp source/gui.cpp source/getentropy.c source/ime_dialog.cpp @@ -46,10 +50,8 @@ add_executable(ezremote_client source/lang.cpp source/main.cpp source/orbis_jbc.c - source/sys_modules.cpp - source/smbclient.cpp + source/system.cpp source/windows.cpp - source/webdavclient.cpp source/zip_util.cpp ) @@ -75,6 +77,7 @@ target_link_libraries(ezremote_client minizip un7zip unrar + json-c kernel SceShellCoreUtil SceSysmodule diff --git a/data/assets/certs/domain.crt b/data/assets/certs/domain.crt new file mode 100644 index 0000000..a588daa --- /dev/null +++ b/data/assets/certs/domain.crt @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDqDCCApCgAwIBAgIUSlUxeW2iMsLD8Lk3+ffGUfxej6QwDQYJKoZIhvcNAQEL +BQAwYzELMAkGA1UEBhMCWloxDDAKBgNVBAgMA1N1bjENMAsGA1UEBwwETW9vbjEQ +MA4GA1UECgwHTWVyY3VyeTERMA8GA1UECwwISG9tZWJyZXcxEjAQBgNVBAMMCWxv +Y2FsaG9zdDAgFw0yMzAyMjUwNzAyMTNaGA8yMDUzMDIxNzA3MDIxM1owYzELMAkG +A1UEBhMCWloxDDAKBgNVBAgMA1N1bjENMAsGA1UEBwwETW9vbjEQMA4GA1UECgwH +TWVyY3VyeTERMA8GA1UECwwISG9tZWJyZXcxEjAQBgNVBAMMCWxvY2FsaG9zdDCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOWQx+pfhpDqd2wPkV5BL6Yf +8UVTCsP13+1YlxZiD93VHhcK23T/YYqSxx6tDHAR4sA/oKELT+dFuhMhC/QE5Sw6 +HD/FwCwdNJ7Ke3z+iUActtInDU5URC0XwdW7wTAt1MLx4T9j7CkoVHsaiDlf6LTG +165bIXD8JKzud26WXHmTCCBCgIU3zcq13jpFeb4Po4rJtuDLwb3gloZzEzdS9S6O +mjVNUSlZeb+ksep3TbJHIACy6WrPJZ+u2aScDOBOt9Gv/UeOYHcvGIFHXddG+kHl +/ay6b7JxNbBNWL57/PswmXcpB16gkBNWCfL1PDmDFEkvd6uJTnPUnMge7CBNzX8C +AwEAAaNSMFAwHwYDVR0jBBgwFoAUeCZ0CXLAs8C5xVsPGIhzu4haXpEwCQYDVR0T +BAIwADAiBgNVHREEGzAZgglsb2NhbGhvc3SCCTEyNy4wLjAuMYIBKjANBgkqhkiG +9w0BAQsFAAOCAQEAsgC/89C7+OAspaOgU5Tr9WFcZ1Nph21WTltBM0z9f4NyeR1Y +b/YoJrvocRWw9gpgCcj7AArSHNsha2+QMBEko3PIpkdMoSHylf2WqYNTCIb8cvJA +pHDYJJR99Cajo0meP5h1mtQdjOVv70Q3jtS6iSdD/KI5VwIRcfDutjHys78Bb2NQ +1KEZuHKwmhE3209OQ5ZbjDQ0gViJFPnfPfnbWuOllpIN27ZwGvlhhM9x7xRvwsWt +puh5wV2TBAYagOT+canBOxugv7L1eOpnNVE49YS0vr5y8JhLuKFoZ0hTi7PeqO4c +mE4zIVwKjIQ6w+N2Vj/ghNjkyJm0azpmnbPtFg== +-----END CERTIFICATE----- diff --git a/data/assets/certs/domain.csr b/data/assets/certs/domain.csr new file mode 100644 index 0000000..db2dcf3 --- /dev/null +++ b/data/assets/certs/domain.csr @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICqDCCAZACAQAwYzELMAkGA1UEBhMCWloxDDAKBgNVBAgMA1N1bjENMAsGA1UE +BwwETW9vbjEQMA4GA1UECgwHTWVyY3VyeTERMA8GA1UECwwISG9tZWJyZXcxEjAQ +BgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AOWQx+pfhpDqd2wPkV5BL6Yf8UVTCsP13+1YlxZiD93VHhcK23T/YYqSxx6tDHAR +4sA/oKELT+dFuhMhC/QE5Sw6HD/FwCwdNJ7Ke3z+iUActtInDU5URC0XwdW7wTAt +1MLx4T9j7CkoVHsaiDlf6LTG165bIXD8JKzud26WXHmTCCBCgIU3zcq13jpFeb4P +o4rJtuDLwb3gloZzEzdS9S6OmjVNUSlZeb+ksep3TbJHIACy6WrPJZ+u2aScDOBO +t9Gv/UeOYHcvGIFHXddG+kHl/ay6b7JxNbBNWL57/PswmXcpB16gkBNWCfL1PDmD +FEkvd6uJTnPUnMge7CBNzX8CAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4IBAQB2gc2Z +7bzytAja4uDQQjQOxZMzwwgfODyQTWhvyEVJxq7iK8Saogn/dpjgeVhNaIgMAGRs +RNQ26cBQxvs9ZfNmNcNvc1eFw9NJicRpHOUjNf0mMHtqiFIpGc9Fnu34p1DLGKJ4 +qp5Kd9cl4Vx96xaPWqCyH+sXFxnIt8lK6K0yKHaDXLKzFmuJvEEc2Z/g0/RRfgq7 +cO9+otlsD3sF6TziNL/KFFYPqgn4Wkx8K8z9ovpMnyvYH1KnQsuhCNr9nUhmA8Wu +o9DMKQbqDYq9NLUmTJMgX75Vi71idbkgOZN7kvmUnEW+Ltf1FLl9AnF5kpkvMTvR +KIcPUOLLdpzwZ8jc +-----END CERTIFICATE REQUEST----- diff --git a/data/assets/certs/domain.ext b/data/assets/certs/domain.ext new file mode 100644 index 0000000..f8dc364 --- /dev/null +++ b/data/assets/certs/domain.ext @@ -0,0 +1,7 @@ +authorityKeyIdentifier=keyid,issuer +basicConstraints=CA:FALSE +subjectAltName = @alt_names +[alt_names] +DNS.1 = localhost +DNS.2 = 127.0.0.1 +DNS.3 = * diff --git a/data/assets/certs/domain.key b/data/assets/certs/domain.key new file mode 100644 index 0000000..cad8069 --- /dev/null +++ b/data/assets/certs/domain.key @@ -0,0 +1,30 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIFHDBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQIDkuJpr20dpYCAggA +MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECAKW47FhDo5vBIIEyNJd7CLIboON +iXmQ5Vzj7nHna+HXfPdrNGUnAtRKQ7oZmAvPJQMqrEO88am5zl/puOThwdJ/b+tp +Ftt76zi8JffShf0fwNeL3zOfiVEUSmGeOfRzx4MV1flivbk70UjHx4ga9Nqdab6t +0dvV8copWkmj+B/sP2zk3+S9Urv6VPz97hq6PTqrmjWm+VwssDJyv9s7KGM/+9bC +/9DQR5AAQbd4e7sxW45cL9desyRfs0XNcYj6Go9sVHzFhKaSx75u6Shd5Rb2N5sX +2Dmm349cy3XimqNBCsrPIp76uLfCIhSp/pgC6phMeIu52SrFwM2OOwCuPkGZyVQv +I6n0vagltBHXYj5a371P9imV8LWTCy326yb6Ro1Mjy6XEMWVIBk/XI/U12APHytf +c1VvCk1pGemD3ArVYpuECdjtwZxxCOneOxeIYgSV/h3GHMHKmQiK36zQOslNNdfy +l7AO6kokITWoW/VPk2FG0tclWJe1aA8WOiqI3ZYRwBlovk9jUrjNqEA3BG/rzAWU +VbApXd4FvbsgLETHRZl1KWvwZFhO9vZ02+CznrnzzMWCb13UipCA7RuePuhdbViT +jOy1JJG408NcwRu0PNwr77oIZu7OrdEPu0u7YJ+SR/q3pxS6u86l6O3lvbUhtOyC +1grybOa+lJXrAL07yrbriCoy8igNIMKiA8blwpwCC/22CtGrY5UJqzpLIZuTLcnB +8pVoFioSGetvsjpzRsv6jCsacdAZwhuYEUCi82wFW1yd3UNCVMh6U8ypspQp3wz3 +tbdoGbzlwbwbgd2o9+MpxzW66s2emEsCBjG+SrNElZBkfAG8ZgSbF3yGlSe778BJ +7O71TEjxmYfUglvn90ZWpV7IH1TNbaKeIOJXkmuqQDaiG6U61kHcq//QvuZfU/tv +TEUlQGqbdYS1E7+byCxubUnD3rclSP1cMTGyUtacHGUzFhiCZfuuDc+1P1Q8wKTe +NkGfMpmXWLSncVUDEPgpsuz+hCtt65BAb0BfCWLZPyBXQ4Qbovk6Z/O5Ta5tyWEl +g2wRqFXUL8ZYk+TKbmSclU+1h3QfFwvyEmEGFi+igKRZR1ERB4cAEEDjOJP+uI7B +3K7lomdeh4kuPG6move8PCm9Dw1GhWPVFCKoan0MW2sNfnhmoOqXkoMT6P+M4U7+ +DjHY+G5Op2jkP+BrHQ99VRApXz40MtLaOdfu6S+IWURnqqwPuL99We8XFMgX3xX4 +++v7lSkcp54uSoN5e/fY/2fYG/RPxaI6+W6oxP4YmxUZjdvGdZvJiJJGqIBzCj1p +26WynwFu25wnsyXBzWo4wzH4Ga6ZtUvb59KFRTSJqQKieLVmX2zNjSps2B2/twax +EQt03AGIbtr677NeYKM3BUws+iw9TyBUjEMsqnpp6EuWhDcPga8WJn1ivw04BenP +uaOw2w1nLe8InaJxahmBKmRiSjX7XX4+PPgB/FwGN89nMBpy8+ujitteOYvlY6Hf +050aTysBmYWu4oCsx/kz8OHpwt7zPO8zkVdtHCGa8+5bm//pLUGHyoDVY2Xj68MD +OMfwbJl0Q4W+bOkCEK4fYhkB7HWPZqxZKujcR/goXBsUCvIk/WuDx8pNnjIas1Qm +MUDSs9XQFGWE8ydRYN4RRw== +-----END ENCRYPTED PRIVATE KEY----- diff --git a/data/assets/certs/rootCA.crt b/data/assets/certs/rootCA.crt new file mode 100644 index 0000000..e7e9b8c --- /dev/null +++ b/data/assets/certs/rootCA.crt @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDqTCCApGgAwIBAgIUbNUnFW+Ibevm3bOTzzznsNO4laIwDQYJKoZIhvcNAQEL +BQAwYzELMAkGA1UEBhMCWloxDDAKBgNVBAgMA1N1bjENMAsGA1UEBwwETW9vbjEQ +MA4GA1UECgwHTWVyY3VyeTERMA8GA1UECwwISG9tZWJyZXcxEjAQBgNVBAMMCWxv +Y2FsaG9zdDAgFw0yMzAyMjUwNjU4MTJaGA8yMDUzMDIxNzA2NTgxMlowYzELMAkG +A1UEBhMCWloxDDAKBgNVBAgMA1N1bjENMAsGA1UEBwwETW9vbjEQMA4GA1UECgwH +TWVyY3VyeTERMA8GA1UECwwISG9tZWJyZXcxEjAQBgNVBAMMCWxvY2FsaG9zdDCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMBF0q8GELLjXu6zTTNtCovU +QVsgg8kSN56p8Xxv5gZHEuhUXjan+UyiklW2aoxJZpyRbE8dpAR78ca6kLUG1LMf +2RX8FDjA6W5xXR2C2FmSYGnPyLigRFPbZv3sb7PyOYhqgPuu1xKMEmq5n1lE9pCV +nO7hAsfwqS3mZrPFL3MZIqrT6HqeSO1tVe8gUUWTm3dm9Yb0E/sVExdG6u0RfbVu +eqHykO4iCUonm3lOigskDbZ7WFKQyVRM3vZbALEpE7YlltcgT14GmG+L8aeFY6iT +FoPDV7bFAGtgg30os4kV135HUNJ80koIoUocwxThuyBpADltIZ5R2FSHBl1XzK8C +AwEAAaNTMFEwHQYDVR0OBBYEFHgmdAlywLPAucVbDxiIc7uIWl6RMB8GA1UdIwQY +MBaAFHgmdAlywLPAucVbDxiIc7uIWl6RMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI +hvcNAQELBQADggEBAGW6HVweWcsIxp2vVzspBaKSp2ECYRpx4xunge/eDWlokAj3 +OCW7kxgPfEbtClLOeQj3p9WolHzABgG+qqIB6kPbGtNXYaXrQbsD6j9f56GFklNK +tuYH3WtDpp5TLsYyj2cLeK2x02Z8k3+r11SqB1DeMPTBAkhXiTwrkUt3axnZuiZC +2Miwzi0b5muMbdecYukB+50xlV8TkiVmWUtQ5cVVE/U640sC6O1GMZG0zO9Ys0+U +xTeB/3Xq5Wg6OQx86GpbD7+8xRhSkdJxoVbuFgh0KNUlBREC/pYobehnwji7WWFH +F7nBdVyedi6qZTa7dVEk4eaXgalemTp9k4rzbZ8= +-----END CERTIFICATE----- diff --git a/data/assets/certs/rootCA.key b/data/assets/certs/rootCA.key new file mode 100644 index 0000000..d00a9ab --- /dev/null +++ b/data/assets/certs/rootCA.key @@ -0,0 +1,30 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIFHDBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQIoyT8iwjhZBECAggA +MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECKy1pYbVGbtDBIIEyIIY1X/XVv5q +ihMCTQbnesuyEstQCw/9BFQ/ka4Ee2D6yJp59gSiEODwce+EgIn1jrgJImOZbnsz +xKtRJXNd+ENBwsZgh8am15o+bJ2WeOztuKcrhOvrRmj8wrDPAon4+sdcfphqRUbG +hilLbV7T8jpE1ScTD/zYU/KKWEIytYTxT+vfHvXYv8oQY9IscwNqx6cnXxNtoO7C +SO87/Apkul3irVHnad29gV/jyj4imlm6gVCmqByaD/JaV/d9Y0hWhZVeSzceP64Q +95kfhUM8AsTJi5A25vWAQAxa2Gi8ywiv+/NRVC4qhzMID4wbqI/2Oy8iEMJJfkaK +Ah/S5lY8sVRpenUmX4kSZs+oKbITc5LNccx5OUESvVZCj/mW9t91uZfTWTt23iac +snYzhH4PvYxCGU7LXzrgS5suv/N3R33E5kcND0dJbKkW4VVVxmv7HUDfs8YqduJn +teQFQNsoNuQO5Te9WsMpamickF/65nrg+OOhsbVkLsuCRPzyXIRgAPBBGFqlr3IG +XK41kQR5I4HTAeFXCClz00LfLrCl+T7IO3NbH+AD1EVGUHYPuwgJBRic/cMbXZwT +Kcxo98Apwsm+OHKRAq4c5wEmUb9ipVSwq6CRUojklrGMclJfXnd9r57FFl/9eYdY +ZEp+jnAqq3M8v2m29dPjja07CTIuimIRgIPaIjWZuZX8oW1GVpapV3JfIun5KXE4 +Sc+ScLA015Gzm/3hgKNke5HGYH49x9V/lYhr9j5AxgdWnoj4H3qbJSu2jJKooYmS +tsimgs3pqz/dygyx9Zmy2L5eb597MYEQwg4kZdFPyixAttmFXRdXVvRmQCB9H8VX +kx6z4Rus/Zh6NM6z0aHvWoaih9jJ444CdnOPLYSngLL5yzI3xunwT67Di9rrkNeL +nVBJP9Ljc9cE4LgK63xAy+25+bZWv/mZ07CBXatc91CCSa/O3KM4eLmOMNaZNU+T +P8EYHR3r24V6TCzud7dLp3k+Glkxj1feiXEktmFxnfUbGoS5Ihw4cVGqrst7hSSE +IaQFIx0X70sKyl/ixxVHWIMdV4Zqdxhf2boNZk7aHx8+yOhCnOEY4/8KUJM98W+W +a6VRhxYucKsz+B3i0BKEZg4sB1bT/6G17JAentfGmKp42IFJR3JeRydEF6ppCaWT +gdLnRlsYDHEpAMcTPsbDiQK3Crid3E0i/2QU5V5VEhR2ncq+oKZ0oy7nwoOV232W +TuodV43urEshbh8RDr321+2UxCgT6AGMAt6BPgx9D/mIZHMVgZalvHqtzPDyN5Av +5LiXct8nl4fO+c0iMdfAw2TfCvl6sIkaAW5ClqbHXxiSg9OUXSrfgBVMkcCmcnB0 +cNbx6Xc6jdLZEtnch+IcYZzj4wmLFx01zVAs9daPxbGw6mg1TloDQ0fYhgixkRSi +NDkztXZzLFx9MB4rYy/v8h08OWwNi/R6IOZDI4DNf7qXEtgqouqa85srsT9Pspc4 +SAN5YzHlo6AKujmUNRo+uYbJGqsssMXQPWNvozxnXIgQsiZ5/Y/x3KsUJu49RveL +baNm/ScI3ghTbt92bPE16ebtodULkxuPFAqXdjWXLjblSVihiKxvQ9wTULB97zHI +1oX6YdWladLddzK/De6JMA== +-----END ENCRYPTED PRIVATE KEY----- diff --git a/data/assets/certs/rootCA.srl b/data/assets/certs/rootCA.srl new file mode 100644 index 0000000..8ddf082 --- /dev/null +++ b/data/assets/certs/rootCA.srl @@ -0,0 +1 @@ +4A5531796DA232C2C3F0B937F9F7C651FC5E8FA5 diff --git a/data/assets/langs/English.ini b/data/assets/langs/English.ini index 2521fe5..c2e63d8 100644 --- a/data/assets/langs/English.ini +++ b/data/assets/langs/English.ini @@ -120,3 +120,12 @@ STR_SAVE=Save STR_MAX_EDIT_FILE_SIZE_MSG=Cannot edit files bigger than STR_DELETE_LINE=Delete Selected Line STR_INSERT_LINE=Insert Below Selected Line +STR_FAIL_GET_TOKEN_MSG=Failed to obtain an access token from +STR_GET_TOKEN_SUCCESS_MSG=Login Success. You may close the browser and return to the application +STR_PERM_DRIVE=See, edit, create, and delete all of your Google Drive files +STR_PERM_DRIVE_APPDATA=See, create, and delete its own configuration data in your Google Drive +STR_PERM_DRIVE_FILE=See, edit, create, and delete only the specific Google Drive files you use with this app +STR_PERM_DRIVE_METADATA=View and manage metadata of files in your Google Drive +STR_PERM_DRIVE_METADATA_RO=See information about your Google Drive files +STR_GOOGLE_LOGIN_FAIL_MSG=Google login failed +STR_GOOGLE_LOGIN_TIMEOUT_MSG=Google login timed out diff --git a/source/actions.cpp b/source/actions.cpp index 5f2ea82..00b0f69 100644 --- a/source/actions.cpp +++ b/source/actions.cpp @@ -4,7 +4,14 @@ #include #include #include -#include "crypt.h" +#include "clients/gdrive.h" +#include "clients/ftpclient.h" +#include "clients/smbclient.h" +#include "clients/webdavclient.h" +#include "clients/apache.h" +#include "clients/nginx.h" +#include "clients/npxserve.h" +#include "clients/iis.h" #include "common.h" #include "fs.h" #include "config.h" @@ -15,15 +22,9 @@ #include "installer.h" #include "web/request.hpp" #include "web/urn.hpp" -#include "sys_modules.h" -#include "ftpclient.h" -#include "smbclient.h" -#include "webdavclient.h" -#include "http/apache.h" -#include "http/nginx.h" -#include "http/npxserve.h" -#include "http/iis.h" +#include "system.h" #include "zip_util.h" +#include "dbglogger.h" namespace Actions { @@ -1109,7 +1110,12 @@ namespace Actions { CONFIG::SaveConfig(); - if (strncmp(remote_settings->server, "https://", 8) == 0 || strncmp(remote_settings->server, "http://", 7) == 0) + if (strncmp(remote_settings->server, GOOGLE_DRIVE_BASE_URL, strlen(GOOGLE_DRIVE_BASE_URL)) == 0) + { + remoteclient = new GDriveClient(); + remoteclient->Connect("", "", ""); + } + else if (strncmp(remote_settings->server, "https://", 8) == 0 || strncmp(remote_settings->server, "http://", 7) == 0) { if (strcmp(remote_settings->http_server_type, HTTP_SERVER_APACHE) == 0) remoteclient = new ApacheClient(); diff --git a/source/http/apache.cpp b/source/clients/apache.cpp similarity index 99% rename from source/http/apache.cpp rename to source/clients/apache.cpp index c298298..3873a70 100644 --- a/source/http/apache.cpp +++ b/source/clients/apache.cpp @@ -2,8 +2,8 @@ #include #include #include "common.h" -#include "remote_client.h" -#include "http/apache.h" +#include "clients/remote_client.h" +#include "clients/apache.h" #include "lang.h" #include "util.h" #include "windows.h" diff --git a/source/http/apache.h b/source/clients/apache.h similarity index 77% rename from source/http/apache.h rename to source/clients/apache.h index 2557f69..4885019 100644 --- a/source/http/apache.h +++ b/source/clients/apache.h @@ -4,9 +4,9 @@ #include #include #include "http/httplib.h" -#include "http/baseclient.h" +#include "clients/remote_client.h" +#include "clients/baseclient.h" #include "common.h" -#include "remote_client.h" class ApacheClient : public BaseClient { diff --git a/source/http/baseclient.cpp b/source/clients/baseclient.cpp similarity index 75% rename from source/http/baseclient.cpp rename to source/clients/baseclient.cpp index 83d4590..21d6f00 100644 --- a/source/http/baseclient.cpp +++ b/source/clients/baseclient.cpp @@ -1,9 +1,10 @@ #include #include #include +#include #include "common.h" -#include "remote_client.h" -#include "http/npxserve.h" +#include "clients/remote_client.h" +#include "clients/baseclient.h" #include "lang.h" #include "util.h" #include "windows.h" @@ -76,12 +77,12 @@ int BaseClient::Get(const std::string &outputfile, const std::string &path, uint std::ofstream file_stream(outputfile, std::ios::binary); bytes_transfered = 0; if (auto res = client->Get(GetFullPath(path), - [&](const char *data, size_t data_length) - { - file_stream.write(data, data_length); - bytes_transfered += data_length; - return true; - })) + [&](const char *data, size_t data_length) + { + file_stream.write(data, data_length); + bytes_transfered += data_length; + return true; + })) { file_stream.close(); return 1; @@ -126,21 +127,22 @@ int BaseClient::Move(const std::string &from, const std::string &to) int BaseClient::Head(const std::string &path, void *buffer, uint64_t len) { char range_header[64]; - sprintf(range_header, "bytes=%lu-%lu", 0L, len-1); + sprintf(range_header, "bytes=%lu-%lu", 0L, len - 1); Headers headers = {{"Range", range_header}}; size_t bytes_read = 0; std::vector body; if (auto res = client->Get(GetFullPath(path), headers, - [&](const char *data, size_t data_length) - { - body.insert(body.end(), data, data+data_length); - bytes_read += data_length; - if (bytes_read > len) - return false; - return true; - })) + [&](const char *data, size_t data_length) + { + body.insert(body.end(), data, data + data_length); + bytes_read += data_length; + if (bytes_read > len) + return false; + return true; + })) { - if (body.size() < len) return 0; + if (body.size() < len) + return 0; memcpy(buffer, body.data(), len); return 1; } @@ -242,3 +244,38 @@ uint32_t BaseClient::SupportedActions() { return REMOTE_ACTION_DOWNLOAD | REMOTE_ACTION_INSTALL; } + +std::string BaseClient::EncodeUrl(const std::string &url) +{ + CURL *curl = curl_easy_init(); + if (curl) + { + char *output = curl_easy_escape(curl, url.c_str(), url.length()); + if (output) + { + std::string encoded_url = std::string(output); + curl_free(output); + return encoded_url; + } + curl_easy_cleanup(curl); + } + return ""; +} + +std::string BaseClient::DecodeUrl(const std::string &url) +{ + CURL *curl = curl_easy_init(); + if (curl) + { + int decode_len; + char *output = curl_easy_unescape(curl, url.c_str(), url.length(), &decode_len); + if (output) + { + std::string decoded_url = std::string(output, decode_len); + curl_free(output); + return decoded_url; + } + curl_easy_cleanup(curl); + } + return ""; +} diff --git a/source/http/baseclient.h b/source/clients/baseclient.h similarity index 90% rename from source/http/baseclient.h rename to source/clients/baseclient.h index 9007a7c..9ac5a65 100644 --- a/source/http/baseclient.h +++ b/source/clients/baseclient.h @@ -4,8 +4,8 @@ #include #include #include "http/httplib.h" +#include "clients/remote_client.h" #include "common.h" -#include "remote_client.h" class BaseClient : public RemoteClient { @@ -33,6 +33,8 @@ public: int Quit(); ClientType clientType(); uint32_t SupportedActions(); + static std::string EncodeUrl(const std::string &url); + static std::string DecodeUrl(const std::string &url); protected: httplib::Client *client; diff --git a/source/ftpclient.cpp b/source/clients/ftpclient.cpp similarity index 99% rename from source/ftpclient.cpp rename to source/clients/ftpclient.cpp index 129b571..d482709 100644 --- a/source/ftpclient.cpp +++ b/source/clients/ftpclient.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include #include @@ -12,7 +12,7 @@ #include #include "lang.h" -#include "ftpclient.h" +#include "clients/ftpclient.h" #include "util.h" #include "windows.h" diff --git a/source/ftpclient.h b/source/clients/ftpclient.h similarity index 99% rename from source/ftpclient.h rename to source/clients/ftpclient.h index 1f4b64d..0bfe11f 100644 --- a/source/ftpclient.h +++ b/source/clients/ftpclient.h @@ -6,7 +6,7 @@ #include #include #include -#include "remote_client.h" +#include "clients/remote_client.h" #define FTP_CLIENT_MAX_FILENAME_LEN 128 diff --git a/source/clients/gdrive.cpp b/source/clients/gdrive.cpp new file mode 100644 index 0000000..2f0d42d --- /dev/null +++ b/source/clients/gdrive.cpp @@ -0,0 +1,190 @@ +#include +#include +#include +#include +#include "config.h" +#include "common.h" +#include "server/http_server.h" +#include "clients/remote_client.h" +#include "clients/gdrive.h" +#include "lang.h" +#include "util.h" +#include "windows.h" +#include "system.h" +#include "dbglogger.h" + +using namespace httplib; + +std::string GetRedirectUrl() +{ + return std::string("https://localhost:" + std::to_string(http_server_port) + "/google_auth"); +} + +std::string GetScopes() +{ + std::vector permissions = Util::Split(gg_account.permissions, ","); + std::string scopes; + for (int i = 0; i < permissions.size(); i++) + { + scopes.append("https://www.googleapis.com/auth/"); + scopes.append(permissions[i]); + if (i < permissions.size() - 1) + { + scopes.append(" "); + } + } + return scopes; +} + +void RefreshAccessToken() +{ + SSLClient client(GOOGLE_OAUTH_HOST); + client.enable_server_certificate_verification(false); + std::string url = std::string("/token?code=") + gg_account.auth_code + "&client_id=" + gg_account.client_id + "&client_secret=" + + gg_account.client_secret + "&grant_type=refresh_token&refresh_token=" + gg_account.refresh_token; + Result result = client.Post(url); + + if (result.error() == Error::Success && result.value().status == 200) + { + json_object *jobj = json_tokener_parse(result.value().body.c_str()); + enum json_type type; + json_object_object_foreach(jobj, key, val) + { + if (strcmp(key, "access_token") == 0) + snprintf(gg_account.access_token, 255, "%s", json_object_get_string(val)); + else if (strcmp(key, "expires_in") == 0) + { + OrbisTick tick; + sceRtcGetCurrentTick(&tick); + gg_account.token_expiry = tick.mytick + (json_object_get_int(val) * 1000000); + } + } + CONFIG::SaveGoolgeAccountInfo(); + } +} + +int login_state; + +int GDriveClient::Connect(const std::string &url, const std::string &user, const std::string &pass) +{ + OrbisTick tick; + sceRtcGetCurrentTick(&tick); + dbglogger_log("token_expiry=%ld, tick=%ld", gg_account.token_expiry, tick.mytick); + if (gg_account.token_expiry < (tick.mytick - 300000000)) + { + SceShellUIUtilLaunchByUriParam param; + param.size = sizeof(SceShellUIUtilLaunchByUriParam); + sceUserServiceGetForegroundUser((int *)¶m.userId); + + std::string auth_url = std::string(GOOGLE_AUTH_URL "?client_id=") + gg_account.client_id + "&redirect_uri=" + GetRedirectUrl() + + "&response_type=code&access_type=offline&scope=" + GetScopes() + "&include_granted_scopes=true"; + auth_url = EncodeUrl(auth_url); + std::string launch_uri = std::string("pswebbrowser:search?url=") + auth_url; + int ret = sceShellUIUtilLaunchByUri(launch_uri.c_str(), ¶m); + dbglogger_log("sceShellUIUtilLaunchByUri - 0x%08x", ret); + + login_state = 0; + OrbisTick tick; + sceRtcGetCurrentTick(&tick); + while (login_state == 0) + { + OrbisTick cur_tick; + sceRtcGetCurrentTick(&cur_tick); + if (cur_tick.mytick - tick.mytick > 120000000) + { + login_state = -2; + break; + } + sceKernelUsleep(100000); + } + + if (login_state == -1) + { + sprintf(response, "%s", lang_strings[STR_GOOGLE_LOGIN_FAIL_MSG]); + return 0; + } + else if (login_state == -2) + { + sprintf(response, "%s", lang_strings[STR_GOOGLE_LOGIN_TIMEOUT_MSG]); + return 0; + } + } + StartRefreshToken(); + + client = new Client(GOOGLE_API_URL); + client->set_bearer_token_auth(gg_account.access_token); + client->set_keep_alive(true); + client->set_follow_location(true); + client->set_connection_timeout(30); + client->set_read_timeout(30); + client->enable_server_certificate_verification(false); + this->connected = true; + + return 1; +} + +std::vector GDriveClient::ListDir(const std::string &path) +{ + std::vector out; + DirEntry entry; + memset(&entry, 0, sizeof(DirEntry)); + if (path[path.length() - 1] == '/' && path.length() > 1) + { + strlcpy(entry.directory, path.c_str(), path.length() - 1); + } + else + { + sprintf(entry.directory, "%s", path.c_str()); + } + sprintf(entry.name, ".."); + sprintf(entry.path, "%s", entry.directory); + sprintf(entry.display_size, "%s", lang_strings[STR_FOLDER]); + entry.file_size = 0; + entry.isDir = true; + entry.selectable = false; + out.push_back(entry); + + return out; +} + +ClientType GDriveClient::clientType() +{ + return CLIENT_TYPE_GOOGLE; +} + +uint32_t GDriveClient::SupportedActions() +{ + return REMOTE_ACTION_ALL; +} + +void *GDriveClient::RefreshTokenThread(void *argp) +{ + while (refresh_token_running) + { + OrbisTick tick; + sceRtcGetCurrentTick(&tick); + if (tick.mytick >= (gg_account.token_expiry - 300000000)) // refresh token 5mins before expiry + { + RefreshAccessToken(); + } + sceKernelUsleep(5000000); // sleep for 5s + } + return NULL; +} + +void GDriveClient::StartRefreshToken() +{ + if (refresh_token_running) return; + + refresh_token_running = true; + int ret = pthread_create(&refresh_token_thid, NULL, RefreshTokenThread, NULL); + if (ret != 0) + { + dbglogger_log("Failed to start refresh token thread"); + } +} + +void GDriveClient::StopRefreshToken() +{ + refresh_token_running = false; +} \ No newline at end of file diff --git a/source/clients/gdrive.h b/source/clients/gdrive.h new file mode 100644 index 0000000..1f1706f --- /dev/null +++ b/source/clients/gdrive.h @@ -0,0 +1,27 @@ +#ifndef GDRIVE_H +#define GDRIVE_H + +#include +#include +#include "http/httplib.h" +#include "clients/remote_client.h" +#include "clients/baseclient.h" +#include "common.h" + +static pthread_t refresh_token_thid; +static bool refresh_token_running = false; +extern int login_state; + +class GDriveClient : public BaseClient +{ +public: + int Connect(const std::string &url, const std::string &user, const std::string &pass); + std::vector ListDir(const std::string &path); + static void *RefreshTokenThread(void *argp); + static void StartRefreshToken(); + static void StopRefreshToken(); + ClientType clientType(); + uint32_t SupportedActions(); +}; + +#endif \ No newline at end of file diff --git a/source/http/iis.cpp b/source/clients/iis.cpp similarity index 98% rename from source/http/iis.cpp rename to source/clients/iis.cpp index 19dc797..7006c5d 100644 --- a/source/http/iis.cpp +++ b/source/clients/iis.cpp @@ -2,8 +2,8 @@ #include #include #include "common.h" -#include "remote_client.h" -#include "http/iis.h" +#include "clients/remote_client.h" +#include "clients/iis.h" #include "lang.h" #include "util.h" #include "windows.h" diff --git a/source/http/iis.h b/source/clients/iis.h similarity index 77% rename from source/http/iis.h rename to source/clients/iis.h index a39ae12..1c4e340 100644 --- a/source/http/iis.h +++ b/source/clients/iis.h @@ -4,9 +4,9 @@ #include #include #include "http/httplib.h" -#include "http/baseclient.h" +#include "clients/remote_client.h" +#include "clients/baseclient.h" #include "common.h" -#include "remote_client.h" class IISClient : public BaseClient { diff --git a/source/http/nginx.cpp b/source/clients/nginx.cpp similarity index 98% rename from source/http/nginx.cpp rename to source/clients/nginx.cpp index 6ac8f24..aa54458 100644 --- a/source/http/nginx.cpp +++ b/source/clients/nginx.cpp @@ -4,8 +4,8 @@ #include #include #include "common.h" -#include "remote_client.h" -#include "http/nginx.h" +#include "clients/remote_client.h" +#include "clients/nginx.h" #include "lang.h" #include "util.h" #include "windows.h" diff --git a/source/http/nginx.h b/source/clients/nginx.h similarity index 77% rename from source/http/nginx.h rename to source/clients/nginx.h index 3c04ba1..1043b03 100644 --- a/source/http/nginx.h +++ b/source/clients/nginx.h @@ -4,9 +4,9 @@ #include #include #include "http/httplib.h" -#include "http/baseclient.h" +#include "clients/baseclient.h" #include "common.h" -#include "remote_client.h" +#include "clients/remote_client.h" class NginxClient : public BaseClient { diff --git a/source/http/npxserve.cpp b/source/clients/npxserve.cpp similarity index 98% rename from source/http/npxserve.cpp rename to source/clients/npxserve.cpp index e495b60..ea40552 100644 --- a/source/http/npxserve.cpp +++ b/source/clients/npxserve.cpp @@ -2,8 +2,8 @@ #include #include #include "common.h" -#include "remote_client.h" -#include "http/npxserve.h" +#include "clients/remote_client.h" +#include "clients/npxserve.h" #include "lang.h" #include "util.h" #include "windows.h" diff --git a/source/http/npxserve.h b/source/clients/npxserve.h similarity index 78% rename from source/http/npxserve.h rename to source/clients/npxserve.h index c222763..9801506 100644 --- a/source/http/npxserve.h +++ b/source/clients/npxserve.h @@ -4,9 +4,9 @@ #include #include #include "http/httplib.h" -#include "http/baseclient.h" +#include "clients/baseclient.h" +#include "clients/remote_client.h" #include "common.h" -#include "remote_client.h" class NpxServeClient : public BaseClient { diff --git a/source/remote_client.h b/source/clients/remote_client.h similarity index 98% rename from source/remote_client.h rename to source/clients/remote_client.h index 22b0fa6..486172a 100644 --- a/source/remote_client.h +++ b/source/clients/remote_client.h @@ -27,6 +27,7 @@ enum ClientType CLIENT_TYPE_SMB, CLIENT_TYPE_WEBDAV, CLIENT_TYPE_HTTP_SERVER, + CLIENT_TYPE_GOOGLE, CLINET_TYPE_UNKNOWN }; diff --git a/source/smbclient.cpp b/source/clients/smbclient.cpp similarity index 99% rename from source/smbclient.cpp rename to source/clients/smbclient.cpp index f8ce036..808b0db 100644 --- a/source/smbclient.cpp +++ b/source/clients/smbclient.cpp @@ -12,7 +12,7 @@ #include #include "fs.h" #include "lang.h" -#include "smbclient.h" +#include "clients/smbclient.h" #include "windows.h" #include "util.h" diff --git a/source/smbclient.h b/source/clients/smbclient.h similarity index 97% rename from source/smbclient.h rename to source/clients/smbclient.h index a26ed7c..bdd1dab 100644 --- a/source/smbclient.h +++ b/source/clients/smbclient.h @@ -8,8 +8,8 @@ #include #include #include +#include "clients/remote_client.h" #include "common.h" -#include "remote_client.h" #define SMB_CLIENT_MAX_FILENAME_LEN 256 diff --git a/source/webdavclient.cpp b/source/clients/webdavclient.cpp similarity index 99% rename from source/webdavclient.cpp rename to source/clients/webdavclient.cpp index abd307a..86be3a3 100644 --- a/source/webdavclient.cpp +++ b/source/clients/webdavclient.cpp @@ -9,10 +9,10 @@ #include #include "lang.h" #include "webdav/client.hpp" -#include "webdavclient.h" +#include "clients/webdavclient.h" #include "windows.h" #include "util.h" -#include "sys_modules.h" +#include "system.h" #define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) diff --git a/source/webdavclient.h b/source/clients/webdavclient.h similarity index 98% rename from source/webdavclient.h rename to source/clients/webdavclient.h index 3464314..f481b22 100644 --- a/source/webdavclient.h +++ b/source/clients/webdavclient.h @@ -6,8 +6,8 @@ #include #include #include "webdav/client.hpp" +#include "clients/remote_client.h" #include "common.h" -#include "remote_client.h" namespace WebDAV { diff --git a/source/config.cpp b/source/config.cpp index f8d6db5..1f5d935 100644 --- a/source/config.cpp +++ b/source/config.cpp @@ -6,11 +6,13 @@ #include #include #include +#include "server/http_server.h" #include "config.h" #include "fs.h" #include "lang.h" #include "crypt.h" #include "base64.h" +#include "dbglogger.h" extern "C" { @@ -32,6 +34,8 @@ PackageUrlInfo install_pkg_url; char favorite_urls[MAX_FAVORITE_URLS][512]; bool auto_delete_tmp_pkg; int max_edit_file_size; +GoogleAccountInfo gg_account; + unsigned char cipher_key[32] = {'s', '5', 'v', '8', 'y', '/', 'B', '?', 'E', '(', 'H', '+', 'M', 'b', 'Q', 'e', 'T', 'h', 'W', 'm', 'Z', 'q', '4', 't', '7', 'w', '9', 'z', '$', 'C', '&', 'F'}; unsigned char cipher_iv[16] = {'Y', 'p', '3', 's', '6', 'v', '9', 'y', '$', 'B', '&', 'E', ')', 'H', '@', 'M'}; @@ -94,7 +98,7 @@ namespace CONFIG } } - void LoadEncryptKeys() + void LoadCipherKeys() { // Get the key and iv for encryption. Inject the account_id/MAC address as part of the key and iv. int user_id; @@ -123,7 +127,7 @@ namespace CONFIG void LoadConfig() { - LoadEncryptKeys(); + LoadCipherKeys(); if (!FS::FolderExists(DATA_PATH)) { @@ -161,6 +165,67 @@ namespace CONFIG max_edit_file_size = ReadInt(CONFIG_GLOBAL, CONFIG_MAX_EDIT_FILE_SIZE, MAX_EDIT_FILE_SIZE); WriteInt(CONFIG_GLOBAL, CONFIG_MAX_EDIT_FILE_SIZE, max_edit_file_size); + // Load Google Account Info + sprintf(gg_account.client_id, "%s", ReadString(CONFIG_GOOGLE, CONFIG_GOOGLE_CLIENT_ID, "")); + WriteString(CONFIG_GOOGLE, CONFIG_GOOGLE_CLIENT_ID, gg_account.client_id); + + // Token Expiry + gg_account.token_expiry = ReadLong(CONFIG_GOOGLE, CONFIG_GOOGLE_TOKEN_EXPIRY, 0); + WriteLong(CONFIG_GOOGLE, CONFIG_GOOGLE_TOKEN_EXPIRY, gg_account.token_expiry); + + // Client Secret + char tmp_gg_secret[512]; + sprintf(tmp_gg_secret, "%s", ReadString(CONFIG_GOOGLE, CONFIG_GOOGLE_CLIENT_SECRET, "")); + std::string encrypted_secret; + if (strlen(tmp_gg_secret) > 0) + { + std::string decrypted_secret; + int ret = Decrypt(tmp_gg_secret, decrypted_secret); + if (ret == 0) + sprintf(gg_account.client_secret, "%s", tmp_gg_secret); + else + sprintf(gg_account.client_secret, "%s", decrypted_secret.c_str()); + Encrypt(gg_account.client_secret, encrypted_secret); + } + WriteString(CONFIG_GOOGLE, CONFIG_GOOGLE_CLIENT_SECRET, encrypted_secret.c_str()); + + // Access Token + sprintf(tmp_gg_secret, "%s", ReadString(CONFIG_GOOGLE, CONFIG_GOOGLE_ACCESS_TOKEN, "")); + std::string encrypted_token; + if (strlen(tmp_gg_secret) > 0) + { + std::string decrypted_secret; + int ret = Decrypt(tmp_gg_secret, decrypted_secret); + if (ret == 0) + sprintf(gg_account.access_token, "%s", tmp_gg_secret); + else + sprintf(gg_account.access_token, "%s", decrypted_secret.c_str()); + Encrypt(gg_account.access_token, encrypted_token); + } + WriteString(CONFIG_GOOGLE, CONFIG_GOOGLE_ACCESS_TOKEN, encrypted_token.c_str()); + + // Refresh Token + sprintf(tmp_gg_secret, "%s", ReadString(CONFIG_GOOGLE, CONFIG_GOOGLE_REFRESH_TOKEN, "")); + std::string encrypted_refresh_token; + if (strlen(tmp_gg_secret) > 0) + { + std::string decrypted_secret; + int ret = Decrypt(tmp_gg_secret, decrypted_secret); + if (ret == 0) + sprintf(gg_account.refresh_token, "%s", tmp_gg_secret); + else + sprintf(gg_account.refresh_token, "%s", decrypted_secret.c_str()); + Encrypt(gg_account.refresh_token, encrypted_refresh_token); + } + WriteString(CONFIG_GOOGLE, CONFIG_GOOGLE_REFRESH_TOKEN, encrypted_refresh_token.c_str()); + + sprintf(gg_account.permissions, "%s", ReadString(CONFIG_GOOGLE, CONFIG_GOOGLE_PERMISSIONS, GOOGLE_DEFAULT_PERMISSIONS)); + WriteString(CONFIG_GOOGLE, CONFIG_GOOGLE_PERMISSIONS, gg_account.permissions); + + // Http Server Info + http_server_port = ReadInt(CONFIG_HTTP_SERVER, CONFIG_HTTP_SERVER_PORT, 8080); + WriteInt(CONFIG_HTTP_SERVER, CONFIG_HTTP_SERVER_PORT, http_server_port); + for (int i = 0; i < sites.size(); i++) { RemoteSettings setting; @@ -212,14 +277,12 @@ namespace CONFIG WriteString(CONFIG_GLOBAL, CONFIG_LAST_SITE, last_site); remote_settings = &site_settings[std::string(last_site)]; - for (int i = 0; i < MAX_FAVORITE_URLS; i++) { const char *index = std::to_string(i).c_str(); sprintf(favorite_urls[i], "%s", ReadString(CONFIG_FAVORITE_URLS, index, "")); WriteString(CONFIG_FAVORITE_URLS, index, favorite_urls[i]); } - WriteIniFile(CONFIG_INI_FILE); CloseIniFile(); } @@ -245,6 +308,38 @@ namespace CONFIG CloseIniFile(); } + void SaveGoolgeAccountInfo() + { + OpenIniFile(CONFIG_INI_FILE); + + std::string encrypted_secret; + if (strlen(gg_account.client_secret) > 0) + Encrypt(gg_account.client_secret, encrypted_secret); + else + encrypted_secret = std::string(gg_account.client_secret); + WriteString(CONFIG_GOOGLE, CONFIG_GOOGLE_CLIENT_SECRET, encrypted_secret.c_str()); + + std::string encrypted_token; + if (strlen(gg_account.access_token) > 0) + Encrypt(gg_account.access_token, encrypted_token); + else + encrypted_token = std::string(gg_account.access_token); + WriteString(CONFIG_GOOGLE, CONFIG_GOOGLE_ACCESS_TOKEN, encrypted_token.c_str()); + + std::string encrypted_refresh_token; + if (strlen(gg_account.refresh_token) > 0) + Encrypt(gg_account.refresh_token, encrypted_refresh_token); + else + encrypted_refresh_token = std::string(gg_account.refresh_token); + WriteString(CONFIG_GOOGLE, CONFIG_GOOGLE_REFRESH_TOKEN, encrypted_refresh_token.c_str()); + + WriteLong(CONFIG_GOOGLE, CONFIG_GOOGLE_TOKEN_EXPIRY, gg_account.token_expiry); + WriteString(CONFIG_GOOGLE, CONFIG_GOOGLE_CLIENT_ID, gg_account.client_id); + WriteString(CONFIG_GOOGLE, CONFIG_GOOGLE_PERMISSIONS, gg_account.permissions); + WriteIniFile(CONFIG_INI_FILE); + CloseIniFile(); + } + void SaveFavoriteUrl(int index, char *url) { OpenIniFile(CONFIG_INI_FILE); @@ -253,52 +348,4 @@ namespace CONFIG WriteIniFile(CONFIG_INI_FILE); CloseIniFile(); } - - void ParseMultiValueString(const char *prefix_list, std::vector &prefixes, bool toLower) - { - std::string prefix = ""; - int length = strlen(prefix_list); - for (int i = 0; i < length; i++) - { - char c = prefix_list[i]; - if (c != ' ' && c != '\t' && c != ',') - { - if (toLower) - { - prefix += std::tolower(c); - } - else - { - prefix += c; - } - } - - if (c == ',' || i == length - 1) - { - prefixes.push_back(prefix); - prefix = ""; - } - } - } - - std::string GetMultiValueString(std::vector &multi_values) - { - std::string vts = std::string(""); - if (multi_values.size() > 0) - { - for (int i = 0; i < multi_values.size() - 1; i++) - { - vts.append(multi_values[i]).append(","); - } - vts.append(multi_values[multi_values.size() - 1]); - } - return vts; - } - - void RemoveFromMultiValues(std::vector &multi_values, std::string value) - { - auto itr = std::find(multi_values.begin(), multi_values.end(), value); - if (itr != multi_values.end()) - multi_values.erase(itr); - } } diff --git a/source/config.h b/source/config.h index 6039fcf..96b034e 100644 --- a/source/config.h +++ b/source/config.h @@ -3,10 +3,11 @@ #include #include +#include #include #include -#include "remote_client.h" +#include "clients/remote_client.h" #define APP_ID "ezremote-client" #define DATA_PATH "/data/" APP_ID @@ -16,6 +17,29 @@ #define CONFIG_GLOBAL "Global" +#define CONFIG_GOOGLE "Google" +#define CONFIG_GOOGLE_CLIENT_ID "google_client_id" +#define CONFIG_GOOGLE_CLIENT_SECRET "google_client_secret" +#define CONFIG_GOOGLE_PERMISSIONS "google_client_permissions" +#define CONFIG_GOOGLE_ACCESS_TOKEN "google_access_token" +#define CONFIG_GOOGLE_REFRESH_TOKEN "google_refresh_token" +#define CONFIG_GOOGLE_TOKEN_EXPIRY "google_token_expiry" + +#define GOOGLE_OAUTH_HOST "oauth2.googleapis.com" +#define GOOGLE_AUTH_URL "https://accounts.google.com/o/oauth2/v2/auth" +#define GOOGLE_API_URL "https://www.googleapis.com" +#define GOOGLE_DRIVE_API_PATH "/drive/v2/files" +#define GOOGLE_DRIVE_BASE_URL "https://drive.google.com" +#define GOOGLE_PERM_DRIVE "drive" +#define GOOGLE_PERM_DRIVE_APPDATA "drive.appdata" +#define GOOGLE_PERM_DRIVE_FILE "drive.file" +#define GOOGLE_PERM_DRIVE_METADATA "drive.metadata" +#define GOOGLE_PERM_DRIVE_METADATA_RO "drive.metadata.readonly" +#define GOOGLE_DEFAULT_PERMISSIONS GOOGLE_PERM_DRIVE "," GOOGLE_PERM_DRIVE_METADATA + +#define CONFIG_HTTP_SERVER "HttpServer" +#define CONFIG_HTTP_SERVER_PORT "http_server_port" + #define CONFIG_REMOTE_SERVER_NAME "remote_server_name" #define CONFIG_REMOTE_SERVER_URL "remote_server_url" #define CONFIG_REMOTE_SERVER_USER "remote_server_user" @@ -66,6 +90,17 @@ struct PackageUrlInfo char password[25]; }; +struct GoogleAccountInfo +{ + char client_id[128]; + char client_secret[64]; + char auth_code[128]; + char access_token[256]; + char refresh_token[64]; + uint64_t token_expiry; + char permissions[92]; +}; + extern std::vector sites; extern std::vector http_servers; extern std::map site_settings; @@ -83,15 +118,14 @@ extern bool auto_delete_tmp_pkg; extern int max_edit_file_size; extern unsigned char cipher_key[32]; extern unsigned char cipher_iv[16]; +extern GoogleAccountInfo gg_account; namespace CONFIG { void LoadConfig(); void SaveConfig(); + void SaveGoolgeAccountInfo(); void SaveFavoriteUrl(int index, char *url); void SetClientType(RemoteSettings *settings); - void RemoveFromMultiValues(std::vector &multi_values, std::string value); - void ParseMultiValueString(const char *prefix_list, std::vector &prefixes, bool toLower); - std::string GetMultiValueString(std::vector &multi_values); } #endif diff --git a/source/fs.cpp b/source/fs.cpp index c6e0e49..0bdd4cb 100644 --- a/source/fs.cpp +++ b/source/fs.cpp @@ -11,7 +11,7 @@ #include "util.h" #include "lang.h" -#include "sys_modules.h" +#include "system.h" #include "windows.h" namespace FS diff --git a/source/inifile.c b/source/inifile.c index 871f283..10908e7 100644 --- a/source/inifile.c +++ b/source/inifile.c @@ -52,7 +52,7 @@ ------------------------------------------------------------------------ Copyright (c) 2000 Carsten Breuer -/************************************************************************/ +************************************************************************/ /* defines for, or consts and inline functions for C++ */ @@ -68,7 +68,7 @@ struct ENTRY *Entry = NULL; struct ENTRY *CurEntry = NULL; -char Result[4096] = +char Result[520] = {""}; FILE *IniFile; @@ -84,7 +84,7 @@ struct ENTRY *MakeNewEntry(void); strupr -de- ------------------------------------------------------------------------- Job : String to Uppercase 22.03.2001 Dieter Engelbrecht dieter@wintop.net -/*========================================================================*/ +*========================================================================*/ #ifdef DONT_HAVE_STRUPR /* DONT_HAVE_STRUPR is set when INI_REMOVE_CR is defined */ void strupr(char *str) @@ -99,6 +99,7 @@ void strupr(char *str) str++; } } +#else #endif /*========================================================================= @@ -109,10 +110,10 @@ void strupr(char *str) Att : Be sure to call CloseIniFile to free all mem allocated during operation! -/*========================================================================*/ +*========================================================================*/ bool OpenIniFile(cchr *FileName) { - char Str[5120]; + char Str[512]; char *pStr; struct ENTRY *pEntry; @@ -127,7 +128,7 @@ bool OpenIniFile(cchr *FileName) return FALSE; } - while (fgets(Str, 5120, IniFile) != NULL) + while (fgets(Str, 512, IniFile) != NULL) { pStr = strchr(Str, '\n'); if (pStr != NULL) @@ -191,7 +192,7 @@ bool OpenIniFile(cchr *FileName) Job : Frees the memory and closes the ini file without any modifications. If you want to write the file use WriteIniFile instead. -/*========================================================================*/ +*========================================================================*/ void CloseIniFile(void) { FreeAllMem(); @@ -207,7 +208,7 @@ void CloseIniFile(void) ------------------------------------------------------------------------- Job : Writes the iniFile to the disk and close it. Frees all memory allocated by WriteIniFile; -/*========================================================================*/ +==========================================================================*/ bool WriteIniFile(const char *FileName) { struct ENTRY *pEntry = Entry; @@ -242,7 +243,7 @@ bool WriteIniFile(const char *FileName) void WriteString(cchr *Section, cchr *pKey, cchr *Value) { EFIND List; - char Str[5120]; + char Str[512]; if (ArePtrValid(Section, pKey, Value) == FALSE) { @@ -291,6 +292,16 @@ void WriteInt(cchr *Section, cchr *pKey, int Value) WriteString(Section, pKey, Val); } +/*========================================================================= + WriteLong : Writes an long to the ini file +*========================================================================*/ +void WriteLong(cchr *Section, cchr *pKey, long Value) +{ + char Val[22]; /* 64bit maximum + sign + \0 */ + sprintf(Val, "%ld", Value); + WriteString(Section, pKey, Val); +} + /*========================================================================= WriteDouble : Writes a double to the ini file *========================================================================*/ @@ -343,6 +354,16 @@ int ReadInt(cchr *Section, cchr *pKey, int Default) return (atoi(ReadString(Section, pKey, Val))); } +/*========================================================================= + ReadLong : Reads a long from the ini file +*========================================================================*/ +long ReadLong(cchr *Section, cchr *pKey, long Default) +{ + char Val[22]; + sprintf(Val, "%ld", Default); + return (atol(ReadString(Section, pKey, Val))); +} + /*========================================================================= ReadDouble : Reads a double from the ini file *========================================================================*/ @@ -463,7 +484,7 @@ bool FindpKey(cchr *Section, cchr *pKey, EFIND *List) { char Search[130]; char Found[130]; - char Text[5120]; + char Text[512]; char *pText; struct ENTRY *pEntry; List->pSec = NULL; @@ -595,7 +616,7 @@ bool AddItemAt(struct ENTRY *EntryAt, char Mode, cchr *Text) *========================================================================*/ bool AddSectionAndpKey(cchr *Section, cchr *pKey, cchr *Value) { - char Text[5120]; + char Text[512]; sprintf(Text, "[%s]", Section); if (AddItem(tpSECTION, Text) == FALSE) { @@ -610,7 +631,7 @@ bool AddSectionAndpKey(cchr *Section, cchr *pKey, cchr *Value) *========================================================================*/ void AddpKey(struct ENTRY *SecEntry, cchr *pKey, cchr *Value) { - char Text[5120]; + char Text[512]; sprintf(Text, "%s=%s", pKey, Value); AddItemAt(SecEntry, tpKEYVALUE, Text); } diff --git a/source/inifile.h b/source/inifile.h index ce9d02f..e6b3676 100644 --- a/source/inifile.h +++ b/source/inifile.h @@ -5,7 +5,7 @@ Author(s) : Carsten Breuer ------------------------------------------------------------------------ Copyright (c) 2000 by Carsten Breuer (C.Breuer@openwin.de) -/************************************************************************/ +************************************************************************/ #ifndef INIFILE_H #define INIFILE_H @@ -54,11 +54,13 @@ bool OpenIniFile(cchr *FileName); bool ReadBool(cchr *Section, cchr *Key, bool Default); int ReadInt(cchr *Section, cchr *Key, int Default); +long ReadLong(cchr *Section, cchr *Key, long Default); double ReadDouble(cchr *Section, cchr *Key, double Default); cchr *ReadString(cchr *Section, cchr *Key, cchr *Default); void WriteBool(cchr *Section, cchr *Key, bool Value); void WriteInt(cchr *Section, cchr *Key, int Value); +void WriteLong(cchr *Section, cchr *Key, long Value); void WriteDouble(cchr *Section, cchr *Key, double Value); void WriteString(cchr *Section, cchr *Key, cchr *Value); diff --git a/source/installer.cpp b/source/installer.cpp index 2f155c0..efeabdb 100644 --- a/source/installer.cpp +++ b/source/installer.cpp @@ -17,9 +17,9 @@ #include "config.h" #include "windows.h" #include "lang.h" -#include "sys_modules.h" +#include "system.h" #include "fs.h" -#include "webdavclient.h" +#include "clients/webdavclient.h" #define BGFT_HEAP_SIZE (1 * 1024 * 1024) diff --git a/source/lang.cpp b/source/lang.cpp index 3b73b6b..05de159 100644 --- a/source/lang.cpp +++ b/source/lang.cpp @@ -127,14 +127,23 @@ char lang_strings[LANG_STRINGS_NUM][LANG_STR_SIZE] = { "This option enables Remote Package Installation. " "This requires a HTTP Server setup on the same host sharing the same folder with anonymous access.", // STR_ENABLE_RPI_FTP_SMB_MSG "This option enables Remote Package Installation. " - "This requires the Server with anonymous access that does not need username/password.", // STR_ENABLE_RPI_WEBDAV_MSG - "Files", // STR_FILES - "Editor", // STR_EDITOR - "Save", // STR_SAVE - "Cannot edit files bigger than", // STR_MAX_EDIT_FILE_SIZE_MSG - "Delete Selected Line", // STR_DELETE_LINE - "Insert Below Selected Line", // STR_INSERT_LINE - "Modified", // STR_MODIFIED + "This requires the Server with anonymous access that does not need username/password.", // STR_ENABLE_RPI_WEBDAV_MSG + "Files", // STR_FILES + "Editor", // STR_EDITOR + "Save", // STR_SAVE + "Cannot edit files bigger than", // STR_MAX_EDIT_FILE_SIZE_MSG + "Delete Selected Line", // STR_DELETE_LINE + "Insert Below Selected Line", // STR_INSERT_LINE + "Modified", // STR_MODIFIED + "Failed to obtain an access token from", // STR_FAIL_GET_TOKEN_MSG + "Login Success. You may close the browser and return to the application", // STR_GET_TOKEN_SUCCESS_MSG + "See, edit, create, and delete all of your Google Drive files", // STR_PERM_DRIVE + "See, create, and delete its own configuration data in your Google Drive", // STR_PERM_DRIVE_APPDATA + "See, edit, create, and delete only the specific Google Drive files you use with this app", // STR_PERM_DRIVE_FILE + "View and manage metadata of files in your Google Drive", // STR_PERM_DRIVE_METADATA + "See information about your Google Drive files", // STR_PERM_DRIVE_METADATA_RO + "Google login failed", // STR_GOOGLE_LOGIN_FAIL_MSG + "Google login timed out", // STR_GOOGLE_LOGIN_TIMEOUT_MSG }; bool needs_extended_font = false; diff --git a/source/lang.h b/source/lang.h index dc8e5bc..903e5cd 100644 --- a/source/lang.h +++ b/source/lang.h @@ -126,7 +126,16 @@ FUNC(STR_MAX_EDIT_FILE_SIZE_MSG) \ FUNC(STR_DELETE_LINE) \ FUNC(STR_INSERT_LINE) \ - FUNC(STR_MODIFIED) + FUNC(STR_MODIFIED) \ + FUNC(STR_FAIL_GET_TOKEN_MSG) \ + FUNC(STR_GET_TOKEN_SUCCESS_MSG) \ + FUNC(STR_PERM_DRIVE) \ + FUNC(STR_PERM_DRIVE_APPDATA) \ + FUNC(STR_PERM_DRIVE_FILE) \ + FUNC(STR_PERM_DRIVE_METADATA) \ + FUNC(STR_PERM_DRIVE_METADATA_RO) \ + FUNC(STR_GOOGLE_LOGIN_FAIL_MSG) \ + FUNC(STR_GOOGLE_LOGIN_TIMEOUT_MSG) #define GET_VALUE(x) x, #define GET_STRING(x) #x, @@ -136,7 +145,7 @@ enum FOREACH_STR(GET_VALUE) }; -#define LANG_STRINGS_NUM 123 +#define LANG_STRINGS_NUM 132 #define LANG_ID_SIZE 64 #define LANG_STR_SIZE 384 extern char lang_identifiers[LANG_STRINGS_NUM][LANG_ID_SIZE]; diff --git a/source/main.cpp b/source/main.cpp index 2605445..8e80b32 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -17,12 +17,14 @@ #include "SDL2/SDL.h" #include "imgui_impl_sdl.h" #include "imgui_impl_sdlrenderer.h" +#include "server/http_server.h" +#include "clients/gdrive.h" #include "config.h" #include "lang.h" #include "gui.h" #include "util.h" #include "installer.h" -#include "sys_modules.h" +#include "system.h" extern "C" { @@ -288,6 +290,7 @@ int main() return 0; CONFIG::LoadConfig(); + HttpServer::Start(); // Create a window context window = SDL_CreateWindow("main", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, FRAME_WIDTH, FRAME_HEIGHT, 0); @@ -316,6 +319,11 @@ int main() atexit(terminate); + OrbisTick tick; + sceRtcGetCurrentTick(&tick); + if (gg_account.token_expiry > (tick.mytick - 300000000)) + GDriveClient::StartRefreshToken(); + GUI::RenderLoop(renderer); SDL_DestroyRenderer(renderer); diff --git a/source/server/http_server.cpp b/source/server/http_server.cpp new file mode 100644 index 0000000..94c0a0d --- /dev/null +++ b/source/server/http_server.cpp @@ -0,0 +1,165 @@ +#include +#include +#include "http/httplib.h" +#include "server/http_server.h" +#include "clients/gdrive.h" +#include "config.h" +#include "windows.h" +#include "lang.h" +#include "system.h" +#include "dbglogger.h" + +#define SERVER_CERT_FILE "/app0/assets/certs/domain.crt" +#define SERVER_PRIVATE_KEY_FILE "/app0/assets/certs/domain.key" +#define SERVER_PRIVATE_KEY_PASSWORD "12345678" + +using namespace httplib; +SSLServer *svr; +int http_server_port = 8080; + +namespace HttpServer +{ + std::string dump_headers(const Headers &headers) + { + std::string s; + char buf[BUFSIZ]; + + for (auto it = headers.begin(); it != headers.end(); ++it) + { + const auto &x = *it; + snprintf(buf, sizeof(buf), "%s: %s\n", x.first.c_str(), x.second.c_str()); + s += buf; + } + + return s; + } + + std::string log(const Request &req, const Response &res) + { + std::string s; + char buf[BUFSIZ]; + + s += "================================\n"; + + snprintf(buf, sizeof(buf), "%s %s %s", req.method.c_str(), + req.version.c_str(), req.path.c_str()); + s += buf; + + std::string query; + for (auto it = req.params.begin(); it != req.params.end(); ++it) + { + const auto &x = *it; + snprintf(buf, sizeof(buf), "%c%s=%s", + (it == req.params.begin()) ? '?' : '&', x.first.c_str(), + x.second.c_str()); + query += buf; + } + snprintf(buf, sizeof(buf), "%s\n", query.c_str()); + s += buf; + + s += dump_headers(req.headers); + + s += "--------------------------------\n"; + + snprintf(buf, sizeof(buf), "%d %s\n", res.status, res.version.c_str()); + s += buf; + s += dump_headers(res.headers); + s += "\n"; + + if (!res.body.empty()) + { + s += res.body; + } + + s += "\n"; + + return s; + } + + void *ServerThread(void *argp) + { + svr->Get("/google_auth", [](const Request &req, Response &res) + { + sprintf(gg_account.auth_code, "%s", req.get_param_value("code").c_str()); + SSLClient client(GOOGLE_OAUTH_HOST); + client.enable_server_certificate_verification(false); + std::string url = std::string("/token?code=") + gg_account.auth_code + "&client_id=" + gg_account.client_id + "&client_secret=" + + gg_account.client_secret + "&redirect_uri=https%3A//localhost%3A8080/google_auth&grant_type=authorization_code"; + Result result = client.Post(url); + + if (result.error() == Error::Success && result.value().status == 200) + { + json_object *jobj = json_tokener_parse(result.value().body.c_str()); + enum json_type type; + json_object_object_foreach(jobj, key, val) + { + if (strcmp(key, "access_token")==0) + snprintf(gg_account.access_token, 255, "%s", json_object_get_string(val)); + else if (strcmp(key, "refresh_token")==0) + snprintf(gg_account.refresh_token, 63, "%s", json_object_get_string(val)); + else if (strcmp(key, "expires_in")==0) + { + OrbisTick tick; + sceRtcGetCurrentTick(&tick); + dbglogger_log("tick=%ld", tick.mytick); + gg_account.token_expiry = tick.mytick + (json_object_get_uint64(val)*1000000); + dbglogger_log("token_expiry=%ld", gg_account.token_expiry); + } + } + CONFIG::SaveGoolgeAccountInfo(); + login_state = 1; + res.set_content(lang_strings[STR_GET_TOKEN_SUCCESS_MSG], "text/plain"); + return; + } + login_state = -1; + std::string str = std::string(lang_strings[STR_FAIL_GET_TOKEN_MSG]) + " Google"; + res.set_content(str.c_str(), "text/plain"); + }); + + svr->Get("/stop", [&](const Request & /*req*/, Response & /*res*/) + { + svr->stop(); + }); + + svr->set_error_handler([](const Request & /*req*/, Response &res) + { + const char *fmt = "

Error Status: %d

"; + char buf[BUFSIZ]; + snprintf(buf, sizeof(buf), fmt, res.status); + res.set_content(buf, "text/html"); + }); + + /* + svr->set_logger([](const Request &req, const Response &res) + { + dbglogger_log("%s", log(req, res).c_str()); + }); + */ + + svr->listen("127.0.0.1", http_server_port); + + return NULL; + } + + void Start() + { + if (svr == nullptr) + svr = new SSLServer(SERVER_CERT_FILE, SERVER_PRIVATE_KEY_FILE, nullptr, nullptr, SERVER_PRIVATE_KEY_PASSWORD); + if (!svr->is_valid()) + { + dbglogger_log("Not valid"); + return; + } + int ret = pthread_create(&http_server_thid, NULL, ServerThread, NULL); + if (ret != 0) + { + dbglogger_log("Failed to start thread"); + } + } + + void Stop() + { + if (svr != nullptr) + svr->stop(); + } +} \ No newline at end of file diff --git a/source/server/http_server.h b/source/server/http_server.h new file mode 100644 index 0000000..faf77e8 --- /dev/null +++ b/source/server/http_server.h @@ -0,0 +1,19 @@ +#ifndef HTTP_SERVER_H +#define HTTP_SERVER_H + +#include "http/httplib.h" + +using namespace httplib; +extern SSLServer *svr; + +static pthread_t http_server_thid; +extern int http_server_port; + +namespace HttpServer +{ + void *ServerThread(void *argp); + void Start(); + void Stop(); +} + +#endif \ No newline at end of file diff --git a/source/sys_modules.cpp b/source/system.cpp similarity index 84% rename from source/sys_modules.cpp rename to source/system.cpp index 573a044..f6b56f2 100644 --- a/source/sys_modules.cpp +++ b/source/system.cpp @@ -2,13 +2,15 @@ #include #include -#include "sys_modules.h" +#include "system.h" int (*sceRtcGetTick)(const OrbisDateTime *inOrbisDateTime, OrbisTick *outTick); int (*sceRtcSetTick)(OrbisDateTime *outOrbisDateTime, const OrbisTick *inputTick); int (*sceRtcConvertLocalTimeToUtc)(const OrbisTick *local_time, OrbisTick *utc); int (*sceRtcConvertUtcToLocalTime)(const OrbisTick *utc, OrbisTick *local_time); int (*sceRtcGetCurrentClockLocalTime)(OrbisDateTime *time); +int (*sceRtcGetCurrentTick)(OrbisTick *outTick); +unsigned int (*sceRtcGetTickResolution)(); int (*sceShellUIUtilLaunchByUri)(const char *uri, SceShellUIUtilLaunchByUriParam *param); int (*sceShellUIUtilInitialize)(); @@ -68,6 +70,18 @@ int load_sys_modules() return -1; } + sceKernelDlsym(handle, "sceRtcGetCurrentTick", (void **)&sceRtcGetCurrentTick); + if (sceRtcGetCurrentTick == NULL) + { + return -1; + } + + sceKernelDlsym(handle, "sceRtcGetTickResolution", (void **)&sceRtcGetTickResolution); + if (sceRtcGetTickResolution == NULL) + { + return -1; + } + handle = sceKernelLoadStartModule("/system/common/lib/libSceShellUIUtil.sprx", 0, NULL, 0, 0, 0); if (handle == 0) { @@ -86,6 +100,7 @@ int load_sys_modules() return -1; } + if (sceShellUIUtilInitialize() < 0) return -1; return 0; } \ No newline at end of file diff --git a/source/sys_modules.h b/source/system.h similarity index 92% rename from source/sys_modules.h rename to source/system.h index 24d69eb..591a9e0 100644 --- a/source/sys_modules.h +++ b/source/system.h @@ -29,6 +29,8 @@ extern int (*sceRtcSetTick)(OrbisDateTime *outOrbisDateTime, const OrbisTick *in extern int (*sceRtcConvertLocalTimeToUtc)(const OrbisTick *local_time, OrbisTick *utc); extern int (*sceRtcConvertUtcToLocalTime)(const OrbisTick *utc, OrbisTick *local_time); extern int (*sceRtcGetCurrentClockLocalTime)(OrbisDateTime *time); +extern int (*sceRtcGetCurrentTick)(OrbisTick *outTick); +extern unsigned int (*sceRtcGetTickResolution)(); extern int (*sceShellUIUtilLaunchByUri)(const char *uri, SceShellUIUtilLaunchByUriParam *param); extern int (*sceShellUIUtilInitialize)(); diff --git a/source/windows.cpp b/source/windows.cpp index 2457236..ad8d0b5 100644 --- a/source/windows.cpp +++ b/source/windows.cpp @@ -13,6 +13,8 @@ #include "lang.h" #include "ime_dialog.h" #include "IconsFontAwesome6.h" +#include "server/http_server.h" +#include "clients/gdrive.h" extern "C" { @@ -1684,6 +1686,8 @@ namespace Windows break; case ACTION_DISCONNECT_AND_EXIT: Actions::Disconnect(); + HttpServer::Stop(); + GDriveClient::StopRefreshToken(); done = true; break; case ACTION_INSTALL_REMOTE_PKG: diff --git a/source/zip_util.cpp b/source/zip_util.cpp index 5cd26a5..205b4a2 100644 --- a/source/zip_util.cpp +++ b/source/zip_util.cpp @@ -12,7 +12,7 @@ #include "common.h" #include "fs.h" #include "lang.h" -#include "sys_modules.h" +#include "system.h" #include "windows.h" #include "zip_util.h"