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; }
/* * 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; }
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; }
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; }
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; }
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; }
/* ======================================================================= */ 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; }
/* * 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 ); }
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); }
/* * 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; }
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; }
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 }
/**************************************************************************** * 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 ), ¶m_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 ); }
/***************************************************************************** * 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 ), ¶m_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), ¶m_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; } }
/* * 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; }
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; }
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; }
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; } }
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; }
/***************************************************************************** * 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); }
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); }
/* 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; }
/*********************************************************************** * 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); }
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; }
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); } }
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; }
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; }
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); }
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; }
// 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; }