예제 #1
0
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;
}
예제 #4
0
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;
}
예제 #7
0
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);
}