void FileStream::openForRead(Blob* blob) { ASSERT(!isMainThread()); if (isHandleValid(m_handle)) return; // FIXME: Need to handle multiple items that may include non-file ones when BlobBuilder is introduced. ASSERT(blob->items().size() >= 1); const FileBlobItem* fileItem = blob->items().at(0)->toFileBlobItem(); if (!fileItem) { ASSERT(false); m_client->didFail(NOT_READABLE_ERR); return; } // Check if the file exists by querying its modification time. We choose not to call fileExists() in order to save an // extra file system call when the modification time is needed to check the validity of the sliced file blob. // Per the spec, we need to return different error codes to differentiate between non-existent file and permission error. // openFile() could not tell use the failure reason. time_t currentModificationTime; if (!getFileModificationTime(fileItem->path(), currentModificationTime)) { m_client->didFail(NOT_FOUND_ERR); return; } // Open the file blob. m_handle = openFile(fileItem->path(), OpenForRead); if (!isHandleValid(m_handle)) { m_client->didFail(NOT_READABLE_ERR); return; } #if ENABLE(BLOB_SLICE) const FileRangeBlobItem* fileRangeItem = fileItem->toFileRangeBlobItem(); if (fileRangeItem) { // Check the modificationt time for the possible file change. if (static_cast<time_t>(fileRangeItem->snapshotModificationTime()) != currentModificationTime) { m_client->didFail(NOT_READABLE_ERR); return; } // Jump to the beginning position if the file has been sliced. if (fileRangeItem->start() > 0) { if (seekFile(m_handle, fileRangeItem->start(), SeekFromBeginning) < 0) { m_client->didFail(NOT_READABLE_ERR); return; } } } #endif // Get the size. m_totalBytesToRead = blob->size(); m_client->didGetSize(m_totalBytesToRead); }
bool CurlCacheEntry::openContentFile() { if (isHandleValid(m_contentFile)) return true; m_contentFile = openFile(m_contentFilename, OpenForWrite); if (isHandleValid(m_contentFile)) return true; LOG(Network, "Cache Error: Could not open %s for write\n", m_contentFilename.latin1().data()); return false; }
CString openTemporaryFile(const char* prefix, PlatformFileHandle& handle) { char appPath[MAX_PATH]; if (WideCharToMultiByte(CP_ACP, 0, GetAppPath(), wcslen(GetAppPath()), appPath, MAX_PATH - 1, NULL, NULL ) > 0) { static int tempFileId = 0; char tempFile[MAX_PATH]; int fileNameLen = sprintf(tempFile, "%s\\%s%04d.tmp", appPath, prefix, tempFileId++); if (tempFileId >= 9999) tempFileId = 0; if (fileNameLen > 0) { HANDLE tempHandle = ::CreateFileA(tempFile, GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (isHandleValid(tempHandle)) { handle = tempHandle; return tempFile; } } } return 0; }
void FileStream::close() { if (isHandleValid(m_handle)) { closeFile(m_handle); m_handle = invalidPlatformFileHandle; } }
void PluginStream::didReceiveData(NetscapePlugInStreamLoader* loader, const char* data, int length) { ASSERT_UNUSED(loader, loader == m_loader); ASSERT(m_streamState == StreamStarted); // If the plug-in cancels the stream in deliverData it could be deleted, // so protect it here. RefPtr<PluginStream> protect(this); if (m_transferMode != NP_ASFILEONLY) { if (!m_deliveryData) m_deliveryData = std::make_unique<Vector<char>>(); int oldSize = m_deliveryData->size(); m_deliveryData->resize(oldSize + length); memcpy(m_deliveryData->data() + oldSize, data, length); deliverData(); } if (m_streamState != StreamStopped && isHandleValid(m_tempFileHandle)) { int bytesWritten = writeToFile(m_tempFileHandle, data, length); if (bytesWritten != length) cancelAndDestroyStream(NPRES_NETWORK_ERR); } }
BT_s32 BT_GetS(BT_HANDLE hFile, BT_u32 ulSize, BT_i8 *s) { BT_ERROR Error; if(!isHandleValid(hFile, &Error)) { return (BT_s32) Error; } BT_i8 *t; BT_s32 c = 0; t = s; while (--ulSize>1 && (c=BT_GetC(hFile, 0)) && (c != '\n' && c != '\r') && c >= 0) { *s++ = c; } if(c < 0) { return c; } if (c == '\n' || c == '\r') { *s++ = c; } else if (ulSize == 1) { *s++ = '\n'; } *s = '\0'; return s - t; }
void closeFile(PlatformFileHandle& handle) { if (isHandleValid(handle)) { ::CloseHandle(handle); handle = invalidPlatformFileHandle; } }
BT_s32 BT_GetC(BT_HANDLE hFile, BT_u32 ulFlags) { BT_ERROR Error = BT_ERR_NONE; if(!isHandleValid(hFile, &Error)) { return Error; } if(!flagsSupported(hFile, ulFlags)) { return BT_ERR_UNSUPPORTED_FLAG; } if(hFile->h.pIf->pFileIF->pfnGetC) { return hFile->h.pIf->pFileIF->pfnGetC(hFile, ulFlags); } BT_u8 c = 0; BT_s32 i = hFile->h.pIf->pFileIF->pfnRead(hFile, ulFlags, 1, &c); if(i < 0) { return i; } if(i != 1) { return BT_ERR_GENERIC; } return c; }
bool CurlCacheEntry::saveResponseHeaders(const ResourceResponse& response) { PlatformFileHandle headerFile = openFile(m_headerFilename, OpenForWrite); if (!isHandleValid(headerFile)) { LOG(Network, "Cache Error: Could not open %s for write\n", m_headerFilename.latin1().data()); return false; } // Headers HTTPHeaderMap::const_iterator it = response.httpHeaderFields().begin(); HTTPHeaderMap::const_iterator end = response.httpHeaderFields().end(); while (it != end) { String headerField = it->key; headerField.append(": "); headerField.append(it->value); headerField.append("\n"); CString headerFieldLatin1 = headerField.latin1(); writeToFile(headerFile, headerFieldLatin1.data(), headerFieldLatin1.length()); m_cachedResponse.setHTTPHeaderField(it->key, it->value); ++it; } closeFile(headerFile); return true; }
void closeFile(PlatformFileHandle& handle) { if (isHandleValid(handle)) { IFILE_Release(handle); handle = invalidPlatformFileHandle; } }
void PluginStream::didReceiveData(NetscapePlugInStreamLoader* loader, const char* data, int length) { ASSERT(loader == m_loader); ASSERT(m_streamState == StreamStarted); // If the plug-in cancels the stream in deliverData it could be deleted, // so protect it here. RefPtr<PluginStream> protect(this); if (m_transferMode != NP_ASFILEONLY) { if (!m_deliveryData) m_deliveryData.set(new Vector<char>); int oldSize = m_deliveryData->size(); m_deliveryData->resize(oldSize + length); memcpy(m_deliveryData->data() + oldSize, data, length); #if PLATFORM(ANDROID) //TODO: This needs to be upstreamed to WebKit. if (!m_delayDeliveryTimer.isActive()) #endif deliverData(); } if (m_streamState != StreamStopped && isHandleValid(m_tempFileHandle)) { int bytesWritten = writeToFile(m_tempFileHandle, data, length); if (bytesWritten != length) cancelAndDestroyStream(NPRES_NETWORK_ERR); } }
void FileStream::read(char* buffer, int length) { ASSERT(!isMainThread()); if (!isHandleValid(m_handle)) { m_client->didFail(NOT_READABLE_ERR); return; } if (m_bytesProcessed >= m_totalBytesToRead) { m_client->didFinish(); return; } long long remaining = m_totalBytesToRead - m_bytesProcessed; int bytesToRead = (remaining < length) ? static_cast<int>(remaining) : length; int bytesRead = readFromFile(m_handle, buffer, bytesToRead); if (bytesRead < 0) { m_client->didFail(NOT_READABLE_ERR); return; } if (!bytesRead) { m_client->didFinish(); return; } m_bytesProcessed += bytesRead; m_client->didRead(buffer, bytesRead); }
bool CacheResult::writeChunkToFile() { PlatformFileHandle file; file = openFile(m_filePath, OpenForWrite); if (!isHandleValid(file)) return false; return WebCore::writeToFile(file, m_buffer->data(), m_bufferSize) == m_bufferSize; }
CString openTemporaryFile(const char*, PlatformFileHandle& handle) { handle = INVALID_HANDLE_VALUE; wchar_t tempPath[MAX_PATH]; int tempPathLength = ::GetTempPath(_countof(tempPath), tempPath); if (tempPathLength <= 0 || tempPathLength > _countof(tempPath)) return CString(); HCRYPTPROV hCryptProv = 0; if (!CryptAcquireContext(&hCryptProv, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) return CString(); String proposedPath; while (1) { wchar_t tempFile[] = L"XXXXXXXX.tmp"; // Use 8.3 style name (more characters aren't helpful due to 8.3 short file names) const int randomPartLength = 8; if (!CryptGenRandom(hCryptProv, randomPartLength * 2, reinterpret_cast<BYTE*>(tempFile))) break; // Limit to valid filesystem characters, also excluding others that could be problematic, like punctuation. // don't include both upper and lowercase since Windows file systems are typically not case sensitive. const char validChars[] = "0123456789abcdefghijklmnopqrstuvwxyz"; for (int i = 0; i < randomPartLength; ++i) tempFile[i] = validChars[tempFile[i] % (sizeof(validChars) - 1)]; ASSERT(wcslen(tempFile) * 2 == sizeof(tempFile) - 2); proposedPath = pathByAppendingComponent(String(tempPath), String(tempFile)); // use CREATE_NEW to avoid overwriting an existing file with the same name handle = CreateFile(proposedPath.charactersWithNullTermination(), GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0); if (!isHandleValid(handle) && GetLastError() == ERROR_ALREADY_EXISTS) continue; break; } CryptReleaseContext(hCryptProv, 0); if (!isHandleValid(handle)) return CString(); return proposedPath.latin1(); }
void FileStream::close() { ASSERT(!isMainThread()); if (isHandleValid(m_handle)) { closeFile(m_handle); m_handle = invalidPlatformFileHandle; } }
void closeFile(PlatformFileHandle& handle) { if (!isHandleValid(handle)) return; g_io_stream_close(G_IO_STREAM(handle), 0, 0); g_object_unref(handle); handle = invalidPlatformFileHandle; }
bool CurlCacheEntry::closeContentFile() { if (!isHandleValid(m_contentFile)) return true; closeFile(m_contentFile); m_contentFile = invalidPlatformFileHandle; return true; }
int writeToFile(PlatformFileHandle handle, const char* data, int length) { if (!isHandleValid(handle)) return -1; int bytesWritten = IFILE_Write(handle, data, length); if (!bytesWritten) return -1; return bytesWritten; }
String openTemporaryFile(const String& prefix, PlatformFileHandle& handle) { GUniquePtr<gchar> filename(g_strdup_printf("%s%s", prefix.utf8().data(), createCanonicalUUIDString().utf8().data())); GUniquePtr<gchar> tempPath(g_build_filename(g_get_tmp_dir(), filename.get(), NULL)); GRefPtr<GFile> file = adoptGRef(g_file_new_for_path(tempPath.get())); handle = g_file_create_readwrite(file.get(), G_FILE_CREATE_NONE, 0, 0); if (!isHandleValid(handle)) return String(); return String::fromUTF8(tempPath.get()); }
BT_ERROR BT_Flush(BT_HANDLE hFile) { BT_ERROR Error; if(!isHandleValid(hFile, &Error)) { return Error; } if(!hFile->h.pIf->pFileIF->pfnFlush) { return BT_ERR_UNSUPPORTED_INTERFACE; } return hFile->h.pIf->pFileIF->pfnFlush(hFile); }
bool FileStream::openForRead(const String& path, long long offset, long long length) { if (isHandleValid(m_handle)) return true; // Open the file. m_handle = openFile(path, OpenForRead); if (!isHandleValid(m_handle)) return false; // Jump to the beginning position if the file has been sliced. if (offset > 0) { if (seekFile(m_handle, offset, SeekFromBeginning) < 0) return false; } m_totalBytesToRead = length; m_bytesProcessed = 0; return true; }
int writeToFile(PlatformFileHandle handle, const char* data, int length) { if (!isHandleValid(handle)) return -1; DWORD bytesWritten; bool success = WriteFile(handle, data, length, &bytesWritten, 0); if (!success) return -1; return static_cast<int>(bytesWritten); }
int readFromFile(PlatformFileHandle handle, char* data, int length) { if (!isHandleValid(handle)) return -1; DWORD bytesRead; bool success = ::ReadFile(handle, data, length, &bytesRead, 0); if (!success) return -1; return static_cast<int>(bytesRead); }
uintptr_t getFuncAddrInDll(const std::string& symbol, HandleType handle) { assert(isHandleValid(handle)); uintptr_t pointer; #ifdef _WIN32 FARPROC test = GetProcAddress(handle, symbol.c_str()); pointer = reinterpret_cast<uintptr_t>(GetProcAddress(handle, symbol.c_str())); #else pointer = reinterpret_cast<uintptr_t>(dlsym(handle, symbol.c_str())); #endif return pointer; }
BT_ERROR BT_Seek(BT_HANDLE hFile, BT_s64 ulOffset, BT_u32 whence) { BT_ERROR Error; if(!isHandleValid(hFile, &Error)) { return Error; } if(!hFile->h.pIf->pFileIF->pfnSeek) { return BT_ERR_UNSUPPORTED_INTERFACE; } return hFile->h.pIf->pFileIF->pfnSeek(hFile, ulOffset, whence); }
BT_s32 BT_Write(BT_HANDLE hFile, BT_u32 ulFlags, BT_u32 ulSize, const void *pBuffer) { BT_ERROR Error = BT_ERR_NONE; if(!isHandleValid(hFile, &Error)) { return Error; } if(!flagsSupported(hFile, ulFlags)) { return BT_ERR_UNSUPPORTED_FLAG; } return hFile->h.pIf->pFileIF->pfnWrite(hFile, ulFlags, ulSize, pBuffer); }
bool CurlCacheEntry::saveCachedData(const char* data, size_t size) { PlatformFileHandle contentFile = openFile(m_contentFilename, OpenForWrite); if (!isHandleValid(contentFile)) { LOG(Network, "Cache Error: Could not open %s for write\n", m_contentFilename.latin1().data()); return false; } // append seekFile(contentFile, 0, SeekFromEnd); writeToFile(contentFile, data, size); closeFile(contentFile); return true; }
ElementType *state(u64 objectHandle) { COMMON_ASSERT(isStateIdValid(ElementType::STATE)); COMMON_ASSERT(m_states[ElementType::STATE].elemSize == sizeof(ElementType)); u64 typeIdFromHandle = objectHandleTypeId(objectHandle); COMMON_ASSERT(isHandleValid(objectHandle)); COMMON_ASSERT(typeIdFromHandle == m_states[ElementType::STATE].typeId); // Type lookup needed here for object ID to index translation const Type &type = m_types[typeIdFromHandle]; return (ElementType *)&m_stateValues[ElementType::STATE] [type.objectIdToIdx[objectHandle & 0xffffffff] * sizeof(ElementType)]; }
BT_BOOL BT_EOF(BT_HANDLE hFile, BT_ERROR *pError) { if(!isHandleValid(hFile, pError)) { return BT_FALSE; } if(!hFile->h.pIf->pFileIF->pfnEOF) { if(pError) { *pError = BT_ERR_UNSUPPORTED_INTERFACE; } return 0; } return hFile->h.pIf->pFileIF->pfnEOF(hFile); }
BT_ERROR BT_CloseHandle(BT_HANDLE hHandle) { if(!isHandleValid(hHandle)) { return BT_ERR_INVALID_HANDLE; } BT_ERROR Error = hHandle->h.pIf->pfnCleanup(hHandle); if(!Error) { BT_DestroyHandle(hHandle); } if(Error == BT_HANDLE_DO_NOT_FREE) { Error = BT_ERR_NONE; } return Error; }