Ejemplo n.º 1
0
// If there is Reprase data already, it still writes new Reparse data
bool SetReparseData(CFSTR path, bool isDir, const void *data, DWORD size)
{
  NFile::NFind::CFileInfo fi;
  if (fi.Find(path))
  {
    if (fi.IsDir() != isDir)
    {
      ::SetLastError(ERROR_DIRECTORY);
      return false;
    }
  }
  else
  {
    if (isDir)
    {
      if (!NDir::CreateComplexDir(path))
        return false;
    }
    else
    {
      CreatePrefixDirOfFile(path);
      COutFile file;
      if (!file.Create(path, CREATE_NEW))
        return false;
    }
  }

  COutFile file;
  if (!file.Open(path,
      FILE_SHARE_WRITE,
      OPEN_EXISTING,
      FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS))
    return false;

  DWORD returnedSize;
  if (!file.DeviceIoControl(my_FSCTL_SET_REPARSE_POINT, (void *)data, size, NULL, 0, &returnedSize))
    return false;
  return true;
}
Ejemplo n.º 2
0
//TODO: clean and optimize!
STDMETHODIMP ExtractCallback::GetStream( UInt32                 index,
                                         ISequentialOutStream** outStream,
                                         Int32                  askExtractMode ) {
    *outStream = 0;
    mOutFileStream.Release();
    // Get Name
    NCOM::CPropVariant prop;
    RINOK( mArchiveHandler->GetProperty( index, kpidPath, &prop ) );
    wstring fullPath;

    if ( prop.vt == VT_EMPTY ) {
        fullPath = kEmptyFileAlias;
    } else {
        if ( prop.vt != VT_BSTR ) {
            return E_FAIL;
        }

        fullPath = prop.bstrVal;
    }

    mFilePath = fullPath;

    if ( askExtractMode != NArchive::NExtract::NAskMode::kExtract ) {
        return S_OK;
    }


    // Get Attrib
    NCOM::CPropVariant prop2;
    RINOK( mArchiveHandler->GetProperty( index, kpidAttrib, &prop2 ) );

    if ( prop2.vt == VT_EMPTY ) {
        mProcessedFileInfo.Attrib = 0;
        mProcessedFileInfo.AttribDefined = false;
    } else {
        if ( prop2.vt != VT_UI4 ) {
            return E_FAIL;
        }

        mProcessedFileInfo.Attrib = prop2.ulVal;
        mProcessedFileInfo.AttribDefined = true;
    }

    RINOK( IsArchiveItemFolder( mArchiveHandler, index, mProcessedFileInfo.isDir ) );
    // Get Modified Time
    NCOM::CPropVariant prop3;
    RINOK( mArchiveHandler->GetProperty( index, kpidMTime, &prop3 ) );
    mProcessedFileInfo.MTimeDefined = false;

    switch ( prop3.vt ) {
        case VT_EMPTY:
            // mProcessedFileInfo.MTime = _utcMTimeDefault;
            break;

        case VT_FILETIME:
            mProcessedFileInfo.MTime = prop3.filetime;
            mProcessedFileInfo.MTimeDefined = true;
            break;

        default:
            return E_FAIL;
    }

    // Get Size
    NCOM::CPropVariant prop4;
    RINOK( mArchiveHandler->GetProperty( index, kpidSize, &prop4 ) );
    bool newFileSizeDefined = ( prop4.vt != VT_EMPTY );
    UInt64 newFileSize;

    if ( newFileSizeDefined ) {
        //taken from ConvertPropVariantToUInt64
        switch ( prop4.vt ) {
            case VT_UI1: newFileSize = prop4.bVal;
                break;
            case VT_UI2: newFileSize = prop4.uiVal;
                break;
            case VT_UI4: newFileSize = prop4.ulVal;
                break;
            case VT_UI8: newFileSize = ( UInt64 )prop4.uhVal.QuadPart;
                break;
            default:
                mErrorMessage = L"151199";
                return E_FAIL;
        }

        //newFileSize = ConvertPropVariantToUInt64( prop4 );
    }


    // Create folders for file
    size_t slashPos = mFilePath.rfind( WSTRING_PATH_SEPARATOR );

    if ( slashPos != wstring::npos ) {
        NFile::NDir::CreateComplexDir( ( mDirectoryPath + mFilePath.substr( 0,
                                                                                        slashPos ) ).c_str() );
    }
    wstring fullProcessedPath = mDirectoryPath + mFilePath;
    mDiskFilePath = fullProcessedPath;

    if ( mProcessedFileInfo.isDir ) {
        NFile::NDir::CreateComplexDir( fullProcessedPath.c_str() );
    } else {
        NFile::NFind::CFileInfo fi;

        if ( mOpener.fileCallback() ) {
            wstring filename;
            filesystem::fsutil::filename( fullProcessedPath, filename, true );
            mOpener.fileCallback()( filename );
        }

        if ( fi.Find( fullProcessedPath.c_str() ) ) {
            if ( !NFile::NDir::DeleteFileAlways( fullProcessedPath.c_str() ) ) {
                //cerr << UString( kCantDeleteOutputFile ) << fullProcessedPath << endl;
                //throw BitException( kCantDeleteOutputFile + fullProcessedPath );
                mErrorMessage = kCantDeleteOutputFile + fullProcessedPath;
                return E_ABORT;
            }
        }

        mOutFileStreamSpec = new COutFileStream;
        CMyComPtr< ISequentialOutStream > outStreamLoc( mOutFileStreamSpec );

        if ( !mOutFileStreamSpec->Open( fullProcessedPath.c_str(), CREATE_ALWAYS ) ) {
            //cerr <<  ( UString )L"cannot open output file " + fullProcessedPath << endl;
            //throw BitException( L"cannot open output file " + fullProcessedPath );
            mErrorMessage = L"Cannot open output file " + fullProcessedPath;
            return E_ABORT;
        }

        mOutFileStream = outStreamLoc;
        *outStream = outStreamLoc.Detach();
    }

    return S_OK;
}