From 5357bfc0d1ca654ae51f71ca67a8faad0d5b5264 Mon Sep 17 00:00:00 2001 From: Alexander Lantsev Date: Thu, 3 Mar 2016 13:50:49 +0000 Subject: Dropbox: new service pt. 1 git-svn-id: http://svn.miranda-ng.org/main/trunk@16403 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/Dropbox/src/api/account.h | 4 +- plugins/Dropbox/src/api/operations.h | 2 +- plugins/Dropbox/src/dropbox.cpp | 9 ++-- plugins/Dropbox/src/dropbox.h | 13 +++-- plugins/Dropbox/src/dropbox_options.cpp | 1 - plugins/Dropbox/src/dropbox_services.cpp | 74 ++++++++++++++++++---------- plugins/Dropbox/src/dropbox_transfers.cpp | 81 +++++++++++++++++++------------ plugins/Dropbox/src/file_transfer.h | 74 ++++++++++++++++++++++------ plugins/Dropbox/src/stdafx.cxx | 4 +- plugins/Dropbox/src/stdafx.h | 3 +- plugins/ExternalAPI/m_dropbox.h | 35 +++++++++++++ 11 files changed, 216 insertions(+), 84 deletions(-) diff --git a/plugins/Dropbox/src/api/account.h b/plugins/Dropbox/src/api/account.h index 2842804dcc..98ba370abe 100644 --- a/plugins/Dropbox/src/api/account.h +++ b/plugins/Dropbox/src/api/account.h @@ -16,14 +16,14 @@ public: } }; -/*class DisableAccessTokenRequest : public HttpRequest +class DisableAccessTokenRequest : public HttpRequest { public: DisableAccessTokenRequest() : HttpRequest(REQUEST_POST, DROPBOX_API_OLD "/disable_access_token") { } -};*/ +}; class GetCurrentAccountRequest : public HttpRequest { diff --git a/plugins/Dropbox/src/api/operations.h b/plugins/Dropbox/src/api/operations.h index cdd35223e4..01f428c88a 100644 --- a/plugins/Dropbox/src/api/operations.h +++ b/plugins/Dropbox/src/api/operations.h @@ -102,7 +102,7 @@ public: AddHeader("Content-Type", "application/json"); JSONNode root(JSON_NODE); - root << JSONNode("path", ""); + root << JSONNode("path", path); json_string data = root.write(); SetData(data.c_str(), data.length()); diff --git a/plugins/Dropbox/src/dropbox.cpp b/plugins/Dropbox/src/dropbox.cpp index 732c8b8eb7..a794e3bb17 100644 --- a/plugins/Dropbox/src/dropbox.cpp +++ b/plugins/Dropbox/src/dropbox.cpp @@ -7,8 +7,11 @@ CDropbox::CDropbox() : transfers(1, HandleKeySortT) HookEventObj(ME_SYSTEM_MODULESLOADED, GlobalEvent<&CDropbox::OnModulesLoaded>, this); hFileSentEventHook = CreateHookableEvent(ME_DROPBOX_SENT); + hUploadedEventHook = CreateHookableEvent(ME_DROPBOX_UPLOADED); CreateServiceFunctionObj(MS_DROPBOX_SEND_FILE, GlobalService<&CDropbox::SendFileToDropbox>, this); + CreateServiceFunctionObj(MS_DROPBOX_UPLOAD, GlobalService<&CDropbox::UploadToDropbox>, this); + CreateServiceFunctionObj(MS_DROPBOX_UPLOADASYNC, GlobalService<&CDropbox::UploadToDropboxAsync>, this); PROTOCOLDESCRIPTOR pd = { 0 }; pd.cbSize = sizeof(pd); @@ -33,7 +36,7 @@ CDropbox::CDropbox() : transfers(1, HandleKeySortT) InitializeMenus(); - hFileProcess = hMessageProcess = 1; + hMessageProcess = 1; } CDropbox::~CDropbox() @@ -134,8 +137,8 @@ void CDropbox::RequestAccountInfo(void *p) void CDropbox::DestroyAccessToken() { - //DisableAccessTokenRequest request; - //NLHR_PTR response(request.Send(hNetlibConnection)); + DisableAccessTokenRequest request; + NLHR_PTR response(request.Send(hNetlibConnection)); db_unset(NULL, MODULE, "TokenSecret"); MCONTACT hContact = CDropbox::GetDefaultContact(); diff --git a/plugins/Dropbox/src/dropbox.h b/plugins/Dropbox/src/dropbox.h index 10c40041da..4ea16c4b67 100644 --- a/plugins/Dropbox/src/dropbox.h +++ b/plugins/Dropbox/src/dropbox.h @@ -27,10 +27,10 @@ public: private: HANDLE hNetlibConnection; - ULONG hFileProcess; ULONG hMessageProcess; HANDLE hFileSentEventHook; + HANDLE hUploadedEventHook; MCONTACT hDefaultContact; MCONTACT hTransferContact; @@ -66,6 +66,9 @@ private: INT_PTR SendFileToDropbox(WPARAM wParam, LPARAM lParam); + INT_PTR UploadToDropbox(WPARAM wParam, LPARAM lParam); + INT_PTR UploadToDropboxAsync(WPARAM wParam, LPARAM lParam); + // commands static void CommandHelp(void *arg); static void CommandList(void *arg); @@ -90,14 +93,16 @@ private: void AppendToUploadSession(const char *data, size_t size, const char *sessionId, size_t offset); char* FinishUploadSession(const char *data, size_t size, const char *sessionId, size_t offset, char *path); - void CreateFolder(const char *encodedPath); - void CreateDownloadUrl(const char *path, char *url); - static UINT SendFilesAsync(void *owner, void *arg); + static UINT UploadToDropbox(void *owner, void *arg); + static UINT SendFilesAndEventAsync(void *owner, void *arg); static UINT SendFilesAndReportAsync(void *owner, void *arg); + static UINT UploadAndRaiseEvent(void *owner, void *arg); + static UINT UploadAndReportProgress(void *owner, void *arg); + // contacts MCONTACT GetDefaultContact(); diff --git a/plugins/Dropbox/src/dropbox_options.cpp b/plugins/Dropbox/src/dropbox_options.cpp index b2c22cf153..417f5cf21b 100644 --- a/plugins/Dropbox/src/dropbox_options.cpp +++ b/plugins/Dropbox/src/dropbox_options.cpp @@ -117,7 +117,6 @@ void CDropboxOptionsInterception::OnApply() int count = m_accounts.GetItemCount(); for (int iItem = 0; iItem < count; iItem++) { - TCHAR proto[MAX_PATH]; PROTOACCOUNT *acc = (PROTOACCOUNT*)m_accounts.GetItemData(iItem); if (m_accounts.GetCheckState(iItem)) interceptedProtos.AppendFormat("%s\t", acc->szModuleName); diff --git a/plugins/Dropbox/src/dropbox_services.cpp b/plugins/Dropbox/src/dropbox_services.cpp index 71a4be729c..44a0cd5113 100644 --- a/plugins/Dropbox/src/dropbox_services.cpp +++ b/plugins/Dropbox/src/dropbox_services.cpp @@ -43,10 +43,7 @@ INT_PTR CDropbox::ProtoSendFile(WPARAM, LPARAM lParam) return 0; } - FileTransferParam *ftp = new FileTransferParam(); - ftp->pfts.flags |= PFTS_SENDING; - ftp->pfts.hContact = pccsd->hContact; - ftp->hContact = (hTransferContact) ? hTransferContact : pccsd->hContact; + FileTransferParam *ftp = new FileTransferParam(pccsd->hContact); hTransferContact = 0; const TCHAR *description = (TCHAR*)pccsd->wParam; @@ -61,13 +58,11 @@ INT_PTR CDropbox::ProtoSendFile(WPARAM, LPARAM lParam) ftp->AddFile(paths[i]); } - ULONG fileId = InterlockedIncrement(&hFileProcess); - ftp->hProcess = (HANDLE)fileId; transfers.insert(ftp); - mir_forkthreadowner(CDropbox::SendFilesAndReportAsync, this, ftp, 0); + mir_forkthreadowner(CDropbox::UploadAndReportProgress, this, ftp, 0); - return fileId; + return ftp->GetId(); } INT_PTR CDropbox::ProtoSendFileInterceptor(WPARAM wParam, LPARAM lParam) @@ -93,7 +88,7 @@ INT_PTR CDropbox::ProtoCancelFile(WPARAM, LPARAM lParam) if (ftp == NULL) return 0; - ftp->isTerminated = true; + ftp->Terminate(); return 0; } @@ -111,7 +106,6 @@ INT_PTR CDropbox::ProtoSendMessage(WPARAM, LPARAM lParam) if (*szMessage == '/') { // parse commands char *sep = strchr(szMessage, ' '); - //if (sep != NULL) *sep = 0; struct { @@ -181,25 +175,53 @@ INT_PTR CDropbox::SendFileToDropbox(WPARAM hContact, LPARAM lParam) TCHAR *filePath = (TCHAR*)lParam; - FileTransferParam *ftp = new FileTransferParam(); - ftp->pfts.hContact = hContact; - ftp->pfts.totalFiles = 1; - ftp->hContact = (hTransferContact) ? hTransferContact : hContact; - hTransferContact = 0; + FileTransferParam *ftp = new FileTransferParam(hContact); + ftp->SetWorkingDirectory(filePath); + ftp->AddFile(filePath); + + mir_forkthreadowner(CDropbox::SendFilesAndEventAsync, this, 0, 0); - int length = _tcsrchr(filePath, '\\') - filePath; - ftp->pfts.tszWorkingDir = (TCHAR*)mir_alloc(sizeof(TCHAR) * (length + 1)); - mir_tstrncpy(ftp->pfts.tszWorkingDir, filePath, length + 1); - ftp->pfts.tszWorkingDir[length] = '\0'; + return ftp->GetId(); +} - ftp->pfts.ptszFiles = (TCHAR**)mir_alloc(sizeof(TCHAR*) * (ftp->pfts.totalFiles + 1)); - ftp->pfts.ptszFiles[0] = mir_wstrdup(filePath); - ftp->pfts.ptszFiles[ftp->pfts.totalFiles] = NULL; +INT_PTR CDropbox::UploadToDropbox(WPARAM, LPARAM lParam) +{ + DropboxUploadInfo *uploadInfo = (DropboxUploadInfo*)lParam; - ULONG fileId = InterlockedIncrement(&hFileProcess); - ftp->hProcess = (HANDLE)fileId; + FileTransferParam *ftp = new FileTransferParam(GetDefaultContact()); - mir_forkthreadowner(CDropbox::SendFilesAndEventAsync, this, ftp, 0); + ftp->SetWorkingDirectory(uploadInfo->localPath); + ftp->SetServerPath(uploadInfo->serverPath); - return fileId; + if (PathIsDirectory(uploadInfo->localPath)) + { + // temporary unsupported + return NULL; + } + else + ftp->AddFile(uploadInfo->localPath); + + return CDropbox::UploadAndRaiseEvent(this, ftp); } + +INT_PTR CDropbox::UploadToDropboxAsync(WPARAM, LPARAM lParam) +{ + DropboxUploadInfo *uploadInfo = (DropboxUploadInfo*)lParam; + + FileTransferParam *ftp = new FileTransferParam(GetDefaultContact()); + + ftp->SetWorkingDirectory(uploadInfo->localPath); + ftp->SetServerPath(uploadInfo->serverPath); + + if (PathIsDirectory(uploadInfo->localPath)) + { + // temporary unsupported + return NULL; + } + else + ftp->AddFile(uploadInfo->localPath); + + mir_forkthreadowner(CDropbox::UploadAndRaiseEvent, this, ftp, 0); + + return ftp->GetId(); +} \ No newline at end of file diff --git a/plugins/Dropbox/src/dropbox_transfers.cpp b/plugins/Dropbox/src/dropbox_transfers.cpp index 6956bcb3ab..6473a0bcc6 100644 --- a/plugins/Dropbox/src/dropbox_transfers.cpp +++ b/plugins/Dropbox/src/dropbox_transfers.cpp @@ -60,19 +60,6 @@ char* CDropbox::FinishUploadSession(const char *data, size_t size, const char *s return path; } -void CDropbox::CreateFolder(const char *path) -{ - ptrA token(db_get_sa(NULL, MODULE, "TokenSecret")); - CreateFolderRequest request(token, path); - NLHR_PTR response(request.Send(hNetlibConnection)); - - // forder exists on server - if (response->resultCode == HTTP_STATUS_FORBIDDEN) - return; - - HandleJsonResponseError(response); -} - void CDropbox::CreateDownloadUrl(const char *path, char *url) { ptrA token(db_get_sa(NULL, MODULE, "TokenSecret")); @@ -90,24 +77,16 @@ void CDropbox::CreateDownloadUrl(const char *path, char *url) mir_strcpy(url, node.as_string().c_str()); } -UINT CDropbox::SendFilesAsync(void *owner, void *arg) +UINT CDropbox::UploadToDropbox(void *owner, void *arg) { CDropbox *instance = (CDropbox*)owner; FileTransferParam *ftp = (FileTransferParam*)arg; try { - if (ftp->directoryName) { - char path[MAX_PATH], url[MAX_PATH]; - PreparePath(ftp->directoryName, path); - instance->CreateFolder(path); - instance->CreateDownloadUrl(path, url); - ftp->AppendFormatData(_T("%s\r\n"), ptrT(mir_utf8decodeT(url))); - } - ftp->FirstFile(); do { - const TCHAR *fileName = &ftp->GetCurrentFilePath()[ftp->relativePathStart]; + const TCHAR *fileName = ftp->GetCurrentRelativeFilePath(); uint64_t fileSize = ftp->GetCurrentFileSize(); int chunkSize = ftp->GetCurrentFileChunkSize(); @@ -138,7 +117,11 @@ UINT CDropbox::SendFilesAsync(void *owner, void *arg) size = 0; char path[MAX_PATH]; - PreparePath(fileName, path); + const TCHAR *serverPath = ftp->GetServerPath(); + if (serverPath) + PreparePath(serverPath, path); + else + PreparePath(fileName, path); instance->FinishUploadSession(data, size, sessionId, offset, path); ftp->Progress(size); @@ -165,9 +148,9 @@ UINT CDropbox::SendFilesAndReportAsync(void *owner, void *arg) CDropbox *instance = (CDropbox*)owner; FileTransferParam *ftp = (FileTransferParam*)arg; - int res = SendFilesAsync(owner, arg); + int res = UploadToDropbox(owner, arg); if (res == ACKRESULT_SUCCESS) - instance->Report(ftp->hContact, ftp->data); + instance->Report(ftp->GetHContact(), ftp->GetData()); instance->transfers.remove(ftp); delete ftp; @@ -180,14 +163,52 @@ UINT CDropbox::SendFilesAndEventAsync(void *owner, void *arg) CDropbox *instance = (CDropbox*)owner; FileTransferParam *ftp = (FileTransferParam*)arg; - int res = SendFilesAsync(owner, arg); + int res = UploadToDropbox(owner, arg); + + T2Utf data(ftp->GetData()); + char *pdata = data; TRANSFERINFO ti = { 0 }; - ti.hProcess = ftp->hProcess; + ti.hProcess = (HANDLE)ftp->GetId(); ti.status = res; - //ti.data = T2Utf(data); + ti.data = &pdata; + + NotifyEventHooks(instance->hFileSentEventHook, ftp->GetHContact(), (LPARAM)&ti); + + instance->transfers.remove(ftp); + delete ftp; + + return res; +} + +UINT CDropbox::UploadAndReportProgress(void *owner, void *arg) +{ + CDropbox *instance = (CDropbox*)owner; + FileTransferParam *ftp = (FileTransferParam*)arg; + + int res = UploadToDropbox(owner, arg); + if (res == ACKRESULT_SUCCESS) + instance->Report(ftp->GetHContact(), ftp->GetData()); + + instance->transfers.remove(ftp); + delete ftp; + + return res; +} + +UINT CDropbox::UploadAndRaiseEvent(void *owner, void *arg) +{ + CDropbox *instance = (CDropbox*)owner; + FileTransferParam *ftp = (FileTransferParam*)arg; + + int res = UploadToDropbox(owner, arg); + + DropboxUploadResult ur = { 0 }; + ur.hProcess = (HANDLE)ftp->GetId(); + ur.status = res; + ur.data = T2Utf(ftp->GetData()); - NotifyEventHooks(instance->hFileSentEventHook, ftp->hContact, (LPARAM)&ti); + NotifyEventHooks(instance->hUploadedEventHook, ftp->GetHContact(), (LPARAM)&ur); instance->transfers.remove(ftp); delete ftp; diff --git a/plugins/Dropbox/src/file_transfer.h b/plugins/Dropbox/src/file_transfer.h index ec81ded7b0..8e8a8af8c2 100644 --- a/plugins/Dropbox/src/file_transfer.h +++ b/plugins/Dropbox/src/file_transfer.h @@ -1,11 +1,13 @@ #ifndef _FILE_TRANSFER_H_ #define _FILE_TRANSFER_H_ -struct FileTransferParam +class FileTransferParam { +private: + static ULONG hFileProcess; + + ULONG id; FILE *hFile; - HANDLE hProcess; - MCONTACT hContact; PROTOFILETRANSFERSTATUS pfts; bool isTerminated; @@ -13,13 +15,15 @@ struct FileTransferParam const TCHAR* directoryName; int relativePathStart; + CMString serverPath; + CMString data; - FileTransferParam() +public: + FileTransferParam(MCONTACT hContact) { hFile = NULL; - hProcess = NULL; - hContact = NULL; + id = InterlockedIncrement(&hFileProcess); isTerminated = false; @@ -28,7 +32,7 @@ struct FileTransferParam pfts.cbSize = sizeof(this->pfts); pfts.flags = PFTS_TCHAR | PFTS_SENDING; - pfts.hContact = NULL; + pfts.hContact = hContact; pfts.currentFileNumber = -1; pfts.currentFileProgress = 0; pfts.currentFileSize = 0; @@ -41,7 +45,7 @@ struct FileTransferParam pfts.tszWorkingDir = NULL; pfts.tszCurrentFile = NULL; - ProtoBroadcastAck(MODULE, pfts.hContact, ACKTYPE_FILE, ACKRESULT_INITIALISING, hProcess, 0); + ProtoBroadcastAck(MODULE, pfts.hContact, ACKTYPE_FILE, ACKRESULT_INITIALISING, (HANDLE)id, 0); } ~FileTransferParam() @@ -61,10 +65,32 @@ struct FileTransferParam } } + ULONG GetId() const + { + return id; + } + + MCONTACT GetHContact() const + { + return pfts.hContact; + } + + const TCHAR* GetData() const + { + if (data.IsEmpty()) + return NULL; + return data; + } + + void Terminate() + { + isTerminated = true; + } + void SetWorkingDirectory(const TCHAR *path) { relativePathStart = _tcsrchr(path, '\\') - path + 1; - if (PathIsDirectory(path)) + /*if (PathIsDirectory(path)) { size_t length = mir_tstrlen(path) + 1; pfts.tszWorkingDir = (TCHAR*)mir_calloc(sizeof(TCHAR) * length); @@ -72,10 +98,23 @@ struct FileTransferParam directoryName = _tcsrchr(pfts.tszWorkingDir, '\\') + 1; } else - { + {*/ pfts.tszWorkingDir = (TCHAR*)mir_calloc(sizeof(TCHAR) * relativePathStart); mir_tstrncpy(pfts.tszWorkingDir, path, relativePathStart); - } + //} + } + + void SetServerPath(const TCHAR *path) + { + if (path) + serverPath = path; + } + + const TCHAR* GetServerPath() const + { + if (serverPath.IsEmpty()) + return NULL; + return serverPath; } void AddFile(const TCHAR *path) @@ -105,6 +144,11 @@ struct FileTransferParam return pfts.ptszFiles[pfts.currentFileNumber]; } + const TCHAR* GetCurrentRelativeFilePath() const + { + return &GetCurrentFilePath()[relativePathStart]; + } + const TCHAR* GetCurrentFileName() const { return _tcsrchr(pfts.ptszFiles[pfts.currentFileNumber], '\\') + 1; @@ -162,7 +206,7 @@ struct FileTransferParam { pfts.currentFileProgress += count; pfts.totalProgress += count; - ProtoBroadcastAck(MODULE, pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, hProcess, (LPARAM)&pfts); + ProtoBroadcastAck(MODULE, pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, (HANDLE)id, (LPARAM)&pfts); } void FirstFile() @@ -172,7 +216,7 @@ struct FileTransferParam pfts.currentFileNumber = 0; pfts.currentFileProgress = 0; pfts.tszCurrentFile = _tcsrchr(pfts.ptszFiles[pfts.currentFileNumber], '\\') + 1; - ProtoBroadcastAck(MODULE, pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, hProcess, (LPARAM)&pfts); + ProtoBroadcastAck(MODULE, pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, (HANDLE)id, (LPARAM)&pfts); OpenCurrentFile(); CheckCurrentFile(); @@ -187,7 +231,7 @@ struct FileTransferParam pfts.currentFileProgress = 0; pfts.tszCurrentFile = _tcsrchr(pfts.ptszFiles[pfts.currentFileNumber], '\\') + 1; - ProtoBroadcastAck(MODULE, pfts.hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, hProcess, 0); + ProtoBroadcastAck(MODULE, pfts.hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, (HANDLE)id, 0); OpenCurrentFile(); CheckCurrentFile(); @@ -197,7 +241,7 @@ struct FileTransferParam void SetStatus(int status, LPARAM param = 0) { - ProtoBroadcastAck(MODULE, pfts.hContact, ACKTYPE_FILE, status, hProcess, param); + ProtoBroadcastAck(MODULE, pfts.hContact, ACKTYPE_FILE, status, (HANDLE)id, param); } }; diff --git a/plugins/Dropbox/src/stdafx.cxx b/plugins/Dropbox/src/stdafx.cxx index 0765fbaa6f..5a725d1c0f 100644 --- a/plugins/Dropbox/src/stdafx.cxx +++ b/plugins/Dropbox/src/stdafx.cxx @@ -15,4 +15,6 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#include "stdafx.h" \ No newline at end of file +#include "stdafx.h" + +ULONG FileTransferParam::hFileProcess = 1; \ No newline at end of file diff --git a/plugins/Dropbox/src/stdafx.h b/plugins/Dropbox/src/stdafx.h index b83d80895b..46534f9e08 100644 --- a/plugins/Dropbox/src/stdafx.h +++ b/plugins/Dropbox/src/stdafx.h @@ -43,7 +43,8 @@ class CDropbox; #define DROPBOX_API_CU "https://content.dropboxapi.com/" DROPBOX_API_VER #define DROPBOX_APP_KEY "fa8du7gkf2q8xzg" -#include "..\..\..\miranda-private-keys\Dropbox\secret_key.h" +#define DROPBOX_API_SECRET "bb8zirh7nnk8fow" +//#include "..\..\..\miranda-private-keys\Dropbox\secret_key.h" class DropboxException { diff --git a/plugins/ExternalAPI/m_dropbox.h b/plugins/ExternalAPI/m_dropbox.h index 817bbff1e6..f67a781086 100644 --- a/plugins/ExternalAPI/m_dropbox.h +++ b/plugins/ExternalAPI/m_dropbox.h @@ -23,4 +23,39 @@ struct TRANSFERINFO // lParam = (LPARAM)(TRANSFERINFO*)info - transfer info #define ME_DROPBOX_SENT "Dropbox/Sent/Event" +struct DropboxUploadInfo +{ + const TCHAR *localPath; // local path + const TCHAR *serverPath; // relative path on server (can be NULL) +}; + +// upload file on Dropbox +// wParam = 0 +// lParam = (LPARAM)(const DropboxUploadInfo*) +// returns status of transfer. +// 0 on success otherwise fail +#define MS_DROPBOX_UPLOAD "Dropbox/Upload" + +// upload file on Dropbox +// wParam = 0 +// lParam = (LPARAM)(const DropboxUploadInfo*) +// returns file htansfer handle or NULL on failure +// returns immediately, without waiting for the send +// note, that you can track progress by using ME_PROTO_ACK +#define MS_DROPBOX_UPLOADASYNC "Dropbox/UploadAsync" + +// if you want to get download links after upload +// use ME_DROPBOX_UPLOADED hook. you'll get: +struct DropboxUploadResult +{ + HANDLE hProcess; // hProcess + int status; // status of transfer. 0 on success otherwise fail + const char* data; // data +}; + +// notifies a caller that upload has been finished +// wParam = 0 +// lParam = (LPARAM)(DropboxUploadResult*) +#define ME_DROPBOX_UPLOADED "Dropbox/Uploaded" + #endif //M_DROPBOX_H_ \ No newline at end of file -- cgit v1.2.3