Skip to content

Commit

Permalink
Added upload and download support, although very hacky...
Browse files Browse the repository at this point in the history
  • Loading branch information
sztupy committed Oct 7, 2010
1 parent 2b76722 commit 7e1b371
Show file tree
Hide file tree
Showing 8 changed files with 329 additions and 497 deletions.
612 changes: 163 additions & 449 deletions adbfsplugin.cpp

Large diffs are not rendered by default.

7 changes: 3 additions & 4 deletions adbfsplugin.def
Expand Up @@ -31,9 +31,6 @@ EXPORTS
FsSetDefaultParams
FsGetPreviewBitmap
FsGetPreviewBitmapW
FsLinksToLocalFiles
FsGetLocalName
FsGetLocalNameW
FsContentGetSupportedField
FsContentGetValue
FsContentGetValueW
Expand All @@ -42,4 +39,6 @@ EXPORTS
FsContentGetDefaultView
FsContentSetValue
FsContentSetValueW
FsContentPluginUnloading
FsContentPluginUnloading
FsDisconnect
FsDisconnectW
18 changes: 10 additions & 8 deletions adbfsplugin.h
@@ -1,5 +1,5 @@
// contents of fsplugin.h version 2.0 (30.Jan.2009)

#pragma once
// ids for FsGetFile
#define FS_FILE_OK 0
#define FS_FILE_EXISTS 1
Expand Down Expand Up @@ -169,9 +169,8 @@ void __stdcall FsSetDefaultParams(FsDefaultParamStruct* dps);

int __stdcall FsGetPreviewBitmap(char* RemoteName,int width,int height,HBITMAP* ReturnedBitmap);
int __stdcall FsGetPreviewBitmapW(WCHAR* RemoteName,int width,int height,HBITMAP* ReturnedBitmap);
BOOL __stdcall FsLinksToLocalFiles(void);
BOOL __stdcall FsGetLocalName(char* RemoteName,int maxlen);
BOOL __stdcall FsGetLocalNameW(WCHAR* RemoteName,int maxlen);
BOOL __stdcall FsDisconnect(char* DisconnectRoot);
BOOL __stdcall FsDisconnectW(WCHAR* DisconnectRoot);

// ************************** content plugin extension ****************************

Expand Down Expand Up @@ -244,7 +243,6 @@ int __stdcall FsContentGetSupportedField(int FieldIndex,char* FieldName,char* Un
int __stdcall FsContentGetValue(char* FileName,int FieldIndex,int UnitIndex,void* FieldValue,int maxlen,int flags);
int __stdcall FsContentGetValueW(WCHAR* FileName,int FieldIndex,int UnitIndex,void* FieldValue,int maxlen,int flags);


void __stdcall FsContentStopGetValue(char* FileName);
void __stdcall FsContentStopGetValueW(WCHAR* FileName);
int __stdcall FsContentGetDefaultSortOrder(int FieldIndex);
Expand All @@ -256,6 +254,10 @@ int __stdcall FsContentSetValueW(WCHAR* FileName,int FieldIndex,int UnitIndex,in
BOOL __stdcall FsContentGetDefaultView(char* ViewContents,char* ViewHeaders,char* ViewWidths,char* ViewOptions,int maxlen);
BOOL __stdcall FsContentGetDefaultViewW(WCHAR* ViewContents,WCHAR* ViewHeaders,WCHAR* ViewWidths,WCHAR* ViewOptions,int maxlen);




extern int PluginNumber;
extern tProgressProc ProgressProc;
extern tLogProc LogProc;
extern tRequestProc RequestProc;
extern tProgressProcW ProgressProcW;
extern tLogProcW LogProcW;
extern tRequestProcW RequestProcW;
1 change: 1 addition & 0 deletions adbfsplugin.vcxproj
Expand Up @@ -47,6 +47,7 @@
<OutDir>.\Debug\</OutDir>
<IntDir>.\Debug\</IntDir>
<LinkIncremental>true</LinkIncremental>
<TargetExt>.wfx</TargetExt>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
Expand Down
155 changes: 127 additions & 28 deletions adbhandler.cpp
@@ -1,5 +1,6 @@
#include "StdAfx.h"
#include "adbhandler.h"
#include "adbfsplugin.h"

using namespace std;

Expand All @@ -16,13 +17,14 @@ __int64 unixTimeToFileTime(unsigned int utime) {
}
/* Convert a Windows filetime_t into a UNIX time_t */
unsigned int fileTimeToUnixTime(__int64 ftime) {
unsigned int tconv = (ftime - EPOCH_DIFF) / RATE_DIFF;
unsigned int tconv = (unsigned int)((ftime - EPOCH_DIFF) / RATE_DIFF);
return (time_t)tconv;
}

string trim( string const& str, const char* sepSet)
{
std::string::size_type const first = str.find_first_not_of(sepSet);
return ( first==std::string::npos ) ? std::string() : str.substr(first, str.find_last_not_of(sepSet)-first+2);
return ( first==std::string::npos ) ? std::string() : str.substr(first, str.find_last_not_of(sepSet)-first+1);
}
/* Get adbfsplugin directory, and replace dll with adb.exe */

Expand All @@ -32,36 +34,84 @@ LPSTR GetAdbFileName() {

__adb__filename = new char[1024];
GetModuleFileName( GetModuleHandle("adbfsplugin.wfx"), __adb__filename, 1024 );
FILE* f = fopen("d:\\log.txt","w+");fprintf(f,"%ls",__adb__filename);fclose(f);
LPSTR filename = PathFindFileName(__adb__filename);
strcpy_s(filename,16,"adb.exe");
return __adb__filename;
}

// quote a string for usage in bash
wstring QuoteString(wstring str) {
wstring result = L"'";
for (auto i = str.begin(); i!= str.end(); i++) {
if (*i==L'\'') {
result.append(L"'\\''");
} else {
result.push_back(*i);
}
}
result.append(L"'");
return result;
}

unsigned char base64table[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
unsigned char base64table2[257] = "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\x3E~~~\x3F\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D~~~\x00~~~\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19~~~~~~\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";

// base64 decode 4 characters to 3 characters
// returns the bytes decoded (might be less because of padding)
int decode64(const char* input, char* output) {
if ((input[3]=='=') && (input[2]=='=') && (input[0]=='=') && (input[1]=='=')) return 0;
unsigned int n = (base64table2[input[0]] << 18) | (base64table2[input[1]] << 12) | (base64table2[input[2]] << 6) | (base64table2[input[3]]);
output[0] = (unsigned char)(n>>16);
output[1] = (unsigned char)((n>>8) & 0xFF);
output[2] = (unsigned char)(n & 0xFF);
return 1 + ((input[3]!='=')?1:0) + ((input[2]!='=')?1:0);
}

int encode64(const char* input, char* output) {
unsigned int n = ((unsigned char)input[0] << 16) | ((unsigned char)input[1] << 8) | (unsigned char)input[2];
output[0] = base64table[n>>18];
output[1] = base64table[(n>>12) & (0x3F)];
output[2] = base64table[(n>>6) & (0x3F)];
output[3] = base64table[(n) & (0x3F)];
return 4;
}

/* ---------------------------
---- Adb Communicator -----
--------------------------- */

AdbCommunicator* AdbCommunicator::_global_adb = 0;

AdbCommunicator::~AdbCommunicator() {
Close();
LogProc(PluginNumber, MSGTYPE_DISCONNECT, "Closing plugin");
}

AdbCommunicator::AdbCommunicator() {
PROCESS_INFORMATION piProcInfo;
STARTUPINFO siStartInfo;
ZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION));
ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
siStartInfo.cb = sizeof(STARTUPINFO);

LogProc(PluginNumber, MSGTYPE_DETAILS, "Starting ADB Server: ");
LogProc(PluginNumber, MSGTYPE_DETAILS, GetAdbFileName());
BOOL retval = CreateProcess(GetAdbFileName(),"adb.exe start-server",NULL,NULL,TRUE,CREATE_NO_WINDOW|CREATE_UNICODE_ENVIRONMENT,NULL,NULL,&siStartInfo,&piProcInfo);
if (!retval) {
throw wstring(L"<0000 - Could not start ADB server>");
}
s = INVALID_SOCKET;
_needsu = true;
actbufsize=0;
actbufpos=0;
}

void AdbCommunicator::Close() {
LogProc(PluginNumber, MSGTYPE_DISCONNECT, "Closing connection /");
closesocket(s);
s = INVALID_SOCKET;
actbufsize=0;
actbufpos=0;
}

void AdbCommunicator::SendStringToServer(char* str) {
Expand All @@ -78,7 +128,7 @@ void AdbCommunicator::SendStringToServer(char* str) {
Close();
throw wstring(L"<000A - no ack data from adb server>");
}
if (strcmpi("FAIL",recbuf)==0) {
if (_strcmpi("FAIL",recbuf)==0) {
// cleanup
recv(s,recbuf,4,MSG_WAITALL);
int datalen;
Expand All @@ -87,13 +137,14 @@ void AdbCommunicator::SendStringToServer(char* str) {
recv(s,data,datalen,MSG_WAITALL);
Close();
throw wstring(L"<000B - FAIL response from adb server>");
} else if (strcmpi("OKAY",recbuf)!=0) {
} else if (_strcmpi("OKAY",recbuf)!=0) {
Close();
throw wstring(L"<000C - Bad response from adb server>");
}
}

void AdbCommunicator::ReConnect() {
LogProc(PluginNumber, MSGTYPE_CONNECT, "CONNECT /");
struct addrinfo *result = NULL, *ptr = NULL, hints;
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
Expand Down Expand Up @@ -140,11 +191,13 @@ void AdbCommunicator::CleanBuffer(bool timeout) {
fd_set set;
FD_ZERO(&set);
FD_SET(s, &set);
char buf[1024];


// cleans input buffer
actbufsize=0;
actbufpos=0;
actbufpospoint=actbuf;
while (select(0, &set, NULL, NULL, (timeout)?NULL:&timeval)!=0) {
recv(s,buf,1024,0);
recv(s,actbuf,BUF_SIZE,0);
if (timeout) return;
}
}
Expand All @@ -158,7 +211,7 @@ void AdbCommunicator::PushCommandW(wstring command) {
CleanBuffer(false);

// add some garbage data to determine where sending starts and where it stops
command = L"echo \"===adbfspluginéá\" ;" + command + L" ; echo \"===adbfspluginéáí\"";
command = L"echo \"===adbfsplugin<--\" ;" + command + L" ; echo \"===adbfsplugin-->\"";

// convert utf-16 command to utf-8
int sizeneeded = WideCharToMultiByte(CP_UTF8,0,command.c_str(),-1,NULL,0,NULL,NULL);
Expand All @@ -174,35 +227,66 @@ void AdbCommunicator::PushCommandW(wstring command) {
}

// throw out initial garbage
wstring* line = ReadLineW();
while ((line!=NULL) && (*line != L"===adbfspluginéá")) {
string* line = ReadLine();
while ((line!=NULL) && (*line != "===adbfsplugin<--")) {
delete line;
line = ReadLineW();
}
line = ReadLine();
}
if (line) delete line;
};

wstring* AdbCommunicator::ReadLineW() {
int AdbCommunicator::ReadBuf(void) {
actbufpos++;
actbufpospoint++;
if (actbufsize<=actbufpos) {
actbufsize = recv(s,actbuf,BUF_SIZE,0);
if (actbufsize!=SOCKET_ERROR) {
actbufpos=0;
actbufpospoint = actbuf;
} else {
actbufpos=0;
actbufpospoint=actbuf;
actbufsize=0;
return SOCKET_ERROR;
}
}
return actbufsize-actbufpos;
}

int AdbCommunicator::PutData(const char * data, int length) {
return send(s,data,length,0);
}

string* AdbCommunicator::ReadLine() {
string input = "";
DWORD bytesRead;
char a;
int state=0; // check for prompt state
bytesRead = recv(s,&a,1,0);
while ((bytesRead!=SOCKET_ERROR) && (bytesRead!=0) && (a!='\n') && (input != "===adbfspluginéáí")) {
input += a;
bytesRead = recv(s,&a,1,0);
bytesRead = ReadBuf();
int size=0;
while ((bytesRead!=SOCKET_ERROR) && (bytesRead!=0) && (*actbufpospoint!='\n') && ((size != 17) || (input != "===adbfsplugin-->"))) {
size++;
input.push_back(*actbufpospoint);
bytesRead = ReadBuf();
}
//LogProc(PluginNumber,MSGTYPE_DETAILS,(char*)input.c_str());
if (bytesRead==SOCKET_ERROR) {
Close();
int d = WSAGetLastError();
throw wstring(L"Socket Error");
}
if (input.empty() || input=="===adbfspluginéáí") {
if (input.empty() || input=="===adbfsplugin-->") {
return NULL;
}
input = trim(input," \t\r\n");
int wide = MultiByteToWideChar(CP_UTF8, 0, input.c_str(), input.length(), NULL, 0);
return new string(trim(input," \t\r\n"));
}

wstring* AdbCommunicator::ReadLineW() {
string* input = ReadLine();
if (input==NULL) return NULL;
int wide = MultiByteToWideChar(CP_UTF8, 0, input->c_str(), input->length()+1, NULL, 0);
LPWSTR output = new wchar_t[wide];
MultiByteToWideChar(CP_UTF8, 0, input.c_str(), input.length(), output, wide);
MultiByteToWideChar(CP_UTF8, 0, input->c_str(), input->length()+1, output, wide);
delete input;
return new wstring(output,wide-1);
}

Expand All @@ -214,10 +298,8 @@ void FillStat(wstring directory, list<FileData*>* fd) {
try {
wstring command = L"busybox stat -c \"%a -%F- %g %u %s %X %Y %Z %N\" ";
for (auto i = fd->begin(); i != fd->end(); i++) {
command.append(L" \"");
command.append(directory);
command.append((*i)->name);
command.append(L"\"");
command.append(L" ");
command.append(QuoteString(directory+(*i)->name));
}
AdbCommunicator::instance()->PushCommandW(command);
wstring* line = AdbCommunicator::instance()->ReadLineW();
Expand Down Expand Up @@ -276,7 +358,7 @@ void GetStat(WIN32_FIND_DATAW* fs, FileData* fd) {
list<FileData*>* DirList(wstring filename) {
auto* result = new list<FileData*>();
try {
AdbCommunicator::instance()->PushCommandW((wstring(L"busybox ls --color=never -1 \"") + filename + L"\"").c_str());
AdbCommunicator::instance()->PushCommandW((wstring(L"busybox ls --color=never -1 ") + QuoteString(filename)).c_str());
wstring* line = AdbCommunicator::instance()->ReadLineW();
while (line!=NULL) {
result->push_back(new FileData(*line));
Expand All @@ -303,3 +385,20 @@ list<FileData*>* DirList(wstring filename) {
return result;
}

bool RunCommand(wstring comm)
{
try {
AdbCommunicator::instance()->PushCommandW(comm);
wstring* line = AdbCommunicator::instance()->ReadLineW();
while (line!=NULL) {
LogProcW(PluginNumber, MSGTYPE_DETAILS, (WCHAR*)line->c_str());
delete line;
line = AdbCommunicator::instance()->ReadLineW();
}
return true;
} catch (wstring e) {
LogProcW(PluginNumber, MSGTYPE_IMPORTANTERROR, (WCHAR*)e.c_str());
return false;
}
}

0 comments on commit 7e1b371

Please sign in to comment.