예제 #1
0
//
// OpenFile
//
// Opens the file ready for streaming
//
HRESULT FileReader::OpenFile()
{
  CAutoLockFR rLock (&m_accessLock);
  
	// Is the file already opened
	if (m_hFile != INVALID_HANDLE_VALUE) 
  {
    //LogDebug("FileReader::OpenFile() file already open");
		return NOERROR;
	}

	// Has a filename been set yet
	if (m_pFileName == NULL) 
  {
    LogDebug("FileReader::OpenFile() no filename");
		return ERROR_INVALID_NAME;
	}
  
	WCHAR *pFileName = NULL;
	DWORD Tmo=14 ;
  HANDLE hFileUnbuff = INVALID_HANDLE_VALUE;
  
  //Can be used to open files in random-access mode to workaround SMB caching problems
  DWORD accessModeFlags = (m_bUseRandomAccess ? FILE_FLAG_RANDOM_ACCESS : FILE_FLAG_SEQUENTIAL_SCAN);       
	
  m_bIsStopping = false;

	pFileName = m_pFileName;

  //LogDebug("FileReader::OpenFile(), Filename: %ws.", pFileName);

	do
	{
	  if (m_bIsStopping)
	    return E_FAIL;
	    
	  if (m_bUseDummyWrites)  //enable SMB2/SMB3 file existence cache workaround
	  {
  		if ((wcsstr(pFileName, L".ts.tsbuffer") != NULL)) //timeshift file only
  		{  	  
    	  CString tempFileName = pFileName;
    	  
    	  int replCount = tempFileName.Replace(L".ts.tsbuffer", randomStrGen(12));
  
        if (replCount > 0)
        {
    	    //LogDebug("FileReader::OpenFile(), try to write dummy file to update SMB2 cache - %ws", tempFileName);
      		hFileUnbuff = ::CreateFileW(tempFileName,		// The filename
      							(DWORD) (GENERIC_READ | GENERIC_WRITE),				// File access
      							(DWORD) (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE), // Share access
      							NULL,						            // Security
      							(DWORD) CREATE_ALWAYS,		  // Open flags
      							(DWORD) (FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE),	// More flags
      							NULL);						          // Template
      
      		if (hFileUnbuff != INVALID_HANDLE_VALUE)
      		{
      		  char tempData[16] = {0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA,0xB,0xC,0xD,0xE,0xF};
      		  DWORD bytesWritten;
            ::WriteFile(hFileUnbuff, tempData, 16, &bytesWritten, NULL);  
          	::CloseHandle(hFileUnbuff); //File is deleted on CloseHandle since FILE_FLAG_DELETE_ON_CLOSE was used
          	hFileUnbuff = INVALID_HANDLE_VALUE; // Invalidate the file
    	      //LogDebug("FileReader::OpenFile(), dummy file write %d bytes to %ws", bytesWritten, tempFileName);
      		}
      	}
      }
    }
    
		// do not try to open a tsbuffer file without SHARE_WRITE so skip this try if we have a buffer file
		if (wcsstr(pFileName, L".ts.tsbuffer") == NULL)   // not tsbuffer files
		{
			// Try to open the file in read-only mode (should fail for 'live' recordings)
			m_hFile = ::CreateFileW(pFileName,      // The filename
						 (DWORD) GENERIC_READ,        // File access
						 (DWORD) FILE_SHARE_READ,     // Share access
						 NULL,                        // Security
						 (DWORD) OPEN_EXISTING,       // Open flags
						 (DWORD) accessModeFlags,     // More flags
						 NULL);                       // Template
			if (m_hFile != INVALID_HANDLE_VALUE) break ;
			  
  		//This is in case file is being recorded to ('live' recordings)
  		m_hFile = ::CreateFileW(pFileName,		// The filename
  							(DWORD) GENERIC_READ,				// File access
  							(DWORD) (FILE_SHARE_READ | FILE_SHARE_WRITE), // Share access
  							NULL,						            // Security
  							(DWORD) OPEN_EXISTING,		  // Open flags
  							(DWORD) accessModeFlags,	                // More flags
  							NULL);						          // Template 
  		if (m_hFile != INVALID_HANDLE_VALUE) break ;
		}
    else  //for tsbuffer files
    {
  		//This is in case file is being recorded to
  		m_hFile = ::CreateFileW(pFileName,		// The filename
  							(DWORD) GENERIC_READ,				// File access
  							(DWORD) (FILE_SHARE_READ | FILE_SHARE_WRITE), // Share access
  							NULL,						            // Security
  							(DWORD) OPEN_EXISTING,		  // Open flags
  							(DWORD) accessModeFlags,	  // More flags
  							NULL);						                // Template 
  		if (m_hFile != INVALID_HANDLE_VALUE) break ;
	  }

		if ((wcsstr(pFileName, L".ts.tsbuffer") != NULL) && (Tmo<10)) //timeshift file only
		{
  	  if (m_bUseDummyWrites)  //enable SMB2/SMB3 file existence cache workaround
  	  {
  		  //Not succeeded in opening file yet, try WRITE_THROUGH dummy file write
    	  CString tempFileName = pFileName;
    	  int replCount = tempFileName.Replace(L".ts.tsbuffer", randomStrGen(12));
  
        if (replCount > 0)
        {
    	    // LogDebug("FileReader::OpenFile(), try to write dummy file to update SMB2 cache - %ws", tempFileName);
      		hFileUnbuff = ::CreateFileW(tempFileName,		// The filename
      							(DWORD) (GENERIC_READ | GENERIC_WRITE),				// File access
      							(DWORD) (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE), // Share access
      							NULL,						            // Security
      							(DWORD) CREATE_ALWAYS,		  // Open flags
      							(DWORD) (FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE | FILE_FLAG_WRITE_THROUGH),	// More flags
      							NULL);						          // Template
      
      		if (hFileUnbuff != INVALID_HANDLE_VALUE)
      		{
      		  char tempData[16] = {0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xA,0xB,0xC,0xD,0xE,0xF};
      		  DWORD bytesWritten;
            ::WriteFile(hFileUnbuff, tempData, 16, &bytesWritten, NULL);  
            Sleep(50);   		  
          	::CloseHandle(hFileUnbuff); //File is deleted on CloseHandle since FILE_FLAG_DELETE_ON_CLOSE was used
          	hFileUnbuff = INVALID_HANDLE_VALUE; // Invalidate the file
    	      LogDebug("FileReader::OpenFile(), dummy file WRITE_THROUGH write %d bytes to %ws", bytesWritten, tempFileName);
      		}
      	}
      }

  		//No luck yet, so try unbuffered open and close (to flush SMB2 cache?),
  		//then go round loop again to open it properly (hopefully....)
  		hFileUnbuff = ::CreateFileW(pFileName,		// The filename
  							(DWORD) GENERIC_READ,				// File access
  							(DWORD) (FILE_SHARE_READ | FILE_SHARE_WRITE), // Share access
  							NULL,						            // Security
  							(DWORD) OPEN_EXISTING,		  // Open flags
  							(DWORD) FILE_FLAG_NO_BUFFERING,	// More flags
  							NULL);						          // Template
  
  		if (hFileUnbuff != INVALID_HANDLE_VALUE)
  		{
      	::CloseHandle(hFileUnbuff);
      	hFileUnbuff = INVALID_HANDLE_VALUE; // Invalidate the file
  		}
  	  //LogDebug("FileReader::OpenFile() unbuff, %d tries to open %ws", 15-Tmo, pFileName);  	  
    }

		Sleep(min((20*(15-Tmo)),250)) ; //wait longer between retries as loop iterations increase
	}
	while(--Tmo) ;
	
	if (Tmo)
	{
    if (Tmo<13) // 1 failed + 1 succeded is quasi-normal, more is a bit suspicious ( disk drive too slow or problem ? )
  			LogDebug("FileReader::OpenFile(), %d tries to succeed opening %ws.", 15-Tmo, pFileName);
	}
	else
	{
	  HRESULT lastErr = HRESULT_FROM_WIN32(GetLastError());	  
		LogDebug("FileReader::OpenFile(), open file failed. Error 0x%x, %ws, filename = %ws", lastErr, HresultToCString(lastErr), pFileName);    
		return E_FAIL;
	}

  //LogDebug("FileReader::OpenFile() handle %i %ws", m_hFile, pFileName );

	LARGE_INTEGER li;
	li.QuadPart = 0;
	::SetFilePointer(m_hFile, li.LowPart, &li.HighPart, FILE_BEGIN);

	return S_OK;

} // Open
예제 #2
0
// Main in-game method for Mastermind. 
void mastermind( istream&in, ostream&out)
{

	char *number = randomStrGen(5); //call to randomStrGen method with default length 5

	//Instructions displayed at the start of the game
	//User must type "begin" to start the game
	out << "Instructions:" << endl;
	out << "Welcome to Mastermind! You are a code breaker whose objective is to crack the secret code ";
	out << "created by Dr. Random. The code is comprised of 5 digits where each digit is between 0-6.";
	out << "With each guess you make, Dr. Random will respond with helpful clues to aid you in deducing ";
	out << "the correct code. Good luck, and let the code breaking begin!" << endl;
	out << "\n\nPlease type begin to begin the game!\n";

	//Initialization and declaration of variables
	string begin;
	string guess;
	char playagain;
	int i=0;
	int blackPin=0;
	int whitePin=0;
	int tries = 0;
	int track = 0;
	int guesses=0;
	char *ARRAY;
	ARRAY = new char[5];
	
	in >> begin; //gets uers input for start game
	while( begin != "begin")
	{
		out << "Please type begin to begin the game!\n";
		in >> begin;
	}
	
	//Checks if user enters begin to start the game
	if(begin=="begin")
	{
		out << "Please enter your first guess: ";
		in >> guess;
		strcpy(ARRAY, guess.c_str());

		//Loop while guesses are still available
		while(!in.fail() && guesses < 9)
		{

			for(int j=0; j < 5; j++)
			{
				track = 1;
				if(ARRAY[j]==number[j])
				{
					blackPin++;
					track = 0;
				}
				for(int k = 0; k<5; k++)
				{
					if(ARRAY[k] == number[j] && k != j && track != 0)
					{
						whitePin++;
						track = 0;
					}
				}
			}
			if(blackPin==5 && guesses != 9)
			{
				guesses=10;
				whitePin = 0;
				tries++;
			}
			out<<"Correct number and position: " << blackPin << endl;
			out <<"Correct number, wrong position: " << whitePin <<endl;
			
			if(blackPin != 5)
			{
				out << "Please enter your next guess: ";
				in >> guess;
				tries++;
			}
			
			strcpy(ARRAY, guess.c_str());
			guesses++;

			//if user does guess code
			if(blackPin==5)
			{
				out << "\nGame over!!!"<< endl;
				out << "It took you " << tries << " tries to guess the correct combination: ";
				
				for(int i=0; i<5; i++)
				{
					out << number[i];
				}
				
				//if user wants to play again...
				out << '\n';
				out << "To play again type y, or type n to quit: ";
				
				in >> playagain;
				if(playagain == 'y' || playagain == 'Y')
				{
					//reset guesses and tries
					guesses = 0;
					tries = 0;
					//new random numbers
					number = randomStrGen(5);
					out << "Please enter your first guess: ";
					in >> guess;
					strcpy(ARRAY, guess.c_str());
				}