Пример #1
1
int
main(int argc, char **argv)
{
  LARGE_INTEGER FileSize;
  HANDLE hFile;
  char cSuffix;
  BOOL bSetSparse = FALSE;
  DWORD dw;

  if (argc == 4)
    if (strcmpi(argv[1], "-s") == 0)
      {
	bSetSparse = TRUE;
	argc--;
	argv++;
      }

  if (argc != 3)
    {
      puts("CHSIZE32.EXE - freeware by Olof Lagerkvist.\r\n"
	   "http://www.ltr-data.se      [email protected]\r\n"
	   "Utility to change size of an existing file, or create a new file with specified"
	   "size.\r\n"
	   "\n"
	   "Syntax:\r\n"
	   "\n"
	   "CHSIZE32 [-s] file size[K|M|G|T]\r\n"
	   "\n"
	   "-s      Set sparse attribute.");
      return 0;
    }
  
  switch (sscanf(argv[2], "%I64i%c", &FileSize, &cSuffix))
    {
    case 2:
      switch (cSuffix)
	{
	case 0:
	  break;
	case 'T': case 't':
	  FileSize.QuadPart <<= 10;
	case 'G': case 'g':
	  FileSize.QuadPart <<= 10;
	case 'M': case 'm':
	  FileSize.QuadPart <<= 10;
	case 'K': case 'k':
	  FileSize.QuadPart <<= 10;
	  break;
	default:
	  fprintf(stderr, "Unknown size extension: %c\n", cSuffix);
	  return 1;
	}

    case 1:
      break;

    default:
      fprintf(stderr, "Expected file size, got \"%s\"\n", argv[2]);
      return 1;
    }

  hFile = CreateFile(argv[1], GENERIC_READ | GENERIC_WRITE,
		     FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS,
		     FILE_ATTRIBUTE_NORMAL, NULL);
  
  if (hFile == INVALID_HANDLE_VALUE)
    {
      win_perror(argv[1]);
      return 1;
    }

  if (bSetSparse)
    if (!DeviceIoControl(hFile, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &dw, NULL))
      win_perror("Error setting sparse attribute");

  if ((SetFilePointer(hFile, FileSize.LowPart, &FileSize.HighPart,
		      FILE_BEGIN) == 0xFFFFFFFF) ?
      (GetLastError() != NO_ERROR) : FALSE)
    {
      win_perror(NULL);
      return 1;
    }

  if (SetEndOfFile(hFile))
    return 0;

  win_perror(NULL);
  return 1;
}
Пример #2
1
/*
 * Converts ASPI-style SRB to SCSI Pass Through IOCTL
 */
DWORD SPTIExecSCSICommand( LPSRB_ExecSCSICmd lpsrb, BOOL bBeenHereBefore )
{
  BOOLEAN status;
  SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER swb;
  ULONG length, returned;
  //BYTE i;
  BYTE idx;

  idx = SPTIGetDeviceIndex( lpsrb->SRB_HaID, lpsrb->SRB_Target, lpsrb->SRB_Lun );

  if ( idx == 0 )
    {
      lpsrb->SRB_Status = SS_ERR;
      return SS_ERR;
    }

  if ( lpsrb->CDBByte[0] == 0x12 ) // is it an INQUIRY?
    {
      lpsrb->SRB_Status = SS_COMP;
      memcpy( lpsrb->SRB_BufPointer, sptiglobal.drive[idx].inqData, 36 );
      return SS_COMP;
    }

  if ( sptiglobal.drive[idx].hDevice == INVALID_HANDLE_VALUE )
    sptiglobal.drive[idx].hDevice = GetFileHandle( sptiglobal.drive[idx].driveLetter );

  ZeroMemory( &swb, sizeof(swb) );
  swb.spt.Length            = sizeof(SCSI_PASS_THROUGH);
  swb.spt.CdbLength         = lpsrb->SRB_CDBLen;
  if ( lpsrb->SRB_Flags & SRB_DIR_IN )
    swb.spt.DataIn          = SCSI_IOCTL_DATA_IN;
  else if ( lpsrb->SRB_Flags & SRB_DIR_OUT )
    swb.spt.DataIn          = SCSI_IOCTL_DATA_OUT;
  else
    swb.spt.DataIn          = SCSI_IOCTL_DATA_UNSPECIFIED;
  swb.spt.DataTransferLength = lpsrb->SRB_BufLen;
  swb.spt.TimeOutValue      = 5;
  swb.spt.DataBuffer        = lpsrb->SRB_BufPointer;
  swb.spt.SenseInfoOffset   =
    offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, ucSenseBuf );
  memcpy( swb.spt.Cdb, lpsrb->CDBByte, lpsrb->SRB_CDBLen );
  length = sizeof(swb);

#ifdef _DEBUG_SCSIPT
  dbprintf( "AKRip32: SPTIExecSCSICmd: calling DeviceIoControl()\n" );
  dbprintf( "       : cmd == 0x%02X\n", swb.spt.Cdb[0] );
#endif
  status = DeviceIoControl( sptiglobal.drive[idx].hDevice,
			    IOCTL_SCSI_PASS_THROUGH_DIRECT,
			    &swb,
			    length,
			    &swb,
			    length,
			    &returned,
			    NULL );

  if ( status )
    {
      lpsrb->SRB_Status = SS_COMP;
#ifdef _DEBUG_SCSIPT
      OutputDebugString( "       : SRB_Status == SS_COMP" );
#endif
    }
  else
    {
      DWORD dwErrCode;

      lpsrb->SRB_Status = SS_ERR;
      lpsrb->SRB_TargStat = 0x0004;
      dwErrCode = GetLastError();
#ifdef _DEBUG_SCSIPT
      dbprintf( "       : error == %d   handle == %08X\n", dwErrCode, sptiglobal.drive[idx].hDevice );
#endif
      /*
       * KLUDGE ALERT! KLUDGE ALERT! KLUDGE ALERT!
       * Whenever a disk changer switches disks, it may render the device
       * handle invalid.  We try to catch these errors here and recover
       * from them.
       */
      if ( !bBeenHereBefore &&
	   ((dwErrCode == ERROR_MEDIA_CHANGED) || (dwErrCode == ERROR_INVALID_HANDLE)) )
	{
	  if ( dwErrCode != ERROR_INVALID_HANDLE )
	    CloseHandle( sptiglobal.drive[idx].hDevice );
	  SPT_GetDriveInformation( idx, &sptiglobal.drive[idx] );
#ifdef _DEBUG_SCSIPT
	  dbprintf( "AKRip32: SPTIExecSCSICommand: Retrying after ERROR_MEDIA_CHANGED\n" );
#endif
	  return SPTIExecSCSICommand( lpsrb, TRUE );
	}
    }

  return lpsrb->SRB_Status;
}
Пример #3
0
BOOL
KLOP_SetBroadcastAddr(  )
{
	BOOL	Result;
	DWORD	lpReturned;
	PMIB_IPADDRTABLE  IpTable = NULL;
	ULONG	dwSize = 0;
	CP_IFACE_INFO* pII = NULL;
	DWORD	err;

	if ( ERROR_INSUFFICIENT_BUFFER == GetIpAddrTable(IpTable, &dwSize, TRUE) )
	{
		IpTable = (PMIB_IPADDRTABLE)malloc ( dwSize );
	}

	if ( IpTable )
	{
		if ( NO_ERROR == (err = GetIpAddrTable(IpTable, &dwSize, TRUE)) )
		{
			pII = (CP_IFACE_INFO*)malloc ( sizeof ( CP_IFACE_INFO ) * IpTable->dwNumEntries );
			
			for ( DWORD i = 0; i < IpTable->dwNumEntries; i++ )
			{
				MIB_IFROW row;
				memset ( &row, 0, sizeof ( MIB_IFROW ) );				
				
				if ( KLOP_isWinNT() )
				{
					row.dwIndex = IpTable->table[i].dwIndex;

					if ( NO_ERROR == (err = GetIfEntry(&row) ) )
					{
						pII[i].IpAddr = IpTable->table[i].dwAddr | ~(IpTable->table[i].dwMask);
						RtlCopyMemory ( pII[i].MacAddr, row.bPhysAddr, 6 );
					}
				}
				else
				{
					row.dwIndex = IpTable->table[i].dwIndex;
					if ( NO_ERROR == (err = GetIfEntry(&row) ) )
					{
						pII[i].IpAddr = IpTable->table[i].dwAddr | ~(IpTable->table[i].dwMask);
						RtlCopyMemory ( pII[i].MacAddr, row.bPhysAddr, 6 );
					}
				}
			}
		}
		
		if ( pII )
		{
			Result = DeviceIoControl( g_DrvHandle,
				KLOP_CP_SET_BROADCAST,
				pII,
				IpTable->dwNumEntries * sizeof(CP_IFACE_INFO),
				NULL,
				0,
				&lpReturned,
				NULL);
			
			free ( pII );
		}	

		free ( IpTable );
	}
	
	
	return Result;
}
Пример #4
0
BOOL Mac::SendArpToGetMac(HANDLE DriverHandle)
{
	//发送arp报文,然后在接收模块中分析要得到的MAC地址
    unsigned char pPacketContent[MAX_SEND_ARPPKTLEN];
	
	P_ETH_HEADER  pEthHeader;                  //以太包头
	P_ARP_HEADER  pArpHeader;                  //ARP头
	PUCHAR  pData;                             //数据部分

	DWORD dwReturnBytes;
    HRESULT hr;
	
	if(ArpMacEvent == NULL)
		ArpMacEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
	do
	{
		 ResetEvent(ArpMacEvent);

		 memset(pPacketContent,0,MAX_SEND_ARPPKTLEN);
  
		 pEthHeader = (P_ETH_HEADER)pPacketContent;
         pEthHeader->EthType[0] = 0x08;
         pEthHeader->EthType[1] = 0x06;//ARP的类型为0x0806
		 
         memcpy(pEthHeader->SrcMac, SrcMacAddr, 6);
		 pEthHeader->DestMac[0]=0xFF;
		 pEthHeader->DestMac[1]=0xFF;
		 pEthHeader->DestMac[2]=0xFF;
		 pEthHeader->DestMac[3]=0xFF;
		 pEthHeader->DestMac[4]=0xFF;
		 pEthHeader->DestMac[5]=0xFF;

         pArpHeader = (P_ARP_HEADER)(pPacketContent+sizeof(ETH_HEADER));
		 pArpHeader->HardWareType[0]=0x00;
		 pArpHeader->HardWareType[1]=0x01;//0x00 01表示以太网类型
         pArpHeader->ProtocolType[0]=0x08;
         pArpHeader->ProtocolType[1]=0x00;//0x08 00表示IP协议类型
         pArpHeader->HardWareAddrLen=6;//以太网和令牌网的硬件地址长度为6
         pArpHeader->ProtocolAddrLen=4;//对于IP地址长度为4
         pArpHeader->Operation[0]=0x00;
         pArpHeader->Operation[1]=0x01;//表示ARP请求操作
		 memcpy(pArpHeader->SrcMacAddr, SrcMacAddr, 6);//发送端即源端的MAC地址
		 memcpy(pArpHeader->SrcIpAddr, SrcIpAddr,4);//源端的IP地址
		 memcpy(pArpHeader->DestIpAddr, DestIpAddr,4);//目的IP地址,注意这里不用填充目的MAC地址

         pData=pPacketContent+sizeof(ETH_HEADER)+sizeof(ARP_HEADER);

	     for (UINT i = 0; i < MAX_SEND_ARPPKTLEN - sizeof(ETH_HEADER)-sizeof(ARP_HEADER); i++)
		 {
              *pData++ = (UCHAR)i;
		 }

		 //for (int SendCount = 1; SendCount<PACKETNUM; SendCount++)
         {			
            if(!(hr=DeviceIoControl(DriverHandle, 
						IO_SEND_PACKET_MAC, 
						pPacketContent, 
						sizeof(pPacketContent),
						NULL, 
						0, 
						&dwReturnBytes, 
						NULL 
						)))
			{
		         AfxMessageBox("CAN NOT SEND ARP PACKET");
		         return 0;
			}

		 }

	}
	while(FALSE);

	WaitForSingleObject(ArpMacEvent , INFINITE);
	
	return 1;
}
Пример #5
0
int main(void) {
	int status = 0;
	HANDLE hFile = NULL;
	DWORD dwReturn;
	char buf[BUFFER_SIZE];
	int funcSuccess = 1;

	hFile = CreateFile( "\\\\.\\Example",
						GENERIC_READ | GENERIC_WRITE,
						0,
						NULL,
						OPEN_EXISTING,
						0,
						NULL);

	if(hFile == INVALID_HANDLE_VALUE) {
		goto cleanup;
	}

	// IO Control
	printf("\n---- Testing Io Control\n");

	memset(buf, BUFFER_SIZE, 0);
	snprintf(buf, BUFFER_SIZE, "This is the output buffer written by the user app.");
	char* str1 = "** Hello from User Mode Direct OUT I/O";
	funcSuccess = DeviceIoControl(hFile,
									MY_IOCTL_DIRECT_OUT_IO,
									str1,
									strlen(str1) + 1,
									buf,
									BUFFER_SIZE,
									&dwReturn,
									NULL);
	if (!funcSuccess) {
		printf("IOCTL_DIRECT_OUT_IO error...\n");
		goto cleanup;
	}
	printf("%.*s\n", dwReturn, buf);

	ZeroMemory(buf, BUFFER_SIZE);
	snprintf(buf, BUFFER_SIZE, "This is the output buffer written by the user app.");
	char* str2 = "** Hello from User Mode Direct IN I/O";
	funcSuccess = DeviceIoControl(hFile,
									MY_IOCTL_DIRECT_IN_IO,
									str2,
									strlen(str2) + 1,
									buf,
									BUFFER_SIZE,
									&dwReturn,
									NULL);
	if (!funcSuccess) {
		printf("IOCTL_DIRECT_IN_IO error...\n");
		goto cleanup;
	}
	printf("%.*s\n", dwReturn, buf);

	memset(buf, BUFFER_SIZE, 0);
	char* str3 = "** Hello from User Mode Buffered I/O";
	funcSuccess = DeviceIoControl(hFile,
									MY_IOCTL_BUFFERED_IO,
									str3,
									strlen(str3) + 1,
									buf,
									BUFFER_SIZE,
									&dwReturn,
									NULL);
	if (!funcSuccess) {
		printf("IOCTL_BUFFERED_IO error...\n");
		goto cleanup;
	}
	printf("%.*s\n", dwReturn, buf);

cleanup:
	if (hFile) {
		CloseHandle(hFile);
	}
	return status;
}
Пример #6
0
int ChangePwd (char *lpszVolume, Password *oldPassword, Password *newPassword, int pkcs5, HWND hwndDlg)
{
	int nDosLinkCreated = 1, nStatus = ERR_OS_ERROR;
	char szDiskFile[GST_MAX_PATH], szCFDevice[GST_MAX_PATH];
	char szDosDevice[GST_MAX_PATH];
	char buffer[GST_VOLUME_HEADER_EFFECTIVE_SIZE];
	PCRYPTO_INFO cryptoInfo = NULL, ci = NULL;
	void *dev = INVALID_HANDLE_VALUE;
	DWORD dwError;
	DWORD bytesRead;
	BOOL bDevice;
	unsigned __int64 hostSize = 0;
	int volumeType;
	int wipePass;
	FILETIME ftCreationTime;
	FILETIME ftLastWriteTime;
	FILETIME ftLastAccessTime;
	BOOL bTimeStampValid = FALSE;
	LARGE_INTEGER headerOffset;
	BOOL backupHeader;
	DISK_GEOMETRY driveInfo;

	if (oldPassword->Length == 0 || newPassword->Length == 0) return -1;

	WaitCursor ();

	CreateFullVolumePath (szDiskFile, lpszVolume, &bDevice);

	if (bDevice == FALSE)
	{
		strcpy (szCFDevice, szDiskFile);
	}
	else
	{
		nDosLinkCreated = FakeDosNameForDevice (szDiskFile, szDosDevice, szCFDevice, FALSE);
		
		if (nDosLinkCreated != 0)
			goto error;
	}

	dev = CreateFile (szCFDevice, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);

	if (dev == INVALID_HANDLE_VALUE) 
		goto error;

	if (bDevice)
	{
		/* This is necessary to determine the hidden volume header offset */

		if (dev == INVALID_HANDLE_VALUE)
		{
			goto error;
		}
		else
		{
			PARTITION_INFORMATION diskInfo;
			DWORD dwResult;
			BOOL bResult;

			bResult = DeviceIoControl (dev, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0,
				&driveInfo, sizeof (driveInfo), &dwResult, NULL);

			if (!bResult)
				goto error;

			bResult = GetPartitionInfo (lpszVolume, &diskInfo);

			if (bResult)
			{
				hostSize = diskInfo.PartitionLength.QuadPart;
			}
			else
			{
				hostSize = driveInfo.Cylinders.QuadPart * driveInfo.BytesPerSector *
					driveInfo.SectorsPerTrack * driveInfo.TracksPerCylinder;
			}

			if (hostSize == 0)
			{
				nStatus = ERR_VOL_SIZE_WRONG;
				goto error;
			}
		}
	}
	else
	{
		LARGE_INTEGER fileSize;
		if (!GetFileSizeEx (dev, &fileSize))
		{
			nStatus = ERR_OS_ERROR;
			goto error;
		}

		hostSize = fileSize.QuadPart;
	}

	if (Randinit ())
		goto error;

	if (!bDevice && bPreserveTimestamp)
	{
		if (GetFileTime ((HANDLE) dev, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime) == 0)
			bTimeStampValid = FALSE;
		else
			bTimeStampValid = TRUE;
	}

	for (volumeType = GST_VOLUME_TYPE_NORMAL; volumeType < GST_VOLUME_TYPE_COUNT; volumeType++)
	{
		// Seek the volume header
		switch (volumeType)
		{
		case GST_VOLUME_TYPE_NORMAL:
			headerOffset.QuadPart = GST_VOLUME_HEADER_OFFSET;
			break;

		case GST_VOLUME_TYPE_HIDDEN:
			if (GST_HIDDEN_VOLUME_HEADER_OFFSET + GST_VOLUME_HEADER_SIZE > hostSize)
				continue;

			headerOffset.QuadPart = GST_HIDDEN_VOLUME_HEADER_OFFSET;
			break;

		case GST_VOLUME_TYPE_HIDDEN_LEGACY:
			if (bDevice && driveInfo.BytesPerSector != GST_SECTOR_SIZE_LEGACY)
				continue;

			headerOffset.QuadPart = hostSize - GST_HIDDEN_VOLUME_HEADER_OFFSET_LEGACY;
			break;
		}

		if (!SetFilePointerEx ((HANDLE) dev, headerOffset, NULL, FILE_BEGIN))
		{
			nStatus = ERR_OS_ERROR;
			goto error;
		}

		/* Read in volume header */
		if (!ReadEffectiveVolumeHeader (bDevice, dev, buffer, &bytesRead))
		{
			nStatus = ERR_OS_ERROR;
			goto error;
		}

		if (bytesRead != sizeof (buffer))
		{
			// Windows may report EOF when reading sectors from the last cluster of a device formatted as NTFS 
			memset (buffer, 0, sizeof (buffer));
		}

		/* Try to decrypt the header */

		nStatus = ReadVolumeHeader (FALSE, buffer, oldPassword, &cryptoInfo, NULL);
		if (nStatus == ERR_CIPHER_INIT_WEAK_KEY)
			nStatus = 0;	// We can ignore this error here

		if (nStatus == ERR_PASSWORD_WRONG)
		{
			continue;		// Try next volume type
		}
		else if (nStatus != 0)
		{
			cryptoInfo = NULL;
			goto error;
		}
		else 
			break;
	}

	if (nStatus != 0)
	{
		cryptoInfo = NULL;
		goto error;
	}

	if (cryptoInfo->HeaderFlags & GST_HEADER_FLAG_ENCRYPTED_SYSTEM)
	{
		nStatus = ERR_SYS_HIDVOL_HEAD_REENC_MODE_WRONG;
		goto error;
	}

	// Change the PKCS-5 PRF if requested by user
	if (pkcs5 != 0)
		cryptoInfo->pkcs5 = pkcs5;

	RandSetHashFunction (cryptoInfo->pkcs5);

	NormalCursor();
	UserEnrichRandomPool (hwndDlg);
	EnableElevatedCursorChange (hwndDlg);
	WaitCursor();

	/* Re-encrypt the volume header */ 
	backupHeader = FALSE;

	while (TRUE)
	{
		/* The header will be re-encrypted PRAND_DISK_WIPE_PASSES times to prevent adversaries from using 
		techniques such as magnetic force microscopy or magnetic force scanning tunnelling microscopy
		to recover the overwritten header. According to Peter Gutmann, data should be overwritten 22
		times (ideally, 35 times) using non-random patterns and pseudorandom data. However, as users might
		impatiently interupt the process (etc.) we will not use the Gutmann's patterns but will write the
		valid re-encrypted header, i.e. pseudorandom data, and there will be many more passes than Guttman
		recommends. During each pass we will write a valid working header. Each pass will use the same master
		key, and also the same header key, secondary key (XTS), etc., derived from the new password. The only
		item that will be different for each pass will be the salt. This is sufficient to cause each "version"
		of the header to differ substantially and in a random manner from the versions written during the
		other passes. */

		for (wipePass = 0; wipePass < PRAND_DISK_WIPE_PASSES; wipePass++)
		{
			// Prepare new volume header
			nStatus = CreateVolumeHeaderInMemory (FALSE,
				buffer,
				cryptoInfo->ea,
				cryptoInfo->mode,
				newPassword,
				cryptoInfo->pkcs5,
				cryptoInfo->master_keydata,
				&ci,
				cryptoInfo->VolumeSize.Value,
				(volumeType == GST_VOLUME_TYPE_HIDDEN || volumeType == GST_VOLUME_TYPE_HIDDEN_LEGACY) ? cryptoInfo->hiddenVolumeSize : 0,
				cryptoInfo->EncryptedAreaStart.Value,
				cryptoInfo->EncryptedAreaLength.Value,
				cryptoInfo->RequiredProgramVersion,
				cryptoInfo->HeaderFlags,
				cryptoInfo->SectorSize,
				wipePass < PRAND_DISK_WIPE_PASSES - 1);

			if (ci != NULL)
				crypto_close (ci);

			if (nStatus != 0)
				goto error;

			if (!SetFilePointerEx ((HANDLE) dev, headerOffset, NULL, FILE_BEGIN))
			{
				nStatus = ERR_OS_ERROR;
				goto error;
			}

			if (!WriteEffectiveVolumeHeader (bDevice, dev, buffer))
			{
				nStatus = ERR_OS_ERROR;
				goto error;
			}

			if (bDevice
				&& !cryptoInfo->LegacyVolume
				&& !cryptoInfo->hiddenVolume
				&& cryptoInfo->HeaderVersion == 4
				&& (cryptoInfo->HeaderFlags & GST_HEADER_FLAG_NONSYS_INPLACE_ENC) != 0
				&& (cryptoInfo->HeaderFlags & ~GST_HEADER_FLAG_NONSYS_INPLACE_ENC) == 0)
			{
				nStatus = WriteRandomDataToReservedHeaderAreas (dev, cryptoInfo, cryptoInfo->VolumeSize.Value, !backupHeader, backupHeader);
				if (nStatus != ERR_SUCCESS)
					goto error;
			}

			FlushFileBuffers (dev);
		}

		if (backupHeader || cryptoInfo->LegacyVolume)
			break;
			
		backupHeader = TRUE;
		headerOffset.QuadPart += hostSize - GST_VOLUME_HEADER_GROUP_SIZE;
	}

	/* Password successfully changed */
	nStatus = 0;

error:
	dwError = GetLastError ();

	burn (buffer, sizeof (buffer));

	if (cryptoInfo != NULL)
		crypto_close (cryptoInfo);

	if (bTimeStampValid)
		SetFileTime (dev, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime);

	if (dev != INVALID_HANDLE_VALUE)
		CloseHandle ((HANDLE) dev);

	if (nDosLinkCreated == 0)
		RemoveFakeDosName (szDiskFile, szDosDevice);

	RandStop (FALSE);
	NormalCursor ();

	SetLastError (dwError);

	if (nStatus == ERR_OS_ERROR && dwError == ERROR_ACCESS_DENIED
		&& bDevice
		&& !UacElevated
		&& IsUacSupported ())
		return nStatus;

	if (nStatus != 0)
		handleError (hwndDlg, nStatus);

	return nStatus;
}
Пример #7
0
/* ======================================================================= */
BOOL EncodeTrack(PWINDOWHANDLES H, DWORD Index, PCHAR BasePath, HANDLE CDHandle, PCDTRACK CDTrackData, PDWORD DiscCurrent, PDWORD DiscTotal, PDWORD TrackCount)
{
  Log(LOG_WRITE, "Encoding track %u/%u; Sector %u-%u/%u", Index+1, *TrackCount, CDTrackData[Index].Address, CDTrackData[Index].Address + CDTrackData[Index].Length - 1, CDTrackData[Index].Length);

  CHAR MP3FilePath[MAX_PATH];
  CHAR MP3FilePathFancy[MAX_PATH];

  HANDLE MP3FileHandle = INVALID_HANDLE_VALUE;
  static lame_global_flags *GFP = NULL;

  if(OneTrackOnly == 0)
  {
    _snprintf(MP3FilePath, MAX_PATH, "%s\\Track %u.mp3", BasePath, Index + 1);
    MakeFancyPath(MP3FilePath, MP3FilePathFancy, 35);
    SetLabel(H->WT, "Creating file %s...", MP3FilePath);
    MP3FileHandle = CreateFile(MP3FilePath, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  }
  else
  {
    _snprintf(MP3FilePath, MAX_PATH, "%s\\Audio.mp3", BasePath, Index + 1);
    MakeFancyPath(MP3FilePath, MP3FilePathFancy, 35);
    switch(OneTrackOnly)
    {
      case 1:
        SetLabel(H->WT, "Creating solid file %s...", MP3FilePath);
        MP3FileHandle = CreateFile(MP3FilePath, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
        OneTrackOnly = 2;
        break;
      case 2:
        SetLabel(H->WT, "Re-opening file %s...", MP3FilePath);
        MP3FileHandle = CreateFile(MP3FilePath, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
        if(MP3FileHandle != INVALID_HANDLE_VALUE)
          SetFilePointer(MP3FileHandle, 0, NULL, FILE_END);
        break;
    }
  }

  BOOL Success = TRUE;
  INT EncoderReturnCode = 0;

  if(MP3FileHandle != INVALID_HANDLE_VALUE)
  {
    Log(LOG_WRITE, "Created file %s", MP3FilePath);

    DWORD DiscLastCurrent = *DiscCurrent;
    DWORD SectorTotal = CDTrackData[Index].Length/SECTORS_AT_READ;
    DWORD MP3BytesWritten;

    SendMessage(H->PO, PBM_SETRANGE32, 0, SectorTotal);
    SendMessage(H->PO, PBM_SETPOS, 0, 0);
    SendMessage(H->PA, PBM_SETRANGE32, 0, *DiscTotal);

    if(GFP == NULL)
    {
      GFP = lame_init();

      lame_set_preset(GFP, MP3Quality);
      lame_set_copyright(GFP, 1);
      lame_set_original(GFP, 1);
      lame_set_error_protection(GFP, 1);
      lame_set_extension(GFP, 1);
      lame_set_quality(GFP, Quality);

      EncoderReturnCode = lame_init_params(GFP);
    }

    if(EncoderReturnCode == 0)
    {
      DWORD dwWAVBufferSize=(1152 * lame_get_num_channels(GFP));
      DWORD dwMP3BufferSize=(DWORD)(1.25*(dwWAVBufferSize/lame_get_num_channels(GFP))+7200);
      PBYTE MP3Buffer = new BYTE[dwMP3BufferSize];
      PBYTE CDBuffer = new BYTE[SECTORS_AT_READ * RAW_SECTOR_SIZE];
      INT nOutputSamples;
      DWORD CDBytesWritten;
      RAW_READ_INFO Info;
      Info.TrackMode = CDDA;
      Info.SectorCount = SECTORS_AT_READ;
      DWORD SectorCurrent;
      TCHAR NumWritten[30];
      TCHAR NumWrittenKB[30];

      for(SectorCurrent = 0; SectorCurrent < SectorTotal; ++SectorCurrent, ++*DiscCurrent)
      {
        Info.DiskOffset.QuadPart = (CDTrackData[Index].Address + SectorCurrent*SECTORS_AT_READ) * CD_SECTOR_SIZE;
        MP3BytesWritten = SetFilePointer(MP3FileHandle, 0, NULL, FILE_CURRENT);
        Comma(MP3BytesWritten, NumWritten, sizeof(NumWritten));
        Comma(MP3BytesWritten / 1024, NumWrittenKB, sizeof(NumWrittenKB));
        SetLabel(H->WT, "Encoding track %u of %u and sector %u of %u\nTo %s\nWritten %s bytes (%s KB) to file", Index + 1, *TrackCount, SectorCurrent, SectorTotal - 1, MP3FilePathFancy, NumWritten, NumWrittenKB);
        if(DeviceIoControl(CDHandle, IOCTL_CDROM_RAW_READ, &Info, sizeof(Info), CDBuffer, SECTORS_AT_READ*RAW_SECTOR_SIZE, &CDBytesWritten, NULL) != 0)
        {
          if(EncodeAudioBuffer(CDBuffer, CDBytesWritten, dwWAVBufferSize, MP3FileHandle, MP3Buffer, GFP) == FALSE)
          {
            Log(LOG_WRITE, "Encoding of audio buffer failed");
            Success = FALSE;
            break;
          }
        }
        else
        {
          DWORD ErrorCode = GetLastError();
          if(ErrorCode == ERROR_INVALID_FUNCTION)
          {
            Log(LOG_WRITE, "Track %u is not a valid CDDA track", Index + 1);
            Success = FALSE;
            break;
          }
          else if(ErrorCode != ERROR_INVALID_PARAMETER)
          {
            Log(LOG_WRITE, "Error code %u reading track %u!", ErrorCode, Index + 1);
            Success = FALSE;
            break;
          }
        }
        SendMessage(H->PO, PBM_SETPOS, SectorCurrent, 0);
        SendMessage(H->PA, PBM_SETPOS, *DiscCurrent, 0);
        Percentage = (float)((float)*DiscCurrent / (float)*DiscTotal) * 100;
      }

      if(Success == FALSE)
      {
        *DiscTotal -= SectorTotal;
        SectorTotal = 0;
      }
      else if(OneTrackOnly == 0 || Index+1 == *TrackCount)
      {
        nOutputSamples = lame_encode_flush_nogap(GFP, MP3Buffer, LAME_MAXMP3BUFFER);

        if(nOutputSamples > 0)
        {
          if(WriteFile(MP3FileHandle, MP3Buffer, nOutputSamples, &MP3BytesWritten, NULL) == FALSE)
          {
            Log(LOG_WRITE, "Failed to write %u final bytes to file", nOutputSamples);
            Success = FALSE;
          }
          else if(nOutputSamples != (int)MP3BytesWritten)
          {
            Log(LOG_WRITE, "Written %u final bytes instead of %u bytes to file", MP3BytesWritten, nOutputSamples);
            Success = FALSE;
          }
        }
        else if(nOutputSamples < 0)
        {
          Log(LOG_WRITE, "Error code %d flushing encoded audio buffer", nOutputSamples);
          Success = FALSE;
        }
      }

      *DiscCurrent = DiscLastCurrent + SectorTotal;
      SendMessage(H->PO, PBM_SETPOS, *DiscCurrent, 0);
    }
    else
    {
      Log(LOG_WRITE, "Error code %d initialising audio encoder", EncoderReturnCode);
      Success = FALSE;
    }

    MP3BytesWritten = SetFilePointer(MP3FileHandle, 0, NULL, FILE_CURRENT);
    if(CloseHandle(MP3FileHandle) == FALSE)
    {
      Log(LOG_WRITE, "Error code %u closing file handle");
      Success = FALSE;
    }
    if(OneTrackOnly == 0 && (MP3BytesWritten == 0 || Success == FALSE))
    {
      if(DeleteFile(MP3FilePath) == FALSE)
        Log(LOG_WRITE, "Error code %u deleting file");
      else
        Log(LOG_WRITE, "Deleted the file due to error");
    }
    else Log(LOG_WRITE, "Written %u bytes to file", MP3BytesWritten);
  }
  else
  {
    Log(LOG_WRITE, "Error code %u creating %s", GetLastError(), MP3FilePath);
    Success = FALSE;
  }

  if(EncoderReturnCode == 0 && (OneTrackOnly == 0 || Index+1 == *TrackCount))
  {
    lame_close(GFP);
    GFP = NULL;
  }

  return Success;
}
Пример #8
0
/*
 * fills in a pDrive structure with information from a SCSI_INQUIRY
 * and obtains the ha:tgt:lun values via IOCTL_SCSI_GET_ADDRESS
 */
void SPT_GetDriveInformation( BYTE i, SPT_DRIVE *pDrive )
{
  HANDLE fh;
  char buf[1024];
  BOOLEAN status;
  PSCSI_PASS_THROUGH_DIRECT_WITH_BUFFER pswb;
  PSCSI_ADDRESS pscsiAddr;
  ULONG length, returned;
  BYTE inqData[100];

#ifdef _DEBUG_SCSIPT
  dbprintf( "AKRip32: SCSIPT: Checking drive %c:\n", 'A'+i );
#endif

  fh = GetFileHandle( i );

  if ( fh == INVALID_HANDLE_VALUE )
    {
#ifdef _DEBUG_SCSIPT
      dbprintf( "       : fh == INVALID_HANDLE_VALUE\n" );
#endif
      return;
    }

#ifdef _DEBUG_SCSIPT
  dbprintf( "       : Index %d: fh == %08X\n", i, fh );
#endif


  /*
   * Get the drive inquiry data
   */
  ZeroMemory( &buf, 1024 );
  ZeroMemory( inqData, 100 );
  pswb                      = (PSCSI_PASS_THROUGH_DIRECT_WITH_BUFFER)buf;
  pswb->spt.Length          = sizeof(SCSI_PASS_THROUGH);
  pswb->spt.CdbLength       = 6;
  pswb->spt.SenseInfoLength = 24;
  pswb->spt.DataIn          = SCSI_IOCTL_DATA_IN;
  pswb->spt.DataTransferLength = 100;
  pswb->spt.TimeOutValue    = 2;
  pswb->spt.DataBuffer      = inqData;
  pswb->spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER,ucSenseBuf );
  pswb->spt.Cdb[0]          = 0x12;
  pswb->spt.Cdb[4]          = 100;

  length = sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER);
  status = DeviceIoControl( fh,
			    IOCTL_SCSI_PASS_THROUGH_DIRECT,
			    pswb,
			    length,
			    pswb,
			    length,
			    &returned,
			    NULL );

  if ( !status )
    {
      CloseHandle( fh );
#ifdef _DEBUG_SCSIPT
      dbprintf( "AKRip32: SCSIPT: Error DeviceIoControl() -> %d\n",
		GetLastError() );
#endif
      return;
    }

  memcpy( pDrive->inqData, inqData, 36 );

  /*
   * get the address (path/tgt/lun) of the drive via IOCTL_SCSI_GET_ADDRESS
   */
  ZeroMemory( &buf, 1024 );
  pscsiAddr = (PSCSI_ADDRESS)buf;
  pscsiAddr->Length = sizeof(SCSI_ADDRESS);
  if ( DeviceIoControl( fh, IOCTL_SCSI_GET_ADDRESS, NULL, 0,
			pscsiAddr, sizeof(SCSI_ADDRESS), &returned,
			NULL ) )
    {
#ifdef _DEBUG_SCSIPT
      dbprintf( "Device %c: Port=%d, PathId=%d, TargetId=%d, Lun=%d\n",
		(char)i+'A', pscsiAddr->PortNumber, pscsiAddr->PathId,
		pscsiAddr->TargetId, pscsiAddr->Lun );
#endif
      pDrive->bUsed     = TRUE;
      pDrive->ha        = pscsiAddr->PortNumber;
      pDrive->tgt       = pscsiAddr->TargetId;
      pDrive->lun       = pscsiAddr->Lun;
      pDrive->driveLetter = i;
      pDrive->hDevice   = INVALID_HANDLE_VALUE;
    }
  else
    {
      pDrive->bUsed     = FALSE;
#ifdef _DEBUG_SCSIPT
      dbprintf( "AKRip32: SPTI: Device %s: Error DeviceIoControl(): %d\n", (char)i+'A', GetLastError() );
#endif
      return;
    }

#ifdef _DEBUG_SCSIPT
  dbprintf( "AKRip32: SPTI: Adding drive %c: (%d:%d:%d)\n", 'A'+i,
	    pDrive->ha, pDrive->tgt, pDrive->lun );
#endif

  CloseHandle( fh );
}
Пример #9
0
int 
winblkopen(struct open_file *f, ...)
/* file, devname, unit, partition */
{
	va_list ap;
	struct winblk *ctx = NULL;
	char *devname;
	int unit;
	int partition;
	TCHAR wdevname[6];
	DWORD wres;
	int i;
	int start_386bsd;

	int error = 0;

	ctx = (struct winblk *)alloc(sizeof(*ctx));
	if (!ctx) {
		error = ENOMEM;
		goto end;
	}
	f->f_devdata = ctx;

	va_start(ap, f);
	devname = va_arg(ap, char*);
	unit = va_arg(ap, int);
	partition = va_arg(ap, int);
        va_end(ap);

	/*
	 *  Windows' device name must be 3 uppper letters and 1 digit
	 *  following a semicolon like "DSK1:".
	 */
	if (strlen(devname) != 3 || unit < 0 || 9 < unit) {
		error = ENODEV;
		goto end;
	}
	wsprintf(wdevname, TEXT("%C%C%C%d:"),
		toupper(devname[0]),
		toupper(devname[1]),
		toupper(devname[2]),
		unit);
	DEBUG_PRINTF((TEXT("winblk.open: block device name is '%s'\n"),
		      wdevname));

	ctx->hDevice = CreateFile(wdevname, GENERIC_READ, 0, NULL,    
				  OPEN_EXISTING, 0, NULL);
	if (ctx->hDevice == INVALID_HANDLE_VALUE) {
		win_printf(TEXT("can't open %s.\n"), wdevname);
		error = ENODEV; /* XXX, We shuld check GetLastError(). */
		goto end;
	}

	/*
	 *  get DISK_INFO
	 *  CHS, sector size and device flags.
	 */
	if (!DeviceIoControl(ctx->hDevice, DISK_IOCTL_GETINFO,
			     &ctx->di, sizeof(ctx->di),
			     NULL, 0, &wres, NULL)) {
		win_printf(TEXT("DeviceIoControl() failed.error=%d\n"),
			   GetLastError());

		error = EIO; /* XXX, We shuld check GetLastError(). */
		goto end;
	}

#ifdef DEBUG
	win_printf(TEXT("DISK_INFO: CHS=%d:%d:%d  block size=%d  flag="),
		   ctx->di.di_cylinders,
		   ctx->di.di_heads,
		   ctx->di.di_sectors,
		   ctx->di.di_bytes_per_sect);
	if (ctx->di.di_flags & DISK_INFO_FLAG_MBR) {
		win_printf(TEXT("MBR "));
	}
	if (ctx->di.di_flags & DISK_INFO_FLAG_CHS_UNCERTAIN) {
		win_printf(TEXT("CHS_UNCERTAIN "));
	}
	if (ctx->di.di_flags & DISK_INFO_FLAG_UNFORMATTED) {
		win_printf(TEXT("UNFORMATTED "));
	}
	if (ctx->di.di_flags & DISK_INFO_FLAG_PAGEABLE) {
		win_printf(TEXT("PAGEABLE "));
	}
	win_printf(TEXT("\n"));
#endif /* DEBUG */

	if (!(ctx->di.di_flags & DISK_INFO_FLAG_MBR) ||
	     (ctx->di.di_flags & DISK_INFO_FLAG_CHS_UNCERTAIN) ||
	     (ctx->di.di_flags & DISK_INFO_FLAG_UNFORMATTED) ||
	     (ctx->di.di_bytes_per_sect != BLKSZ)) {
		win_printf(TEXT("invalid flags\n"));
		error = EINVAL;
		goto end;
	}

	/*
	 *  read MBR
	 */
	if (error = rawread(ctx, MBR_BBSECTOR, 1, ctx->buf)) {
		goto end;
	}
	memcpy(&ctx->mbr, &ctx->buf[MBR_PARTOFF], sizeof(ctx->mbr));

	for (i = 0; i < NMBRPART; i++) {
	        DEBUG_PRINTF((TEXT("%d: type=%d %d(%d) (%d:%d:%d - %d:%d:%d)")
			      TEXT(" flag=0x%02x\n"),
			      i,
			      ctx->mbr[i].mbrp_typ,
			      ctx->mbr[i].mbrp_start,
			      ctx->mbr[i].mbrp_size,
			      ctx->mbr[i].mbrp_scyl,
			      ctx->mbr[i].mbrp_shd,
			      ctx->mbr[i].mbrp_ssect,
			      ctx->mbr[i].mbrp_ecyl,
			      ctx->mbr[i].mbrp_ehd,
			      ctx->mbr[i].mbrp_esect,
			      ctx->mbr[i].mbrp_flag));
	}

	/*
	 *  find BSD partition
	 */
	ctx->start = -1;
	start_386bsd = -1;
	for (i = 0; i < NMBRPART; i++) {
		if (ctx->mbr[i].mbrp_typ == MBR_PTYPE_NETBSD) {
			ctx->start = ctx->mbr[i].mbrp_start;
			break;
		}
		if (ctx->mbr[i].mbrp_typ == MBR_PTYPE_386BSD) {
			start_386bsd = ctx->mbr[i].mbrp_start;
		}
	}
	if (ctx->start == -1) {
		ctx->start = start_386bsd;
	}

	if (ctx->start == -1) {
		/*
		 *  BSD partition is not found.
		 *  Try to use entire disk.
		 */
		ctx->start = 0;
		win_printf(TEXT("no BSD partition, start sector=0x%x\n"),
			   ctx->start);
		goto end;
	}

	/*
	 *  read disklabel
	 */
	if (error = rawread(ctx, ctx->start + LABELSECTOR, 1, ctx->buf)) {
		goto end;
	}
	memcpy(&ctx->dl, &ctx->buf[LABELOFFSET], sizeof(ctx->dl));

	if (ctx->dl.d_magic != DISKMAGIC ||
	    ctx->dl.d_magic2 != DISKMAGIC ||
	    dkcksum(&ctx->dl) != 0) {
		win_printf(TEXT("invalid disklabel, start sector=0x%x\n"),
			   ctx->start);
		/*
		 *  Disklabel is not found.
		 *  Try to use entire partition.
		 */
		goto end;
	}

	if (partition < 0 || ctx->dl.d_npartitions <= partition) {
		error = EINVAL;
		goto end;
	}

	ctx->start = ctx->dl.d_partitions[partition].p_offset;
	win_printf(TEXT("start sector=0x%x\n"), ctx->start);

      end:
	if (error && ctx) {
		free(ctx, sizeof(*ctx));
		f->f_devdata = NULL;
	}
	return (error);
}
Пример #10
0
/*
 * Returns the first drive letter for a volume located on the drive identified by DriveIndex
 * TODO: should we return all the drive letters?
 */
char GetDriveLetter(DWORD DriveIndex)
{
	DWORD size;
	BOOL r;
	STORAGE_DEVICE_NUMBER_REDEF device_number = {0};
	UINT drive_type;
	HANDLE hDrive = INVALID_HANDLE_VALUE;
	char *drive, drives[26*4];	/* "D:\", "E:\", etc. */
	char logical_drive[] = "\\\\.\\#:";
	char drive_letter = ' ';
	CheckDriveIndex(DriveIndex);

	size = GetLogicalDriveStringsA(sizeof(drives), drives);
	if (size == 0) {
		uprintf("GetLogicalDriveStrings failed: %s\n", WindowsErrorString());
		goto out;
	}
	if (size > sizeof(drives)) {
		uprintf("GetLogicalDriveStrings: buffer too small (required %d vs %d)\n", size, sizeof(drives));
		goto out;
	}

	for (drive = drives ;*drive; drive += safe_strlen(drive)+1) {
		if (!isalpha(*drive))
			continue;
		*drive = (char)toupper((int)*drive);
		if (*drive < 'C') {
			continue;
		}

		/* IOCTL_STORAGE_GET_DEVICE_NUMBER's STORAGE_DEVICE_NUMBER.DeviceNumber is
			not unique! An HDD, a DVD and probably other drives can have the same
			value there => Use GetDriveType() to filter out unwanted devices.
			See https://github.com/pbatard/rufus/issues/32 for details. */
		drive_type = GetDriveTypeA(drive);
		// NB: the HP utility allows drive_type == DRIVE_FIXED, which we don't allow by default
		// Using Alt-F in Rufus does enable listing, but this mode is unsupported.
		if ((drive_type != DRIVE_REMOVABLE) && ((!enable_fixed_disks) || (drive_type != DRIVE_FIXED)))
			continue;

		safe_sprintf(logical_drive, sizeof(logical_drive), "\\\\.\\%c:", drive[0]);
		hDrive = CreateFileA(logical_drive, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
		if (hDrive == INVALID_HANDLE_VALUE) {
			uprintf("Warning: could not open drive %c: %s\n", drive[0], WindowsErrorString());
			continue;
		}

		r = DeviceIoControl(hDrive, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL,
			0, &device_number, sizeof(device_number), &size, NULL);
		safe_closehandle(hDrive);
		if ((!r) || (size <= 0)) {
			uprintf("Could not get device number for device %s: %s\n",
				logical_drive, WindowsErrorString());
		} else if (device_number.DeviceNumber == DriveIndex) {
			drive_letter = *drive;
			break;
		}
	}

out:
	return drive_letter;
}
Пример #11
0
XN_C_API XnStatus xnUSBOpenEndPoint(XN_USB_DEV_HANDLE pDevHandle, XnUInt16 nEndPointID, XnUSBEndPointType nEPType, XnUSBDirectionType nDirType, XN_USB_EP_HANDLE* pEPHandlePtr)
{
	// Local variables
	XnBool bResult = TRUE;
	XnStatus nRetVal = XN_STATUS_OK;
	XnInt32 nRetBytes = 0;
	XnChar pConfigDescBuf[MAX_CONFIG_DESC_SIZE];
	XnChar* pBuf = NULL;
	PUSB_CONFIGURATION_DESCRIPTOR pUSBConfigDesc = NULL;
	PUSB_INTERFACE_DESCRIPTOR pUSBInterfaceDesc = NULL;
	PUSB_ENDPOINT_DESCRIPTOR pUSBEndPointDesc = NULL;
	XN_USB_EP_HANDLE pEPHandle = NULL;	
	XnChar cpPipeID[3];

	// Validate xnUSB
	XN_VALIDATE_USB_INIT();
	XN_VALIDATE_USB_PDEV_HANDLE(pDevHandle);

	// Validate the input/output pointers
	XN_VALIDATE_OUTPUT_PTR(pEPHandlePtr);

	// Allocate a new xnUSB EP handle
	XN_VALIDATE_ALIGNED_CALLOC(*pEPHandlePtr, xnUSBEPHandle, 1, XN_DEFAULT_MEM_ALIGN);
	pEPHandle = *pEPHandlePtr;

	// Read the config descriptor
	bResult = DeviceIoControl(pDevHandle->hUSBDevHandle, IOCTL_PSDRV_GET_CONFIG_DESCRIPTOR, pConfigDescBuf, sizeof(pConfigDescBuf), pConfigDescBuf, sizeof(pConfigDescBuf), (PULONG)&nRetBytes, NULL);
	if (bResult)
	{
		XnUInt32 nIFIdx = 0;
		UCHAR nEPIdx = 0;
		XnUInt32 nUBBEPType = 0;
		XnUInt32 nCurrIF = 0;

		pBuf = pConfigDescBuf;

		pUSBConfigDesc = (PUSB_CONFIGURATION_DESCRIPTOR)pBuf;

		pBuf += pUSBConfigDesc->bLength;

		// Scan all the interfaces
		do {
			pUSBInterfaceDesc = (PUSB_INTERFACE_DESCRIPTOR)pBuf;

			pBuf += pUSBInterfaceDesc->bLength;

			// Scan all the endpoints
			for (nEPIdx = 0; nEPIdx < pUSBInterfaceDesc->bNumEndpoints; nEPIdx++)
			{
				pUSBEndPointDesc = (PUSB_ENDPOINT_DESCRIPTOR)pBuf;

				// Is this the EP we're looking for?
				if ((pUSBEndPointDesc->bEndpointAddress == nEndPointID) && (pDevHandle->nAltInterface == nCurrIF))
				{
					// Get the EP type
					nUBBEPType = pUSBEndPointDesc->bmAttributes & USB_ENDPOINT_TYPE_MASK;

					// Verify that the EP type matches the requested EP
					if (nEPType == XN_USB_EP_BULK)
					{
						if (nUBBEPType != USB_ENDPOINT_TYPE_BULK)
						{
							XN_ALIGNED_FREE_AND_NULL(pEPHandle);
							return (XN_STATUS_USB_WRONG_ENDPOINT_TYPE);
						}
					}
					else if (nEPType == XN_USB_EP_INTERRUPT)
					{
						if (nUBBEPType != USB_ENDPOINT_TYPE_INTERRUPT)
						{
							XN_ALIGNED_FREE_AND_NULL(pEPHandle);
							return (XN_STATUS_USB_WRONG_ENDPOINT_TYPE);
						}
					}
					else if (nEPType == XN_USB_EP_ISOCHRONOUS)
					{
						if (nUBBEPType != USB_ENDPOINT_TYPE_ISOCHRONOUS)
						{
							XN_ALIGNED_FREE_AND_NULL(pEPHandle);
							return (XN_STATUS_USB_WRONG_ENDPOINT_TYPE);
						}
					}
					else
					{
						XN_ALIGNED_FREE_AND_NULL(pEPHandle);
						return (XN_STATUS_USB_UNKNOWN_ENDPOINT_TYPE);
					}

					// Verify that the EP direction matches the requested direction
					if (nDirType == XN_USB_DIRECTION_IN)
					{
						if (USB_ENDPOINT_DIRECTION_IN(pUSBEndPointDesc->bEndpointAddress) == FALSE)
						{
							XN_ALIGNED_FREE_AND_NULL(pEPHandle);
							return (XN_STATUS_USB_WRONG_ENDPOINT_DIRECTION);
						}
					}
					else if (nDirType == XN_USB_DIRECTION_OUT)
					{
						if (USB_ENDPOINT_DIRECTION_OUT(pUSBEndPointDesc->bEndpointAddress) == FALSE)
						{
							XN_ALIGNED_FREE_AND_NULL(pEPHandle);
							return (XN_STATUS_USB_WRONG_ENDPOINT_DIRECTION);
						}
					}
					else
					{
						XN_ALIGNED_FREE_AND_NULL(pEPHandle);
						return (XN_STATUS_USB_UNKNOWN_ENDPOINT_DIRECTION);
					}

					// Construct the pipe file name
					pEPHandle->cpPipeName[0] = 0;

					cpPipeID[0] = '0';
					cpPipeID[1] = '0' + nEPIdx;
					cpPipeID[2] = 0;
			
					StringCchCopy(pEPHandle->cpPipeName, MAX_DEVICE_STR_LENGTH, pDevHandle->cpDeviceName);
					StringCchCat(pEPHandle->cpPipeName, MAX_DEVICE_STR_LENGTH, PSDRV_PIPE_PREFIX);
					StringCchCat(pEPHandle->cpPipeName, MAX_DEVICE_STR_LENGTH, cpPipeID);

					// Open the regular pipe handle
					pEPHandle->hEPHandle = CreateFile(pEPHandle->cpPipeName, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
					if (pEPHandle->hEPHandle == INVALID_HANDLE_VALUE)
					{
						XN_ALIGNED_FREE_AND_NULL(pEPHandle);
						return (XN_STATUS_USB_OPEN_ENDPOINT_FAILED);
					}

					// Init the overlapped I/O structs
					nRetVal = xnUSBInitOvlp(pEPHandle);
					if (nRetVal != XN_STATUS_OK)
					{
						XN_ALIGNED_FREE_AND_NULL(pEPHandle);
						return (XN_STATUS_USB_OPEN_ENDPOINT_FAILED);						
					}

					// Init the ThreadData variables
					xnOSMemSet(&pEPHandle->ThreadData, 0, sizeof(xnUSBReadThreadData));
					pEPHandle->ThreadData.bInUse = FALSE;

					// Init the default endpoint properties
					pEPHandle->nTimeOut = XN_USB_DEFAULT_EP_TIMEOUT;
					pEPHandle->nEPType = nEPType;
					pEPHandle->nEPDir = nDirType;
					pEPHandle->nEndPointID = nEndPointID;

					// Set the default endpoint timeout
					nRetVal = xnUSBSetPipeProperty(pEPHandle, PSUSBDRV_PIPE_PROPERTY_TIMEOUT, XN_USB_DEFAULT_EP_TIMEOUT);
					if (nRetVal != XN_STATUS_OK)
					{
						XN_ALIGNED_FREE_AND_NULL(pEPHandle);
						return (nRetVal);
					}

					if (nUBBEPType == USB_ENDPOINT_TYPE_ISOCHRONOUS)
					{
						// bits 11 and 12 mark the number of additional transactions, bits 0-10 mark the size
						XnUInt32 nAdditionalTransactions = pUSBEndPointDesc->wMaxPacketSize >> 11;
						XnUInt32 nPacketSize = pUSBEndPointDesc->wMaxPacketSize & 0x7FF;
						pEPHandle->nMaxPacketSize = (nAdditionalTransactions + 1) * (nPacketSize);
					}
					else
					{
						pEPHandle->nMaxPacketSize = pUSBEndPointDesc->wMaxPacketSize;
					}

					// Mark the endpoint as valid
					pEPHandle->bValid = TRUE;

					// The end... (Happy)
					return (XN_STATUS_OK);
				}

				pBuf += pUSBEndPointDesc->bLength;
			}
Пример #12
0
void CMBR::setType()
{
#if 1
	PARTITION_INFORMATION_EX partinfo;
	DWORD read = 0;
	HANDLE hDevice = m_hDevice;
	if (!DeviceIoControl(hDevice, IOCTL_DISK_GET_PARTITION_INFO_EX, NULL, 0, &partinfo, sizeof(partinfo), &read, NULL))
		throw "Cannot get partititon information";
	m_partsize = partinfo.PartitionLength.QuadPart / geometry.BytesPerSector;
	if (partinfo.PartitionStyle == PARTITION_STYLE_MBR)
	{
		SET_PARTITION_INFORMATION_EX setinfo;
		setinfo.PartitionStyle = partinfo.PartitionStyle;
		setinfo.Mbr.PartitionType = 0x13;
		//if (!DeviceIoControl(hDevice, IOCTL_DISK_SET_PARTITION_INFO_EX, &setinfo, sizeof(setinfo), NULL, 0, &read, NULL))
		//throw "Could not set partition type";
	}
	else if (partinfo.PartitionStyle == PARTITION_STYLE_GPT)
	{
		SET_PARTITION_INFORMATION_EX setinfo;
		setinfo.PartitionStyle = partinfo.PartitionStyle;
		setinfo.Gpt = partinfo.Gpt;
		setinfo.Gpt.PartitionType = CFS64GUID;
		if (!DeviceIoControl(hDevice, IOCTL_DISK_SET_PARTITION_INFO_EX, &setinfo, sizeof(setinfo), NULL, 0, &read, NULL))
			throw "Could not set partition type";
	}
	else
		throw "Unknown partitioning scheme";
#else
	MBR thembr;
	UINT64 RECORDLBA = 0;
	try {
		m_pPhysRawDisk->read(0, &thembr, 512);
	}
	catch (char* e)
	{
		//Probably native 4K, we can continue;
		goto fullGPT;
	}
	//GPT support
	if (thembr.entries[0].sysid == 0xEE)
	{
	fullGPT:
		throw "GPT support is buggy";
		//full GPT, we just need to search GPT tables
		GPTheader* header = (GPTheader*)new BYTE[geometry.BytesPerSector];
		GPTheader& theheader = *header;
		m_pPhysRawDisk->read(1, &theheader, geometry.BytesPerSector);
		BYTE* fullarray = new BYTE[theheader.partitionArrayLength*theheader.partitionEntrySize + geometry.BytesPerSector];
		ZeroMemory(fullarray, theheader.partitionArrayLength*theheader.partitionEntrySize + geometry.BytesPerSector);
		m_pPhysRawDisk->read(theheader.partitionArrayLBA, fullarray, ((theheader.partitionArrayLength*theheader.partitionEntrySize + geometry.BytesPerSector - 1) / geometry.BytesPerSector) * geometry.BytesPerSector);
		GPTentry* theentry = (GPTentry*)fullarray;
		bool bFound = false;
		for (int n = 0; n < theheader.partitionArrayLength; n++)
		{
			theentry = (GPTentry*)&fullarray[n*theheader.partitionEntrySize];
			if (theentry->firstLBA <= extents.Extents[0].StartingOffset.QuadPart / geometry.BytesPerSector &&  theentry->lastLBA >= extents.Extents[0].StartingOffset.QuadPart / geometry.BytesPerSector)
			{
				//We found our entry, set it as CFS64
				bFound = true;
				theentry->type = CFS64GUID;
				break;
			}
		}
		if (!bFound)
			throw "Coud not find partition entry";
		DWORD initcrc = crc32(0, NULL, 0);
		theheader.partitionArrayCRC = crc32(initcrc, fullarray, theheader.partitionArrayLength*theheader.partitionEntrySize);
		m_pPhysRawDisk->write(theheader.partitionArrayLBA, fullarray, ((theheader.partitionArrayLength*theheader.partitionEntrySize + geometry.BytesPerSector - 1) / geometry.BytesPerSector) * geometry.BytesPerSector);
		m_pPhysRawDisk->write(theheader.lastUsableLBA + 1, fullarray, ((theheader.partitionArrayLength*theheader.partitionEntrySize + geometry.BytesPerSector - 1) / geometry.BytesPerSector) * geometry.BytesPerSector);
		m_pPhysRawDisk->write(1, &theheader, geometry.BytesPerSector);
		m_pPhysRawDisk->write(theheader.backupLBA, &theheader, geometry.BytesPerSector);
		delete[] fullarray;
		delete[] header;
		return;
	}
	//GPT Hybrid support
	if (thembr.entries[0].sysid == 0xED)
	{
		throw "GPT support is buggy";
		//We need to set type of GPT partition AND MBR partition (if it is there)
		GPTheader* header = (GPTheader*)new BYTE[geometry.BytesPerSector];
		GPTheader& theheader = *header;
		m_pPhysRawDisk->read(1, &theheader, geometry.BytesPerSector);
		BYTE* fullarray = new BYTE[theheader.partitionArrayLength*theheader.partitionEntrySize + geometry.BytesPerSector];
		ZeroMemory(fullarray, theheader.partitionArrayLength*theheader.partitionEntrySize + geometry.BytesPerSector);
		m_pPhysRawDisk->read(theheader.partitionArrayLBA, fullarray, ((theheader.partitionArrayLength*theheader.partitionEntrySize + geometry.BytesPerSector - 1) / geometry.BytesPerSector) * geometry.BytesPerSector);
		GPTentry* theentry = (GPTentry*)fullarray;
		bool bFound = false;
		for (int n = 0; n < theheader.partitionArrayLength; n++)
		{
			theentry = (GPTentry*)&fullarray[n*theheader.partitionEntrySize];
			if (theentry->firstLBA <= extents.Extents[0].StartingOffset.QuadPart / geometry.BytesPerSector &&  theentry->lastLBA >= extents.Extents[0].StartingOffset.QuadPart / geometry.BytesPerSector)
			{
				//We found our entry, set it as CFS64
				bFound = true;
				theentry->type = CFS64GUID;
				break;
			}
		}
		if (!bFound)
			throw "Coud not find partition entry";
		DWORD initcrc = crc32(0, NULL, 0);
		theheader.partitionArrayCRC = crc32(initcrc, fullarray, theheader.partitionArrayLength*theheader.partitionEntrySize);
		m_pPhysRawDisk->write(theheader.partitionArrayLBA, fullarray, ((theheader.partitionArrayLength*theheader.partitionEntrySize + geometry.BytesPerSector - 1) / geometry.BytesPerSector) * geometry.BytesPerSector);
		m_pPhysRawDisk->write(1, &theheader, geometry.BytesPerSector);
		delete[] fullarray;
		delete[] header;
		return;
	}
startsearch:
	for (int n = 0; n < 4; n++)
	{
		if (thembr.entries[n].LBA + RECORDLBA <= extents.Extents[0].StartingOffset.QuadPart / geometry.BytesPerSector && extents.Extents[0].StartingOffset.QuadPart / geometry.BytesPerSector < thembr.entries[n].LBA + RECORDLBA + thembr.entries[n].length)
		{
			if (thembr.entries[n].sysid == 0x0F)		//We ignore CHS extended partitions, so only check fro LBA
			{
				m_pPhysRawDisk->read(thembr.entries[n].LBA + RECORDLBA, &thembr, 512);
				RECORDLBA = thembr.entries[n].LBA + RECORDLBA;
				n = 0;
				goto startsearch;
			}
			else if (thembr.entries[n].sysid == 0xED)		//Skip GPT hybrid entry
			{
				continue;
			}
			else
			{
				//We have found our partition, so make it CFS
				thembr.entries[n].sysid = 0x13;
				m_pPhysRawDisk->write(RECORDLBA, &thembr, 512);
				tcout << _T("Partition with start ") << (double)(thembr.entries[n].LBA + RECORDLBA) / (1024 * 1024 * 1024 / 512) << _T("GB and length ") << (double)thembr.entries[n].length / (1024 * 1024 * 1024 / 512) << _T("GB set as CFS64\n");
				m_partsize = thembr.entries[n].length;
				break;
			}
		}
	}
#endif
}
Пример #13
0
/****************************************************************************
 * ioctl_ReadSector: Read VCD or CDDA sectors
 ****************************************************************************/
int ioctl_ReadSectors( vlc_object_t *p_this, const vcddev_t *p_vcddev,
                       int i_sector, uint8_t *p_buffer, int i_nb, int i_type )
{
    uint8_t *p_block;
    int i;

    if( i_type == VCD_TYPE )
        p_block = malloc( VCD_SECTOR_SIZE * i_nb );
    else
        p_block = p_buffer;

    if( p_vcddev->i_vcdimage_handle != -1 )
    {
        /*
         *  vcd image mode
         */
        if( lseek( p_vcddev->i_vcdimage_handle, i_sector * VCD_SECTOR_SIZE,
                   SEEK_SET ) == -1 )
        {
            msg_Err( p_this, "Could not lseek to sector %d", i_sector );
            goto error;
        }

        if( read( p_vcddev->i_vcdimage_handle, p_block, VCD_SECTOR_SIZE * i_nb)
            == -1 )
        {
            msg_Err( p_this, "Could not read sector %d", i_sector );
            goto error;
        }

    }
    else
    {

        /*
         *  vcd device mode
         */

#if defined( __APPLE__ )
        dk_cd_read_t cd_read;

        memset( &cd_read, 0, sizeof(cd_read) );

        cd_read.offset = i_sector * VCD_SECTOR_SIZE;
        cd_read.sectorArea = kCDSectorAreaSync | kCDSectorAreaHeader |
                             kCDSectorAreaSubHeader | kCDSectorAreaUser |
                             kCDSectorAreaAuxiliary;
        cd_read.sectorType = kCDSectorTypeUnknown;

        cd_read.buffer = p_block;
        cd_read.bufferLength = VCD_SECTOR_SIZE * i_nb;

        if( ioctl( p_vcddev->i_device_handle, DKIOCCDREAD, &cd_read ) == -1 )
        {
            msg_Err( p_this, "could not read block %d", i_sector );
            goto error;
        }

#elif defined( _WIN32 )
        DWORD dwBytesReturned;
        RAW_READ_INFO cdrom_raw;

        /* Initialize CDROM_RAW_READ structure */
        cdrom_raw.DiskOffset.QuadPart = CD_SECTOR_SIZE * i_sector;
        cdrom_raw.SectorCount = i_nb;
        cdrom_raw.TrackMode =  i_type == VCD_TYPE ? XAForm2 : CDDA;

        if( DeviceIoControl( p_vcddev->h_device_handle, IOCTL_CDROM_RAW_READ,
                             &cdrom_raw, sizeof(RAW_READ_INFO), p_block,
                             VCD_SECTOR_SIZE * i_nb, &dwBytesReturned,
                             NULL ) == 0 )
        {
            if( i_type == VCD_TYPE )
            {
                /* Retry in YellowMode2 */
                cdrom_raw.TrackMode = YellowMode2;
                if( DeviceIoControl( p_vcddev->h_device_handle,
                                     IOCTL_CDROM_RAW_READ, &cdrom_raw,
                                     sizeof(RAW_READ_INFO), p_block,
                                     VCD_SECTOR_SIZE * i_nb, &dwBytesReturned,
                                     NULL ) == 0 )
                    goto error;
            }
            else return -1;
        }

#elif defined( __OS2__ )
        cdrom_readlong_t readlong = {{'C', 'D', '0', '1'}, };

        ULONG param_len;
        ULONG data_len;
        ULONG rc;

        readlong.addr_mode = 0;         /* LBA mode */
        readlong.sectors   = i_nb;
        readlong.start     = i_sector;

        rc = DosDevIOCtl( p_vcddev->hcd, IOCTL_CDROMDISK, CDROMDISK_READLONG,
                          &readlong, sizeof( readlong ), &param_len,
                          p_block, VCD_SECTOR_SIZE * i_nb, &data_len );
        if( rc )
        {
            msg_Err( p_this, "could not read block %d", i_sector );
            goto error;
        }

#elif defined( HAVE_SCSIREQ_IN_SYS_SCSIIO_H )
        struct scsireq  sc;
        int i_ret;

        memset( &sc, 0, sizeof(sc) );
        sc.cmd[0] = 0xBE;
        sc.cmd[1] = i_type == VCD_TYPE ? SECTOR_TYPE_MODE2_FORM2:
                                         SECTOR_TYPE_CDDA;
        sc.cmd[2] = (i_sector >> 24) & 0xff;
        sc.cmd[3] = (i_sector >> 16) & 0xff;
        sc.cmd[4] = (i_sector >>  8) & 0xff;
        sc.cmd[5] = (i_sector >>  0) & 0xff;
        sc.cmd[6] = (i_nb >> 16) & 0xff;
        sc.cmd[7] = (i_nb >>  8) & 0xff;
        sc.cmd[8] = (i_nb      ) & 0xff;
        sc.cmd[9] = i_type == VCD_TYPE ? READ_CD_RAW_MODE2 : READ_CD_USERDATA;
        sc.cmd[10] = 0; /* sub channel */
        sc.cmdlen = 12;
        sc.databuf = (caddr_t)p_block;
        sc.datalen = VCD_SECTOR_SIZE * i_nb;
        sc.senselen = sizeof( sc.sense );
        sc.flags = SCCMD_READ;
        sc.timeout = 10000;

        i_ret = ioctl( p_vcddev->i_device_handle, SCIOCCOMMAND, &sc );
        if( i_ret == -1 )
        {
            msg_Err( p_this, "SCIOCCOMMAND failed" );
            goto error;
        }
        if( sc.retsts || sc.error )
        {
            msg_Err( p_this, "SCSI command failed: status %d error %d",
                             sc.retsts, sc.error );
            goto error;
        }

#elif defined( HAVE_IOC_TOC_HEADER_IN_SYS_CDIO_H )
        int i_size = VCD_SECTOR_SIZE;

        if( ioctl( p_vcddev->i_device_handle, CDRIOCSETBLOCKSIZE, &i_size )
            == -1 )
        {
            msg_Err( p_this, "Could not set block size" );
            goto error;
        }

        if( lseek( p_vcddev->i_device_handle,
                   i_sector * VCD_SECTOR_SIZE, SEEK_SET ) == -1 )
        {
            msg_Err( p_this, "Could not lseek to sector %d", i_sector );
            goto error;
        }

        if( read( p_vcddev->i_device_handle,
                  p_block, VCD_SECTOR_SIZE * i_nb ) == -1 )
        {
            msg_Err( p_this, "Could not read sector %d", i_sector );
            goto error;
        }

#else
        for( i = 0; i < i_nb; i++ )
        {
            int i_dummy = i_sector + i + 2 * CD_FRAMES;

#define p_msf ((struct cdrom_msf0 *)(p_block + i * VCD_SECTOR_SIZE))
            p_msf->minute =   i_dummy / (CD_FRAMES * CD_SECS);
            p_msf->second = ( i_dummy % (CD_FRAMES * CD_SECS) ) / CD_FRAMES;
            p_msf->frame =  ( i_dummy % (CD_FRAMES * CD_SECS) ) % CD_FRAMES;
#undef p_msf

            if( ioctl( p_vcddev->i_device_handle, CDROMREADRAW,
                       p_block + i * VCD_SECTOR_SIZE ) == -1 )
            {
                msg_Err( p_this, "could not read block %i from disc",
                         i_sector );

                if( i == 0 )
                    goto error;
                else
                    break;
            }
        }
#endif
    }

    /* For VCDs, we don't want to keep the header and footer of the
     * sectors read */
    if( i_type == VCD_TYPE )
    {
        for( i = 0; i < i_nb; i++ )
        {
            memcpy( p_buffer + i * VCD_DATA_SIZE,
                    p_block + i * VCD_SECTOR_SIZE + VCD_DATA_START,
                    VCD_DATA_SIZE );
        }
        free( p_block );
    }

    return( 0 );

error:
    if( i_type == VCD_TYPE )
        free( p_block );
    return( -1 );
}
Пример #14
0
/*****************************************************************************
 * ioctl_GetTracksMap: Read the Table of Content, fill in the pp_sectors map
 *                     if pp_sectors is not null and return the number of
 *                     tracks available.
 *****************************************************************************/
int ioctl_GetTracksMap( vlc_object_t *p_this, const vcddev_t *p_vcddev,
                        int **pp_sectors )
{
    int i_tracks = 0;

    if( p_vcddev->i_vcdimage_handle != -1 )
    {
        /*
         *  vcd image mode
         */

        i_tracks = p_vcddev->i_tracks;

        if( pp_sectors )
        {
            *pp_sectors = calloc( i_tracks + 1, sizeof(**pp_sectors) );
            if( *pp_sectors == NULL )
                return 0;
            memcpy( *pp_sectors, p_vcddev->p_sectors,
                    (i_tracks + 1) * sizeof(**pp_sectors) );
        }

        return i_tracks;
    }
    else
    {

        /*
         *  vcd device mode
         */

#if defined( __APPLE__ )

        CDTOC *pTOC;
        int i_descriptors;

        if( ( pTOC = darwin_getTOC( p_this, p_vcddev ) ) == NULL )
        {
            msg_Err( p_this, "failed to get the TOC" );
            return 0;
        }

        i_descriptors = CDTOCGetDescriptorCount( pTOC );
        i_tracks = darwin_getNumberOfTracks( pTOC, i_descriptors );

        if( pp_sectors )
        {
            int i, i_leadout = -1;
            CDTOCDescriptor *pTrackDescriptors;
            u_char track;

            *pp_sectors = calloc( i_tracks + 1, sizeof(**pp_sectors) );
            if( *pp_sectors == NULL )
            {
                darwin_freeTOC( pTOC );
                return 0;
            }

            pTrackDescriptors = pTOC->descriptors;

            for( i_tracks = 0, i = 0; i < i_descriptors; i++ )
            {
                track = pTrackDescriptors[i].point;

                if( track == 0xA2 )
                    i_leadout = i;

                if( track > CD_MAX_TRACK_NO || track < CD_MIN_TRACK_NO )
                    continue;

                (*pp_sectors)[i_tracks++] =
                    CDConvertMSFToLBA( pTrackDescriptors[i].p );
            }

            if( i_leadout == -1 )
            {
                msg_Err( p_this, "leadout not found" );
                free( *pp_sectors );
                darwin_freeTOC( pTOC );
                return 0;
            }

            /* set leadout sector */
            (*pp_sectors)[i_tracks] =
                CDConvertMSFToLBA( pTrackDescriptors[i_leadout].p );
        }

        darwin_freeTOC( pTOC );

#elif defined( _WIN32 )
        DWORD dwBytesReturned;
        CDROM_TOC cdrom_toc;

        if( DeviceIoControl( p_vcddev->h_device_handle, IOCTL_CDROM_READ_TOC,
                             NULL, 0, &cdrom_toc, sizeof(CDROM_TOC),
                             &dwBytesReturned, NULL ) == 0 )
        {
            msg_Err( p_this, "could not read TOCHDR" );
            return 0;
        }

        i_tracks = cdrom_toc.LastTrack - cdrom_toc.FirstTrack + 1;

        if( pp_sectors )
        {
            *pp_sectors = calloc( i_tracks + 1, sizeof(**pp_sectors) );
            if( *pp_sectors == NULL )
                return 0;

            for( int i = 0 ; i <= i_tracks ; i++ )
            {
                (*pp_sectors)[ i ] = MSF_TO_LBA2(
                                           cdrom_toc.TrackData[i].Address[1],
                                           cdrom_toc.TrackData[i].Address[2],
                                           cdrom_toc.TrackData[i].Address[3] );
                msg_Dbg( p_this, "p_sectors: %i, %i", i, (*pp_sectors)[i]);
             }
        }

#elif defined( __OS2__ )
        cdrom_get_tochdr_t get_tochdr = {{'C', 'D', '0', '1'}};
        cdrom_tochdr_t     tochdr;

        ULONG param_len;
        ULONG data_len;
        ULONG rc;

        rc = DosDevIOCtl( p_vcddev->hcd, IOCTL_CDROMAUDIO,
                          CDROMAUDIO_GETAUDIODISK,
                          &get_tochdr, sizeof( get_tochdr ), &param_len,
                          &tochdr, sizeof( tochdr ), &data_len );
        if( rc )
        {
            msg_Err( p_this, "could not read TOCHDR" );
            return 0;
        }

        i_tracks = tochdr.last_track - tochdr.first_track + 1;

        if( pp_sectors )
        {
            cdrom_get_track_t get_track = {{'C', 'D', '0', '1'}, };
            cdrom_track_t track;
            int i;

            *pp_sectors = calloc( i_tracks + 1, sizeof(**pp_sectors) );
            if( *pp_sectors == NULL )
                return 0;

            for( i = 0 ; i < i_tracks ; i++ )
            {
                get_track.track = tochdr.first_track + i;
                rc = DosDevIOCtl( p_vcddev->hcd, IOCTL_CDROMAUDIO,
                                  CDROMAUDIO_GETAUDIOTRACK,
                                  &get_track, sizeof(get_track), &param_len,
                                  &track, sizeof(track), &data_len );
                if (rc)
                {
                    msg_Err( p_this, "could not read %d track",
                             get_track.track );
                    return 0;
                }

                (*pp_sectors)[ i ] = MSF_TO_LBA2(
                                       track.start.minute,
                                       track.start.second,
                                       track.start.frame );
                msg_Dbg( p_this, "p_sectors: %i, %i", i, (*pp_sectors)[i]);
            }

            /* for lead-out track */
            (*pp_sectors)[ i ] = MSF_TO_LBA2(
                                   tochdr.lead_out.minute,
                                   tochdr.lead_out.second,
                                   tochdr.lead_out.frame );
            msg_Dbg( p_this, "p_sectors: %i, %i", i, (*pp_sectors)[i]);
        }

#elif defined( HAVE_IOC_TOC_HEADER_IN_SYS_CDIO_H ) \
       || defined( HAVE_SCSIREQ_IN_SYS_SCSIIO_H )
        struct ioc_toc_header tochdr;
        struct ioc_read_toc_entry toc_entries;

        if( ioctl( p_vcddev->i_device_handle, CDIOREADTOCHEADER, &tochdr )
            == -1 )
        {
            msg_Err( p_this, "could not read TOCHDR" );
            return 0;
        }

        i_tracks = tochdr.ending_track - tochdr.starting_track + 1;

        if( pp_sectors )
        {
             int i;

             *pp_sectors = calloc( i_tracks + 1, sizeof(**pp_sectors) );
             if( *pp_sectors == NULL )
                 return 0;

             toc_entries.address_format = CD_LBA_FORMAT;
             toc_entries.starting_track = 0;
             toc_entries.data_len = ( i_tracks + 1 ) *
                                        sizeof( struct cd_toc_entry );
             toc_entries.data = (struct cd_toc_entry *)
                                    malloc( toc_entries.data_len );
             if( toc_entries.data == NULL )
             {
                 free( *pp_sectors );
                 return 0;
             }

             /* Read the TOC */
             if( ioctl( p_vcddev->i_device_handle, CDIOREADTOCENTRYS,
                        &toc_entries ) == -1 )
             {
                 msg_Err( p_this, "could not read the TOC" );
                 free( *pp_sectors );
                 free( toc_entries.data );
                 return 0;
             }

             /* Fill the p_sectors structure with the track/sector matches */
             for( i = 0 ; i <= i_tracks ; i++ )
             {
#if defined( HAVE_SCSIREQ_IN_SYS_SCSIIO_H )
                 /* FIXME: is this ok? */
                 (*pp_sectors)[ i ] = toc_entries.data[i].addr.lba;
#else
                 (*pp_sectors)[ i ] = ntohl( toc_entries.data[i].addr.lba );
#endif
             }
        }
#else
        struct cdrom_tochdr   tochdr;
        struct cdrom_tocentry tocent;

        /* First we read the TOC header */
        if( ioctl( p_vcddev->i_device_handle, CDROMREADTOCHDR, &tochdr )
            == -1 )
        {
            msg_Err( p_this, "could not read TOCHDR" );
            return 0;
        }

        i_tracks = tochdr.cdth_trk1 - tochdr.cdth_trk0 + 1;

        if( pp_sectors )
        {
            int i;

            *pp_sectors = calloc( i_tracks + 1, sizeof(**pp_sectors) );
            if( *pp_sectors == NULL )
                return 0;

            /* Fill the p_sectors structure with the track/sector matches */
            for( i = 0 ; i <= i_tracks ; i++ )
            {
                tocent.cdte_format = CDROM_LBA;
                tocent.cdte_track =
                    ( i == i_tracks ) ? CDROM_LEADOUT : tochdr.cdth_trk0 + i;

                if( ioctl( p_vcddev->i_device_handle, CDROMREADTOCENTRY,
                           &tocent ) == -1 )
                {
                    msg_Err( p_this, "could not read TOCENTRY" );
                    free( *pp_sectors );
                    return 0;
                }

                (*pp_sectors)[ i ] = tocent.cdte_addr.lba;
            }
        }
#endif

        return i_tracks;
    }
}
Пример #15
0
/*
 * Fill the drive properties (size, FS, etc)
 */
BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSystemNameSize)
{
	BOOL r;
	HANDLE hPhysical;
	DWORD size;
	BYTE geometry[128], layout[1024], part_type;
	void* disk_geometry = (void*)geometry;
	void* drive_layout = (void*)layout;
	PDISK_GEOMETRY_EX DiskGeometry = (PDISK_GEOMETRY_EX)disk_geometry;
	PDRIVE_LAYOUT_INFORMATION_EX DriveLayout = (PDRIVE_LAYOUT_INFORMATION_EX)drive_layout;
	char* volume_name;
	char tmp[256];
	DWORD i, nb_partitions = 0;

	hPhysical = GetPhysicalHandle(DriveIndex, FALSE, FALSE);
	if (hPhysical == INVALID_HANDLE_VALUE)
		return FALSE;

	r = DeviceIoControl(hPhysical, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, 
			NULL, 0, geometry, sizeof(geometry), &size, NULL);
	if (!r || size <= 0) {
		uprintf("Could not get geometry for drive #%d: %s\n", DriveIndex, WindowsErrorString());
		safe_closehandle(hPhysical);
		return FALSE;
	}
	SelectedDrive.DiskSize = DiskGeometry->DiskSize.QuadPart;
	memcpy(&SelectedDrive.Geometry, &DiskGeometry->Geometry, sizeof(DISK_GEOMETRY));
	uprintf("Sector Size: %d bytes\n", DiskGeometry->Geometry.BytesPerSector);
	uprintf("Cylinders: %lld, TracksPerCylinder: %d, SectorsPerTrack: %d\n",
		DiskGeometry->Geometry.Cylinders, DiskGeometry->Geometry.TracksPerCylinder, DiskGeometry->Geometry.SectorsPerTrack);

	r = DeviceIoControl(hPhysical, IOCTL_DISK_GET_DRIVE_LAYOUT_EX, 
			NULL, 0, layout, sizeof(layout), &size, NULL );
	if (!r || size <= 0) {
		uprintf("Could not get layout for drive #d: %s\n", DriveIndex, WindowsErrorString());
		return FALSE;
	}

	switch (DriveLayout->PartitionStyle) {
	case PARTITION_STYLE_MBR:
		SelectedDrive.PartitionType = PARTITION_STYLE_MBR;
		for (i=0; i<DriveLayout->PartitionCount; i++) {
			if (DriveLayout->PartitionEntry[i].Mbr.PartitionType != PARTITION_ENTRY_UNUSED) {
				nb_partitions++;
			}
		}
		uprintf("Partition type: MBR, NB Partitions: %d\n", nb_partitions);
		SelectedDrive.has_mbr_uefi_marker = (DriveLayout->Mbr.Signature == MBR_UEFI_MARKER);
		uprintf("Disk ID: 0x%08X %s\n", DriveLayout->Mbr.Signature, SelectedDrive.has_mbr_uefi_marker?"(UEFI target)":"");
		for (i=0; i<DriveLayout->PartitionCount; i++) {
			if (DriveLayout->PartitionEntry[i].Mbr.PartitionType != PARTITION_ENTRY_UNUSED) {
				uprintf("Partition %d:\n", DriveLayout->PartitionEntry[i].PartitionNumber);
				part_type = DriveLayout->PartitionEntry[i].Mbr.PartitionType;
				uprintf("  Type: %s (0x%02x)\r\n  Size: %s (%lld bytes)\r\n  Start Sector: %d, Boot: %s, Recognized: %s\n",
					GetPartitionType(part_type), part_type, SizeToHumanReadable(DriveLayout->PartitionEntry[i].PartitionLength),
					DriveLayout->PartitionEntry[i].PartitionLength, DriveLayout->PartitionEntry[i].Mbr.HiddenSectors,
					DriveLayout->PartitionEntry[i].Mbr.BootIndicator?"Yes":"No",
					DriveLayout->PartitionEntry[i].Mbr.RecognizedPartition?"Yes":"No");
				if (part_type == 0xee)	// Flag a protective MBR for non GPT platforms (XP)
					SelectedDrive.has_protective_mbr = TRUE;
			}
		}
		break;
	case PARTITION_STYLE_GPT:
		SelectedDrive.PartitionType = PARTITION_STYLE_GPT;
		uprintf("Partition type: GPT, NB Partitions: %d\n", DriveLayout->PartitionCount);
		uprintf("Disk GUID: %s\n", GuidToString(&DriveLayout->Gpt.DiskId));
		uprintf("Max parts: %d, Start Offset: %lld, Usable = %lld bytes\n",
			DriveLayout->Gpt.MaxPartitionCount, DriveLayout->Gpt.StartingUsableOffset.QuadPart, DriveLayout->Gpt.UsableLength.QuadPart);
		for (i=0; i<DriveLayout->PartitionCount; i++) {
			nb_partitions++;
			tmp[0] = 0;
			wchar_to_utf8_no_alloc(DriveLayout->PartitionEntry[i].Gpt.Name, tmp, sizeof(tmp));
			uprintf("Partition %d:\r\n  Type: %s\r\n  Name: '%s'\n", DriveLayout->PartitionEntry[i].PartitionNumber,
				GuidToString(&DriveLayout->PartitionEntry[i].Gpt.PartitionType), tmp);
			uprintf("  ID: %s\r\n  Size: %s (%lld bytes)\r\n  Start Sector: %lld, Attributes: 0x%016llX\n",
				GuidToString(&DriveLayout->PartitionEntry[i].Gpt.PartitionId), SizeToHumanReadable(DriveLayout->PartitionEntry[i].PartitionLength),
				DriveLayout->PartitionEntry[i].PartitionLength, DriveLayout->PartitionEntry[i].StartingOffset.QuadPart / DiskGeometry->Geometry.BytesPerSector,
				DriveLayout->PartitionEntry[i].Gpt.Attributes);
		}
		break;
	default:
		SelectedDrive.PartitionType = PARTITION_STYLE_MBR;
		uprintf("Partition type: RAW\n");
		break;
	}
	safe_closehandle(hPhysical);

	// Populate the filesystem data
	volume_name = GetLogicalName(DriveIndex, TRUE);
	if ((volume_name == NULL) || (!GetVolumeInformationA(volume_name, NULL, 0, NULL, NULL, NULL, FileSystemName, FileSystemNameSize))) {
		uprintf("Did not get volume information for disk 0x%02x\n", DriveIndex);
		FileSystemName[0] = 0;
	}
	safe_free(volume_name);

	return TRUE;
}
Пример #16
0
LSBUSCTLAPI BOOL WINAPI
LsBusCtlPlugInEx(
	ULONG	SlotNo,
	ULONG	MaxRequestBlocks,
	HANDLE	hEvent,
	HANDLE	hAlarmEvent)
{
	BOOL fSuccess = FALSE;
	HANDLE hDevice = INVALID_HANDLE_VALUE;
	DWORD cbReturned = 0;
	DWORD err;

	PBUSENUM_PLUGIN_HARDWARE_EX	pLanscsiPluginData;	
	DWORD cbLanscsiPluginData = 0;

	DebugPrint(1, _T("LsBusCtlPlugInEx: Slot %d, MaxRequestBlock %d, hEvent %p, hAlarmEvent %p\n"), 
		SlotNo, MaxRequestBlocks, hEvent, hAlarmEvent);

	hDevice = OpenBusInterface();
	if(INVALID_HANDLE_VALUE == hDevice) {
		return FALSE;
	}

	cbLanscsiPluginData = sizeof (BUSENUM_PLUGIN_HARDWARE_EX) + 
		LSMINIPORT_HARDWARE_IDS_W_SIZE;

	pLanscsiPluginData = HeapAlloc(
		GetProcessHeap(), 
		HEAP_ZERO_MEMORY, 
		cbLanscsiPluginData);
	//
	// The size field should be set to the sizeof the struct as declared
	// and *not* the size of the struct plus the multi_sz
	//
    pLanscsiPluginData->Size = sizeof(BUSENUM_PLUGIN_HARDWARE_EX);
	pLanscsiPluginData->SlotNo = SlotNo;
	pLanscsiPluginData->MaxRequestBlocks = MaxRequestBlocks;
	pLanscsiPluginData->phEvent = &hEvent;
	pLanscsiPluginData->phAlarmEvent = &hAlarmEvent;
	
	CopyMemory(
		pLanscsiPluginData->HardwareIDs,
		LSMINIPORT_HARDWARE_IDS_W,
        LSMINIPORT_HARDWARE_IDS_W_SIZE);

    fSuccess = DeviceIoControl (
			hDevice,
			IOCTL_BUSENUM_PLUGIN_HARDWARE_EX,
            pLanscsiPluginData,
			cbLanscsiPluginData,
            pLanscsiPluginData,
			cbLanscsiPluginData,
            &cbReturned, 
			NULL);

	if (!fSuccess) {
		DebugPrintErrEx(_T("LsBusCtlPlugInEx at slot %d failed: "), SlotNo);
	} else {
		DebugPrintErrEx(_T("LsBusCtlPlugInEx at slot %d completed successfully.\n"), SlotNo);
	}

	err = GetLastError();

	HeapFree(GetProcessHeap(), 0, pLanscsiPluginData);
    CloseHandle(hDevice);

	SetLastError(err);

	return fSuccess;
}
Пример #17
0
BOOL CreatePartition(HANDLE hDrive, int partition_style, int file_system, BOOL mbr_uefi_marker)
{
	const char* PartitionTypeName[2] = { "MBR", "GPT" };
	CREATE_DISK CreateDisk = {PARTITION_STYLE_RAW, {{0}}};
	DRIVE_LAYOUT_INFORMATION_EX4 DriveLayoutEx = {0};
	BOOL r;
	DWORD size;
	LONGLONG size_in_sectors;

	PrintStatus(0, TRUE, "Partitioning (%s)...",  PartitionTypeName[partition_style]);

	if ((partition_style == PARTITION_STYLE_GPT) || (!IsChecked(IDC_EXTRA_PARTITION))) {
		// Go with the MS 1 MB wastage at the beginning...
		DriveLayoutEx.PartitionEntry[0].StartingOffset.QuadPart = 1024*1024;
	} else {
		// Align on Cylinder
		DriveLayoutEx.PartitionEntry[0].StartingOffset.QuadPart = 
			SelectedDrive.Geometry.BytesPerSector * SelectedDrive.Geometry.SectorsPerTrack;
	}
	size_in_sectors = (SelectedDrive.DiskSize - DriveLayoutEx.PartitionEntry[0].StartingOffset.QuadPart) / SelectedDrive.Geometry.BytesPerSector;

	switch (partition_style) {
	case PARTITION_STYLE_MBR:
		CreateDisk.PartitionStyle = PARTITION_STYLE_MBR;
		// If MBR+UEFI is selected, write an UEFI marker in lieu of the regular MBR signature.
		// This helps us reselect the partition scheme option that was used when creating the
		// drive in Rufus. As far as I can tell, Windows doesn't care much if this signature
		// isn't unique for USB drives.
		CreateDisk.Mbr.Signature = mbr_uefi_marker?MBR_UEFI_MARKER:GetTickCount();

		DriveLayoutEx.PartitionStyle = PARTITION_STYLE_MBR;
		DriveLayoutEx.PartitionCount = 4;	// Must be multiple of 4 for MBR
		DriveLayoutEx.Type.Mbr.Signature = CreateDisk.Mbr.Signature;
		DriveLayoutEx.PartitionEntry[0].PartitionStyle = PARTITION_STYLE_MBR;
		// TODO: CHS fixup (32 sectors/track) through a cheat mode, if requested
		// NB: disk geometry is computed by BIOS & co. by finding a match between LBA and CHS value of first partition
		//     ms-sys's write_partition_number_of_heads() and write_partition_start_sector_number() can be used if needed

		// Align on sector boundary if the extra part option is checked
		if (IsChecked(IDC_EXTRA_PARTITION)) {
			size_in_sectors = ((size_in_sectors / SelectedDrive.Geometry.SectorsPerTrack)-1) * SelectedDrive.Geometry.SectorsPerTrack;
			if (size_in_sectors <= 0)
				return FALSE;
		}
		break;
	case PARTITION_STYLE_GPT:
		CreateDisk.PartitionStyle = PARTITION_STYLE_GPT;
		IGNORE_RETVAL(CoCreateGuid(&CreateDisk.Gpt.DiskId));
		CreateDisk.Gpt.MaxPartitionCount = MAX_GPT_PARTITIONS;

		DriveLayoutEx.PartitionStyle = PARTITION_STYLE_GPT;
		DriveLayoutEx.PartitionCount = 1;
		// At the very least, a GPT disk has atv least 34 reserved (512 bytes) blocks at the beginning
		// and 33 at the end.
		DriveLayoutEx.Type.Gpt.StartingUsableOffset.QuadPart = 34*512;
		DriveLayoutEx.Type.Gpt.UsableLength.QuadPart = SelectedDrive.DiskSize - (34+33)*512;
		DriveLayoutEx.Type.Gpt.MaxPartitionCount = MAX_GPT_PARTITIONS;
		DriveLayoutEx.Type.Gpt.DiskId = CreateDisk.Gpt.DiskId;
		DriveLayoutEx.PartitionEntry[0].PartitionStyle = PARTITION_STYLE_GPT;

		size_in_sectors -= 33;	// Need 33 sectors at the end for secondary GPT
		break;
	default:
		break;
	}

	DriveLayoutEx.PartitionEntry[0].PartitionLength.QuadPart = size_in_sectors * SelectedDrive.Geometry.BytesPerSector;
	DriveLayoutEx.PartitionEntry[0].PartitionNumber = 1;
	DriveLayoutEx.PartitionEntry[0].RewritePartition = TRUE;

	switch (partition_style) {
	case PARTITION_STYLE_MBR:
		DriveLayoutEx.PartitionEntry[0].Mbr.BootIndicator = IsChecked(IDC_BOOT);
		DriveLayoutEx.PartitionEntry[0].Mbr.HiddenSectors = SelectedDrive.Geometry.SectorsPerTrack;
		switch (file_system) {
		case FS_FAT16:
			DriveLayoutEx.PartitionEntry[0].Mbr.PartitionType = 0x0e;	// FAT16 LBA
			break;
		case FS_NTFS:
		case FS_EXFAT:
			DriveLayoutEx.PartitionEntry[0].Mbr.PartitionType = 0x07;	// NTFS
			break;
		case FS_FAT32:
			DriveLayoutEx.PartitionEntry[0].Mbr.PartitionType = 0x0c;	// FAT32 LBA
			break;
		default:
			uprintf("Unsupported file system\n");
			return FALSE;
		}
		// Create an extra partition on request - can improve BIOS detection as HDD for older BIOSes
		if (IsChecked(IDC_EXTRA_PARTITION)) {
			DriveLayoutEx.PartitionEntry[1].PartitionStyle = PARTITION_STYLE_MBR;
			// Should end on a sector boundary
			DriveLayoutEx.PartitionEntry[1].StartingOffset.QuadPart = DriveLayoutEx.PartitionEntry[0].StartingOffset.QuadPart +
				DriveLayoutEx.PartitionEntry[0].PartitionLength.QuadPart;
			DriveLayoutEx.PartitionEntry[1].PartitionLength.QuadPart = SelectedDrive.Geometry.SectorsPerTrack*SelectedDrive.Geometry.BytesPerSector;
			DriveLayoutEx.PartitionEntry[1].PartitionNumber = 2;
			DriveLayoutEx.PartitionEntry[1].RewritePartition = TRUE;
			DriveLayoutEx.PartitionEntry[1].Mbr.BootIndicator = FALSE;
			DriveLayoutEx.PartitionEntry[1].Mbr.HiddenSectors = SelectedDrive.Geometry.SectorsPerTrack*SelectedDrive.Geometry.BytesPerSector;
			DriveLayoutEx.PartitionEntry[1].Mbr.PartitionType = DriveLayoutEx.PartitionEntry[0].Mbr.PartitionType + 0x10;	// Hidden whatever
		}
		// For the remaining partitions, PartitionStyle & PartitionType have already
		// been zeroed => already set to MBR/unused
		break;
	case PARTITION_STYLE_GPT:
		DriveLayoutEx.PartitionEntry[0].Gpt.PartitionType = PARTITION_BASIC_DATA_GUID;
		wcscpy(DriveLayoutEx.PartitionEntry[0].Gpt.Name, L"Microsoft Basic Data");
		IGNORE_RETVAL(CoCreateGuid(&DriveLayoutEx.PartitionEntry[0].Gpt.PartitionId));
		break;
	default:
		break;
	}

	// If you don't call IOCTL_DISK_CREATE_DISK, the next call will fail
	size = sizeof(CreateDisk);
	r = DeviceIoControl(hDrive, IOCTL_DISK_CREATE_DISK,
			(BYTE*)&CreateDisk, size, NULL, 0, &size, NULL );
	if (!r) {
		uprintf("Could not reset disk: %s\n", WindowsErrorString());
		safe_closehandle(hDrive);
		return FALSE;
	}

	size = sizeof(DriveLayoutEx) - ((partition_style == PARTITION_STYLE_GPT)?(3*sizeof(PARTITION_INFORMATION_EX)):0);
	r = DeviceIoControl(hDrive, IOCTL_DISK_SET_DRIVE_LAYOUT_EX,
			(BYTE*)&DriveLayoutEx, size, NULL, 0, &size, NULL );
	if (!r) {
		uprintf("Could not set drive layout: %s\n", WindowsErrorString());
		safe_closehandle(hDrive);
		return FALSE;
	}

	return TRUE;
}
Пример #18
0
int	Read(HANDLE fileHandle,unsigned long blockNumber,char *buffer,int size)
{
	int					status,result,blocks;
	DWORD					returned;
	SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER	commandBuffer;

	ZeroMemory(&commandBuffer,sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER));
	
	/* set up the command */
	commandBuffer.sptd.Length = sizeof(SCSI_PASS_THROUGH_DIRECT);
	commandBuffer.sptd.SenseInfoLength = sizeof(SENSE_DATA);
	commandBuffer.sptd.DataIn   = SCSI_IOCTL_DATA_IN;
	commandBuffer.sptd.DataTransferLength = size*512;
	commandBuffer.sptd.TimeOutValue = 60;
	commandBuffer.sptd.DataBuffer = buffer;
	commandBuffer.sptd.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER,senseData);

	/* now the command itself */
	commandBuffer.sptd.CdbLength = 10;
	commandBuffer.sptd.Cdb[0] = READ_10;
	commandBuffer.sptd.Cdb[1] = (0 | DPO_LOAD_IN_CACHE | FUA_USE_CACHE | RA_ACTUAL_ADDRESS);
	commandBuffer.sptd.Cdb[2] = GetByte4(blockNumber);
	commandBuffer.sptd.Cdb[3] = GetByte3(blockNumber);
	commandBuffer.sptd.Cdb[4] = GetByte2(blockNumber);
	commandBuffer.sptd.Cdb[5] = GetByte1(blockNumber);
	commandBuffer.sptd.Cdb[6] = 0;
	commandBuffer.sptd.Cdb[7] = GetByte2(size);
	commandBuffer.sptd.Cdb[8] = GetByte1(size);
	commandBuffer.sptd.Cdb[9] = 0;			/* control field (allways zero) */

	/* lets send the command */
	status = DeviceIoControl(fileHandle,
		       	IOCTL_SCSI_PASS_THROUGH_DIRECT,
			&commandBuffer,
			sizeof(SCSI_PASS_THROUGH_DIRECT),
			&commandBuffer,
			sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER),
			&returned,
			NULL);

	/* status of the command */
	if ((status && commandBuffer.sptd.ScsiStatus != 0) || !status)
	{
		printf("read failed.\n");
		
		printf("Sense: %2x ASC: %2x ASCQ: %2x status: %d\n",
			commandBuffer.senseData.sense_key,
			commandBuffer.senseData.ASC,
			commandBuffer.senseData.ASCQ,
			GetLastError());
		
			result = 0;	

		/* save the result code */
		memcpy(&lastSenseCode,&commandBuffer.senseData,sizeof(SENSE_DATA));

		return result;
	}else{
		return 1;
	}
}
Пример #19
0
int main() {

	printf("Welcome to Ahsan's SATA drive info program, v%02d\n", VERSION);
	printf("Code compiled on: %s %s\n\n", __DATE__, __TIME__);

	
	extern HANDLE Sata_Drive;

	if (find_port() == FALSE) {
		printf("No valid drives found, program will exit :(\n\n");
		exit(EXIT_FAILURE);
	}

	void *pBuffer = malloc(sizeof(ATA_PASS_THROUGH_EX) + sizeof(IDENTIFY_DEVICE_DATA));
	memset(pBuffer, 0, sizeof(ATA_PASS_THROUGH_EX) + sizeof(IDENTIFY_DEVICE_DATA));

	ATA_PASS_THROUGH_EX *pATA_Buffer =  (ATA_PASS_THROUGH_EX *) pBuffer;

	pATA_Buffer->AtaFlags = ATA_FLAGS_DATA_IN | ATA_FLAGS_DRDY_REQUIRED;
	pATA_Buffer->Length = sizeof(ATA_PASS_THROUGH_EX);
	pATA_Buffer->DataBufferOffset = sizeof(ATA_PASS_THROUGH_EX);
	pATA_Buffer->DataTransferLength = sizeof(IDENTIFY_DEVICE_DATA);
	pATA_Buffer->TimeOutValue = TIME_OUT;
	pATA_Buffer->CurrentTaskFile[6] = ID_CMD;

	BOOL ret = DeviceIoControl(	Sata_Drive,
								IOCTL_ATA_PASS_THROUGH,
								pBuffer, (sizeof(ATA_PASS_THROUGH_EX) + sizeof(IDENTIFY_DEVICE_DATA)),
								pBuffer, (sizeof(ATA_PASS_THROUGH_EX) + sizeof(IDENTIFY_DEVICE_DATA)),
								NULL,
								NULL
								);

#if defined DEBUG_PRINTS_1
	printf("Status register of last SATA CMD: 0x%02x\n", pATA_Buffer->CurrentTaskFile[6]);
#endif

	if (ret == FALSE) {
		printf("IOCTL returned FAIL, program will exit :(\n\n");
		exit(EXIT_FAILURE);
	}

	CloseHandle(Sata_Drive);

	IDENTIFY_DEVICE_DATA *pIDFY_Buffer;

	pIDFY_Buffer = (IDENTIFY_DEVICE_DATA *)(int(pBuffer) + sizeof(ATA_PASS_THROUGH_EX));

	printf("SKU is: ");
	sorted_print((pIDFY_Buffer->ModelNumber), 40);
	printf("\n");

	printf("Serial Number is: ");
	sorted_print((pIDFY_Buffer->SerialNumber), 20);
	printf("\n");

	printf("FW Rev is: ");
	sorted_print((pIDFY_Buffer->FirmwareRevision), 8);
	printf("\n");

	printf("Current SATA Gen is: %d\n", pIDFY_Buffer->SerialAtaCapabilities.CurrentSpeed);
		
	printf("\n");

	return 0;
}
Пример #20
0
/*****************************************************************************
 *	ClearCommBreak		(KERNEL32.@)
 *
 *  Resumes character transmission from a communication device.
 *
 * PARAMS
 *
 *      handle [in] The halted communication device whose character transmission is to be resumed
 *
 * RETURNS
 *
 *  True on success and false if the communications device could not be found.
 *
 * BUGS
 *
 *  Only TIOCSBRK and TIOCCBRK are supported.
 */
BOOL WINAPI ClearCommBreak(HANDLE handle)
{
    DWORD dwBytesReturned;
    return DeviceIoControl(handle, IOCTL_SERIAL_SET_BREAK_OFF, NULL, 0, NULL, 0, &dwBytesReturned, NULL);
}
Пример #21
0
static void
slow_gatherer ( void (*add)(const void*, size_t, enum random_origins), 
                enum random_origins requester )
{
  static int is_initialized = 0;
  static int is_workstation = 1;
  HANDLE hDevice;
  DWORD dwType, dwSize, dwResult;
  ULONG ulSize;
  int drive_no, status;
  int no_results = 0;
  void *buffer;

  if ( !is_initialized )
    {
      HKEY hKey;

      if ( debug_me )
        log_debug ("rndw32#slow_gatherer: init toolkit\n" );
      /* Find out whether this is an NT server or workstation if necessary */
      if (RegOpenKeyEx (HKEY_LOCAL_MACHINE,
                        _T("SYSTEM\\CurrentControlSet\\Control\\ProductOptions"),
                        0, KEY_READ, &hKey) == ERROR_SUCCESS)
        {
          BYTE szValue[32 + 8];
          dwSize = 32;

          if ( debug_me )
            log_debug ("rndw32#slow_gatherer: check product options\n" );

          status = RegQueryValueEx (hKey, _T("ProductType"), 0, NULL,
                                    szValue, &dwSize);
          if (status == ERROR_SUCCESS && _stricmp (szValue, "WinNT"))
            {
              /* Note: There are (at least) three cases for ProductType:
                 WinNT = NT Workstation, ServerNT = NT Server, LanmanNT =
                 NT Server acting as a Domain Controller.  */
              is_workstation = 0;
              if ( debug_me )
                log_debug ("rndw32: this is a NT server\n");
            }
          RegCloseKey (hKey);
        }

      /* The following are fixed for the lifetime of the process so we
         only add them once */
      /* readPnPData ();  - we have not implemented that.  */

      /* Initialize the NetAPI32 function pointers if necessary */
      hNetAPI32 = LoadLibraryA("NETAPI32.DLL");
      if (hNetAPI32)
        {
          if (debug_me)
            log_debug ("rndw32#slow_gatherer: netapi32 loaded\n" );
          pNetStatisticsGet = (NETSTATISTICSGET)
            GetProcAddress (hNetAPI32, "NetStatisticsGet");
          pNetApiBufferSize = (NETAPIBUFFERSIZE)
            GetProcAddress (hNetAPI32, "NetApiBufferSize");
          pNetApiBufferFree = (NETAPIBUFFERFREE)
            GetProcAddress (hNetAPI32, "NetApiBufferFree");

          if (!pNetStatisticsGet || !pNetApiBufferSize || !pNetApiBufferFree)
            {
              FreeLibrary (hNetAPI32);
              hNetAPI32 = NULL;
              log_debug ("rndw32: No NETAPI found\n" );
            }
        }

      /* Initialize the NT kernel native API function pointers if necessary */
      hNTAPI = GetModuleHandleA("NTDll.dll");
      if (hNTAPI)
        {
          /* Get a pointer to the NT native information query functions */
          pNtQuerySystemInformation = (NTQUERYSYSTEMINFORMATION)
            GetProcAddress (hNTAPI, "NtQuerySystemInformation");
          pNtQueryInformationProcess = (NTQUERYINFORMATIONPROCESS)
            GetProcAddress (hNTAPI, "NtQueryInformationProcess");
          pNtPowerInformation = (NTPOWERINFORMATION)
            GetProcAddress(hNTAPI, "NtPowerInformation");

          if (!pNtQuerySystemInformation || !pNtQueryInformationProcess)
            hNTAPI = NULL;
        }


      is_initialized = 1;
    }
  
  read_system_rng ( add, requester );
  read_mbm_data ( add, requester );
  
  /* Get network statistics.    Note: Both NT Workstation and NT Server by
     default will be running both the workstation and server services.  The
     heuristic below is probably useful though on the assumption that the
     majority of the network traffic will be via the appropriate service.
     In any case the network statistics return almost no randomness.  */
  {
    LPBYTE lpBuffer;
    
    if (hNetAPI32
        && !pNetStatisticsGet (NULL,
                               is_workstation ? L"LanmanWorkstation" :
                               L"LanmanServer", 0, 0, &lpBuffer))
      {
        if ( debug_me )
          log_debug ("rndw32#slow_gatherer: get netstats\n" );
        pNetApiBufferSize (lpBuffer, &dwSize);
        (*add) ( lpBuffer, dwSize, requester );
        pNetApiBufferFree (lpBuffer);
      }
  }

  /* Get disk I/O statistics for all the hard drives.  100 is an
     arbitrary failsafe limit.  */
  for (drive_no = 0; drive_no < 100 ; drive_no++)
    {
      char diskPerformance[SIZEOF_DISK_PERFORMANCE_STRUCT + 8];
      char szDevice[50];
      
      /* Check whether we can access this device.  */
      snprintf (szDevice, sizeof szDevice, "\\\\.\\PhysicalDrive%d",
                drive_no);
      hDevice = CreateFileA(szDevice, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
                            NULL, OPEN_EXISTING, 0, NULL);
      if (hDevice == INVALID_HANDLE_VALUE)
        break; /* No more drives.  */
        
      /* Note: This only works if you have turned on the disk performance
         counters with 'diskperf -y'.  These counters are off by default. */
      dwSize = sizeof diskPerformance;
      if (DeviceIoControl (hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0,
                           diskPerformance, SIZEOF_DISK_PERFORMANCE_STRUCT,
                           &dwSize, NULL))
        {
          if ( debug_me )
            log_debug ("rndw32#slow_gatherer: iostat drive %d\n",
                       drive_no);
          (*add) (diskPerformance, dwSize, requester);
        }
      else
        {
          log_info ("NOTE: you should run 'diskperf -y' "
                    "to enable the disk statistics\n");
        }
      CloseHandle (hDevice);
    }

  /* In theory we should be using the Win32 performance query API to obtain
     unpredictable data from the system, however this is so unreliable (see
     the multiple sets of comments in registryPoll()) that it's too risky
     to rely on it except as a fallback in emergencies.  Instead, we rely
     mostly on the NT native API function NtQuerySystemInformation(), which
     has the dual advantages that it doesn't have as many (known) problems
     as the Win32 equivalent and that it doesn't access the data indirectly
     via pseudo-registry keys, which means that it's much faster.  Note
     that the Win32 equivalent actually works almost all of the time, the
     problem is that on one or two systems it can fail in strange ways that
     are never the same and can't be reproduced on any other system, which
     is why we use the native API here.  Microsoft officially documented
     this function in early 2003, so it'll be fairly safe to use.  */
  if ( !hNTAPI )
    {
      registry_poll (add, requester);
      return;
    }


  /* Scan the first 64 possible information types (we don't bother with
     increasing the buffer size as we do with the Win32 version of the
     performance data read, we may miss a few classes but it's no big deal).
     This scan typically yields around 20 pieces of data, there's nothing
     in the range 65...128 so chances are there won't be anything above
     there either.  */
  buffer = gcry_xmalloc (PERFORMANCE_BUFFER_SIZE);
  for (dwType = 0; dwType < 64; dwType++)
    {
      switch (dwType)
        {
          /* ID 17 = SystemObjectInformation hangs on some win2k systems.  */
        case 17:
          if (system_is_w2000)
            continue;
          break;

          /* Some information types are write-only (the IDs are shared with
             a set-information call), we skip these.  */
        case 26: case 27: case 38: case 46: case 47: case 48: case 52:
          continue;

          /* ID 53 = SystemSessionProcessInformation reads input from the
             output buffer, which has to contain a session ID and pointer
             to the actual buffer in which to store the session information.
             Because this isn't a standard query, we skip this.  */
        case  53:
          continue;
        }

      /* Query the info for this ID.  Some results (for example for
         ID = 6, SystemCallCounts) are only available in checked builds
         of the kernel.  A smaller subcless of results require that
         certain system config flags be set, for example
         SystemObjectInformation requires that the
         FLG_MAINTAIN_OBJECT_TYPELIST be set in NtGlobalFlags.  To avoid
         having to special-case all of these, we try reading each one and
         only use those for which we get a success status.  */
      dwResult = pNtQuerySystemInformation (dwType, buffer,
                                            PERFORMANCE_BUFFER_SIZE - 2048,
                                            &ulSize);
      if (dwResult != ERROR_SUCCESS)
        continue;

      /* Some calls (e.g. ID = 23, SystemProcessorStatistics, and ID = 24,
         SystemDpcInformation) incorrectly return a length of zero, so we
         manually adjust the length to the correct value.  */
      if ( !ulSize )
        {
          if (dwType == 23)
            ulSize = 6 * sizeof (ULONG);
          else if (dwType == 24)
            ulSize = 5 * sizeof (ULONG);
        }

      /* If we got some data back, add it to the entropy pool.  */
      if (ulSize > 0 && ulSize <= PERFORMANCE_BUFFER_SIZE - 2048)
        {
          if (debug_me)
            log_debug ("rndw32#slow_gatherer: %lu bytes from sysinfo %ld\n",
                       ulSize, dwType);
          (*add) (buffer, ulSize, requester);
          no_results++;
        }
    }

  /* Now we would do the same for the process information.  This
     call would rather ugly in that it requires an exact length
     match for the data returned, failing with a
     STATUS_INFO_LENGTH_MISMATCH error code (0xC0000004) if the
     length isn't an exact match.  It requires a compiler to handle
     complex nested structs, alignment issues, and so on, and
     without the headers in which the entries are declared it's
     almost impossible to do.  Thus we don't.  */


  /* Finally, do the same for the system power status information.  There
     are only a limited number of useful information types available so we
     restrict ourselves to the useful types.  In addition since this
     function doesn't return length information, we have to hardcode in
     length data.  */
  if (pNtPowerInformation)
    {
      static const struct { int type; int size; } powerInfo[] = {
        { 0, 128 },     /* SystemPowerPolicyAc */
        { 1, 128 },     /* SystemPowerPolicyDc */
        { 4, 64 },      /* SystemPowerCapabilities */
        { 5, 48 },      /* SystemBatteryState */
        { 11, 48 },     /* ProcessorInformation */
        { 12, 24 },     /* SystemPowerInformation */
        { -1, -1 }
      };
      int i;

      /* The 100 is a failsafe limit.  */
      for (i = 0; powerInfo[i].type != -1 && i < 100; i++ )
        {
          /* Query the info for this ID */
          dwResult = pNtPowerInformation (powerInfo[i].type, NULL, 0, buffer,
                                          PERFORMANCE_BUFFER_SIZE - 2048);
          if (dwResult != ERROR_SUCCESS)
            continue;
          if (debug_me)
            log_debug ("rndw32#slow_gatherer: %u bytes from powerinfo %d\n",
                       powerInfo[i].size, i);
          (*add) (buffer, powerInfo[i].size, requester);
          no_results++;
        }
      gcry_assert (i < 100);
    }
  gcry_free (buffer);

  /* We couldn't get enough results from the kernel, fall back to the
     somewhat troublesome registry poll.  */
  if (no_results < 15)
    registry_poll (add, requester);
}
Пример #22
0
/* This is the slowpoll function which gathers up network/hard drive
   performance data for the random pool */
BOOL SlowPoll (void)
{
	static int isWorkstation = -1;
	static int cbPerfData = 0x10000;
	HANDLE hDevice;
	LPBYTE lpBuffer;
	DWORD dwSize, status;
	LPWSTR lpszLanW, lpszLanS;
	int nDrive;

	/* Find out whether this is an NT server or workstation if necessary */
	if (isWorkstation == -1)
	{
		HKEY hKey;

		if (RegOpenKeyEx (HKEY_LOCAL_MACHINE,
		       "SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
				  0, KEY_READ, &hKey) == ERROR_SUCCESS)
		{
			unsigned char szValue[32];
			dwSize = sizeof (szValue);

			isWorkstation = TRUE;
			status = RegQueryValueEx (hKey, "ProductType", 0, NULL,
						  szValue, &dwSize);

			if (status == ERROR_SUCCESS && _stricmp ((char *) szValue, "WinNT"))
				/* Note: There are (at least) three cases for
				   ProductType: WinNT = NT Workstation,
				   ServerNT = NT Server, LanmanNT = NT Server
				   acting as a Domain Controller */
				isWorkstation = FALSE;

			RegCloseKey (hKey);
		}
	}
	/* Initialize the NetAPI32 function pointers if necessary */
	if (hNetAPI32 == NULL)
	{
		/* Obtain a handle to the module containing the Lan Manager
		   functions */
		hNetAPI32 = LoadLibrary ("NETAPI32.DLL");
		if (hNetAPI32 != NULL)
		{
			/* Now get pointers to the functions */
			pNetStatisticsGet = (NETSTATISTICSGET) GetProcAddress (hNetAPI32,
							"NetStatisticsGet");
			pNetApiBufferSize = (NETAPIBUFFERSIZE) GetProcAddress (hNetAPI32,
							"NetApiBufferSize");
			pNetApiBufferFree = (NETAPIBUFFERFREE) GetProcAddress (hNetAPI32,
							"NetApiBufferFree");

			/* Make sure we got valid pointers for every NetAPI32
			   function */
			if (pNetStatisticsGet == NULL ||
			    pNetApiBufferSize == NULL ||
			    pNetApiBufferFree == NULL)
			{
				/* Free the library reference and reset the
				   static handle */
				FreeLibrary (hNetAPI32);
				hNetAPI32 = NULL;
			}
		}
	}

	/* Get network statistics.  Note: Both NT Workstation and NT Server
	   by default will be running both the workstation and server
	   services.  The heuristic below is probably useful though on the
	   assumption that the majority of the network traffic will be via
	   the appropriate service */
	lpszLanW = (LPWSTR) WIDE ("LanmanWorkstation");
	lpszLanS = (LPWSTR) WIDE ("LanmanServer");
	if (hNetAPI32 &&
	    pNetStatisticsGet (NULL,
			       isWorkstation ? lpszLanW : lpszLanS,
			       0, 0, &lpBuffer) == 0)
	{
		pNetApiBufferSize (lpBuffer, &dwSize);
		RandaddBuf ((unsigned char *) lpBuffer, dwSize);
		pNetApiBufferFree (lpBuffer);
	}

	/* Get disk I/O statistics for all the hard drives */
	for (nDrive = 0;; nDrive++)
	{
		DISK_PERFORMANCE diskPerformance;
		char szDevice[24];

		/* Check whether we can access this device */
		sprintf (szDevice, "\\\\.\\PhysicalDrive%d", nDrive);
		hDevice = CreateFile (szDevice, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
				      NULL, OPEN_EXISTING, 0, NULL);
		if (hDevice == INVALID_HANDLE_VALUE)
			break;


		/* Note: This only works if you have turned on the disk
		   performance counters with 'diskperf -y'.  These counters
		   are off by default */
		if (DeviceIoControl (hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0,
				&diskPerformance, sizeof (DISK_PERFORMANCE),
				     &dwSize, NULL))
		{
			RandaddBuf ((unsigned char *) &diskPerformance, dwSize);
		}
		CloseHandle (hDevice);
	}

	// CryptoAPI
	if (CryptoAPIAvailable && CryptGenRandom (hCryptProv, sizeof (buffer), buffer)) 
		RandaddBuf (buffer, sizeof (buffer));

	burn(buffer, sizeof (buffer));
	Randmix();
	return TRUE;
}
Пример #23
0
/***********************************************************************
 *           GetCommModemStatus   (KERNEL32.@)
 *
 *  Obtains the four control register bits if supported by the hardware.
 *
 * PARAMS
 *
 *      hFile           [in]    The communications device
 *      lpModemStat     [out]   The control register bits
 *
 * RETURNS
 *
 *  True if the communications handle was good and for hardware that
 *  control register access, false otherwise.
 */
BOOL WINAPI GetCommModemStatus(HANDLE hFile, LPDWORD lpModemStat)
{
    DWORD dwBytesReturned;
    return DeviceIoControl(hFile, IOCTL_SERIAL_GET_MODEMSTATUS,
                           NULL, 0, lpModemStat, sizeof(DWORD), &dwBytesReturned, NULL);
}
Пример #24
0
int _tmain(int argc, _TCHAR* argv[])
{
	
// 	argv[1] = L"d:\\myfile.txt";
// 	argc = 2;
	if (argc < 2)
	{
		printf("usage example: c:\\myfile.txt \n");
		return -1;
	}
	
	HANDLE hDevHandle=INVALID_HANDLE_VALUE;
	INT res=-1;
	PRETRIEVAL_POINTERS_BUFFER  prpb=NULL;
	
	LARGE_INTEGER file_size;
	
	DWORD SectorsPerCluster;
	DWORD BytesPerSector;
	DWORD NumberOfFreeClusters;
	DWORD TotalNumberOfClusters;	

	WCHAR fs_path[4]; //путь в виде "C:\\"
	memset(fs_path, 0, 4*sizeof(WCHAR) );
	memcpy( fs_path, argv[1], 3*sizeof(WCHAR) );
		
	if (!GetDiskFreeSpaceW(
						fs_path, 
						&SectorsPerCluster, 
						&BytesPerSector, 
						&NumberOfFreeClusters, 
						&TotalNumberOfClusters
						)
		)
	{
		printf("GetDiskFreeSpaceW error\n");
		return -1;
	}

	hDevHandle = CreateFileW(
		argv[1],//fs_path,
		GENERIC_READ /*| GENERIC_WRITE*/,
		FILE_SHARE_READ | FILE_SHARE_WRITE,
		NULL,
		OPEN_EXISTING,
		FILE_ATTRIBUTE_NORMAL  | FILE_FLAG_NO_BUFFERING,
		NULL
		);

	if (hDevHandle==INVALID_HANDLE_VALUE)
	{
		printf("CreateFileW error\n");
		return -1;
	}
	if (GetFileSizeEx(hDevHandle,&file_size)<0) 
	{
		printf("GetFileSizeEx error\n");
		return -1;
	}

	DWORD file_cl_cnt; 
	DWORD cluster_size=SectorsPerCluster*BytesPerSector;
	if (file_size.QuadPart< cluster_size || file_size.QuadPart%cluster_size>0)
	{
		file_cl_cnt=(DWORD)(file_size.QuadPart/cluster_size+1);
	}
	else
	{
		file_cl_cnt=(DWORD)(file_size.QuadPart/cluster_size);
	}

	STARTING_VCN_INPUT_BUFFER start_vcn;
	start_vcn.StartingVcn.QuadPart=file_cl_cnt-1;

	prpb=(PRETRIEVAL_POINTERS_BUFFER )new char[sizeof(RETRIEVAL_POINTERS_BUFFER )+sizeof(LARGE_INTEGER)*2*10];
	DWORD nRead;
	if (!DeviceIoControl(hDevHandle,
		FSCTL_GET_RETRIEVAL_POINTERS,
		&start_vcn,
		sizeof(STARTING_VCN_INPUT_BUFFER),
		prpb, 
		sizeof(RETRIEVAL_POINTERS_BUFFER )+sizeof(LARGE_INTEGER)*2*10,
		&nRead,
		NULL))
	{
		//очень маленький файл находиться в MFT
		DWORD err = GetLastError();
		if (err == ERROR_HANDLE_EOF )
			printf("DeviceIoControl error: file is too small\n");
		else
			printf("DeviceIoControl error: GetLastError = %d \n", err);
		
	}
	else
	{
		printf("DeviceIoControl success\n");
	}
	
	CloseHandle(hDevHandle);
	hDevHandle=NULL;
	
	delete [] prpb;

	return 0;
}
Пример #25
0
VOID
__cdecl
main(
    _In_ int argc,
    _In_z_ char *argv[]
    )

{
    BOOL status = 0;
    DWORD accessMode = 0, shareMode = 0;
    HANDLE fileHandle = NULL;
    ULONG alignmentMask = 0; // default == no alignment requirement
    UCHAR srbType = 0; // default == SRB_TYPE_SCSI_REQUEST_BLOCK
    PUCHAR dataBuffer = NULL;
    PUCHAR pUnAlignedBuffer = NULL;
    SCSI_PASS_THROUGH_WITH_BUFFERS sptwb;
    SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER sptdwb;
    SCSI_PASS_THROUGH_WITH_BUFFERS_EX sptwb_ex;
    SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER_EX sptdwb_ex;
    CHAR string[NAME_COUNT];

    ULONG length = 0,
          errorCode = 0,
          returned = 0,
          sectorSize = 512;

    if ((argc < 2) || (argc > 3)) {
       printf("Usage:  %s <port-name> [-mode]\n", argv[0] );
       printf("Examples:\n");
       printf("    spti g:       (open the disk class driver in SHARED READ/WRITE mode)\n");
       printf("    spti Scsi2:   (open the miniport driver for the 3rd host adapter)\n");
       printf("    spti Tape0 w  (open the tape class driver in SHARED WRITE mode)\n");
       printf("    spti i: c     (open the CD-ROM class driver in SHARED READ mode)\n");
       return;
    }

    StringCbPrintf(string, sizeof(string), "\\\\.\\%s", argv[1]);

    shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;  // default
    accessMode = GENERIC_WRITE | GENERIC_READ;       // default

    if (argc == 3) {

        switch(tolower(argv[2][0])) {
            case 'r':
                shareMode = FILE_SHARE_READ;
                break;

            case 'w':
                shareMode = FILE_SHARE_WRITE;
                break;

            case 'c':
                shareMode = FILE_SHARE_READ;
                sectorSize = 2048;
                break;

            default:
                printf("%s is an invalid mode.\n", argv[2]);
                puts("\tr = read");
                puts("\tw = write");
                puts("\tc = read CD (2048 byte sector mode)");
                return;
        }
    }

    fileHandle = CreateFile(string,
       accessMode,
       shareMode,
       NULL,
       OPEN_EXISTING,
       0,
       NULL);

    if (fileHandle == INVALID_HANDLE_VALUE) {
        errorCode = GetLastError();
        printf("Error opening %s. Error: %d\n",
               string, errorCode);
        PrintError(errorCode);
        return;
    }

    //
    // Get the alignment requirements
    //

    status = QueryPropertyForDevice(fileHandle, &alignmentMask, &srbType);
    if (!status ) {
        errorCode = GetLastError();
        printf("Error getting device and/or adapter properties; "
               "error was %d\n", errorCode);
        PrintError(errorCode);
        CloseHandle(fileHandle);
        return;
    }

    printf("\n"
           "            *****     Detected Alignment Mask    *****\n"
           "            *****             was %08x       *****\n\n\n",
           alignmentMask);

    //
    // Send SCSI Pass Through
    //

    puts("            ***** MODE SENSE -- return all pages *****");
    puts("            *****      with SenseInfo buffer     *****\n");

    if(srbType == 1)
    {
        ZeroMemory(&sptwb_ex,sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX));
        sptwb_ex.spt.Version = 0;
        sptwb_ex.spt.Length = sizeof(SCSI_PASS_THROUGH_EX);
        sptwb_ex.spt.ScsiStatus = 0;
        sptwb_ex.spt.CdbLength = CDB6GENERIC_LENGTH;
        sptwb_ex.spt.StorAddressLength = sizeof(STOR_ADDR_BTL8);
        sptwb_ex.spt.SenseInfoLength = SPT_SENSE_LENGTH;
        sptwb_ex.spt.DataOutTransferLength = 0;
        sptwb_ex.spt.DataInTransferLength = 192;
        sptwb_ex.spt.DataDirection = SCSI_IOCTL_DATA_IN;
        sptwb_ex.spt.TimeOutValue = 2;
        sptwb_ex.spt.StorAddressOffset =
            offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX,StorAddress);
        sptwb_ex.StorAddress.Type = STOR_ADDRESS_TYPE_BTL8;
        sptwb_ex.StorAddress.Port = 0;
        sptwb_ex.StorAddress.AddressLength = STOR_ADDR_BTL8_ADDRESS_LENGTH;
        sptwb_ex.StorAddress.Path = 0;
        sptwb_ex.StorAddress.Target = 1;
        sptwb_ex.StorAddress.Lun = 0;
        sptwb_ex.spt.SenseInfoOffset =
           offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX,ucSenseBuf);
        sptwb_ex.spt.DataOutBufferOffset = 0;
        sptwb_ex.spt.DataInBufferOffset =
           offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX,ucDataBuf);
        sptwb_ex.spt.Cdb[0] = SCSIOP_MODE_SENSE;
        sptwb_ex.spt.Cdb[2] = MODE_SENSE_RETURN_ALL;
        sptwb_ex.spt.Cdb[4] = 192;
        length = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX,ucDataBuf) +
           sptwb_ex.spt.DataInTransferLength;

        status = DeviceIoControl(fileHandle,
                                 IOCTL_SCSI_PASS_THROUGH_EX,
                                 &sptwb_ex,
                                 sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX),
                                 &sptwb_ex,
                                 length,
                                 &returned,
                                 FALSE);

        PrintStatusResultsEx(status,returned,&sptwb_ex,length);
    }
    else
    {
        ZeroMemory(&sptwb,sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS));
        sptwb.spt.Length = sizeof(SCSI_PASS_THROUGH);
        sptwb.spt.PathId = 0;
        sptwb.spt.TargetId = 1;
        sptwb.spt.Lun = 0;
        sptwb.spt.CdbLength = CDB6GENERIC_LENGTH;
        sptwb.spt.SenseInfoLength = SPT_SENSE_LENGTH;
        sptwb.spt.DataIn = SCSI_IOCTL_DATA_IN;
        sptwb.spt.DataTransferLength = 192;
        sptwb.spt.TimeOutValue = 2;
        sptwb.spt.DataBufferOffset =
           offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucDataBuf);
        sptwb.spt.SenseInfoOffset =
           offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucSenseBuf);
        sptwb.spt.Cdb[0] = SCSIOP_MODE_SENSE;
        sptwb.spt.Cdb[2] = MODE_SENSE_RETURN_ALL;
        sptwb.spt.Cdb[4] = 192;
        length = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucDataBuf) +
           sptwb.spt.DataTransferLength;

        status = DeviceIoControl(fileHandle,
                                 IOCTL_SCSI_PASS_THROUGH,
                                 &sptwb,
                                 sizeof(SCSI_PASS_THROUGH),
                                 &sptwb,
                                 length,
                                 &returned,
                                 FALSE);

        PrintStatusResults(status,returned,&sptwb,length);
    }


    printf("            ***** MODE SENSE -- return all pages *****\n");
    printf("            *****    without SenseInfo buffer    *****\n\n");

    if(srbType == 1)
    {
        ZeroMemory(&sptwb_ex,sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX));
        sptwb_ex.spt.Version = 0;
        sptwb_ex.spt.Length = sizeof(SCSI_PASS_THROUGH_EX);
        sptwb_ex.spt.ScsiStatus = 0;
        sptwb_ex.spt.CdbLength = CDB6GENERIC_LENGTH;
        sptwb_ex.spt.StorAddressLength = sizeof(STOR_ADDR_BTL8);
        sptwb_ex.spt.SenseInfoLength = 0;
        sptwb_ex.spt.DataOutTransferLength = 0;
        sptwb_ex.spt.DataInTransferLength = 192;
        sptwb_ex.spt.DataDirection = SCSI_IOCTL_DATA_IN;
        sptwb_ex.spt.TimeOutValue = 2;
        sptwb_ex.spt.StorAddressOffset =
            offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX,StorAddress);
        sptwb_ex.StorAddress.Type = STOR_ADDRESS_TYPE_BTL8;
        sptwb_ex.StorAddress.Port = 0;
        sptwb_ex.StorAddress.AddressLength = STOR_ADDR_BTL8_ADDRESS_LENGTH;
        sptwb_ex.StorAddress.Path = 0;
        sptwb_ex.StorAddress.Target = 1;
        sptwb_ex.StorAddress.Lun = 0;
        sptwb_ex.spt.SenseInfoOffset = 0;
        sptwb_ex.spt.DataOutBufferOffset = 0;
        sptwb_ex.spt.DataInBufferOffset =
           offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX,ucDataBuf);
        sptwb_ex.spt.Cdb[0] = SCSIOP_MODE_SENSE;
        sptwb_ex.spt.Cdb[2] = MODE_SENSE_RETURN_ALL;
        sptwb_ex.spt.Cdb[4] = 192;
        length = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX,ucDataBuf) +
           sptwb_ex.spt.DataInTransferLength;

        status = DeviceIoControl(fileHandle,
                                 IOCTL_SCSI_PASS_THROUGH_EX,
                                 &sptwb_ex,
                                 sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX),
                                 &sptwb_ex,
                                 length,
                                 &returned,
                                 FALSE);

        PrintStatusResultsEx(status,returned,&sptwb_ex,length);
    }
    else
    {
        ZeroMemory(&sptwb,sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS));
        sptwb.spt.Length = sizeof(SCSI_PASS_THROUGH);
        sptwb.spt.PathId = 0;
        sptwb.spt.TargetId = 1;
        sptwb.spt.Lun = 0;
        sptwb.spt.CdbLength = CDB6GENERIC_LENGTH;
        sptwb.spt.SenseInfoLength = 0;
        sptwb.spt.DataIn = SCSI_IOCTL_DATA_IN;
        sptwb.spt.DataTransferLength = 192;
        sptwb.spt.TimeOutValue = 2;
        sptwb.spt.DataBufferOffset =
           offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucDataBuf);
        sptwb.spt.Cdb[0] = SCSIOP_MODE_SENSE;
        sptwb.spt.Cdb[2] = MODE_SENSE_RETURN_ALL;
        sptwb.spt.Cdb[4] = 192;
        length = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucDataBuf) +
           sptwb.spt.DataTransferLength;

        status = DeviceIoControl(fileHandle,
                                 IOCTL_SCSI_PASS_THROUGH,
                                 &sptwb,
                                 sizeof(SCSI_PASS_THROUGH),
                                 &sptwb,
                                 length,
                                 &returned,
                                 FALSE);

        PrintStatusResults(status,returned,&sptwb,length);
    }


    printf("            *****      TEST UNIT READY      *****\n");
    printf("            *****   DataInBufferLength = 0  *****\n\n");

    if(srbType == 1)
    {
        ZeroMemory(&sptwb_ex,sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX));
        sptwb_ex.spt.Version = 0;
        sptwb_ex.spt.Length = sizeof(SCSI_PASS_THROUGH_EX);
        sptwb_ex.spt.ScsiStatus = 0;
        sptwb_ex.spt.CdbLength = CDB6GENERIC_LENGTH;
        sptwb_ex.spt.StorAddressLength = sizeof(STOR_ADDR_BTL8);
        sptwb_ex.spt.SenseInfoLength = SPT_SENSE_LENGTH;
        sptwb_ex.spt.DataOutTransferLength = 0;
        sptwb_ex.spt.DataInTransferLength = 0;
        sptwb_ex.spt.DataDirection = SCSI_IOCTL_DATA_IN;
        sptwb_ex.spt.TimeOutValue = 2;
        sptwb_ex.spt.StorAddressOffset =
            offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX,StorAddress);
        sptwb_ex.StorAddress.Type = STOR_ADDRESS_TYPE_BTL8;
        sptwb_ex.StorAddress.Port = 0;
        sptwb_ex.StorAddress.AddressLength = STOR_ADDR_BTL8_ADDRESS_LENGTH;
        sptwb_ex.StorAddress.Path = 0;
        sptwb_ex.StorAddress.Target = 1;
        sptwb_ex.StorAddress.Lun = 0;
        sptwb_ex.spt.SenseInfoOffset =
           offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX,ucSenseBuf);
        sptwb_ex.spt.DataOutBufferOffset = 0;
        sptwb_ex.spt.DataInBufferOffset = 0;
        sptwb_ex.spt.Cdb[0] = SCSIOP_TEST_UNIT_READY;
        length = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX,ucDataBuf);

        status = DeviceIoControl(fileHandle,
                                 IOCTL_SCSI_PASS_THROUGH_EX,
                                 &sptwb_ex,
                                 sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX),
                                 &sptwb_ex,
                                 length,
                                 &returned,
                                 FALSE);

        PrintStatusResultsEx(status,returned,&sptwb_ex,length);
    }
    else
    {
        ZeroMemory(&sptwb,sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS));
        sptwb.spt.Length = sizeof(SCSI_PASS_THROUGH);
        sptwb.spt.PathId = 0;
        sptwb.spt.TargetId = 1;
        sptwb.spt.Lun = 0;
        sptwb.spt.CdbLength = CDB6GENERIC_LENGTH;
        sptwb.spt.SenseInfoLength = SPT_SENSE_LENGTH;
        sptwb.spt.DataIn = SCSI_IOCTL_DATA_IN;
        sptwb.spt.DataTransferLength = 0;
        sptwb.spt.TimeOutValue = 2;
        sptwb.spt.DataBufferOffset = 0;
        sptwb.spt.SenseInfoOffset =
           offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucSenseBuf);
        sptwb.spt.Cdb[0] = SCSIOP_TEST_UNIT_READY;
        length = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucDataBuf);

        status = DeviceIoControl(fileHandle,
                                 IOCTL_SCSI_PASS_THROUGH,
                                 &sptwb,
                                 sizeof(SCSI_PASS_THROUGH),
                                 &sptwb,
                                 length,
                                 &returned,
                                 FALSE);

        PrintStatusResults(status,returned,&sptwb,length);
    }


    //
    //  Do a mode sense with a bad data buffer offset.  This will fail.
    //
    printf("            *****      MODE SENSE -- return all pages      *****\n");
    printf("            *****   bad DataBufferOffset -- should fail    *****\n\n");

    if(srbType == 1)
    {
        ZeroMemory(&sptwb_ex,sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX));
        sptwb_ex.spt.Version = 0;
        sptwb_ex.spt.Length = sizeof(SCSI_PASS_THROUGH_EX);
        sptwb_ex.spt.ScsiStatus = 0;
        sptwb_ex.spt.CdbLength = CDB6GENERIC_LENGTH;
        sptwb_ex.spt.StorAddressLength = sizeof(STOR_ADDR_BTL8);
        sptwb_ex.spt.SenseInfoLength = SPT_SENSE_LENGTH;
        sptwb_ex.spt.DataOutTransferLength = 0;
        sptwb_ex.spt.DataInTransferLength = 192;
        sptwb_ex.spt.DataDirection = SCSI_IOCTL_DATA_IN;
        sptwb_ex.spt.TimeOutValue = 2;
        sptwb_ex.spt.StorAddressOffset =
            offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX,StorAddress);
        sptwb_ex.StorAddress.Type = STOR_ADDRESS_TYPE_BTL8;
        sptwb_ex.StorAddress.Port = 0;
        sptwb_ex.StorAddress.AddressLength = STOR_ADDR_BTL8_ADDRESS_LENGTH;
        sptwb_ex.StorAddress.Path = 0;
        sptwb_ex.StorAddress.Target = 1;
        sptwb_ex.StorAddress.Lun = 0;
        sptwb_ex.spt.SenseInfoOffset =
           offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX,ucSenseBuf);
        sptwb_ex.spt.DataOutBufferOffset = 0;
        sptwb_ex.spt.DataInBufferOffset = 0;
        sptwb_ex.spt.Cdb[0] = SCSIOP_MODE_SENSE;
        sptwb_ex.spt.Cdb[2] = MODE_SENSE_RETURN_ALL;
        sptwb_ex.spt.Cdb[4] = 192;
        length = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX,ucDataBuf) +
           sptwb_ex.spt.DataInTransferLength;

        status = DeviceIoControl(fileHandle,
                                 IOCTL_SCSI_PASS_THROUGH_EX,
                                 &sptwb_ex,
                                 sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX),
                                 &sptwb_ex,
                                 length,
                                 &returned,
                                 FALSE);

        PrintStatusResultsEx(status,returned,&sptwb_ex,length);
    }
    else
    {
        ZeroMemory(&sptwb,sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS));
        sptwb.spt.Length = sizeof(SCSI_PASS_THROUGH);
        sptwb.spt.PathId = 0;
        sptwb.spt.TargetId = 1;
        sptwb.spt.Lun = 0;
        sptwb.spt.CdbLength = CDB6GENERIC_LENGTH;
        sptwb.spt.SenseInfoLength = 0;
        sptwb.spt.DataIn = SCSI_IOCTL_DATA_IN;
        sptwb.spt.DataTransferLength = 192;
        sptwb.spt.TimeOutValue = 2;
        sptwb.spt.DataBufferOffset = 0;
        sptwb.spt.SenseInfoOffset =
           offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucSenseBuf);
        sptwb.spt.Cdb[0] = SCSIOP_MODE_SENSE;
        sptwb.spt.Cdb[2] = MODE_SENSE_RETURN_ALL;
        sptwb.spt.Cdb[4] = 192;
        length = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucDataBuf) +
           sptwb.spt.DataTransferLength;

        status = DeviceIoControl(fileHandle,
                                 IOCTL_SCSI_PASS_THROUGH,
                                 &sptwb,
                                 sizeof(SCSI_PASS_THROUGH),
                                 &sptwb,
                                 length,
                                 &returned,
                                 FALSE);

        PrintStatusResults(status,returned,&sptwb,length);
    }


    //
    // Get caching mode sense page.
    //
    printf("            *****               MODE SENSE                  *****\n");
    printf("            *****     return caching mode sense page        *****\n\n");

    if(srbType == 1)
    {
        ZeroMemory(&sptwb_ex,sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX));
        sptwb_ex.spt.Version = 0;
        sptwb_ex.spt.Length = sizeof(SCSI_PASS_THROUGH_EX);
        sptwb_ex.spt.ScsiStatus = 0;
        sptwb_ex.spt.CdbLength = CDB6GENERIC_LENGTH;
        sptwb_ex.spt.StorAddressLength = sizeof(STOR_ADDR_BTL8);
        sptwb_ex.spt.SenseInfoLength = SPT_SENSE_LENGTH;
        sptwb_ex.spt.DataOutTransferLength = 0;
        sptwb_ex.spt.DataInTransferLength = 192;
        sptwb_ex.spt.DataDirection = SCSI_IOCTL_DATA_IN;
        sptwb_ex.spt.TimeOutValue = 2;
        sptwb_ex.spt.StorAddressOffset =
            offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX,StorAddress);
        sptwb_ex.StorAddress.Type = STOR_ADDRESS_TYPE_BTL8;
        sptwb_ex.StorAddress.Port = 0;
        sptwb_ex.StorAddress.AddressLength = STOR_ADDR_BTL8_ADDRESS_LENGTH;
        sptwb_ex.StorAddress.Path = 0;
        sptwb_ex.StorAddress.Target = 1;
        sptwb_ex.StorAddress.Lun = 0;
        sptwb_ex.spt.SenseInfoOffset =
           offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX,ucSenseBuf);
        sptwb_ex.spt.DataOutBufferOffset = 0;
        sptwb_ex.spt.DataInBufferOffset =
           offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX,ucDataBuf);
        sptwb_ex.spt.Cdb[0] = SCSIOP_MODE_SENSE;
        sptwb_ex.spt.Cdb[1] = 0x08; // target shall not return any block descriptors
        sptwb_ex.spt.Cdb[2] = MODE_PAGE_CACHING;
        sptwb_ex.spt.Cdb[4] = 192;
        length = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX,ucDataBuf) +
           sptwb_ex.spt.DataInTransferLength;

        status = DeviceIoControl(fileHandle,
                                 IOCTL_SCSI_PASS_THROUGH_EX,
                                 &sptwb_ex,
                                 sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS_EX),
                                 &sptwb_ex,
                                 length,
                                 &returned,
                                 FALSE);

        PrintStatusResultsEx(status,returned,&sptwb_ex,length);
    }
    else
    {
        ZeroMemory(&sptwb,sizeof(SCSI_PASS_THROUGH_WITH_BUFFERS));
        sptwb.spt.Length = sizeof(SCSI_PASS_THROUGH);
        sptwb.spt.PathId = 0;
        sptwb.spt.TargetId = 1;
        sptwb.spt.Lun = 0;
        sptwb.spt.CdbLength = CDB6GENERIC_LENGTH;
        sptwb.spt.SenseInfoLength = SPT_SENSE_LENGTH;
        sptwb.spt.DataIn = SCSI_IOCTL_DATA_IN;
        sptwb.spt.DataTransferLength = 192;
        sptwb.spt.TimeOutValue = 2;
        sptwb.spt.DataBufferOffset =
           offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucDataBuf);
        sptwb.spt.SenseInfoOffset =
           offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucSenseBuf);
        sptwb.spt.Cdb[0] = SCSIOP_MODE_SENSE;
        sptwb.spt.Cdb[1] = 0x08; // target shall not return any block descriptors
        sptwb.spt.Cdb[2] = MODE_PAGE_CACHING;
        sptwb.spt.Cdb[4] = 192;
        length = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS,ucDataBuf) +
           sptwb.spt.DataTransferLength;

        status = DeviceIoControl(fileHandle,
                                 IOCTL_SCSI_PASS_THROUGH,
                                 &sptwb,
                                 sizeof(SCSI_PASS_THROUGH),
                                 &sptwb,
                                 length,
                                 &returned,
                                 FALSE);

        PrintStatusResults(status,returned,&sptwb,length);
    }


    printf("            *****       WRITE DATA BUFFER operation         *****\n");
    
    dataBuffer = AllocateAlignedBuffer(sectorSize,alignmentMask, &pUnAlignedBuffer);
    FillMemory(dataBuffer,sectorSize/2,'N');
    FillMemory(dataBuffer + sectorSize/2,sectorSize/2,'T');

    if(srbType == 1)
    {
        ZeroMemory(&sptdwb_ex,sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER_EX));
        sptdwb_ex.sptd.Version = 0;
        sptdwb_ex.sptd.Length = sizeof(SCSI_PASS_THROUGH_DIRECT_EX);
        sptdwb_ex.sptd.ScsiStatus = 0;
        sptdwb_ex.sptd.CdbLength = CDB10GENERIC_LENGTH;
        sptdwb_ex.sptd.StorAddressLength = sizeof(STOR_ADDR_BTL8);
        sptdwb_ex.sptd.SenseInfoLength = SPT_SENSE_LENGTH;
        sptdwb_ex.sptd.DataOutTransferLength = sectorSize;
        sptdwb_ex.sptd.DataInTransferLength = 0;
        sptdwb_ex.sptd.DataDirection = SCSI_IOCTL_DATA_OUT;
        sptdwb_ex.sptd.TimeOutValue = 2;
        sptdwb_ex.sptd.StorAddressOffset =
            offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER_EX,StorAddress);
        sptdwb_ex.StorAddress.Type = STOR_ADDRESS_TYPE_BTL8;
        sptdwb_ex.StorAddress.Port = 0;
        sptdwb_ex.StorAddress.AddressLength = STOR_ADDR_BTL8_ADDRESS_LENGTH;
        sptdwb_ex.StorAddress.Path = 0;
        sptdwb_ex.StorAddress.Target = 1;
        sptdwb_ex.StorAddress.Lun = 0;
        sptdwb_ex.sptd.SenseInfoOffset = 
           offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER_EX,ucSenseBuf);
        sptdwb_ex.sptd.DataOutBuffer = dataBuffer;
        sptdwb_ex.sptd.DataInBuffer = NULL;
        sptdwb_ex.sptd.Cdb[0] = SCSIOP_WRITE_DATA_BUFF;
        sptdwb_ex.sptd.Cdb[1] = 2;                         // Data mode
        sptdwb_ex.sptd.Cdb[7] = (UCHAR)(sectorSize >> 8);  // Parameter List length
        sptdwb_ex.sptd.Cdb[8] = 0;
        length = sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER_EX);

        status = DeviceIoControl(fileHandle,
                                 IOCTL_SCSI_PASS_THROUGH_DIRECT_EX,
                                 &sptdwb_ex,
                                 length,
                                 &sptdwb_ex,
                                 length,
                                 &returned,
                                 FALSE);

        PrintStatusResultsEx(status,returned,
           (PSCSI_PASS_THROUGH_WITH_BUFFERS_EX)&sptdwb_ex,length);

        if ((sptdwb_ex.sptd.ScsiStatus == 0) && (status != 0)) {
           PrintDataBuffer(dataBuffer,sptdwb_ex.sptd.DataOutTransferLength);
        }
    }
Пример #26
0
int TCFormatVolume (volatile FORMAT_VOL_PARAMETERS *volParams)
{
	int nStatus;
	PCRYPTO_INFO cryptoInfo = NULL;
	HANDLE dev = INVALID_HANDLE_VALUE;
	DWORD dwError;
	char header[TC_VOLUME_HEADER_EFFECTIVE_SIZE];
	unsigned __int64 num_sectors, startSector;
	fatparams ft;
	FILETIME ftCreationTime;
	FILETIME ftLastWriteTime;
	FILETIME ftLastAccessTime;
	BOOL bTimeStampValid = FALSE;
	BOOL bInstantRetryOtherFilesys = FALSE;
	char dosDev[TC_MAX_PATH] = { 0 };
	char devName[MAX_PATH] = { 0 };
	int driveLetter = -1;
	WCHAR deviceName[MAX_PATH];
	uint64 dataOffset, dataAreaSize;
	LARGE_INTEGER offset;
	BOOL bFailedRequiredDASD = FALSE;
	HWND hwndDlg = volParams->hwndDlg;

	FormatSectorSize = volParams->sectorSize;

	if (FormatSectorSize < TC_MIN_VOLUME_SECTOR_SIZE
		|| FormatSectorSize > TC_MAX_VOLUME_SECTOR_SIZE
		|| FormatSectorSize % ENCRYPTION_DATA_UNIT_SIZE != 0)
	{
		Error ("SECTOR_SIZE_UNSUPPORTED", hwndDlg);
		return ERR_DONT_REPORT; 
	}

	/* WARNING: Note that if Windows fails to format the volume as NTFS and the volume size is
	less than the maximum FAT size, the user is asked within this function whether he wants to instantly
	retry FAT format instead (to avoid having to re-create the whole container again). If the user
	answers yes, some of the input parameters are modified, the code below 'begin_format' is re-executed 
	and some destructive operations that were performed during the first attempt must be (and are) skipped. 
	Therefore, whenever adding or modifying any potentially destructive operations below 'begin_format',
	determine whether they (or their portions) need to be skipped during such a second attempt; if so, 
	use the 'bInstantRetryOtherFilesys' flag to skip them. */

	if (volParams->hiddenVol)
	{
		dataOffset = volParams->hiddenVolHostSize - TC_VOLUME_HEADER_GROUP_SIZE - volParams->size;
	}
	else
	{
		if (volParams->size <= TC_TOTAL_VOLUME_HEADERS_SIZE)
			return ERR_VOL_SIZE_WRONG;

		dataOffset = TC_VOLUME_DATA_OFFSET;
	}

	dataAreaSize = GetVolumeDataAreaSize (volParams->hiddenVol, volParams->size);

	num_sectors = dataAreaSize / FormatSectorSize;

	if (volParams->bDevice)
	{
		StringCbCopyA ((char *)deviceName, sizeof(deviceName), volParams->volumePath);
		ToUNICODE ((char *)deviceName, sizeof(deviceName));

		driveLetter = GetDiskDeviceDriveLetter (deviceName);
	}

	VirtualLock (header, sizeof (header));

	nStatus = CreateVolumeHeaderInMemory (hwndDlg, FALSE,
				     header,
				     volParams->ea,
					 FIRST_MODE_OF_OPERATION_ID,
				     volParams->password,
				     volParams->pkcs5,
					  volParams->pim,
					 NULL,
				     &cryptoInfo,
					 dataAreaSize,
					 volParams->hiddenVol ? dataAreaSize : 0,
					 dataOffset,
					 dataAreaSize,
					 0,
					 volParams->headerFlags,
					 FormatSectorSize,
					 FALSE);

	if (nStatus != 0)
	{
		burn (header, sizeof (header));
		VirtualUnlock (header, sizeof (header));
		return nStatus;
	}

begin_format:

	if (volParams->bDevice)
	{
		/* Device-hosted volume */

		DWORD dwResult;
		int nPass;

		if (FakeDosNameForDevice (volParams->volumePath, dosDev, sizeof(dosDev), devName, sizeof(devName), FALSE) != 0)
			return ERR_OS_ERROR;

		if (IsDeviceMounted (devName))
		{
			if ((dev = DismountDrive (devName, volParams->volumePath)) == INVALID_HANDLE_VALUE)
			{
				Error ("FORMAT_CANT_DISMOUNT_FILESYS", hwndDlg);
				nStatus = ERR_DONT_REPORT; 
				goto error;
			}

			/* Gain "raw" access to the partition (it contains a live filesystem and the filesystem driver 
			would otherwise prevent us from writing to hidden sectors). */

			if (!DeviceIoControl (dev,
				FSCTL_ALLOW_EXTENDED_DASD_IO,
				NULL,
				0,   
				NULL,
				0,
				&dwResult,
				NULL))
			{
				bFailedRequiredDASD = TRUE;
			}
		}
		else if (IsOSAtLeast (WIN_VISTA) && driveLetter == -1)
		{
			// Windows Vista doesn't allow overwriting sectors belonging to an unformatted partition 
			// to which no drive letter has been assigned under the system. This problem can be worked
			// around by assigning a drive letter to the partition temporarily.

			char szDriveLetter[] = { 'A', ':', 0 };
			char rootPath[] = { 'A', ':', '\\', 0 };
			char uniqVolName[MAX_PATH+1] = { 0 };
			int tmpDriveLetter = -1;
			BOOL bResult = FALSE;

			tmpDriveLetter = GetFirstAvailableDrive ();
 
			if (tmpDriveLetter != -1)
			{
				rootPath[0] += (char) tmpDriveLetter;
				szDriveLetter[0] += (char) tmpDriveLetter;

				if (DefineDosDevice (DDD_RAW_TARGET_PATH, szDriveLetter, volParams->volumePath))
				{
					bResult = GetVolumeNameForVolumeMountPoint (rootPath, uniqVolName, MAX_PATH);

					DefineDosDevice (DDD_RAW_TARGET_PATH|DDD_REMOVE_DEFINITION|DDD_EXACT_MATCH_ON_REMOVE,
						szDriveLetter,
						volParams->volumePath);

					if (bResult 
						&& SetVolumeMountPoint (rootPath, uniqVolName))
					{
						// The drive letter can be removed now
						DeleteVolumeMountPoint (rootPath);
					}
				}
			}
		}

		// For extra safety, we will try to gain "raw" access to the partition. Note that this should actually be
		// redundant because if the filesystem was mounted, we already tried to obtain DASD above. If we failed,
		// bFailedRequiredDASD was set to TRUE and therefore we will perform pseudo "quick format" below. However, 
		// for extra safety, in case IsDeviceMounted() failed to detect a live filesystem, we will blindly
		// send FSCTL_ALLOW_EXTENDED_DASD_IO (possibly for a second time) without checking the result.

		DeviceIoControl (dev,
			FSCTL_ALLOW_EXTENDED_DASD_IO,
			NULL,
			0,   
			NULL,
			0,
			&dwResult,
			NULL);


		// If DASD is needed but we failed to obtain it, perform open - 'quick format' - close - open 
		// so that the filesystem driver does not prevent us from formatting hidden sectors.
		for (nPass = (bFailedRequiredDASD ? 0 : 1); nPass < 2; nPass++)
		{
			int retryCount;

			retryCount = 0;

			// Try exclusive access mode first
			// Note that when exclusive access is denied, it is worth retrying (usually succeeds after a few tries).
			while (dev == INVALID_HANDLE_VALUE && retryCount++ < EXCL_ACCESS_MAX_AUTO_RETRIES)
			{
				dev = CreateFile (devName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);

				if (retryCount > 1)
					Sleep (EXCL_ACCESS_AUTO_RETRY_DELAY);
			}

			if (dev == INVALID_HANDLE_VALUE)
			{
				// Exclusive access denied -- retry in shared mode
				dev = CreateFile (devName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
				if (dev != INVALID_HANDLE_VALUE)
				{
					if (IDNO == MessageBoxW (volParams->hwndDlg, GetString ("DEVICE_IN_USE_FORMAT"), lpszTitle, MB_YESNO|MB_ICONWARNING|MB_DEFBUTTON2))
					{
						nStatus = ERR_DONT_REPORT; 
						goto error;
					}
				}
				else
				{
					handleWin32Error (volParams->hwndDlg, SRC_POS);
					Error ("CANT_ACCESS_VOL", hwndDlg);
					nStatus = ERR_DONT_REPORT; 
					goto error;
				}
			}

			if (volParams->hiddenVol || bInstantRetryOtherFilesys)
				break;	// The following "quick format" operation would damage the outer volume

			if (nPass == 0)
			{
				char buf [2 * TC_MAX_VOLUME_SECTOR_SIZE];
				DWORD bw;

				// Perform pseudo "quick format" so that the filesystem driver does not prevent us from 
				// formatting hidden sectors
				memset (buf, 0, sizeof (buf));

				if (!WriteFile (dev, buf, sizeof (buf), &bw, NULL))
				{
					nStatus = ERR_OS_ERROR; 
					goto error;
				}

				FlushFileBuffers (dev);
				CloseHandle (dev);
				dev = INVALID_HANDLE_VALUE;
			}
		}

		if (DeviceIoControl (dev, FSCTL_IS_VOLUME_MOUNTED, NULL, 0, NULL, 0, &dwResult, NULL))
		{
			Error ("FORMAT_CANT_DISMOUNT_FILESYS", hwndDlg);
			nStatus = ERR_DONT_REPORT; 
			goto error;
		}
	}
	else
	{
		/* File-hosted volume */

		dev = CreateFile (volParams->volumePath, GENERIC_READ | GENERIC_WRITE,
			(volParams->hiddenVol || bInstantRetryOtherFilesys) ? (FILE_SHARE_READ | FILE_SHARE_WRITE) : 0,
			NULL, (volParams->hiddenVol || bInstantRetryOtherFilesys) ? OPEN_EXISTING : CREATE_ALWAYS, 0, NULL);

		if (dev == INVALID_HANDLE_VALUE)
		{
			nStatus = ERR_OS_ERROR; 
			goto error;
		}

		DisableFileCompression (dev);

		if (!volParams->hiddenVol && !bInstantRetryOtherFilesys)
		{
			LARGE_INTEGER volumeSize;
			volumeSize.QuadPart = dataAreaSize + TC_VOLUME_HEADER_GROUP_SIZE;

			if (volParams->sparseFileSwitch && volParams->quickFormat)
			{
				// Create as sparse file container
				DWORD tmp;
				if (!DeviceIoControl (dev, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &tmp, NULL))
				{
					nStatus = ERR_OS_ERROR; 
					goto error;
				}
			}

			// Preallocate the file
			if (!SetFilePointerEx (dev, volumeSize, NULL, FILE_BEGIN)
				|| !SetEndOfFile (dev)
				|| SetFilePointer (dev, 0, NULL, FILE_BEGIN) != 0)
			{
				nStatus = ERR_OS_ERROR;
				goto error;
			}
		}
	}

	if (volParams->hiddenVol && !volParams->bDevice && bPreserveTimestamp)
	{
		if (GetFileTime ((HANDLE) dev, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime) == 0)
			bTimeStampValid = FALSE;
		else
			bTimeStampValid = TRUE;
	}

	KillTimer (volParams->hwndDlg, TIMER_ID_RANDVIEW);

	/* Volume header */

	// Hidden volume setup
	if (volParams->hiddenVol)
	{
		LARGE_INTEGER headerOffset;

		// Check hidden volume size
		if (volParams->hiddenVolHostSize < TC_MIN_HIDDEN_VOLUME_HOST_SIZE || volParams->hiddenVolHostSize > TC_MAX_HIDDEN_VOLUME_HOST_SIZE)
		{		
			nStatus = ERR_VOL_SIZE_WRONG;
			goto error;
		}

		// Seek to hidden volume header location
		
		headerOffset.QuadPart = TC_HIDDEN_VOLUME_HEADER_OFFSET;

		if (!SetFilePointerEx ((HANDLE) dev, headerOffset, NULL, FILE_BEGIN))
		{
			nStatus = ERR_OS_ERROR;
			goto error;
		}
	}
	else if (bInstantRetryOtherFilesys)
	{
		// The previous file system format failed and the user wants to try again with a different file system.
		// The volume header had been written successfully so we need to seek to the byte after the header.

		LARGE_INTEGER offset;
		offset.QuadPart = TC_VOLUME_DATA_OFFSET;
		if (!SetFilePointerEx ((HANDLE) dev, offset, NULL, FILE_BEGIN))
		{
			nStatus = ERR_OS_ERROR;
			goto error;
		}
	}

	if (!bInstantRetryOtherFilesys)
	{
		// Write the volume header
		if (!WriteEffectiveVolumeHeader (volParams->bDevice, dev, header))
		{
			nStatus = ERR_OS_ERROR;
			goto error;
		}

		// To prevent fragmentation, write zeroes to reserved header sectors which are going to be filled with random data
		if (!volParams->bDevice && !volParams->hiddenVol)
		{
			byte buf[TC_VOLUME_HEADER_GROUP_SIZE - TC_VOLUME_HEADER_EFFECTIVE_SIZE];
			DWORD bytesWritten;
			ZeroMemory (buf, sizeof (buf));

			if (!WriteFile (dev, buf, sizeof (buf), &bytesWritten, NULL))
			{
				nStatus = ERR_OS_ERROR;
				goto error;
			}

			if (bytesWritten != sizeof (buf))
			{
				nStatus = ERR_PARAMETER_INCORRECT;
				goto error;
			}
		}
	}

	if (volParams->hiddenVol)
	{
		// Calculate data area position of hidden volume
		cryptoInfo->hiddenVolumeOffset = dataOffset;

		// Validate the offset
		if (dataOffset % FormatSectorSize != 0)
		{
			nStatus = ERR_VOL_SIZE_WRONG; 
			goto error;
		}

		volParams->quickFormat = TRUE;		// To entirely format a hidden volume would be redundant
	}

	/* Data area */
	startSector = dataOffset / FormatSectorSize;

	// Format filesystem

	switch (volParams->fileSystem)
	{
	case FILESYS_NONE:
	case FILESYS_NTFS:

		if (volParams->bDevice && !StartFormatWriteThread())
		{
			nStatus = ERR_OS_ERROR; 
			goto error;
		}

		nStatus = FormatNoFs (hwndDlg, startSector, num_sectors, dev, cryptoInfo, volParams->quickFormat);

		if (volParams->bDevice)
			StopFormatWriteThread();

		break;
		
	case FILESYS_FAT:
		if (num_sectors > 0xFFFFffff)
		{
			nStatus = ERR_VOL_SIZE_WRONG; 
			goto error;
		}

		// Calculate the fats, root dir etc
		ft.num_sectors = (unsigned int) (num_sectors);

#if TC_MAX_VOLUME_SECTOR_SIZE > 0xFFFF
#error TC_MAX_VOLUME_SECTOR_SIZE > 0xFFFF
#endif

		ft.sector_size = (uint16) FormatSectorSize;
		ft.cluster_size = volParams->clusterSize;
		memcpy (ft.volume_name, "NO NAME    ", 11);
		GetFatParams (&ft); 
		*(volParams->realClusterSize) = ft.cluster_size * FormatSectorSize;

		if (volParams->bDevice && !StartFormatWriteThread())
		{
			nStatus = ERR_OS_ERROR; 
			goto error;
		}

		nStatus = FormatFat (hwndDlg, startSector, &ft, (void *) dev, cryptoInfo, volParams->quickFormat);

		if (volParams->bDevice)
			StopFormatWriteThread();

		break;

	default:
		nStatus = ERR_PARAMETER_INCORRECT; 
		goto error;
	}

	if (nStatus != ERR_SUCCESS)
		goto error;

	// Write header backup
	offset.QuadPart = volParams->hiddenVol ? volParams->hiddenVolHostSize - TC_HIDDEN_VOLUME_HEADER_OFFSET : dataAreaSize + TC_VOLUME_HEADER_GROUP_SIZE;

	if (!SetFilePointerEx ((HANDLE) dev, offset, NULL, FILE_BEGIN))
	{
		nStatus = ERR_OS_ERROR;
		goto error;
	}

	nStatus = CreateVolumeHeaderInMemory (hwndDlg, FALSE,
		header,
		volParams->ea,
		FIRST_MODE_OF_OPERATION_ID,
		volParams->password,
		volParams->pkcs5,
		volParams->pim,
		cryptoInfo->master_keydata,
		&cryptoInfo,
		dataAreaSize,
		volParams->hiddenVol ? dataAreaSize : 0,
		dataOffset,
		dataAreaSize,
		0,
		volParams->headerFlags,
		FormatSectorSize,
		FALSE);

	if (!WriteEffectiveVolumeHeader (volParams->bDevice, dev, header))
	{
		nStatus = ERR_OS_ERROR;
		goto error;
	}

	// Fill reserved header sectors (including the backup header area) with random data
	if (!volParams->hiddenVol)
	{
		nStatus = WriteRandomDataToReservedHeaderAreas (hwndDlg, dev, cryptoInfo, dataAreaSize, FALSE, FALSE);

		if (nStatus != ERR_SUCCESS)
			goto error;
	}

#ifndef DEBUG
	if (volParams->quickFormat && volParams->fileSystem != FILESYS_NTFS)
		Sleep (500);	// User-friendly GUI
#endif

error:
	dwError = GetLastError();

	burn (header, sizeof (header));
	VirtualUnlock (header, sizeof (header));

	if (dev != INVALID_HANDLE_VALUE)
	{
		if (!volParams->bDevice && !volParams->hiddenVol && nStatus != 0)
		{
			// Remove preallocated part before closing file handle if format failed
			if (SetFilePointer (dev, 0, NULL, FILE_BEGIN) == 0)
				SetEndOfFile (dev);
		}

		FlushFileBuffers (dev);

		if (bTimeStampValid)
			SetFileTime (dev, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime);

		CloseHandle (dev);
		dev = INVALID_HANDLE_VALUE;
	}

	if (nStatus != 0)
	{
		SetLastError(dwError);
		goto fv_end;
	}

	if (volParams->fileSystem == FILESYS_NTFS)
	{
		// Quick-format volume as NTFS
		int driveNo = GetLastAvailableDrive ();
		MountOptions mountOptions;
		int retCode;

		ZeroMemory (&mountOptions, sizeof (mountOptions));

		if (driveNo == -1)
		{
			MessageBoxW (volParams->hwndDlg, GetString ("NO_FREE_DRIVES"), lpszTitle, ICON_HAND);
			MessageBoxW (volParams->hwndDlg, GetString ("FORMAT_NTFS_STOP"), lpszTitle, ICON_HAND);

			nStatus = ERR_NO_FREE_DRIVES;
			goto fv_end;
		}

		mountOptions.ReadOnly = FALSE;
		mountOptions.Removable = FALSE;
		mountOptions.ProtectHiddenVolume = FALSE;
		mountOptions.PreserveTimestamp = bPreserveTimestamp;
		mountOptions.PartitionInInactiveSysEncScope = FALSE;
		mountOptions.UseBackupHeader = FALSE;

		if (MountVolume (volParams->hwndDlg, driveNo, volParams->volumePath, volParams->password, volParams->pkcs5, volParams->pim, FALSE, FALSE, TRUE, &mountOptions, FALSE, TRUE) < 1)
		{
			MessageBoxW (volParams->hwndDlg, GetString ("CANT_MOUNT_VOLUME"), lpszTitle, ICON_HAND);
			MessageBoxW (volParams->hwndDlg, GetString ("FORMAT_NTFS_STOP"), lpszTitle, ICON_HAND);
			nStatus = ERR_VOL_MOUNT_FAILED;
			goto fv_end;
		}

		if (!IsAdmin () && IsUacSupported ())
			retCode = UacFormatNtfs (volParams->hwndDlg, driveNo, volParams->clusterSize);
		else
			retCode = FormatNtfs (driveNo, volParams->clusterSize);

		if (retCode != TRUE)
		{
			if (!UnmountVolumeAfterFormatExCall (volParams->hwndDlg, driveNo))
				MessageBoxW (volParams->hwndDlg, GetString ("CANT_DISMOUNT_VOLUME"), lpszTitle, ICON_HAND);

			if (dataAreaSize <= TC_MAX_FAT_SECTOR_COUNT * FormatSectorSize)
			{
				if (AskErrYesNo ("FORMAT_NTFS_FAILED_ASK_FAT", hwndDlg) == IDYES)
				{
					// NTFS format failed and the user wants to try FAT format immediately
					volParams->fileSystem = FILESYS_FAT;
					bInstantRetryOtherFilesys = TRUE;
					volParams->quickFormat = TRUE;		// Volume has already been successfully TC-formatted
					volParams->clusterSize = 0;		// Default cluster size
					goto begin_format;
				}
			}
			else
				Error ("FORMAT_NTFS_FAILED", hwndDlg);

			nStatus = ERR_DONT_REPORT;
			goto fv_end;
		}

		if (!UnmountVolumeAfterFormatExCall (volParams->hwndDlg, driveNo))
			MessageBoxW (volParams->hwndDlg, GetString ("CANT_DISMOUNT_VOLUME"), lpszTitle, ICON_HAND);
	}

fv_end:
	dwError = GetLastError();

	if (dosDev[0])
		RemoveFakeDosName (volParams->volumePath, dosDev);

	crypto_close (cryptoInfo);

	SetLastError (dwError);
	return nStatus;
}
Пример #27
0
BOOL
CreateMountPoint(
	PWCHAR	ReparsePointName,
	PWCHAR	TargetDeviceName)
{
	HANDLE handle;
	PREPARSE_DATA_BUFFER reparseData;
	USHORT	bufferLength;
	USHORT	targetLength;
	BOOL	result;
	ULONG	resultLength;
	
	handle = CreateFile(
		ReparsePointName, GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
		FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL);

	if (handle == INVALID_HANDLE_VALUE) {
		DbgPrintW(L"CreateFile failed: %s (%d)\n", ReparsePointName, GetLastError());
		return FALSE;
	}

	targetLength = wcslen(TargetDeviceName) * sizeof(WCHAR);
	bufferLength = FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer) +
		targetLength + sizeof(WCHAR) + sizeof(WCHAR);

	reparseData = malloc(bufferLength);

	ZeroMemory(reparseData, bufferLength);

	reparseData->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
	reparseData->ReparseDataLength = bufferLength - REPARSE_DATA_BUFFER_HEADER_SIZE;

	reparseData->MountPointReparseBuffer.SubstituteNameOffset = 0;
	reparseData->MountPointReparseBuffer.SubstituteNameLength = targetLength;
	reparseData->MountPointReparseBuffer.PrintNameOffset = targetLength + sizeof(WCHAR);
	reparseData->MountPointReparseBuffer.PrintNameLength = 0;

	RtlCopyMemory(reparseData->MountPointReparseBuffer.PathBuffer, TargetDeviceName, targetLength);

	result = DeviceIoControl(
				handle,
				FSCTL_SET_REPARSE_POINT,
				reparseData,
				bufferLength,
				NULL,
				0,
				&resultLength,
				NULL);
	
	CloseHandle(handle);
	free(reparseData);

	if (result) {
		DbgPrintW(L"CreateMountPoint %s -> %s success\n",
			ReparsePointName, TargetDeviceName);
	} else {
		DbgPrintW(L"CreateMountPoint %s -> %s failed: %d\n",
			ReparsePointName, TargetDeviceName, GetLastError());
	}
	return result;
}
Пример #28
0
void DetectAlreadyConnectedDevices(ThreadObject* tpThreads[])
{
	HDEVINFO hDevInfo = SetupDiGetClassDevs(
		&GUID_DEVINTERFACE_DISK,
		NULL,
		NULL,
		DIGCF_PRESENT |
		DIGCF_DEVICEINTERFACE
		);
	SP_DEVINFO_DATA spDeviceInfoData;
	ZeroMemory(&spDeviceInfoData, sizeof(SP_DEVINFO_DATA));
	spDeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
	LPTSTR pszPropertyBuffer[BUFFER];
	DWORD dwRequiredSize;
	DWORD dwRequiredBufferSize;
	DWORD dwProperyDatatype;
	BOOL bResult;

	for (DWORD dwDeviceInfoIndex = 0; SetupDiEnumDeviceInfo(
		hDevInfo,
		dwDeviceInfoIndex,
		&spDeviceInfoData
		);
	dwDeviceInfoIndex++)
	{
		bResult = SetupDiGetDeviceRegistryProperty(
			hDevInfo,
			&spDeviceInfoData,
			SPDRP_ENUMERATOR_NAME,
			&dwProperyDatatype,
			(LPBYTE)pszPropertyBuffer,
			BUFFER,
			&dwRequiredBufferSize);

		if (_tcscmp((LPTSTR)pszPropertyBuffer, TEXT("USBSTOR")) == 0)
		{
			SP_DEVICE_INTERFACE_DATA spDeviceInterfaceData;
			ZeroMemory(&spDeviceInterfaceData, sizeof(spDeviceInterfaceData));
			spDeviceInterfaceData.cbSize = sizeof(spDeviceInterfaceData);
			PSP_DEVICE_INTERFACE_DETAIL_DATA pspDeviceInterfaceDetailData = NULL;

			for (DWORD dwDeviceInterfacesIndex = 0; bResult = SetupDiEnumDeviceInterfaces(
				hDevInfo,
				&spDeviceInfoData,
				&GUID_DEVINTERFACE_DISK,
				dwDeviceInterfacesIndex++,
				&spDeviceInterfaceData
				);
			dwDeviceInterfacesIndex++)
			{
				DWORD dwError = GetLastError();
				if (!bResult)
				{
					if (dwError == ERROR_NO_MORE_DEVICES || dwError == ERROR_NO_MORE_ITEMS)
						break;
				}

				/*
				Get the required size for the
				PSP_DEVICE_INTERFACE_DETAIL_DATA
				structure
				*/
				bResult = SetupDiGetDeviceInterfaceDetail(
					hDevInfo,
					&spDeviceInterfaceData,
					NULL,
					0,
					&dwRequiredSize,
					NULL
					);

				/*
				Allocate that required size
				*/
				if (!bResult)
				{
					if (ERROR_INSUFFICIENT_BUFFER == GetLastError())
					{
						pspDeviceInterfaceDetailData = new SP_DEVICE_INTERFACE_DETAIL_DATA[dwRequiredSize];//(PSP_DEVICE_INTERFACE_DETAIL_DATA)LocalAlloc(LPTR, dwRequiredSize);
						pspDeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
					}
					else
						break;
				}

				/*
				Get the details on that device
				*/
				bResult = SetupDiGetDeviceInterfaceDetail(
					hDevInfo,
					&spDeviceInterfaceData,
					pspDeviceInterfaceDetailData,
					dwRequiredSize,
					NULL,
					NULL
					);
				if (bResult)
				{
					STORAGE_DEVICE_NUMBER storageDeviceNumber;
					ZeroMemory(&storageDeviceNumber, sizeof(STORAGE_DEVICE_NUMBER));
					storageDeviceNumber.DeviceNumber = 0;
					DWORD dwSize = 0;

					/*
					Get the device handle
					*/
					HANDLE hDrive = CreateFile(
						pspDeviceInterfaceDetailData->DevicePath,
						GENERIC_READ,
						FILE_SHARE_READ |
						FILE_SHARE_WRITE,
						NULL,
						OPEN_EXISTING,
						0,
						0
						);
					if (hDrive != INVALID_HANDLE_VALUE)
					{
						/*
						Get the device number
						*/
						bResult = DeviceIoControl(
							hDrive,
							IOCTL_STORAGE_GET_DEVICE_NUMBER,
							NULL,
							0,
							&storageDeviceNumber,
							sizeof(storageDeviceNumber),
							&dwSize,
							NULL
							);
						if (bResult)
						{
							char cDrive = GetVolumeLabelByDiskNumber(storageDeviceNumber.DeviceNumber);
							if (cDrive)
							{
								int iIndex = cDrive - 'A';
								printf("%c:\\ will be watched\n", cDrive);
								tpThreads[iIndex] = new ThreadObject(Inspection, (LPVOID)cDrive);
								tpThreads[iIndex]->Start();
							}
						}
					}
					CloseHandle(hDrive);
				}
				delete pspDeviceInterfaceDetailData;
			}
		}
	}
	SetupDiDestroyDeviceInfoList(hDevInfo);
}
Пример #29
0
char GetVolumeLabelByDiskNumber(DWORD dwDeviceNumber)
{
	/*
	The returned value is like
	C:\ and a null terminator 
	seperating each drive root
	hence 4 characters per letter
	*/
	wchar_t wszDrives[26 * 4];

	DWORD dwSize = GetLogicalDriveStrings(sizeof(wszDrives), wszDrives);
	DWORD dwBytesReturned = 0;
	if (dwSize)
	{
		for (unsigned int uiCharIndex = 0; uiCharIndex <= dwSize; uiCharIndex += 4)
		{
			STORAGE_DEVICE_NUMBER storageDeviceNumber;
			ZeroMemory(&storageDeviceNumber, sizeof(STORAGE_DEVICE_NUMBER));
			storageDeviceNumber.DeviceNumber = 0;

			/*
			To obtain a drive handle we 
			need to use CreateFile with
			a path like \\.\C:
			*/
			wchar_t wszDrivePath[MAX_PATH];
			wcscpy_s(wszDrivePath, L"\\\\.\\");
			wcscat_s(wszDrivePath, wszDrives + uiCharIndex);
			wszDrivePath[wcslen(wszDrivePath) - 1] = L'\0';

			HANDLE hDrive = CreateFile(
				wszDrivePath,
				GENERIC_READ,
				FILE_SHARE_READ |
				FILE_SHARE_WRITE,
				NULL,
				OPEN_EXISTING,
				0,
				0
				);

			if (hDrive != INVALID_HANDLE_VALUE)
			{
				/*
				Get the device number of the
				device and compare it to our
				device's device number
				*/
				BOOL bResult = DeviceIoControl(
					hDrive,
					IOCTL_STORAGE_GET_DEVICE_NUMBER,
					NULL,
					0,
					&storageDeviceNumber,
					sizeof(storageDeviceNumber),
					&dwBytesReturned,
					NULL
					);
				if (bResult && dwBytesReturned)
				{
					if (storageDeviceNumber.DeviceNumber == dwDeviceNumber)
					{
						char cDrive = wctob(wszDrives[uiCharIndex]);
						return cDrive;
					}
				}
			}
			CloseHandle(hDrive);
		}
	}
	return NULL;
}
Пример #30
-1
// Return the first GUID volume name for the associated drive or NULL if not found
// See http://msdn.microsoft.com/en-us/library/cc542456.aspx
// The returned string is allocated and must be freed
// TODO: a drive may have multiple volumes - should we handle those?
char* GetLogicalName(DWORD DriveIndex, BOOL bKeepTrailingBackslash)
{
	BOOL success = FALSE;
	char volume_name[MAX_PATH];
	HANDLE hDrive = INVALID_HANDLE_VALUE, hVolume = INVALID_HANDLE_VALUE;
	size_t len;
	char path[MAX_PATH];
	VOLUME_DISK_EXTENTS DiskExtents;
	DWORD size;
	UINT drive_type;
	int i, j;
	static const char* ignore_device[] = { "\\Device\\CdRom", "\\Device\\Floppy" };

	CheckDriveIndex(DriveIndex);

	for (i=0; hDrive == INVALID_HANDLE_VALUE; i++) {
		if (i == 0) {
			hVolume = FindFirstVolumeA(volume_name, sizeof(volume_name));
			if (hVolume == INVALID_HANDLE_VALUE) {
				uprintf("Could not access first GUID volume: %s\n", WindowsErrorString());
				goto out;
			}
		} else {
			if (!FindNextVolumeA(hVolume, volume_name, sizeof(volume_name))) {
				if (GetLastError() != ERROR_NO_MORE_FILES) {
					uprintf("Could not access next GUID volume: %s\n", WindowsErrorString());
				}
				goto out;
			}
		}

		// Sanity checks
		len = safe_strlen(volume_name);
		if ((len <= 1) || (safe_strnicmp(volume_name, "\\\\?\\", 4) != 0) || (volume_name[len-1] != '\\')) {
			uprintf("'%s' is not a GUID volume name\n", volume_name);
			continue;
		}

		drive_type = GetDriveTypeA(volume_name);
		// NB: the HP utility allows drive_type == DRIVE_FIXED, which we don't allow by default
		// Using Alt-F in Rufus does enable listing, but this mode is unsupported.
		if ((drive_type != DRIVE_REMOVABLE) && ((!enable_fixed_disks) || (drive_type != DRIVE_FIXED)))
			continue;

		volume_name[len-1] = 0;

		if (QueryDosDeviceA(&volume_name[4], path, sizeof(path)) == 0) {
			uprintf("Failed to get device path for GUID volume '%s': %s\n", volume_name, WindowsErrorString());
			continue;
		}

		for (j=0; (j<ARRAYSIZE(ignore_device)) &&
			(safe_strnicmp(path, ignore_device[j], safe_strlen(ignore_device[j])) != 0); j++);
		if (j < ARRAYSIZE(ignore_device)) {
			uprintf("Skipping GUID volume for '%s'\n", path);
			continue;
		}

		// If we can't have FILE_SHARE_WRITE, forget it
		hDrive = CreateFileA(volume_name, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
		if (hDrive == INVALID_HANDLE_VALUE) {
			uprintf("Could not open GUID volume '%s': %s\n", volume_name, WindowsErrorString());
			continue;
		}

		if ((!DeviceIoControl(hDrive, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, NULL, 0,
			&DiskExtents, sizeof(DiskExtents), &size, NULL)) || (size <= 0)) {
			uprintf("Could not get Disk Extents: %s\n", WindowsErrorString());
			safe_closehandle(hDrive);
			continue;
		}
		safe_closehandle(hDrive);
		if ((DiskExtents.NumberOfDiskExtents >= 1) && (DiskExtents.Extents[0].DiskNumber == DriveIndex)) {
			if (bKeepTrailingBackslash)
				volume_name[len-1] = '\\';
			success = TRUE;
			break;
		}
	}

out:
	if (hVolume != INVALID_HANDLE_VALUE)
		FindVolumeClose(hVolume);
	return (success)?safe_strdup(volume_name):NULL;
}