int impl_fuse_context::walk_directory(void *buf, const char *name, const struct stat *stbuf, FUSE_OFF_T off) { walk_data *wd=(walk_data*)buf; WIN32_FIND_DATAW find_data={0}; utf8_to_wchar_buf(name,find_data.cFileName,MAX_PATH); GetShortPathNameW(find_data.cFileName,find_data.cAlternateFileName,MAX_PATH); struct FUSE_STAT stat={0}; if (stbuf!=NULL) stat=*stbuf; else { //No stat buffer - use 'getattr'. //TODO: fill directory params here!!! if (strcmp(name,".")==0 || strcmp(name,"..")==0) //Special entries stat.st_mode|=S_IFDIR; else CHECKED(wd->ctx->ops_.getattr((wd->dirname+name).c_str(),&stat)); } if (S_ISLNK(stat.st_mode)) { std::string resolved; CHECKED(wd->ctx->resolve_symlink(wd->dirname+name,&resolved)); CHECKED(wd->ctx->ops_.getattr(resolved.c_str(),&stat)); } convertStatlikeBuf(&stat,name,&find_data); return wd->delegate(&find_data,wd->DokanFileInfo); }
int impl_fuse_context::get_volume_information(LPWSTR volume_name_buffer,DWORD volume_name_size, LPWSTR file_system_name_buffer, DWORD file_system_name_size, PDOKAN_FILE_INFO dokan_file_info, LPDWORD volume_flags) { // case sensitive *volume_flags = 3; if(volname_) utf8_to_wchar_buf(volname_,volume_name_buffer,volume_name_size); else utf8_to_wchar_buf(DEFAULT_FUSE_VOLUME_NAME,volume_name_buffer,volume_name_size); if(fsname_) utf8_to_wchar_buf(fsname_,file_system_name_buffer,file_system_name_size); else utf8_to_wchar_buf(DEFAULT_FUSE_FILESYSTEM_NAME,file_system_name_buffer, file_system_name_size); return 0; }
int impl_fuse_context::get_volume_information(LPWSTR volume_name_buffer,DWORD volume_name_size, LPWSTR file_system_name_buffer, DWORD file_system_name_size, PDOKAN_FILE_INFO dokan_file_info) { if (volume_name_buffer && volume_name_size){ if(volname_) utf8_to_wchar_buf(volname_,volume_name_buffer,volume_name_size); else utf8_to_wchar_buf(DEFAULT_FUSE_VOLUME_NAME,volume_name_buffer,volume_name_size); } if (file_system_name_buffer && file_system_name_size){ if(fsname_) utf8_to_wchar_buf(fsname_,file_system_name_buffer,file_system_name_size); else utf8_to_wchar_buf(DEFAULT_FUSE_FILESYSTEM_NAME,file_system_name_buffer, file_system_name_size); } return 0; }
int impl_fuse_context::walk_directory(void *buf, const char *name, const struct FUSE_STAT *stbuf, FUSE_OFF_T off) { walk_data *wd=(walk_data*)buf; WIN32_FIND_DATAW find_data={0}; utf8_to_wchar_buf(name,find_data.cFileName,MAX_PATH); // fix name if wrong encoding if (!find_data.cFileName[0]) { struct FUSE_STAT stbuf={0}; utf8_to_wchar_buf_old(name,find_data.cFileName,MAX_PATH); std::string new_name = wchar_to_utf8_cstr(find_data.cFileName); if (wd->ctx->ops_.getattr && wd->ctx->ops_.rename && new_name.length() && wd->ctx->ops_.getattr(new_name.c_str(),&stbuf) == -ENOENT) wd->ctx->ops_.rename(name, new_name.c_str()); } memset(find_data.cAlternateFileName, 0, sizeof(find_data.cAlternateFileName)); struct FUSE_STAT stat={0}; if (stbuf!=NULL) stat=*stbuf; else { //No stat buffer - use 'getattr'. //TODO: fill directory params here!!! if (strcmp(name,".")==0 || strcmp(name,"..")==0) //Special entries stat.st_mode|=S_IFDIR; else CHECKED(wd->ctx->ops_.getattr((wd->dirname+name).c_str(),&stat)); } if (S_ISLNK(stat.st_mode)) { std::string resolved; CHECKED(wd->ctx->resolve_symlink(wd->dirname+name,&resolved)); CHECKED(wd->ctx->ops_.getattr(resolved.c_str(),&stat)); } convertStatlikeBuf(&stat,name,&find_data); uint32_t attrs = 0xFFFFFFFFu; if (wd->ctx->ops_.win_get_attributes) attrs = wd->ctx->ops_.win_get_attributes((wd->dirname+name).c_str()); if (attrs != 0xFFFFFFFFu) find_data.dwFileAttributes = attrs; return wd->delegate(&find_data,wd->DokanFileInfo); }
void Drive::Mount(HWND hwnd) { // check drive empty or require a new drive while (GetDriveType(mnt) != DRIVE_NO_ROOT_DIR) { char drive = SelectFreeDrive(hwnd); if (!drive) return; _stprintf(mnt, _T("%c:\\"), drive); Save(); } // check directory existence if (!isDirectory(wchar_to_utf8_cstr(dir.c_str()).c_str())) { if (YesNo(hwnd, _T("Directory does not exists. Remove from list?"))) Drives::Delete(shared_from_this()); return; } // TODO check configuration still exists ?? ... no can cause recursion problem // search if executable is present TCHAR executable[MAX_PATH]; if (!SearchPath(NULL, _T("encfs.exe"), NULL, LENGTH(executable), executable, NULL)) throw truntime_error(_T("Unable to find encfs.exe file")); // ask a password to mount TCHAR pass[128+2]; if (!GetPassword(hwnd, pass, LENGTH(pass)-2)) return; _tcscat(pass, _T("\r\n")); // mount using a sort of popen TCHAR cmd[2048]; _sntprintf(cmd, LENGTH(cmd), _T("\"%s\" -S \"%s\" %c:"), executable, dir.c_str(), mnt[0]); boost::shared_ptr<SubProcessInformations> proc(new SubProcessInformations); proc->creationFlags = CREATE_NEW_PROCESS_GROUP|CREATE_NO_WINDOW; if (!CreateSubProcess(cmd, proc.get())) { DWORD err = GetLastError(); memset(pass, 0, sizeof(pass)); _sntprintf(cmd, LENGTH(cmd), _T("Error: %s (%u)"), proc->errorPart, (unsigned) err); throw truntime_error(cmd); } subProcess = proc; // send the password std::string pwd = wchar_to_utf8_cstr(pass); DWORD written; WriteFile(proc->hIn, pwd.c_str(), pwd.length(), &written, NULL); CloseHandle(proc->hIn); // close input so sub process does not any more proc->hIn = NULL; memset(pass, 0, sizeof(pass)); memset((char*) pwd.c_str(), 0, pwd.length()); mounted = false; // wait for mount, read error and give feedback for (unsigned n = 0; n < 5*10; ++n) { // drive appeared if (GetDriveType(mnt) != DRIVE_NO_ROOT_DIR) { if (Drives::autoShow) Show(hwnd); break; } // process terminated DWORD readed; char output[2048]; switch (WaitForSingleObject(subProcess->hProcess, 200)) { case WAIT_OBJECT_0: case WAIT_ABANDONED: if (ReadFile(proc->hOut, output, sizeof(output)-1, &readed, NULL)) { output[readed] = 0; utf8_to_wchar_buf(output, cmd, LENGTH(cmd)); } else { _stprintf(cmd, _T("Unknown error mounting drive %c:"), mnt[0]); } subProcess.reset(); throw truntime_error(cmd); } } if (subProcess) mounted = true; Save(); // save for resume }