QString readWindowsSymLink(const QString &path) { QString result; FileHandleWrapper dirHandle(path); if (dirHandle.handle() != INVALID_HANDLE_VALUE) { REPARSE_DATA_BUFFER* reparseStructData = (REPARSE_DATA_BUFFER*)calloc(1, MAXIMUM_REPARSE_DATA_BUFFER_SIZE); DWORD bytesReturned = 0; if (::DeviceIoControl(dirHandle.handle(), FSCTL_GET_REPARSE_POINT, 0, 0, reparseStructData, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &bytesReturned, 0)) { if (reparseStructData->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) { int length = reparseStructData->MountPointReparseBuffer.SubstituteNameLength / sizeof(wchar_t); int offset = reparseStructData->MountPointReparseBuffer.SubstituteNameOffset / sizeof(wchar_t); const wchar_t* PathBuffer = &reparseStructData->MountPointReparseBuffer.PathBuffer[offset]; result = QString::fromWCharArray(PathBuffer, length); } else if (reparseStructData->ReparseTag == IO_REPARSE_TAG_SYMLINK) { int length = reparseStructData->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(wchar_t); int offset = reparseStructData->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(wchar_t); const wchar_t* PathBuffer = &reparseStructData->SymbolicLinkReparseBuffer.PathBuffer[offset]; result = QString::fromWCharArray(PathBuffer, length); } // cut-off "//?/" and "/??/" if (result.size() > 4 && result.at(0) == QLatin1Char('\\') && result.at(2) == QLatin1Char('?') && result.at(3) == QLatin1Char('\\')) result = result.mid(4); } free(reparseStructData); } return result; }
void CqTiffOutputFile::nextSubImage(const CqTexFileHeader& header) { m_fileHandle->writeDirectory(); m_currentLine = 0; // Write header data to this directory. CqTiffDirHandle dirHandle(m_fileHandle); dirHandle.writeHeader(header); }
void CqTiffOutputFile::writeTiledPixels(const CqMixedImageBuffer& buffer) { SqTileInfo tileInfo = m_header.find<Attr::TileInfo>(); // Check that the buffer has a height that is a multiple of the tile height. if( buffer.height() % tileInfo.height != 0 && m_currentLine + buffer.height() != m_header.height() ) { AQSIS_THROW_XQERROR(XqInternal, EqE_Bug, "pixel buffer with height = " << buffer.height() << " must be a multiple " "of requested tile height (= " << tileInfo.height << ") or run exactly to " "the full image height (= " << m_header.height() << ")."); } CqTiffDirHandle dirHandle(m_fileHandle); const TqUint8* rawBuf = buffer.rawData(); const TqInt bytesPerPixel = buffer.channelList().bytesPerPixel(); boost::scoped_array<TqUint8> tileBuf( new TqUint8[bytesPerPixel*tileInfo.width*tileInfo.height]); const TqInt rowStride = bytesPerPixel*buffer.width(); const TqInt tileRowStride = bytesPerPixel*tileInfo.width; const TqInt endLine = m_currentLine + buffer.height(); const TqInt numTileCols = (buffer.width()-1)/tileInfo.width + 1; for(TqInt line = m_currentLine; line < endLine; line += tileInfo.height) { // srcBuf will point to the beginning of the memory region which will // become the tile. const TqUint8* srcBuf = rawBuf; for(TqInt tileCol = 0; tileCol < numTileCols; ++tileCol) { const TqInt tileDataLen = min(tileRowStride, rowStride - tileCol*tileRowStride); const TqInt tileDataHeight = min(tileInfo.height, buffer.height() - line); // Copy parts of the scanlines into the tile buffer. stridedCopy(tileBuf.get(), tileRowStride, srcBuf, rowStride, tileDataHeight, tileDataLen); TIFFWriteTile(dirHandle.tiffPtr(), reinterpret_cast<tdata_t>(const_cast<TqUint8*>(tileBuf.get())), tileCol*tileInfo.width, line, 0, 0); srcBuf += tileRowStride; } rawBuf += rowStride*tileInfo.height; } m_currentLine = endLine; }
Link createJunction(const QString &linkPath, const QString &targetPath) { if (!QDir().mkpath(linkPath)) { qWarning() << "Cannot create the mount directory" << linkPath; return Link(linkPath); } FileHandleWrapper dirHandle(linkPath); if (dirHandle.handle() == INVALID_HANDLE_VALUE) { qWarning() << "Cannot open" << linkPath << ":" << QInstaller::windowsErrorString(GetLastError()); return Link(linkPath); } const QString szDestDir = QString::fromLatin1("\\??\\").arg(targetPath).replace(QLatin1Char('/'), QLatin1Char('\\')); // Allocates a block of memory for an array of num elements(1) and initializes all its bits to zero. REPARSE_DATA_BUFFER* reparseStructData = (REPARSE_DATA_BUFFER*)calloc(1, MAXIMUM_REPARSE_DATA_BUFFER_SIZE); reparseStructData->Reserved = 0; reparseStructData->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; reparseStructData->MountPointReparseBuffer.PrintNameLength = 0; reparseStructData->MountPointReparseBuffer.SubstituteNameOffset = 0; reparseStructData->MountPointReparseBuffer.SubstituteNameLength = szDestDir.length(); reparseStructData->MountPointReparseBuffer.PrintNameOffset = szDestDir.length() + sizeof(WCHAR); uint spaceAfterGeneralData = sizeof(USHORT) * 5 + sizeof(WCHAR); //should be 12 reparseStructData->ReparseDataLength = szDestDir.length() + spaceAfterGeneralData; #ifndef Q_CC_MINGW StringCchCopy(reparseStructData->MountPointReparseBuffer.PathBuffer, 1024, (wchar_t*)szDestDir.utf16()); #else wcsncpy(reparseStructData->MountPointReparseBuffer.PathBuffer, (wchar_t*)szDestDir.utf16(), 1024); #endif DWORD bytesReturned; if (!::DeviceIoControl(dirHandle.handle(), FSCTL_SET_REPARSE_POINT, reparseStructData, reparseStructData->ReparseDataLength + REPARSE_DATA_BUFFER_HEADER_SIZE, 0, 0, &bytesReturned, 0)) { qWarning() << "Cannot set the reparse point for" << linkPath << "to" << targetPath << ":" << QInstaller::windowsErrorString(GetLastError()); } return Link(linkPath); }
void CqTiffOutputFile::initialize() { // make sure all channels are the same type. if(m_header.channelList().sharedChannelType() == Channel_TypeUnknown) AQSIS_THROW_XQERROR(XqInternal, EqE_Limit, "tiff cannot store multiple pixel types in the same image"); // Use lzw compression if the compression hasn't been specified. if(!m_header.findPtr<Attr::Compression>()) m_header.set<Attr::Compression>("lzw"); // Timestamp the file. m_header.setTimestamp(); /// \todo more checking & validation of the header. // Now load the initial settings into the TIFF. CqTiffDirHandle dirHandle(m_fileHandle); dirHandle.writeHeader(m_header); }
void CqTiffOutputFile::writeScanlinePixels(const CqMixedImageBuffer& buffer) { CqTiffDirHandle dirHandle(m_fileHandle); // Simplest possible implementation using scanline TIFF I/O. Could use // Strip-based IO if performance is ever a problem here. const TqUint8* rawBuf = buffer.rawData(); const TqInt rowStride = buffer.channelList().bytesPerPixel()*buffer.width(); const TqInt endLine = m_currentLine + buffer.height(); // Temporary buffer for scanlines. We need to copy the data into here // since libtiff trashes the buffer when encoding is turned on. (The TIFF // docs don't seem to mention this though, ugh.) boost::scoped_array<TqUint8> lineBuf(new TqUint8[rowStride]); for(TqInt line = m_currentLine; line < endLine; ++line) { // copy the data into temp buffer. std::memcpy(lineBuf.get(), rawBuf, rowStride); // write data TIFFWriteScanline( dirHandle.tiffPtr(), reinterpret_cast<tdata_t>(lineBuf.get()), static_cast<uint32>(line) ); rawBuf += rowStride; } m_currentLine = endLine; }
bool removeJunction(const QString &path) { // Allocates a block of memory for an array of num elements(1) and initializes all its bits to zero. REPARSE_DATA_BUFFER* reparseStructData = (REPARSE_DATA_BUFFER*)calloc(1, MAXIMUM_REPARSE_DATA_BUFFER_SIZE); reparseStructData->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; { // extra scope because we need to close the dirHandle before we can remove that directory FileHandleWrapper dirHandle(path); DWORD bytesReturned; if (!::DeviceIoControl(dirHandle.handle(), FSCTL_DELETE_REPARSE_POINT, reparseStructData, REPARSE_GUID_DATA_BUFFER_HEADER_SIZE, 0, 0, &bytesReturned, 0)) { qWarning() << "Cannot remove the reparse point" << path << ":" << QInstaller::windowsErrorString(GetLastError()); return false; } } return QDir().rmdir(path); }