osd_file::error osd_file::remove(std::string const &filename) { osd::text::tstring tempstr = osd::text::to_tstring(filename); error filerr = error::NONE; if (!DeleteFile(tempstr.c_str())) filerr = win_error_to_file_error(GetLastError()); return filerr; }
osd_file::error osd_file::remove(std::string const &filename) { TCHAR *tempstr = tstring_from_utf8(filename.c_str()); if (!tempstr) return error::OUT_OF_MEMORY; error filerr = error::NONE; if (!DeleteFile(tempstr)) filerr = win_error_to_file_error(GetLastError()); osd_free(tempstr); return filerr; }
file_error win_write_ptty(osd_file *file, const void *buffer, UINT64 offset, UINT32 count, UINT32 *actual) { BOOL res; DWORD bytes_wrote; res = WriteFile(file->handle, buffer, count, &bytes_wrote, NULL); if(res == FALSE) return win_error_to_file_error(GetLastError()); if(actual != NULL) *actual = bytes_wrote; return FILERR_NONE; }
osd_file::error osd_get_full_path(std::string &dst, std::string const &path) { // convert the path to TCHARs osd::text::tstring t_path = osd::text::to_tstring(path); // cannonicalize the path TCHAR buffer[MAX_PATH]; if (!GetFullPathName(t_path.c_str(), ARRAY_LENGTH(buffer), buffer, nullptr)) return win_error_to_file_error(GetLastError()); // convert the result back to UTF-8 osd::text::from_tstring(dst, buffer); return osd_file::error::NONE; }
osd_file::error osd_get_full_path(std::string &dst, std::string const &path) { // convert the path to TCHARs TCHAR *t_path = tstring_from_utf8(path.c_str()); osd_disposer<TCHAR> t_path_disposer(t_path); if (!t_path) return osd_file::error::OUT_OF_MEMORY; // cannonicalize the path TCHAR buffer[MAX_PATH]; if (!GetFullPathName(t_path, ARRAY_LENGTH(buffer), buffer, nullptr)) return win_error_to_file_error(GetLastError()); // convert the result back to UTF-8 char *result = utf8_from_tstring(buffer); osd_disposer<char> result_disposer(result); if (!result) return osd_file::error::OUT_OF_MEMORY; dst = result; return osd_file::error::NONE; }
file_error osd_open(const char *path, UINT32 openflags, osd_file **file, UINT64 *filesize) { DWORD disposition, access, sharemode; file_error filerr = FILERR_NONE; const TCHAR *src; DWORD upper; TCHAR *t_path; TCHAR *dst; // convert path to TCHAR t_path = tstring_from_utf8(path); if (t_path == NULL) { filerr = FILERR_OUT_OF_MEMORY; goto error; } // allocate a file object, plus space for the converted filename *file = (osd_file *)malloc(sizeof(**file) + sizeof(TCHAR) * _tcslen(t_path)); if (*file == NULL) { filerr = FILERR_OUT_OF_MEMORY; goto error; } // convert the path into something Windows compatible dst = (*file)->filename; for (src = t_path; *src != 0; src++) *dst++ = *src;//(*src == '/') ? '\\' : *src; *dst++ = 0; // select the file open modes if (openflags & OPEN_FLAG_WRITE) { disposition = (!is_path_to_physical_drive(path) && (openflags & OPEN_FLAG_CREATE)) ? CREATE_ALWAYS : OPEN_EXISTING; access = (openflags & OPEN_FLAG_READ) ? (GENERIC_READ | GENERIC_WRITE) : GENERIC_WRITE; sharemode = 0; } else if (openflags & OPEN_FLAG_READ) { disposition = OPEN_EXISTING; access = GENERIC_READ; sharemode = FILE_SHARE_READ; } else { filerr = FILERR_INVALID_ACCESS; goto error; } // attempt to open the file (*file)->handle = CreateFile((*file)->filename, access, sharemode, NULL, disposition, 0, NULL); if ((*file)->handle == INVALID_HANDLE_VALUE) { DWORD error = GetLastError(); // create the path if necessary if (error == ERROR_PATH_NOT_FOUND && (openflags & OPEN_FLAG_CREATE) && (openflags & OPEN_FLAG_CREATE_PATHS)) { TCHAR *pathsep = _tcsrchr((*file)->filename, '\\'); if (pathsep != NULL) { // create the path up to the file *pathsep = 0; error = create_path_recursive((*file)->filename); *pathsep = '\\'; // attempt to reopen the file if (error == NO_ERROR) (*file)->handle = CreateFile((*file)->filename, access, sharemode, NULL, disposition, 0, NULL); } } // if we still failed, clean up and free if ((*file)->handle == INVALID_HANDLE_VALUE) { filerr = win_error_to_file_error(error); goto error; } } // get the file size *filesize = GetFileSize((*file)->handle, &upper); *filesize |= (UINT64)upper << 32; error: // cleanup if (filerr != FILERR_NONE && *file != NULL) { free(*file); *file = NULL; } free(t_path); return filerr; }
osd_file::error osd_file::open(std::string const &orig_path, UINT32 openflags, ptr &file, std::uint64_t &filesize) { std::string path; try { osd_subst_env(path, orig_path); } catch (...) { return error::OUT_OF_MEMORY; } if (win_check_socket_path(path)) return win_open_socket(path, openflags, file, filesize); else if (win_check_ptty_path(path)) return win_open_ptty(path, openflags, file, filesize); // convert path to TCHAR TCHAR *t_path = tstring_from_utf8(path.c_str()); osd_disposer<TCHAR> t_path_disposer(t_path); if (!t_path) return error::OUT_OF_MEMORY; // convert the path into something Windows compatible for (TCHAR *src = t_path; *src != 0; src++) *src = /* ('/' == *src) ? '\\' : */ *src; // select the file open modes DWORD disposition, access, sharemode; if (openflags & OPEN_FLAG_WRITE) { disposition = (!is_path_to_physical_drive(path.c_str()) && (openflags & OPEN_FLAG_CREATE)) ? CREATE_ALWAYS : OPEN_EXISTING; access = (openflags & OPEN_FLAG_READ) ? (GENERIC_READ | GENERIC_WRITE) : GENERIC_WRITE; sharemode = FILE_SHARE_READ; } else if (openflags & OPEN_FLAG_READ) { disposition = OPEN_EXISTING; access = GENERIC_READ; sharemode = FILE_SHARE_READ; } else { return error::INVALID_ACCESS; } // attempt to open the file HANDLE h = CreateFile(t_path, access, sharemode, nullptr, disposition, 0, nullptr); if (INVALID_HANDLE_VALUE == h) { DWORD err = GetLastError(); // create the path if necessary if ((ERROR_PATH_NOT_FOUND == err) && (openflags & OPEN_FLAG_CREATE) && (openflags & OPEN_FLAG_CREATE_PATHS)) { TCHAR *pathsep = _tcsrchr(t_path, '\\'); if (pathsep != nullptr) { // create the path up to the file *pathsep = 0; err = create_path_recursive(t_path); *pathsep = '\\'; // attempt to reopen the file if (err == NO_ERROR) { h = CreateFile(t_path, access, sharemode, nullptr, disposition, 0, nullptr); err = GetLastError(); } } } // if we still failed, clean up and free if (INVALID_HANDLE_VALUE == h) return win_error_to_file_error(err); } // get the file size DWORD upper, lower; lower = GetFileSize(h, &upper); if (INVALID_FILE_SIZE == lower) { DWORD const err = GetLastError(); if (NO_ERROR != err) { CloseHandle(h); return win_error_to_file_error(err); } } try { file = std::make_unique<win_osd_file>(h); filesize = (std::uint64_t(upper) << 32) | lower; return error::NONE; } catch (...) { CloseHandle(h); return error::OUT_OF_MEMORY; } }
osd_file::error osd_file::open(std::string const &orig_path, uint32_t openflags, ptr &file, std::uint64_t &filesize) { std::string path; try { osd_subst_env(path, orig_path); } catch (...) { return error::OUT_OF_MEMORY; } if (win_check_socket_path(path)) return win_open_socket(path, openflags, file, filesize); else if (win_check_ptty_path(path)) return win_open_ptty(path, openflags, file, filesize); // convert path to TCHAR osd::text::tstring t_path = osd::text::to_tstring(path); // convert the path into something Windows compatible (the actual interesting part appears // to have been commented out???) for (auto iter = t_path.begin(); iter != t_path.end(); iter++) *iter = /* ('/' == *iter) ? '\\' : */ *iter; // select the file open modes DWORD disposition, access, sharemode; if (openflags & OPEN_FLAG_WRITE) { disposition = (!is_path_to_physical_drive(path.c_str()) && (openflags & OPEN_FLAG_CREATE)) ? CREATE_ALWAYS : OPEN_EXISTING; access = (openflags & OPEN_FLAG_READ) ? (GENERIC_READ | GENERIC_WRITE) : GENERIC_WRITE; sharemode = FILE_SHARE_READ; } else if (openflags & OPEN_FLAG_READ) { disposition = OPEN_EXISTING; access = GENERIC_READ; sharemode = FILE_SHARE_READ; } else { return error::INVALID_ACCESS; } // attempt to open the file HANDLE h = CreateFile(t_path.c_str(), access, sharemode, nullptr, disposition, 0, nullptr); if (INVALID_HANDLE_VALUE == h) { DWORD err = GetLastError(); // create the path if necessary if ((ERROR_PATH_NOT_FOUND == err) && (openflags & OPEN_FLAG_CREATE) && (openflags & OPEN_FLAG_CREATE_PATHS)) { auto pathsep = t_path.rfind('\\'); if (pathsep != decltype(t_path)::npos) { // create the path up to the file t_path[pathsep] = 0; err = create_path_recursive(&t_path[0]); t_path[pathsep] = '\\'; // attempt to reopen the file if (err == NO_ERROR) { h = CreateFile(t_path.c_str(), access, sharemode, nullptr, disposition, 0, nullptr); err = GetLastError(); } } } // if we still failed, clean up and free if (INVALID_HANDLE_VALUE == h) return win_error_to_file_error(err); } // get the file size DWORD upper, lower; lower = GetFileSize(h, &upper); if (INVALID_FILE_SIZE == lower) { DWORD const err = GetLastError(); if (NO_ERROR != err) { CloseHandle(h); return win_error_to_file_error(err); } } try { file = std::make_unique<win_osd_file>(h); filesize = (std::uint64_t(upper) << 32) | lower; return error::NONE; } catch (...) { CloseHandle(h); return error::OUT_OF_MEMORY; } }