bool CCollectionFile::InitFromLink(CString sLink)
{
	CED2KLink* pLink = NULL;
	CED2KFileLink* pFileLink = NULL;
	try 
	{
		pLink = CED2KLink::CreateLinkFromUrl(sLink);
		if(!pLink)
			throw GetResString(IDS_ERR_NOTAFILELINK);
		pFileLink = pLink->GetFileLink();
		if (!pFileLink)
			throw GetResString(IDS_ERR_NOTAFILELINK);
	} 
	catch (CString error) 
	{
		CString strBuffer;
		strBuffer.Format(GetResString(IDS_ERR_INVALIDLINK),error);
		LogError(LOG_STATUSBAR, GetResString(IDS_ERR_LINKERROR), strBuffer);
		return false;
	}

	taglist.Add(new CTag(FT_FILEHASH, pFileLink->GetHashKey()));
	md4cpy(m_abyFileHash, pFileLink->GetHashKey());

	taglist.Add(new CTag(FT_FILESIZE, pFileLink->GetSize()));
	SetFileSize(pFileLink->GetSize());

	taglist.Add(new CTag(FT_FILENAME, pFileLink->GetName()));
	SetFileName(pFileLink->GetName(), false, false);

	delete pLink;
	return true;
}
Example #2
0
/////////////////////////////////////////////////////////////////////////////////////////
///CAICHRecoveryHashSet
CAICHRecoveryHashSet::CAICHRecoveryHashSet(CKnownFile* pOwner, EMFileSize nSize)
	: m_pHashTree(0, true, PARTSIZE)
{
	m_eStatus = AICH_EMPTY;
	m_pOwner = pOwner;
	if (nSize != (uint64)0)
		SetFileSize(nSize);
}
Example #3
0
FILE *fopen(char *name, char *mode)
{
long handle, lmode, fcreate, fdiscard, erc, fappend;

	erc = 0;
	handle = 0;
	fappend = 0;
	fcreate = 0;
	fdiscard = 0;

	if (*mode=='r')
		lmode = 0;
	else if (*mode=='w')
	{
		lmode = 1;
		fcreate = 1;
		fdiscard = 1;
	}
	else if (*mode=='a') {
		fappend = 1;
		fcreate = 1;
		lmode = 1;
	}
	else
		return (0);

	/* see if they want to update also */

	if ((mode[1] == '+') || (mode[2] == '+'))
		lmode = 1;

	if (fcreate)		/* try to create with archive bit set */
		erc =  CreateFile(name, strlen(name), 0x20);

	if (erc == ErcDupName)
		erc = 0;

	if (!erc)
		erc =  OpenFile(name, strlen(name), lmode, 1, &handle);
	if (erc)
	{
		error_num = erc;
		handle = 0;
	}
	if ((!erc) && (fappend))
	{
		erc = SetFileLFA(handle, 0xffffffff);		/* EOF */
	}
	if ((!erc) && (fdiscard))
	{
		erc = SetFileSize(handle, 0);		/*  */
	}

	return (handle);
}
Example #4
0
CBarShader::CBarShader(uint32_t dwHeight, uint32_t dwWidth, COLORREF crColor /*= 0*/, uint64_t qwFileSize /*= 1*/)
{
	m_iWidth = dwWidth;
	m_iHeight = dwHeight;
	m_qwFileSize = 0;
	m_Spans.SetAt(0, crColor);
	m_Spans.SetAt(qwFileSize, 0);
	m_pdblModifiers = NULL;
	m_bIsPreview = false;
	m_used3dlevel = 0;
	SetFileSize(qwFileSize);
}
Example #5
0
CKnownFile::CKnownFile(CEC_SharedFile_Tag *tag) : CECID(tag->ID())
{
	Init();
	
	SetFileName(CPath(tag->FileName()));
	m_abyFileHash = tag->FileHash();
	SetFileSize(tag->SizeFull());
	m_AvailPartFrequency.insert(m_AvailPartFrequency.end(), m_iPartCount, 0);
	m_iUpPriorityEC = tag->Prio();
	m_AICHMasterHash = tag->GetAICHHash();
	m_filePath = CPath(tag->FilePath());
}
Example #6
0
static NTSTATUS SetFileSize(FSP_FILE_SYSTEM *FileSystem,
    FSP_FSCTL_TRANSACT_REQ *Request,
    PVOID FileNode0, UINT64 NewSize, BOOLEAN SetAllocationSize,
    FSP_FSCTL_FILE_INFO *FileInfo)
{
    MEMFS *Memfs = (MEMFS *)FileSystem->UserContext;
    MEMFS_FILE_NODE *FileNode = (MEMFS_FILE_NODE *)FileNode0;

    if (SetAllocationSize)
    {
        if (FileNode->FileInfo.AllocationSize != NewSize)
        {
            if (NewSize > Memfs->MaxFileSize)
                return STATUS_DISK_FULL;

            PVOID FileData = realloc(FileNode->FileData, (size_t)NewSize);
            if (0 == FileData && 0 != NewSize)
                return STATUS_INSUFFICIENT_RESOURCES;

            FileNode->FileData = FileData;

            FileNode->FileInfo.AllocationSize = NewSize;
            if (FileNode->FileInfo.FileSize > NewSize)
                FileNode->FileInfo.FileSize = NewSize;
        }
    }
    else
    {
        if (FileNode->FileInfo.FileSize != NewSize)
        {
            if (FileNode->FileInfo.AllocationSize < NewSize)
            {
                UINT64 AllocationUnit = MEMFS_SECTOR_SIZE * MEMFS_SECTORS_PER_ALLOCATION_UNIT;
                UINT64 AllocationSize = (NewSize + AllocationUnit - 1) / AllocationUnit * AllocationUnit;

                NTSTATUS Result = SetFileSize(FileSystem, Request, FileNode, AllocationSize, TRUE,
                    FileInfo);
                if (!NT_SUCCESS(Result))
                    return Result;
            }

            if (FileNode->FileInfo.FileSize < NewSize)
                memset((PUINT8)FileNode->FileData + FileNode->FileInfo.FileSize, 0,
                    (size_t)(NewSize - FileNode->FileInfo.FileSize));
            FileNode->FileInfo.FileSize = NewSize;
        }
    }

    *FileInfo = FileNode->FileInfo;

    return STATUS_SUCCESS;
}
Example #7
0
//#warning Experimental: Construct a CKnownFile from a CSearchFile
CKnownFile::CKnownFile(const CSearchFile &searchFile)
:
// This will copy the file hash
CAbstractFile(static_cast<const CAbstractFile &>(searchFile))
{
	Init();
	
	// Use CKnownFile::SetFileName()
	SetFileName(searchFile.GetFileName());

	// Use CKnownFile::SetFileSize()
	SetFileSize(searchFile.GetFileSize());
}
Example #8
0
static NTSTATUS Write(FSP_FILE_SYSTEM *FileSystem,
    FSP_FSCTL_TRANSACT_REQ *Request,
    PVOID FileNode0, PVOID Buffer, UINT64 Offset, ULONG Length,
    BOOLEAN WriteToEndOfFile, BOOLEAN ConstrainedIo,
    PULONG PBytesTransferred, FSP_FSCTL_FILE_INFO *FileInfo)
{
#if defined(DEBUG_BUFFER_CHECK)
    SYSTEM_INFO SystemInfo;
    GetSystemInfo(&SystemInfo);
    for (PUINT8 P = (PUINT8)Buffer, EndP = P + Length; EndP > P; P += SystemInfo.dwPageSize)
        __try
        {
            *P = *P | 0;
            assert(0);
        }
        __except (EXCEPTION_EXECUTE_HANDLER)
        {
            /* ignore! */
        }
#endif

    MEMFS_FILE_NODE *FileNode = (MEMFS_FILE_NODE *)FileNode0;
    UINT64 EndOffset;

    if (ConstrainedIo)
    {
        if (Offset >= FileNode->FileInfo.FileSize)
            return STATUS_SUCCESS;
        EndOffset = Offset + Length;
        if (EndOffset > FileNode->FileInfo.FileSize)
            EndOffset = FileNode->FileInfo.FileSize;
    }
    else
    {
        if (WriteToEndOfFile)
            Offset = FileNode->FileInfo.FileSize;
        EndOffset = Offset + Length;
        if (EndOffset > FileNode->FileInfo.FileSize)
            SetFileSize(FileSystem, Request, FileNode, EndOffset, FALSE, FileInfo);
    }

    memcpy((PUINT8)FileNode->FileData + Offset, Buffer, (size_t)(EndOffset - Offset));

    *PBytesTransferred = (ULONG)(EndOffset - Offset);
    *FileInfo = FileNode->FileInfo;

    return STATUS_SUCCESS;
}
CCollectionFile::CCollectionFile(CFileDataIO* in_data)
{
	UINT tagcount = in_data->ReadUInt32();

	for (UINT i = 0; i < tagcount; i++)
	{
		CTag* toadd = new CTag(in_data, true);
		if (toadd)
			taglist.Add(toadd);
	}
	
	CTag* pTagHash = GetTag(FT_FILEHASH);
	if(pTagHash)
		SetFileHash(pTagHash->GetHash());
	else
		ASSERT(0);
	
	// here we have two choices
	//	- if the server/client sent us a filetype, we could use it (though it could be wrong)
	//	- we always trust our filetype list and determine the filetype by the extension of the file
	//
	// if we received a filetype from server, we use it.
	// if we did not receive a filetype, we determine it by examining the file's extension.
	//
	// but, in no case, we will use the receive file type when adding this search result to the download queue, to avoid
	// that we are using 'wrong' file types in part files. (this has to be handled when creating the part files)
	const CString& rstrFileType = GetStrTagValue(FT_FILETYPE);
	SetFileName(GetStrTagValue(FT_FILENAME), false, rstrFileType.IsEmpty());
	SetFileSize(GetIntTagValue(FT_FILESIZE));
	if (!rstrFileType.IsEmpty())
	{
		if (_tcscmp(rstrFileType, _T(ED2KFTSTR_PROGRAM))==0)
		{
			CString strDetailFileType = GetFileTypeByName(GetFileName());
			if (!strDetailFileType.IsEmpty())
				SetFileType(strDetailFileType);
			else
				SetFileType(rstrFileType);
		}
		else
			SetFileType(rstrFileType);
	}

	if(!GetFileSize() || !GetFileName().Compare(_T("")))
		ASSERT(0);
}
Example #10
0
void IDownloadTask::OnProgressUpdate(unsigned int downloadTotal, unsigned downloadNow)
{
    if (downloadTotal > 0 && downloadNow > 0)
    {
        if (0 == GetLastOffSet())
        {
            SetFileSize(downloadTotal);
        }
        SetLastOffSet(GetFileSize() - downloadTotal + downloadNow);
        time_t tnow;
        time(&tnow);
        if (tnow != m_lastUpdateTime || downloadNow == downloadTotal)
        {
            m_lastUpdateTime = tnow;
            FireDownloadProgressUpdateEvent();
        }
    }
}
Example #11
0
/******************************************************************
 * my_truncate
 *
 * is used to implement SetFileSize. Would be nicer, if 
 * ACTION_SET_FILE_SIZE would call host SetFileSize directly,
 * but we would have to modify ../filesys.cpp, which I wanted
 * to avoid so far..
 *
 * WARNING: SetFileSize seems to be broken, at least for
 *          AROS/hosted filesystems !? Even the test
 *          in the AROS svn fails..
 ******************************************************************/
int my_truncate (const TCHAR *name, uae_u64 len) {

  LONG newsize;
  BPTR fh;
  int ret=0;

  DebOut("name: %s, len: %d\n", name, len);

  if(len>MAXFILESIZE32) {
    DebOut("filesize is >2GB!\n");
    return -1;
  }

  fh=Open(name, MODE_READWRITE);
  if(!fh) {
    SetLastError(IoErr());
    DebOut("return -1 (%d)\n", IoErr());

    return -1;
  }

#warning SetFileSize might be broken..
  newsize=SetFileSize(fh, (LONG) len, OFFSET_BEGINNING);

  DebOut("newsize: %d\n", newsize);

  if(newsize==-1) {
    SetLastError(IoErr());
    DebOut("return -1 (%d)\n", IoErr());
    ret=-1;
  }

  if(fh) {
    Close(fh);
  }

  return ret;
}
Example #12
0
EFI_STATUS
SetFileInfo (
  IN BOOTMON_FS_INSTANCE *Instance,
  IN BOOTMON_FS_FILE     *File,
  IN UINTN                BufferSize,
  IN EFI_FILE_INFO       *Info
  )
{
  EFI_STATUS             Status;

  Status = EFI_SUCCESS;

  // Note that a call to this function on a file opened read-only is only
  // invalid if it actually changes fields, so  we don't immediately fail if the
  // OpenMode is wrong.
  // Also note that the only fields supported are filename and size, others are
  // ignored.

  if (File != Instance->RootFile) {
    if (!(File->OpenMode & EFI_FILE_MODE_WRITE)) {
      return EFI_ACCESS_DENIED;
    }

    Status = SetFileName (File, Info->FileName);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    // Update file size
    Status = SetFileSize (Instance, File, Info->FileSize);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }
  return Status;
}
Example #13
0
/**
  Set information about a file.

  @param[in]  Instance  A pointer to the description of the volume
                        the file belongs to.
  @param[in]  File      A pointer to the description of the file.
  @param[in]  Info      A pointer to the file information to write.

  @retval  EFI_SUCCESS           The information was set.
  @retval  EFI_ACCESS_DENIED     An attempt is being made to change the
                                 EFI_FILE_DIRECTORY Attribute.
  @retval  EFI_ACCESS_DENIED     The file was opened in read-only mode and an
                                 attempt is being made to modify a field other
                                 than Attribute.
  @retval  EFI_ACCESS_DENIED     An attempt is made to change the name of a file
                                 to a file that is already present.
  @retval  EFI_WRITE_PROTECTED   An attempt is being made to modify a read-only
                                 attribute.
  @retval  EFI_OUT_OF_RESOURCES  An allocation needed to process the request
                                 failed.

**/
STATIC
EFI_STATUS
SetFileInfo (
  IN BOOTMON_FS_INSTANCE  *Instance,
  IN BOOTMON_FS_FILE      *File,
  IN EFI_FILE_INFO        *Info
  )
{
  EFI_STATUS  Status;
  BOOLEAN     FileSizeIsDifferent;
  BOOLEAN     FileNameIsDifferent;
  BOOLEAN     TimeIsDifferent;

  //
  // A directory can not be changed to a file and a file can
  // not be changed to a directory.
  //
  if ((Info->Attribute & EFI_FILE_DIRECTORY)      !=
      (File->Info->Attribute & EFI_FILE_DIRECTORY)  ) {
    return EFI_ACCESS_DENIED;
  }

  FileSizeIsDifferent = (Info->FileSize != File->Info->FileSize);
  FileNameIsDifferent = (StrnCmp (
                           Info->FileName,
                           File->Info->FileName,
                           MAX_NAME_LENGTH - 1
                           ) != 0);
  //
  // Check if the CreateTime, LastAccess or ModificationTime
  // have been changed. The file system does not support file
  // timestamps thus the three times in "File->Info" are
  // always equal to zero. The following comparison actually
  // checks if all three times are still equal to 0 or not.
  //
  TimeIsDifferent = CompareMem (
                      &Info->CreateTime,
                      &File->Info->CreateTime,
                      3 * sizeof (EFI_TIME)
                      ) != 0;

  //
  // For a file opened in read-only mode, only the Attribute field can be
  // modified. The root directory open mode is forced to read-only at opening
  // thus the following test protects the root directory to be somehow modified.
  //
  if (File->OpenMode == EFI_FILE_MODE_READ) {
    if (FileSizeIsDifferent || FileNameIsDifferent || TimeIsDifferent) {
      return EFI_ACCESS_DENIED;
    }
  }

  if (TimeIsDifferent) {
    return EFI_WRITE_PROTECTED;
  }

  if (FileSizeIsDifferent) {
    Status = SetFileSize (Instance, File, Info->FileSize);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  //
  // Note down in RAM the Attribute field but we can not
  // ask to store it in flash for the time being.
  //
  File->Info->Attribute = Info->Attribute;

  if (FileNameIsDifferent) {
    Status = SetFileName (Instance, File, Info->FileName);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  return EFI_SUCCESS;
}
Example #14
0
int ftruncate(int fd, int newsize)
{
   int result = SetFileSize(__stdfiledes[fd],newsize,OFFSET_BEGINNING);
   if (result != -1) return 0;
   return(result);
}
Example #15
0
bool CKnownFile::LoadTagsFromFile(const CFileDataIO* file)
{
	uint32 tagcount = file->ReadUInt32();
	for (uint32 j = 0; j != tagcount; ++j) {
		CTag newtag(*file, true);
		switch(newtag.GetNameID()){
			case FT_FILENAME:
				if (GetFileName().IsOk()) {
					// Unlike eMule, we actually prefer the second
					// filename tag, since we use it to specify the
					// 'universial' filename (see CPath::ToUniv).
					CPath path = CPath::FromUniv(newtag.GetStr());

					// May be invalid, if from older versions where
					// unicoded filenames be saved as empty-strings.
					if (path.IsOk()) {
						SetFileName(path);
					}
				} else {
					SetFileName(CPath(newtag.GetStr()));
				}
				break;
			
			case FT_FILESIZE:
				SetFileSize(newtag.GetInt());
				m_AvailPartFrequency.clear();
				m_AvailPartFrequency.insert(
					m_AvailPartFrequency.begin(),
					GetPartCount(), 0);
				break;
			
			case FT_ATTRANSFERRED:
				statistic.alltimetransferred += newtag.GetInt();
				break;
			
			case FT_ATTRANSFERREDHI:
				statistic.alltimetransferred =
					(((uint64)newtag.GetInt()) << 32) +
					((uint64)statistic.alltimetransferred);
				break;
			
			case FT_ATREQUESTED:
				statistic.alltimerequested = newtag.GetInt();
				break;
			
			case FT_ATACCEPTED:
				statistic.alltimeaccepted = newtag.GetInt();
				break;
			
			case FT_ULPRIORITY:
				m_iUpPriority = newtag.GetInt();
				if( m_iUpPriority == PR_AUTO ){
					m_iUpPriority = PR_HIGH;
					m_bAutoUpPriority = true;
				} else {
					if (	m_iUpPriority != PR_VERYLOW &&
						m_iUpPriority != PR_LOW &&
						m_iUpPriority != PR_NORMAL &&
						m_iUpPriority != PR_HIGH &&
						m_iUpPriority != PR_VERYHIGH &&
						m_iUpPriority != PR_POWERSHARE) {
						m_iUpPriority = PR_NORMAL;
					}
					
					m_bAutoUpPriority = false;
				}
				break;
			
			case FT_PERMISSIONS:
				// Ignore it, it's not used anymore.
				break;
			
			case FT_AICH_HASH: {
				CAICHHash hash;
				bool hashSizeOk =
					hash.DecodeBase32(newtag.GetStr()) == CAICHHash::GetHashSize();
				wxASSERT(hashSizeOk);
				if (hashSizeOk) {
					m_pAICHHashSet->SetMasterHash(hash, AICH_HASHSETCOMPLETE);
				}
				break;
			}
			
			case FT_KADLASTPUBLISHSRC:
				SetLastPublishTimeKadSrc( newtag.GetInt(), 0 );
				
				if(GetLastPublishTimeKadSrc() > (uint32)time(NULL)+KADEMLIAREPUBLISHTIMES) {
					//There may be a posibility of an older client that saved a random number here.. This will check for that..
					SetLastPublishTimeKadSrc(0, 0);
				}
				break;
			
			case FT_KADLASTPUBLISHNOTES:
				SetLastPublishTimeKadNotes( newtag.GetInt() );
				break;
			
			case FT_KADLASTPUBLISHKEY:
				// Just purge it
				wxASSERT( newtag.IsInt() );
				break;
				
			default:
				// Store them here and write them back on saving.
				m_taglist.push_back(newtag);
		}	
	}
	
	return true;
}
Example #16
0
status_t 
Inode::Append(Transaction& transaction, off_t bytes)
{
	return SetFileSize(transaction, Size() + bytes);
}
Example #17
0
bool CmdLineParser::_ReadParametersFromCmdLine(const int argc, const char *argv[], Profile *pProfile, struct Synchronization *synch)
{
    /* Process any command-line options */
    int nParamCnt = argc - 1;
    const char** args = argv + 1;

    // create targets
    vector<Target> vTargets;
    int iFirstFile = -1;
    for (int i = 1; i < argc; i++)
    {
        if (argv[i][0] != '-' && argv[i][0] != '/')
        {
            iFirstFile = i;
            Target target;
            target.SetPath(argv[i]);
            vTargets.push_back(target);
        }
    }

    // find block size (other parameters may be stated in terms of blocks)
    for (int x = 1; x < argc; ++x)
    {
        if ((nullptr != argv[x]) && (('-' == argv[x][0]) || ('/' == argv[x][0])) && ('b' == argv[x][1]) && ('\0' != argv[x][2]))
        {
            _dwBlockSize = 0;
            UINT64 ullBlockSize;
            if (_GetSizeInBytes(&argv[x][2], ullBlockSize))
            {
                for (auto i = vTargets.begin(); i != vTargets.end(); i++)
                {
                    // TODO: UINT64->DWORD
                    i->SetBlockSizeInBytes((DWORD)ullBlockSize);
                }
            }
            else
            {
                fprintf(stderr, "Invalid block size passed to -b\n");
                exit(1);
            }
            _dwBlockSize = (DWORD)ullBlockSize;
            break;
        }
    }

    TimeSpan timeSpan;
    bool bExit = false;
    while (nParamCnt)
    {
        const char* arg = *args;
        bool fError = false;

        // check if it is a parameter or already path
        if ('-' != *arg && '/' != *arg)
        {
            break;
        }

        // skip '-' or '/'
        ++arg;

        if ('\0' == *arg)
        {
            fprintf(stderr, "Invalid option\n");
            exit(1);
        }

        switch (*arg)
        {
        case '?':
            _DisplayUsageInfo(argv[0]);
            exit(0);

        case 'a':    //affinity
            //-a1,2,3,4 (assign threads to cpus 1,2,3,4 (round robin))
            if (!_ParseAffinity(arg, &timeSpan))
            {
                fError = true;
            }
            break;

        case 'b':    //block size
            // nop - block size has been taken care of before the loop
            break;

        case 'B':    //base file offset (offset from the beggining of the file), cannot be used with 'random'
            if (*(arg + 1) != '\0')
            {
                UINT64 cb;
                if (_GetSizeInBytes(arg + 1, cb))
                {
                    for (auto i = vTargets.begin(); i != vTargets.end(); i++)
                    {
                        i->SetBaseFileOffsetInBytes(cb);
                    }
                }
                else
                {
                    fprintf(stderr, "Invalid base file offset passed to -B\n");
                    fError = true;
                }
            }
            else
            {
                fError = true;
            }
            break;

        case 'c':    //create file of the given size
            if (*(arg + 1) != '\0')
            {
                UINT64 cb;
                if (_GetSizeInBytes(arg + 1, cb))
                {
                    for (auto i = vTargets.begin(); i != vTargets.end(); i++)
                    {
                        i->SetFileSize(cb);
                        i->SetCreateFile(true);
                    }
                }
                else
                {
                    fprintf(stderr, "Invalid file size passed to -c\n");
                    fError = true;
                }
            }
            else
            {
                fError = true;
            }
            break;

        case 'C':    //cool down time
            {
                int c = atoi(arg + 1);
                if (c >= 0)
                {
                    timeSpan.SetCooldown(c);
                }
                else
                {
                    fError = true;
                }
            }
            break;

        case 'd':    //duration
            {
                int x = atoi(arg + 1);
                if (x > 0)
                {
                    timeSpan.SetDuration(x);
                }
                else
                {
                    fError = true;
                }
            }
            break;

        case 'D':    //standard deviation
            {
                timeSpan.SetCalculateIopsStdDev(true);

                int x = atoi(arg + 1);
                if (x > 0)
                {
                    timeSpan.SetIoBucketDurationInMilliseconds(x);
                }
            }
            break;

        case 'e':    //etw
            if (!_ParseETWParameter(arg, pProfile))
            {
                fError = true;
            }
            break;

        case 'f':
            if ('r' == *(arg + 1))
            {
                for (auto i = vTargets.begin(); i != vTargets.end(); i++)
                {
                    i->SetRandomAccessHint(true);
                }
            }
            else if ('s' == *(arg + 1))
            {
                for (auto i = vTargets.begin(); i != vTargets.end(); i++)
                {
                    i->SetSequentialScanHint(true);
                }
            }
            else
            {
                if (*(arg + 1) != '\0')
                {
                    UINT64 cb;
                    if (_GetSizeInBytes(arg + 1, cb))
                    {
                        for (auto i = vTargets.begin(); i != vTargets.end(); i++)
                        {
                            i->SetMaxFileSize(cb);
                        }
                    }
                    else
                    {
                        fprintf(stderr, "Invalid max file size passed to -f\n");
                        fError = true;
                    }
                }
                else
                {
                    fError = true;
                }
            }
            break;

        case 'F':    //total number of threads
            {
                int c = atoi(arg + 1);
                if (c > 0)
                {
                    timeSpan.SetThreadCount(c);
                }
                else
                {
                    fError = true;
                }
            }
            break;

        case 'g':    //throughput in bytes per millisecond
            {
                int c = atoi(arg + 1);
                if (c > 0)
                {
                    for (auto i = vTargets.begin(); i != vTargets.end(); i++)
                    {
                        i->SetThroughput(c);
                    }
                }
                else
                {
                    fError = true;
                }
            }
            break;

        case 'h':    //disable both software and hardware caching
            for (auto i = vTargets.begin(); i != vTargets.end(); i++)
            {
                i->SetDisableAllCache(true);
            }
            break;

        case 'i':    //number of IOs to issue before think time
            {
                int c = atoi(arg + 1);
                if (c > 0)
                {
                    for (auto i = vTargets.begin(); i != vTargets.end(); i++)
                    {
                        i->SetBurstSize(c);
                        i->SetUseBurstSize(true);
                    }
                }
                else
                {
                    fError = true;
                }
            }
            break;

        case 'j':    //time to wait between bursts of IOs
            {
                int c = atoi(arg + 1);
                if (c > 0)
                {
                    for (auto i = vTargets.begin(); i != vTargets.end(); i++)
                    {
                        i->SetThinkTime(c);
                        i->SetEnableThinkTime(true);
                    }
                }
                else
                {
                    fError = true;
                }
            }
            break;

        case 'I':   //io priority
            {
                int x = atoi(arg + 1);
                if (x > 0 && x < 4)
                {
                    PRIORITY_HINT hint[] = { IoPriorityHintVeryLow, IoPriorityHintLow, IoPriorityHintNormal };
                    for (auto i = vTargets.begin(); i != vTargets.end(); i++)
                    {
                        i->SetIOPriorityHint(hint[x - 1]);
                    }
                }
                else
                {
                    fError = true;
                }
            }
            break;

        case 'l':    //large pages
            for (auto i = vTargets.begin(); i != vTargets.end(); i++)
            {
                i->SetUseLargePages(true);
            }
            break;
        
        case 'L':    //measure latency
            timeSpan.SetMeasureLatency(true);
            break;

        case 'n':    //disable affinity (by default simple affinity is turned on)
            timeSpan.SetDisableAffinity(true);
            break;

        case 'o':    //request count (1==synchronous)
            {
                int c = atoi(arg + 1);
                if (c > 0)
                {
                    for (auto i = vTargets.begin(); i != vTargets.end(); i++)
                    {
                        i->SetRequestCount(c);
                    }
                }
                else
                {
                    fError = true;
                }
            }
            break;

        case 'p':    //start async IO operations with the same offset
            //makes sense only for -o2 and greater
            for (auto i = vTargets.begin(); i != vTargets.end(); i++)
            {
                i->SetUseParallelAsyncIO(true);
            }
            break;

        case 'P':    //show progress every x IO operations
            {
                int c = atoi(arg + 1);
                if (c < 1)
                {
                    c = 65536;
                }
                pProfile->SetProgress(c);
            }
            break;

        case 'r':    //random access
            {
                UINT64 cb = _dwBlockSize;
                if (*(arg + 1) != '\0')
                {
                    if (!_GetSizeInBytes(arg + 1, cb) || (cb == 0))
                    {
                        fprintf(stderr, "Invalid alignment passed to -r\n");
                        fError = true;
                    }
                }
                if (!fError)
                {
                    for (auto i = vTargets.begin(); i != vTargets.end(); i++)
                    {
                        i->SetUseRandomAccessPattern(true);
                        i->SetBlockAlignmentInBytes(cb);
                    }
                }
            }
            break;

        case 'R':    //custom result parser
            if (0 != *(arg + 1))
            {
                const char* pszArg = arg + 1;
                if (strcmp(pszArg, "xml") == 0)
                {
                    pProfile->SetResultsFormat(ResultsFormat::Xml);
                }
                else if (strcmp(pszArg, "text") != 0)
                {
                    fError = true;
                    fprintf(stderr, "Invalid results format: '%s'.\n", pszArg);
                }
            }
            else
            {
                fError = true;
            }
            break;

        case 's':    //stride size
            {
                int idx = 1;

                if ('i' == *(arg + idx))
                {
                    // do interlocked sequential mode
                    // ISSUE-REVIEW: this does nothing if -r is specified
                    // ISSUE-REVIEW: this does nothing if -p is specified
                    // ISSUE-REVIEW: this does nothing if we are single-threaded 
                    for (auto i = vTargets.begin(); i != vTargets.end(); i++)
                    {
                        i->SetUseInterlockedSequential(true);
                    }

                    idx++;
                }
                
                if (*(arg + idx) != '\0')
                {
                    UINT64 cb;
                    if (_GetSizeInBytes(arg + idx, cb))
                    {
                        for (auto i = vTargets.begin(); i != vTargets.end(); i++)
                        {
                            i->SetBlockAlignmentInBytes(cb);
                        }
                    }
                    else
                    {
                        fprintf(stderr, "Invalid stride size passed to -s\n");
                        fError = true;
                    }
                }
            }
            break;

        case 'S':   //disable OS caching (software buffering)
            //IMPORTANT: File access must begin at byte offsets within the file that are integer multiples of the volume's sector size. 
            // File access must be for numbers of bytes that are integer multiples of the volume's sector size. For example, if the sector
            // size is 512 bytes, an application can request reads and writes of 512, 1024, or 2048 bytes, but not of 335, 981, or 7171 bytes. 
            // Buffer addresses for read and write operations should be sector aligned (aligned on addresses in memory that are integer
            // multiples of the volume's sector size). Depending on the disk, this requirement may not be enforced. 
            for (auto i = vTargets.begin(); i != vTargets.end(); i++)
            {
                i->SetDisableOSCache(true);
            }
            break;

        case 't':    //number of threads per file
            {
                int c = atoi(arg + 1);
                if (c > 0)
                {
                    for (auto i = vTargets.begin(); i != vTargets.end(); i++)
                    {
                        i->SetThreadsPerFile(c);
                    }
                }
                else
                {
                    fError = true;
                }
            }
            break;

        case 'T':    //offsets between threads reading the same file
            {
                UINT64 cb;
                if (_GetSizeInBytes(arg + 1, cb) && (cb > 0))
                {
                    for (auto i = vTargets.begin(); i != vTargets.end(); i++)
                    {
                        i->SetThreadStrideInBytes(cb);
                    }
                }
                else
                {
                    fprintf(stderr, "Invalid offset passed to -T\n");
                    fError = true;
                }
            }
            break;

        case 'v':    //verbose mode
            pProfile->SetVerbose(true);
            break;

        case 'w':    //write test [default=read]
            {
                int c = -1;
                if (*(arg + 1) == '\0')
                {
                    c = _ulWriteRatio;
                }
                else
                {
                    c = atoi(arg + 1);
                    if (c < 0 || c > 100)
                    {
                        c = -1;
                        fError = true;
                    }
                }
                if (c != -1)
                {
                    for (auto i = vTargets.begin(); i != vTargets.end(); i++)
                    {
                        i->SetWriteRatio(c);
                    }
                }
            }
            break;

        case 'W':    //warm up time
            {
                int c = atoi(arg + 1);
                if (c >= 0)
                {
                    timeSpan.SetWarmup(c);
                }
                else
                {
                    fError = true;
                }
            }
            break;

        case 'x':    //completion routines
            timeSpan.SetCompletionRoutines(true);
            break;

        case 'y':    //external synchronization
            switch (*(arg + 1))
            {

            case 's':
                _hEventStarted = CreateEvent(NULL, TRUE, FALSE, arg + 2);
                if (NULL == _hEventStarted)
                {
                    fprintf(stderr, "Error creating/opening start notification event: '%s'\n", arg + 2);
                    exit(1);    // TODO: this class shouldn't terminate the process
                }
                break;

            case 'f':
                _hEventFinished = CreateEvent(NULL, TRUE, FALSE, arg + 2);
                if (NULL == _hEventFinished)
                {
                    fprintf(stderr, "Error creating/opening finish notification event: '%s'\n", arg + 2);
                    exit(1);    // TODO: this class shouldn't terminate the process
                }
                break;

            case 'r':
                synch->hStartEvent = CreateEvent(NULL, TRUE, FALSE, arg + 2);
                if (NULL == synch->hStartEvent)
                {
                    fprintf(stderr, "Error creating/opening wait-for-start event: '%s'\n", arg + 2);
                    exit(1);    // TODO: this class shouldn't terminate the process
                }
                break;

            case 'p':
                synch->hStopEvent = CreateEvent(NULL, TRUE, FALSE, arg + 2);
                if (NULL == synch->hStopEvent)
                {
                    fprintf(stderr, "Error creating/opening force-stop event: '%s'\n", arg + 2);
                    exit(1);    // TODO: this class shouldn't terminate the process
                }
                break;

            case 'e':
                {
                    HANDLE hEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, arg + 2);
                    if (NULL == hEvent)
                    {
                        fprintf(stderr, "Error opening event '%s'\n", arg + 2);
                        exit(1);    // TODO: this class shouldn't terminate the process
                    }
                    if (!SetEvent(hEvent))
                    {
                        fprintf(stderr, "Error setting event '%s'\n", arg + 2);
                        exit(1);    // TODO: this class shouldn't terminate the process
                    }
                    CloseHandle(hEvent);
                    printf("Succesfully set event: '%s'\n", arg + 2);
                    bExit = true;
                    break;
                }

            default:
                fError = true;
            }

        case 'z':    //random seed
            if (*(arg + 1) == '\0')
            {
                timeSpan.SetRandSeed((ULONG)GetTickCount64());
            }
            else
            {
                int c = atoi(arg + 1);
                if (c >= 0)
                {
                    timeSpan.SetRandSeed(c);
                }
                else
                {
                    fError = true;
                }
            }
            break;

        case 'Z':    //zero write buffers
            if (*(arg + 1) == '\0')
            {
                for (auto i = vTargets.begin(); i != vTargets.end(); i++)
                {
                    i->SetZeroWriteBuffers(true);
                }
            }
            else
            {
                UINT64 cb = 0;
                string sPath;
                if (_GetRandomDataWriteBufferData(string(arg + 1), cb, sPath) && (cb > 0))
                {
                    for (auto i = vTargets.begin(); i != vTargets.end(); i++)
                    {
                        i->SetRandomDataWriteBufferSize(cb);
                        i->SetRandomDataWriteBufferSourcePath(sPath);
                    }
                }
                else
                {
                    fprintf(stderr, "Invalid size passed to -Z\n");
                    fError = true;
                }
            }
            break;

        default:
            fprintf(stderr, "Invalid option: '%s'\n", arg);
            exit(1);                    // TODO: this class shouldn't terminate the process
        }

        if (fError)
        {
            fprintf(stderr, "Incorrectly provided option: '%s'\n", arg);
            exit(1);                    // TODO: this class shouldn't terminate the process
        }

        --nParamCnt;
        ++args;
    }

    //
    // exit if a user specified an action which was already satisfied and doesn't require running test
    //
    if (bExit)
    {
        printf("Now exiting...\n");
        exit(1);                        // TODO: this class shouldn't terminate the process
    }

    if (vTargets.size() < 1)
    {
        fprintf(stderr, "You need to provide at least one filename\n");
        return false;
    }

    for (auto i = vTargets.begin(); i != vTargets.end(); i++)
    {
        timeSpan.AddTarget(*i);
    }
    pProfile->AddTimeSpan(timeSpan);

    return true;
}