diff options
author | aunsane <aunsane@gmail.com> | 2017-04-25 02:26:25 +0300 |
---|---|---|
committer | aunsane <aunsane@gmail.com> | 2017-04-25 02:27:36 +0300 |
commit | 71b5d463456a90d1d0ea58c7ace0aa5e8216eec8 (patch) | |
tree | 725ff7c747d994741a9f3c70938f93e19aeb53fd | |
parent | 26092086b62afd9bdef93f4756ae7558ec681e9a (diff) |
CloudFile: initial OneDrive implementation
-rw-r--r-- | plugins/CloudFile/CloudFile.vcxproj | 4 | ||||
-rw-r--r-- | plugins/CloudFile/res/onedrive.ico | bin | 0 -> 7886 bytes | |||
-rw-r--r-- | plugins/CloudFile/res/resource.rc | 2 | ||||
-rw-r--r-- | plugins/CloudFile/src/Services/google_api.h | 7 | ||||
-rw-r--r-- | plugins/CloudFile/src/Services/google_service.cpp | 2 | ||||
-rw-r--r-- | plugins/CloudFile/src/Services/microsoft_api.h | 138 | ||||
-rw-r--r-- | plugins/CloudFile/src/Services/microsoft_service.cpp | 262 | ||||
-rw-r--r-- | plugins/CloudFile/src/Services/microsoft_service.h | 31 | ||||
-rw-r--r-- | plugins/CloudFile/src/cloud_service.cpp | 1 | ||||
-rw-r--r-- | plugins/CloudFile/src/http_request.h | 30 | ||||
-rw-r--r-- | plugins/CloudFile/src/icons.cpp | 9 | ||||
-rw-r--r-- | plugins/CloudFile/src/resource.h | 7 | ||||
-rw-r--r-- | plugins/CloudFile/src/stdafx.h | 1 |
13 files changed, 464 insertions, 30 deletions
diff --git a/plugins/CloudFile/CloudFile.vcxproj b/plugins/CloudFile/CloudFile.vcxproj index c16966ec41..4349de9dcc 100644 --- a/plugins/CloudFile/CloudFile.vcxproj +++ b/plugins/CloudFile/CloudFile.vcxproj @@ -26,10 +26,6 @@ <Import Project="$(ProjectDir)..\..\build\vc.common\plugin.props" /> </ImportGroup> <ItemGroup> - <ClInclude Include="src\Dropbox\*.h" /> - <ClCompile Include="src\Dropbox\*.cpp"> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - </ClCompile> <ClInclude Include="src\Services\*.h" /> <ClCompile Include="src\Services\*.cpp"> <PrecompiledHeader>NotUsing</PrecompiledHeader> diff --git a/plugins/CloudFile/res/onedrive.ico b/plugins/CloudFile/res/onedrive.ico Binary files differnew file mode 100644 index 0000000000..502cee9bb7 --- /dev/null +++ b/plugins/CloudFile/res/onedrive.ico diff --git a/plugins/CloudFile/res/resource.rc b/plugins/CloudFile/res/resource.rc index 13f09b8340..3e7b688e25 100644 --- a/plugins/CloudFile/res/resource.rc +++ b/plugins/CloudFile/res/resource.rc @@ -68,6 +68,8 @@ IDI_DROPBOX ICON "dropbox.ico" IDI_GDRIVE ICON "gdrive.ico" +IDI_ONEDRIVE ICON "onedrive.ico" + IDI_YADISK ICON "yadisk.ico" diff --git a/plugins/CloudFile/src/Services/google_api.h b/plugins/CloudFile/src/Services/google_api.h index cf405dda36..50d12fc5d3 100644 --- a/plugins/CloudFile/src/Services/google_api.h +++ b/plugins/CloudFile/src/Services/google_api.h @@ -57,9 +57,9 @@ namespace GDriveAPI StartUploadFileRequest(const char *token, const char *name) : HttpRequest(REQUEST_POST, GDRIVE_UPLOAD) { - AddUrlParameter("access_token=%s", token); AddUrlParameter("uploadType=resumable"); + AddBearerAuthHeader(token); AddHeader("Content-Type", "application/json"); JSONNode params(JSON_NODE); @@ -91,7 +91,7 @@ namespace GDriveAPI CreateFolderRequest(const char *token, const char *path) : HttpRequest(REQUEST_PUT, GDRIVE_API) { - AddUrlParameter("access_token=%s", token); + AddBearerAuthHeader(token); AddHeader("Content-Type", "application/json"); JSONNode params(JSON_NODE); @@ -110,8 +110,7 @@ namespace GDriveAPI GrantPermissionsRequest(const char *token, const char *fileId) : HttpRequest(REQUEST_POST, FORMAT, GDRIVE_API "/%s/permissions", fileId) { - AddUrlParameter("access_token=%s", token); - + AddBearerAuthHeader(token); AddHeader("Content-Type", "application/json"); JSONNode params(JSON_NODE); diff --git a/plugins/CloudFile/src/Services/google_service.cpp b/plugins/CloudFile/src/Services/google_service.cpp index 3c88ffd366..f7ab294135 100644 --- a/plugins/CloudFile/src/Services/google_service.cpp +++ b/plugins/CloudFile/src/Services/google_service.cpp @@ -140,7 +140,7 @@ void CGDriveService::StartUploadFile(char *uploadUri, const char *name) { ptrA token(db_get_sa(NULL, GetModule(), "TokenSecret")); GDriveAPI::StartUploadFileRequest request(token, name); - NETLIBHTTPREQUEST* response = request.Send(hConnection); + NLHR_PTR response(request.Send(hConnection)); if (response == NULL) throw Exception(HttpStatusToError()); diff --git a/plugins/CloudFile/src/Services/microsoft_api.h b/plugins/CloudFile/src/Services/microsoft_api.h new file mode 100644 index 0000000000..b7f6ebd073 --- /dev/null +++ b/plugins/CloudFile/src/Services/microsoft_api.h @@ -0,0 +1,138 @@ +#ifndef _ONEDRIVESERVICE_API_H_ +#define _ONEDRIVESERVICE_API_H_ + +namespace OneDriveAPI +{ +#define MS_OAUTH "https://login.microsoftonline.com/common/oauth2/v2.0" +#define ONEDRIVE_API "https://graph.microsoft.com/v1.0/drive" + +#define MS_APP_ID "72b87ac7-42eb-4a97-a620-91a7f8d8b5ae" + + class GetAccessTokenRequest : public HttpRequest + { + public: + GetAccessTokenRequest(const char *code) : + HttpRequest(REQUEST_POST, MS_OAUTH "/token") + { + AddHeader("Content-Type", "application/x-www-form-urlencoded"); + + CMStringA data = "redirect_uri=https%3A%2F%2Flogin.microsoftonline.com%2Fcommon%2Foauth2%2Fnativeclient"; + data.AppendFormat("&client_id=%s&grant_type=authorization_code&code=%s", MS_APP_ID, code); + SetData(data.GetBuffer(), data.GetLength()); + } + }; + + class RefreshTokenRequest : public HttpRequest + { + public: + RefreshTokenRequest(const char *refreshToken) : + HttpRequest(REQUEST_POST, MS_OAUTH "/token") + { + AddHeader("Content-Type", "application/x-www-form-urlencoded"); + + CMStringA data(CMStringDataFormat::FORMAT, + "client_id=%s&client_secret=%s&grant_type=refresh_token&refresh_token=%s", + MS_APP_ID, MS_CLIENT_SECRET, refreshToken); + SetData(data.GetBuffer(), data.GetLength()); + } + }; + + /*class RevokeAccessTokenRequest : public HttpRequest + { + public: + RevokeAccessTokenRequest(const char *token) : + HttpRequest(REQUEST_POST, MS_OAUTH "/logout") + { + AddUrlParameter("token=%s", token); + } + };*/ + + class CreateUploadSessionRequest : public HttpRequest + { + public: + CreateUploadSessionRequest(const char *token, const char *name) : + HttpRequest(REQUEST_POST, FORMAT, ONEDRIVE_API "/root:/%s:/createUploadSession", name) + { + AddBearerAuthHeader(token); + AddHeader("Content-Type", "application/json"); + + JSONNode params(JSON_NODE); + params + << JSONNode("@microsoft.graph.conflictBehavior", "rename") + << JSONNode("name", name); + + json_string data = params.write(); + SetData(data.c_str(), data.length()); + } + + CreateUploadSessionRequest(const char *token, const char *parentId, const char *name) : + HttpRequest(REQUEST_POST, FORMAT, ONEDRIVE_API "/items/%s:/%s:/createUploadSession", parentId, name) + { + AddBearerAuthHeader(token); + AddHeader("Content-Type", "application/json"); + + JSONNode params(JSON_NODE); + params + << JSONNode("@microsoft.graph.conflictBehavior", "rename") + << JSONNode("name", name); + + json_string data = params.write(); + SetData(data.c_str(), data.length()); + } + }; + + class UploadFileChunkRequest : public HttpRequest + { + public: + UploadFileChunkRequest(const char *uploadUri, const char *chunk, size_t chunkSize, uint64_t offset, uint64_t fileSize) : + HttpRequest(REQUEST_PUT, uploadUri) + { + uint64_t rangeMin = offset; + uint64_t rangeMax = offset + chunkSize - 1; + CMStringA range(CMStringDataFormat::FORMAT, "bytes %I64u-%I64u/%I64u", rangeMin, rangeMax, fileSize); + AddHeader("Content-Range", range); + + SetData(chunk, chunkSize); + } + }; + + class CreateFolderRequest : public HttpRequest + { + public: + CreateFolderRequest(const char *token, const char *path) : + HttpRequest(REQUEST_PUT, ONEDRIVE_API "/items/root/children") + { + AddBearerAuthHeader(token); + AddHeader("Content-Type", "application/json"); + + JSONNode params(JSON_NODE); + params + << JSONNode("name", path) + << JSONNode("folder", ""); + + json_string data = params.write(); + SetData(data.c_str(), data.length()); + } + }; + + class CreateSharedLinkRequest : public HttpRequest + { + public: + CreateSharedLinkRequest(const char *token, const char *path) : + HttpRequest(REQUEST_POST, FORMAT, ONEDRIVE_API "/items/%s/createLink", path) + { + AddBearerAuthHeader(token); + AddHeader("Content-Type", "application/json"); + + JSONNode params(JSON_NODE); + params + << JSONNode("type", "view") + << JSONNode("scope", "anonymous"); + + json_string data = params.write(); + SetData(data.c_str(), data.length()); + } + }; +}; + +#endif //_ONEDRIVESERVICE_API_H_ diff --git a/plugins/CloudFile/src/Services/microsoft_service.cpp b/plugins/CloudFile/src/Services/microsoft_service.cpp new file mode 100644 index 0000000000..d002db45e6 --- /dev/null +++ b/plugins/CloudFile/src/Services/microsoft_service.cpp @@ -0,0 +1,262 @@ +#include "..\stdafx.h" +#include "microsoft_api.h" + +COneDriveService::COneDriveService(HNETLIBUSER hConnection) + : CCloudService(hConnection) +{ +} + +const char* COneDriveService::GetModule() const +{ + return "Microsoft"; +} + +const wchar_t* COneDriveService::GetText() const +{ + return L"OneDrive"; +} + +HANDLE COneDriveService::GetIcon() const +{ + return GetIconHandle(IDI_ONEDRIVE); +} + +bool COneDriveService::IsLoggedIn() +{ + ptrA token(db_get_sa(NULL, GetModule(), "TokenSecret")); + if (!token || token[0] == 0) + return false; + time_t now = time(NULL); + time_t expiresIn = db_get_dw(NULL, GetModule(), "ExpiresIn"); + return now < expiresIn; +} + +void COneDriveService::Login() +{ + ptrA token(db_get_sa(NULL, GetModule(), "TokenSecret")); + ptrA refreshToken(db_get_sa(NULL, GetModule(), "RefreshToken")); + if (token && refreshToken && refreshToken[0]) { + OneDriveAPI::RefreshTokenRequest request(refreshToken); + NLHR_PTR response(request.Send(hConnection)); + + JSONNode root = GetJsonResponse(response); + + JSONNode node = root.at("access_token"); + db_set_s(NULL, GetModule(), "TokenSecret", node.as_string().c_str()); + + node = root.at("expires_in"); + time_t expiresIn = time(NULL) + node.as_int(); + db_set_dw(NULL, GetModule(), "ExpiresIn", expiresIn); + + return; + } + + COAuthDlg dlg(this, MS_OAUTH "/authorize?response_type=code&scope=offline_access%20https%3A%2F%2Fgraph.microsoft.com%2Ffiles.readWrite&redirect_uri=https%3A%2F%2Flogin.microsoftonline.com%2Fcommon%2Foauth2%2Fnativeclient&client_id=" MS_APP_ID, RequestAccessTokenThread); + dlg.DoModal(); +} + +void COneDriveService::Logout() +{ + mir_forkthreadex(RevokeAccessTokenThread, this); +} + +unsigned COneDriveService::RequestAccessTokenThread(void *owner, void *param) +{ + HWND hwndDlg = (HWND)param; + COneDriveService *service = (COneDriveService*)owner; + + if (service->IsLoggedIn()) + service->Logout(); + + char requestToken[128]; + GetDlgItemTextA(hwndDlg, IDC_OAUTH_CODE, requestToken, _countof(requestToken)); + + OneDriveAPI::GetAccessTokenRequest request(requestToken); + NLHR_PTR response(request.Send(service->hConnection)); + + if (response == NULL || response->resultCode != HTTP_CODE_OK) { + const char *error = response->dataLength + ? response->pData + : service->HttpStatusToError(response->resultCode); + + Netlib_Logf(service->hConnection, "%s: %s", service->GetModule(), error); + ShowNotification(TranslateT("server does not respond"), MB_ICONERROR); + return 0; + } + + JSONNode root = JSONNode::parse(response->pData); + if (root.empty()) { + Netlib_Logf(service->hConnection, "%s: %s", service->GetModule(), service->HttpStatusToError(response->resultCode)); + ShowNotification(TranslateT("server does not respond"), MB_ICONERROR); + return 0; + } + + JSONNode node = root.at("error"); + if (!node.isnull()) { + ptrW error_description(mir_a2u_cp(node.as_string().c_str(), CP_UTF8)); + Netlib_Logf(service->hConnection, "%s: %s", service->GetModule(), service->HttpStatusToError(response->resultCode)); + ShowNotification((wchar_t*)error_description, MB_ICONERROR); + return 0; + } + + node = root.at("access_token"); + db_set_s(NULL, service->GetModule(), "TokenSecret", node.as_string().c_str()); + + node = root.at("expires_in"); + time_t expiresIn = time(NULL) + node.as_int(); + db_set_dw(NULL, service->GetModule(), "ExpiresIn", expiresIn); + + node = root.at("refresh_token"); + db_set_s(NULL, service->GetModule(), "RefreshToken", node.as_string().c_str()); + + SetDlgItemTextA(hwndDlg, IDC_OAUTH_CODE, ""); + + EndDialog(hwndDlg, 1); + + return 0; +} + +unsigned COneDriveService::RevokeAccessTokenThread(void *param) +{ + //COneDriveService *service = (COneDriveService*)param; + + /*ptrA token(db_get_sa(NULL, service->GetModule(), "TokenSecret")); + OneDriveAPI::RevokeAccessTokenRequest request(token); + NLHR_PTR response(request.Send(service->hConnection));*/ + + return 0; +} + +void COneDriveService::HandleJsonError(JSONNode &node) +{ + JSONNode error = node.at("error"); + if (!error.isnull()) { + json_string tag = error.at("message").as_string(); + throw Exception(tag.c_str()); + } +} + +void COneDriveService::CreateUploadSession(char *uploadUri, const char *name, const char *parentId) +{ + ptrA token(db_get_sa(NULL, GetModule(), "TokenSecret")); + OneDriveAPI::CreateUploadSessionRequest request = mir_strlen(parentId) + ? OneDriveAPI::CreateUploadSessionRequest(token, parentId, name) + : OneDriveAPI::CreateUploadSessionRequest(token, name); + NLHR_PTR response(request.Send(hConnection)); + + JSONNode root = GetJsonResponse(response); + JSONNode node = root.at("uploadUrl"); + mir_strcpy(uploadUri, node.as_string().c_str()); +} + +void COneDriveService::UploadFileChunk(const char *uploadUri, const char *chunk, size_t chunkSize, uint64_t offset, uint64_t fileSize, char *itemId) +{ + OneDriveAPI::UploadFileChunkRequest request(uploadUri, chunk, chunkSize, offset, fileSize); + NLHR_PTR response(request.Send(hConnection)); + + if (response == NULL) + throw Exception(HttpStatusToError()); + + if (response->resultCode == HTTP_CODE_ACCEPTED) + return; + + if (HTTP_CODE_SUCCESS(response->resultCode)) { + JSONNode root = GetJsonResponse(response); + JSONNode id = root.at("id"); + mir_strcpy(itemId, id.as_string().c_str()); + return; + } + + if (response->dataLength) + throw Exception(response->pData); + throw Exception(HttpStatusToError(response->resultCode)); +} + +void COneDriveService::CreateFolder(const char *path, char *itemId) +{ + ptrA token(db_get_sa(NULL, GetModule(), "TokenSecret")); + OneDriveAPI::CreateFolderRequest request(token, path); + NLHR_PTR response(request.Send(hConnection)); + + JSONNode root = GetJsonResponse(response); + JSONNode node = root.at("id"); + mir_strcpy(itemId, node.as_string().c_str()); +} + +void COneDriveService::CreateSharedLink(const char *itemId, char *url) +{ + ptrA token(db_get_sa(NULL, GetModule(), "TokenSecret")); + OneDriveAPI::CreateSharedLinkRequest request(token, itemId); + NLHR_PTR response(request.Send(hConnection)); + + JSONNode root = GetJsonResponse(response); + JSONNode node = root.at("webUrl"); + mir_strcpy(url, node.as_string().c_str()); +} + +UINT COneDriveService::Upload(FileTransferParam *ftp) +{ + try { + if (!IsLoggedIn()) + Login(); + + if (!IsLoggedIn()) { + ftp->SetStatus(ACKRESULT_FAILED); + return ACKRESULT_FAILED; + } + + char folderId[32] = { 0 }; + const wchar_t *folderName = ftp->GetFolderName(); + if (folderName) { + char path[MAX_PATH], link[MAX_PATH]; + PreparePath(folderName, path); + CreateFolder(path, folderId); + CreateSharedLink(path, link); + ftp->AppendFormatData(L"%s\r\n", ptrW(mir_utf8decodeW(link))); + } + + ftp->FirstFile(); + do + { + const wchar_t *fileName = ftp->GetCurrentRelativeFilePath(); + uint64_t fileSize = ftp->GetCurrentFileSize(); + + uint64_t offset = 0; + char fileId[32]; + char uploadUri[1024]; + CreateUploadSession(uploadUri, T2Utf(fileName), folderId); + + size_t chunkSize = ftp->GetCurrentFileChunkSize(); + mir_ptr<char>chunk((char*)mir_calloc(chunkSize)); + + size_t size = 0; + for (size_t i = 0; i < (fileSize / chunkSize); i++) + { + ftp->CheckCurrentFile(); + + size = ftp->ReadCurrentFile(chunk, chunkSize); + if (size == 0) + break; + + UploadFileChunk(uploadUri, chunk, size, offset, fileSize, fileId); + + offset += size; + ftp->Progress(size); + } + + if (!wcschr(fileName, L'\\')) { + char url[MAX_PATH]; + CreateSharedLink(fileId, url); + ftp->AppendFormatData(L"%s\r\n", ptrW(mir_utf8decodeW(url))); + } + } while (ftp->NextFile()); + } + catch (Exception &ex) { + Netlib_Logf(hConnection, "%s: %s", MODULE, ex.what()); + ftp->SetStatus(ACKRESULT_FAILED); + return ACKRESULT_FAILED; + } + + ftp->SetStatus(ACKRESULT_SUCCESS); + return ACKRESULT_SUCCESS; +} diff --git a/plugins/CloudFile/src/Services/microsoft_service.h b/plugins/CloudFile/src/Services/microsoft_service.h new file mode 100644 index 0000000000..bf689ee8c2 --- /dev/null +++ b/plugins/CloudFile/src/Services/microsoft_service.h @@ -0,0 +1,31 @@ +#ifndef _CLOUDFILE_ONEDRIVE_H_ +#define _CLOUDFILE_ONEDRIVE_H_ + +class COneDriveService : public CCloudService +{ +private: + static unsigned RequestAccessTokenThread(void *owner, void *param); + static unsigned __stdcall RevokeAccessTokenThread(void *param); + + void HandleJsonError(JSONNode &node); + + void CreateUploadSession(char *uploadUri, const char *name, const char *parentId = NULL); + void UploadFileChunk(const char *uploadUri, const char *chunk, size_t chunkSize, uint64_t offset, uint64_t fileSize, char *itemId); + void CreateFolder(const char *path, char *itemId); + void CreateSharedLink(const char *itemId, char *url); + +public: + COneDriveService(HNETLIBUSER hConnection); + + const char* GetModule() const; + const wchar_t* GetText() const; + HANDLE GetIcon() const; + + bool IsLoggedIn(); + void Login(); + void Logout(); + + UINT Upload(FileTransferParam *ftp); +}; + +#endif //_CLOUDFILE_ONEDRIVE_H_
\ No newline at end of file diff --git a/plugins/CloudFile/src/cloud_service.cpp b/plugins/CloudFile/src/cloud_service.cpp index a14af9b821..ee2bebe4d4 100644 --- a/plugins/CloudFile/src/cloud_service.cpp +++ b/plugins/CloudFile/src/cloud_service.cpp @@ -11,6 +11,7 @@ void InitServices() { Services.insert(new CDropboxService(hNetlibConnection)); Services.insert(new CGDriveService(hNetlibConnection)); + //Services.insert(new COneDriveService(hNetlibConnection)); Services.insert(new CYandexService(hNetlibConnection)); PROTOCOLDESCRIPTOR pd = { sizeof(pd) }; diff --git a/plugins/CloudFile/src/http_request.h b/plugins/CloudFile/src/http_request.h index 1308ae2291..39d0d98b57 100644 --- a/plugins/CloudFile/src/http_request.h +++ b/plugins/CloudFile/src/http_request.h @@ -51,58 +51,60 @@ protected: void AddBasicAuthHeader(LPCSTR szLogin, LPCSTR szPassword) { - char cPair[128]; + size_t length = mir_strlen(szLogin) + mir_strlen(szPassword) + 1; + ptrA cPair((char*)mir_calloc(length + 1)); mir_snprintf( cPair, - _countof(cPair), + length, "%s:%s", szLogin, szPassword); - char *ePair = (char *)mir_base64_encode((BYTE*)cPair, (UINT)mir_strlen(cPair)); + ptrA ePair(mir_base64_encode((BYTE*)(char*)cPair, length)); - char value[128]; + length = mir_strlen(ePair) + 7; + char *value = (char*)mir_calloc(length + 1); mir_snprintf( value, - _countof(value), + length, "Basic %s", ePair); - mir_free(ePair); - headers = (NETLIBHTTPHEADER*)mir_realloc(headers, sizeof(NETLIBHTTPHEADER)*(headersCount + 1)); headers[headersCount].szName = mir_strdup("Authorization"); - headers[headersCount].szValue = mir_strdup(value); + headers[headersCount].szValue = value; headersCount++; } void AddBearerAuthHeader(LPCSTR szValue) { - char value[128]; + size_t length = mir_strlen(szValue) + 8; + char *value = (char*)mir_calloc(length + 1); mir_snprintf( value, - _countof(value), + length, "Bearer %s", szValue); headers = (NETLIBHTTPHEADER*)mir_realloc(headers, sizeof(NETLIBHTTPHEADER)*(headersCount + 1)); headers[headersCount].szName = mir_strdup("Authorization"); - headers[headersCount].szValue = mir_strdup(value); + headers[headersCount].szValue = value; headersCount++; } void AddOAuthHeader(LPCSTR szValue) { - char value[128]; + size_t length = mir_strlen(szValue) + 7; + char *value = (char*)mir_calloc(length + 1); mir_snprintf( value, - _countof(value), + length, "OAuth %s", szValue); headers = (NETLIBHTTPHEADER*)mir_realloc(headers, sizeof(NETLIBHTTPHEADER)*(headersCount + 1)); headers[headersCount].szName = mir_strdup("Authorization"); - headers[headersCount].szValue = mir_strdup(value); + headers[headersCount].szValue = value; headersCount++; } diff --git a/plugins/CloudFile/src/icons.cpp b/plugins/CloudFile/src/icons.cpp index 75671f18ae..da7efb957d 100644 --- a/plugins/CloudFile/src/icons.cpp +++ b/plugins/CloudFile/src/icons.cpp @@ -2,10 +2,11 @@ static IconItem iconList[] = { - { LPGEN("Upload file(s)"), "upload", IDI_UPLOAD }, - { LPGEN("Dropbox"), "dropbox", IDI_DROPBOX }, - { LPGEN("GDrive"), "gdrive", IDI_GDRIVE }, - { LPGEN("YaDisk"), "yadisk", IDI_YADISK } + { LPGEN("Upload file(s)"), "upload", IDI_UPLOAD }, + { LPGEN("Dropbox"), "dropbox", IDI_DROPBOX }, + { LPGEN("GDrive"), "gdrive", IDI_GDRIVE }, + { LPGEN("OneDrive"), "onedrive", IDI_ONEDRIVE }, + { LPGEN("YaDisk"), "yadisk", IDI_YADISK } }; void InitializeIcons() diff --git a/plugins/CloudFile/src/resource.h b/plugins/CloudFile/src/resource.h index 755d176034..db382f9fb1 100644 --- a/plugins/CloudFile/src/resource.h +++ b/plugins/CloudFile/src/resource.h @@ -1,13 +1,14 @@ //{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. -// Used by C:\Users\unsane\Projects\c++\miranda-ng\plugins\CloudFile\res\resource.rc +// Used by c:\Users\unsane\Projects\c++\miranda-ng\plugins\CloudFile\res\resource.rc // #define IDOK 1 #define IDCANCEL 2 #define IDI_UPLOAD 101 #define IDI_DROPBOX 102 #define IDI_GDRIVE 103 -#define IDI_YADISK 104 +#define IDI_ONEDRIVE 104 +#define IDI_YADISK 105 #define IDD_OAUTH 120 #define IDC_OAUTH_CODE 121 #define IDC_OAUTH_AUTHORIZE 122 @@ -21,7 +22,7 @@ // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 110 +#define _APS_NEXT_RESOURCE_VALUE 130 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1013 #define _APS_NEXT_SYMED_VALUE 101 diff --git a/plugins/CloudFile/src/stdafx.h b/plugins/CloudFile/src/stdafx.h index 4cbb6eace4..e5cc3db535 100644 --- a/plugins/CloudFile/src/stdafx.h +++ b/plugins/CloudFile/src/stdafx.h @@ -66,6 +66,7 @@ public: #include "oauth.h" #include "Services\dropbox_service.h" #include "Services\google_service.h" +#include "Services\microsoft_service.h" #include "Services\yandex_service.h" extern LIST<CCloudService> Services; void InitServices(); |