diff --git a/adbfsplugin.cpp b/adbfsplugin.cpp index 5f80d1a..e7c6ba7 100644 --- a/adbfsplugin.cpp +++ b/adbfsplugin.cpp @@ -16,10 +16,10 @@ char inifilename[MAX_PATH]="adbfsplugin.ini"; // Unused in this plugin, may be char* strlcpy(char* p,char*p2,int maxlen) { if ((int)strlen(p2)>=maxlen) { - strncpy(p,p2,maxlen); + strncpy_s(p,maxlen+1,p2,maxlen); p[maxlen]=0; } else - strcpy(p,p2); + strcpy_s(p,maxlen+1,p2); return p; } @@ -60,27 +60,26 @@ int __stdcall FsInitW(int PluginNr,tProgressProcW pProgressProcW,tLogProcW pLogP return WSAStartup(MAKEWORD(2,2), &wsaData); } -typedef struct { - WCHAR PathW[wdirtypemax]; - WCHAR LastFoundNameW[wdirtypemax]; - HANDLE searchhandle; -} tLastFindStuct,*pLastFindStuct; - typedef struct { list* result; wstring path; int origlength; } FindDataHandle; -HANDLE __stdcall FsFindFirstW(WCHAR* Path,WIN32_FIND_DATAW *FindData) -{ - cacheMap.clear(); +wstring PathConverter(WCHAR* Path) { wstring path = Path; for (auto iter = path.begin(); iter != path.end(); iter++) { if ((*iter)==L'\\') { *iter = L'/'; } } + return path; +} + +HANDLE __stdcall FsFindFirstW(WCHAR* Path,WIN32_FIND_DATAW *FindData) +{ + cacheMap.clear(); + wstring path = PathConverter(Path); if (path.back()!=L'/') { path.push_back(L'/'); } @@ -165,57 +164,17 @@ BOOL __stdcall FsMkDir(char* Path) BOOL __stdcall FsMkDirW(WCHAR* Path) { - if (wcslen(Path)PushCommandW(L"busybox uuencode -m "+QuoteString(PathConverter(RemoteName))+L" x"); + string* line = AdbCommunicator::instance()->ReadLine(); + __int64 savedsize = 0; + __int64 fullsize = ((__int64)ri->SizeHigh << 32) | ri->SizeLow; + ProgressProcW(PluginNumber,RemoteName,LocalName,0); + int outsize = 0; + char out[BUF_SIZE*4]; + while (line!=NULL) { + if (line->find_first_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=")==wstring::npos) { + int inputsize = line->size(); + const char* pos = line->c_str(); + while (*pos) { + outsize += decode64(pos,out+outsize); + pos = pos+4; + } + } + if (outsize>BUF_SIZE*4-128) { + if (fwrite(out,1,outsize,f)!=outsize) { + return FS_FILE_WRITEERROR; + } + savedsize+=outsize; + outsize=0; + if (ProgressProcW(PluginNumber,RemoteName,LocalName,(int)((double)savedsize/fullsize*100))) { + AdbCommunicator::disconnect(); + return FS_FILE_USERABORT; + } + } + delete line; + line = AdbCommunicator::instance()->ReadLine(); + } + if (outsize!=0) { + if (fwrite(out,1,outsize,f)!=outsize) { + return FS_FILE_WRITEERROR; + } + outsize=0; } + ProgressProcW(PluginNumber,RemoteName,LocalName,100); + fclose(f); + return FS_FILE_OK; + } catch (wstring e) { + fclose(f); + return FS_FILE_READERROR; } } @@ -309,45 +255,84 @@ int __stdcall FsGetFile(char* RemoteName,char* LocalName,int CopyFlags,RemoteInf int __stdcall FsPutFileW(WCHAR* LocalName,WCHAR* RemoteName,int CopyFlags) { - int err; - BOOL ok,OverWrite,Resume,Move; - - OverWrite=CopyFlags & FS_COPYFLAGS_OVERWRITE; - Resume=CopyFlags & FS_COPYFLAGS_RESUME; - Move=CopyFlags & FS_COPYFLAGS_MOVE; - if (Resume) - return FS_FILE_NOTSUPPORTED; - - if (wcslen(RemoteName)PushCommandW(L"busybox uudecode -o " + QuoteString(PathConverter(RemoteName))); + ProgressProcW(PluginNumber,LocalName,RemoteName,0); + + AdbCommunicator::instance()->PutData("begin-base64 644 x\n",19); + + DWORD sizelo,sizehigh; + sizelo = GetCompressedFileSizeW(LocalName,&sizehigh); + __int64 savedsize = 0; + __int64 fullsize = ((__int64)sizehigh << 32) | sizelo; + + char buf[45]; + int read=fread(buf,1,45,f); + char out[61]; + out[60]='\n'; + while (read==45) { + int outwr=0; + int inr=0; + while (inr!=45) { + encode64(buf+inr,out+outwr); + outwr+=4; + inr+=3; + } + AdbCommunicator::instance()->PutData(out,61); + AdbCommunicator::instance()->CleanBuffer(false); + read=fread(buf,1,45,f); + savedsize += inr; + if (ProgressProcW(PluginNumber,LocalName,RemoteName,(int)((double)savedsize/fullsize*100))) { + AdbCommunicator::disconnect(); + return FS_FILE_USERABORT; + } } + if (read>0) { + int outwr=0; + int inr=0; + while(read>2) { + encode64(buf+inr,out+outwr); + inr+=3; + outwr+=4; + read-=3; + } + if (read==2) { + buf[inr+2]=0; + encode64(buf+inr,out+outwr); + outwr+=4; + out[outwr-1]='='; + out[outwr]='\n'; + } else if (read==1) { + buf[inr+1]=0; + buf[inr+2]=0; + encode64(buf+inr,out+outwr); + outwr+=4; + out[outwr-2]='='; + out[outwr-1]='='; + out[outwr]='\n'; + } + AdbCommunicator::instance()->PutData(out,outwr+1); + } + AdbCommunicator::instance()->PutData("====\x04\n",6); + Sleep(100); + /*string *line = AdbCommunicator::instance()->ReadLine(); + while (line!=NULL) { + delete line; + line = AdbCommunicator::instance()->ReadLine(); + }*/ + + ProgressProcW(PluginNumber,LocalName,RemoteName,100); + fclose(f); + } catch (wstring e) { + fclose(f); + return FS_FILE_WRITEERROR; } + return FS_FILE_OK; } int __stdcall FsPutFile(char* LocalName,char* RemoteName,int CopyFlags) @@ -358,10 +343,7 @@ int __stdcall FsPutFile(char* LocalName,char* RemoteName,int CopyFlags) BOOL __stdcall FsDeleteFileW(WCHAR* RemoteName) { - if (wcslen(RemoteName)=width || bigy>=height) && (bigx>0 && bigy>0)) { - stretchy=MulDiv(width,bigy,bigx); - if (stretchy<=height) { - w=width; - h=stretchy; - if (h<1) h=1; - } else { - stretchx=MulDiv(height,bigx,bigy); - w=stretchx; - if (w<1) w=1; - h=height; - } - - maindc=GetDC(GetDesktopWindow()); - dc_thumbnail=CreateCompatibleDC(maindc); - dc_image=CreateCompatibleDC(maindc); - bmp_thumbnail=CreateCompatibleBitmap(maindc,w,h); - ReleaseDC(GetDesktopWindow(),maindc); - oldbmp_image=(HBITMAP)SelectObject(dc_image,bmp_image); - oldbmp_thumbnail=(HBITMAP)SelectObject(dc_thumbnail,bmp_thumbnail); - if(is_nt) { - SetStretchBltMode(dc_thumbnail,HALFTONE); - SetBrushOrgEx(dc_thumbnail,0,0,&pt); - - } else { - SetStretchBltMode(dc_thumbnail,COLORONCOLOR); - } - StretchBlt(dc_thumbnail,0,0,w,h,dc_image,0,0,bigx,bigy,SRCCOPY); - SelectObject(dc_image,oldbmp_image); - SelectObject(dc_thumbnail,oldbmp_thumbnail); - DeleteDC(dc_image); - DeleteDC(dc_thumbnail); - DeleteObject(bmp_image); - *ReturnedBitmap=bmp_thumbnail; - return FS_BITMAP_EXTRACTED; - } else { - *ReturnedBitmap=bmp_image; - return FS_BITMAP_EXTRACTED; - } - } - return FS_BITMAP_NONE; - } - } else { - memmove(RemoteName,RemoteName+pluginrootlen,strlen(RemoteName+pluginrootlen)+1); - return FS_BITMAP_EXTRACT_YOURSELF | FS_BITMAP_CACHE; - } + return FS_BITMAP_NONE; } int __stdcall FsGetPreviewBitmapW(WCHAR* RemoteName,int width,int height,HBITMAP* ReturnedBitmap) @@ -652,46 +445,20 @@ void __stdcall FsSetDefaultParams(FsDefaultParamStruct* dps) strlcpy(inifilename,dps->DefaultIniName,MAX_PATH-1); } -BOOL __stdcall FsLinksToLocalFiles() -{ - return true; -} - -BOOL __stdcall FsGetLocalName(char* RemoteName,int maxlen) -{ - if (strlen(RemoteName)mode & 0400) { text[0]='r'; } if (fd->mode & 0200) { text[1]='w'; } if (fd->mode & 0100) { text[2]='x'; } @@ -742,13 +500,13 @@ int __stdcall FsContentGetValueT(BOOL unicode,WCHAR* FileName,int FieldIndex,int case 3: { char* text = (char*)FieldValue; if (fd->type==REGFILE) { - strcpy(text,"file"); + strcpy_s(text,maxlen,"file"); } else if (fd->type==DIRECTORY) { - strcpy(text,"dir"); + strcpy_s(text,maxlen,"dir"); } else if (fd->type==LINK) { - strcpy(text,"link"); + strcpy_s(text,maxlen,"link"); } else { - strcpy(text,"other"); + strcpy_s(text,maxlen,"other"); } break; } @@ -805,58 +563,7 @@ BOOL __stdcall FsContentGetDefaultView(char* ViewContents,char* ViewHeaders,char int __stdcall FsContentSetValueW(WCHAR* FileName,int FieldIndex,int UnitIndex,int FieldType,void* FieldValue,int flags) { - int retval=ft_nomorefields; - FILETIME oldcreationtime,newcreationtime; - FILETIME *p1,*p2,*FieldTime; - SYSTEMTIME st1,st2; - HANDLE f; - - if (FileName==NULL) // indicates end of operation -> may be used to flush data - return ft_nosuchfield; - - if (FieldIndex<0 || FieldIndex>=fieldcount) - return ft_nosuchfield; - else if ((fieldflags[FieldIndex] & 1)==0) - return ft_nosuchfield; - else { - switch (FieldIndex) { - case 1: // "creationdate" - case 3: // "accessdate" - FieldTime=(FILETIME*)FieldValue; - p1=NULL;p2=NULL; - if (FieldIndex==1) - p1=&oldcreationtime; - else - p2=&oldcreationtime; - - f= CreateFileT(FileName+pluginrootlen, - GENERIC_READ|GENERIC_WRITE, // Open for reading+writing - 0, // Do not share - NULL, // No security - OPEN_EXISTING, // Existing file only - FILE_ATTRIBUTE_NORMAL, // Normal file - NULL); - if (flags & setflags_only_date) { - GetFileTime(f,p1,p2,NULL); - FileTimeToLocalFileTime(&oldcreationtime,&newcreationtime); - FileTimeToSystemTime(&newcreationtime,&st2); - FileTimeToLocalFileTime(FieldTime,&newcreationtime); - FileTimeToSystemTime(&newcreationtime,&st1); - st1.wHour=st2.wHour; - st1.wMinute=st2.wMinute; - st1.wSecond=st2.wSecond; - st1.wMilliseconds=st2.wMilliseconds; - SystemTimeToFileTime(&st1,&newcreationtime); - LocalFileTimeToFileTime(&newcreationtime,&oldcreationtime); - } else - oldcreationtime=*FieldTime; - if (!SetFileTime(f,p1,p2,NULL)) - retval=ft_fileerror; - CloseHandle(f); - break; - } - } - return retval; + return ft_fileerror; } int __stdcall FsContentSetValue(char* FileName,int FieldIndex,int UnitIndex,int FieldType,void* FieldValue,int flags) @@ -867,8 +574,15 @@ int __stdcall FsContentSetValue(char* FileName,int FieldIndex,int UnitIndex,int void __stdcall FsContentPluginUnloading(void) { - // If you do something in a background thread, you may - // wait in this function until the thread has finished - // its work to prevent Total Commander from closing! - // MessageBox(0,"fsplugin unloading!","Test",0); + AdbCommunicator::disconnect(); } + +BOOL __stdcall FsDisconnect(char* DisconnectRoot) { + AdbCommunicator::disconnect(); + return TRUE; +} + +BOOL __stdcall FsDisconnectW(WCHAR* DisconnectRoot) { + AdbCommunicator::disconnect(); + return TRUE; +} \ No newline at end of file diff --git a/adbfsplugin.def b/adbfsplugin.def index c70d9ec..21904f4 100644 --- a/adbfsplugin.def +++ b/adbfsplugin.def @@ -31,9 +31,6 @@ EXPORTS FsSetDefaultParams FsGetPreviewBitmap FsGetPreviewBitmapW - FsLinksToLocalFiles - FsGetLocalName - FsGetLocalNameW FsContentGetSupportedField FsContentGetValue FsContentGetValueW @@ -42,4 +39,6 @@ EXPORTS FsContentGetDefaultView FsContentSetValue FsContentSetValueW - FsContentPluginUnloading \ No newline at end of file + FsContentPluginUnloading + FsDisconnect + FsDisconnectW \ No newline at end of file diff --git a/adbfsplugin.h b/adbfsplugin.h index 029a487..1e204f8 100644 --- a/adbfsplugin.h +++ b/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 @@ -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 **************************** @@ -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); @@ -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; \ No newline at end of file diff --git a/adbfsplugin.vcxproj b/adbfsplugin.vcxproj index 087ffcb..4b55d5a 100644 --- a/adbfsplugin.vcxproj +++ b/adbfsplugin.vcxproj @@ -47,6 +47,7 @@ .\Debug\ .\Debug\ true + .wfx diff --git a/adbhandler.cpp b/adbhandler.cpp index 77858fa..154b466 100644 --- a/adbhandler.cpp +++ b/adbhandler.cpp @@ -1,5 +1,6 @@ #include "StdAfx.h" #include "adbhandler.h" +#include "adbfsplugin.h" using namespace std; @@ -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 */ @@ -32,18 +34,59 @@ 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; @@ -51,17 +94,24 @@ AdbCommunicator::AdbCommunicator() { 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) { @@ -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; @@ -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; @@ -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; } } @@ -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); @@ -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); } @@ -214,10 +298,8 @@ void FillStat(wstring directory, list* 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(); @@ -276,7 +358,7 @@ void GetStat(WIN32_FIND_DATAW* fs, FileData* fd) { list* DirList(wstring filename) { auto* result = new list(); 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)); @@ -303,3 +385,20 @@ list* 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; + } +} + diff --git a/adbhandler.h b/adbhandler.h index 4e89a9b..b1051e3 100644 --- a/adbhandler.h +++ b/adbhandler.h @@ -1,21 +1,33 @@ #include "StdAfx.h" +#define BUF_SIZE 8192 +// Singleton class AdbCommunicator { public: static AdbCommunicator* instance() { if (!_global_adb) _global_adb = new AdbCommunicator(); return _global_adb; }; + static void disconnect() { if (_global_adb) delete _global_adb; _global_adb = NULL; } std::wstring* ReadLineW(); + std::string* ReadLine(); + int PutData(const char* data, int length); + void CleanBuffer(bool timeout); void PushCommandW(std::wstring command); void SetSU(bool needsu); private: AdbCommunicator(); - ~AdbCommunicator() {}; + ~AdbCommunicator(); void ReConnect(); void Close(); void SendStringToServer(char* str); - void CleanBuffer(bool timeout); + int ReadBuf(void); + SOCKET s; bool _needsu; static AdbCommunicator* _global_adb; + + char actbuf[BUF_SIZE]; + char* actbufpospoint; + int actbufsize; + int actbufpos; }; enum FileTypeEnum { @@ -25,7 +37,6 @@ enum FileTypeEnum { class FileData { public: FileData(std::wstring _name) { type=REGFILE; mode=0; size=0;accessTime=0;modificationTime=0;changeTime=0;uid=0;gid=0; name = _name; alt_name = _name; cache_name = _name; }; - //FileData(FileData& other) { type = other.type; mode = other.mode; size = other.size; accessTime = other.accessTime; modificationTime = other.modificationTime; changeTime = other.changeTime; uid = other.uid; gid = other.gid; name = other.name; alt_name = other.alt_name; }; FileData() { type=REGFILE; mode=0; size=0;accessTime=0;modificationTime=0;changeTime=0;uid=0;gid=0; name = L""; alt_name = L""; cache_name = L""; }; ~FileData() { }; FileTypeEnum type; @@ -38,5 +49,10 @@ class FileData { std::wstring cache_name; }; +int decode64(const char* input, char* output); +int encode64(const char* input, char* output); + std::list* DirList(std::wstring filename); -void GetStat(WIN32_FIND_DATAW* fs, FileData* fd); \ No newline at end of file +void GetStat(WIN32_FIND_DATAW* fs, FileData* fd); +bool RunCommand(std::wstring comm); +std::wstring QuoteString(std::wstring str); \ No newline at end of file diff --git a/cunicode.cpp b/cunicode.cpp index 6561263..533761e 100644 --- a/cunicode.cpp +++ b/cunicode.cpp @@ -47,10 +47,10 @@ WCHAR* awlcopy(WCHAR* outname,char* inname,int maxlen) WCHAR* wcslcpy(WCHAR *str1,const WCHAR *str2,int imaxlen) { if ((int)wcslen(str2)>=imaxlen-1) { - wcsncpy(str1,str2,imaxlen-1); + wcsncpy_s(str1,imaxlen,str2,imaxlen-1); str1[imaxlen-1]=0; } else - wcscpy(str1,str2); + wcscpy_s(str1,imaxlen,str2); return str1; } @@ -58,10 +58,10 @@ WCHAR* wcslcat(wchar_t *str1,const WCHAR *str2,int imaxlen) { int l1=(int)wcslen(str1); if ((int)wcslen(str2)+l1>=imaxlen-1) { - wcsncpy(str1+l1,str2,imaxlen-1-l1); + wcsncpy_s(str1+l1,imaxlen,str2,imaxlen-1-l1); str1[imaxlen-1]=0; } else - wcscat(str1,str2); + wcscat_s(str1,imaxlen,str2); return str1; } diff --git a/cunicode.h b/cunicode.h index 992cb6f..45dcfb5 100644 --- a/cunicode.h +++ b/cunicode.h @@ -1,3 +1,4 @@ +#pragma once BOOL usys();