size_t Pipe::write(HANDLE handle, void* buffer, DWORD bytesToWrite) { size_t bytesWritten = 0; DWORD written = 0; DWORD remainingBytes = bytesToWrite; while (remainingBytes > 0) { if (!WriteFile( handle, (void*)((char*)buffer + bytesWritten), remainingBytes, &written, nullptr)) { DWORD error = GetLastError(); XLOGF( ERR, "Error while writing to the pipe : bytesWritten {}, {} : {}", bytesWritten, error, win32ErrorToString(error)); throw makeWin32ErrorExplicit(error, "Error while writing to the pipe"); } bytesWritten += written; remainingBytes -= written; } XLOG(DBG5) << "Pipe::Write-- bytesToWrite:" << bytesToWrite << "bytesWritten" << bytesWritten << std::endl; return bytesWritten; }
size_t Pipe::read(HANDLE handle, void* buffer, DWORD bytesToRead) { size_t bytesRead = 0; DWORD read = 0; DWORD remainingBytes = bytesToRead; while (remainingBytes > 0) { if (!ReadFile( handle, ((char*)buffer + bytesRead), remainingBytes, &read, nullptr)) { DWORD error = GetLastError(); XLOGF( ERR, "Error while reading from the pipe : bytesRead {}, Error: {} : {}", bytesRead, error, win32ErrorToString(error)); throw makeWin32ErrorExplicit(error, "Error while reading from the pipe"); } bytesRead += read; remainingBytes -= read; } XLOG(DBG5) << "Pipe::read-- bytesToRead:" << bytesToRead << "bytesRead" << bytesRead << std::endl; return bytesRead; }
static bool mzGetFileTime(const std::string &filename, tm_zip *tmzip, uLong *dostime) { // Don't fail when building with -Werror (void) filename; (void) tmzip; (void) dostime; #ifdef _WIN32 FILETIME ftLocal; HANDLE hFind; WIN32_FIND_DATAW ff32; std::wstring wFilename = utf8::utf8ToUtf16(filename); hFind = FindFirstFileW(wFilename.c_str(), &ff32); if (hFind != INVALID_HANDLE_VALUE) { FileTimeToLocalFileTime(&ff32.ftLastWriteTime, &ftLocal); FileTimeToDosDateTime(&ftLocal, ((LPWORD) dostime) + 1, ((LPWORD) dostime) + 0); FindClose(hFind); return true; } else { FLOGE("%s: FindFirstFileW() failed: %s", filename.c_str(), win32ErrorToString(GetLastError()).c_str()); } #elif defined unix || defined __APPLE__ || defined __ANDROID__ struct stat sb; struct tm t; if (stat(filename.c_str(), &sb) == 0) { time_t mtime = sb.st_mtime; if (!localtime_r(&mtime, &t)) { LOGE("localtime() failed"); return false; } tmzip->tm_sec = t.tm_sec; tmzip->tm_min = t.tm_min; tmzip->tm_hour = t.tm_hour; tmzip->tm_mday = t.tm_mday; tmzip->tm_mon = t.tm_mon ; tmzip->tm_year = t.tm_year; return true; } else { FLOGE("%s: stat() failed: %s", filename.c_str(), strerror(errno)); } #endif return false; }
std::string FileUtils::createTemporaryDir(const std::string &directory) { #ifdef _WIN32 // This Win32 code is adapted from the awesome libuv library (MIT-licensed) // https://github.com/libuv/libuv/blob/v1.x/src/win/fs.c static const char *possible = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; static const size_t numChars = 62; static const size_t numX = 6; static const char *suffix = "\\mbp-"; HCRYPTPROV hProv; std::string newPath; bool ret = CryptAcquireContext( &hProv, // phProv nullptr, // pszContainer nullptr, // pszProvider PROV_RSA_FULL, // dwProvType CRYPT_VERIFYCONTEXT // dwFlags ); if (!ret) { FLOGE("CryptAcquireContext() failed: %s", win32ErrorToString(GetLastError()).c_str()); return std::string(); } std::vector<char> buf(directory.begin(), directory.end()); // Path buf.insert(buf.end(), suffix, suffix + strlen(suffix)); // "\mbp-" buf.resize(buf.size() + numX); // Unique part buf.push_back('\0'); // 0-terminator char *unique = buf.data() + buf.size() - numX - 1; unsigned int tries = TMP_MAX; do { uint64_t v; ret = CryptGenRandom( hProv, // hProv sizeof(v), // dwLen (BYTE *) &v // pbBuffer ); if (!ret) { FLOGE("CryptGenRandom() failed: %s", win32ErrorToString(GetLastError()).c_str()); break; } for (size_t i = 0; i < numX; ++i) { unique[i] = possible[v % numChars]; v /= numChars; } // This is not particularly fast, but it'll do for now std::wstring wBuf = utf8::utf8ToUtf16(buf.data()); ret = CreateDirectoryW( wBuf.c_str(), // lpPathName nullptr // lpSecurityAttributes ); if (ret) { newPath = buf.data(); break; } else if (GetLastError() != ERROR_ALREADY_EXISTS) { FLOGE("CreateDirectoryW() failed: %s", win32ErrorToString(GetLastError()).c_str()); break; } } while (--tries); bool released = CryptReleaseContext( hProv, // hProv 0 // dwFlags ); assert(released); return newPath; #else std::string dirTemplate(directory); dirTemplate += "/mbp-XXXXXX"; // mkdtemp modifies buffer std::vector<char> buf(dirTemplate.begin(), dirTemplate.end()); buf.push_back('\0'); if (mkdtemp(buf.data())) { return buf.data(); } return std::string(); #endif }
std::string HResultErrorCategory::message(int error) const { return win32ErrorToString(error); }