Hi
Taking a break from a major project, I came across a post by Raymond Chen that explains very well how to infer whether or not a file is on a SSD, looking a the seek penalty of a drive.
https://devblogs.microsoft.com/oldnewthing/20201023-00/?p=104395 (https://devblogs.microsoft.com/oldnewthing/20201023-00/?p=104395)
It takes a few steps to get this information.
Since it caught my attention, I translated it into asm and stepped into an old problem.
Structures used to communicate with the kernel are almost always aligned 8 bytes long, regardless of the bitness of your application. I had to adjust some structures (VOLUME_DISK_EXTENTS, STORAGE_PROPERTY_QUERY, DEVICE_SEEK_PENALTY_DESCRIPTOR, etc.) in the winioctl.inc file to use the API correctly.
IsFileOnSSD proc pFilePath:PSTRING
local hVolume:HANDLE, hDisk:HANDLE, dBytesWritten:DWORD
local Query:STORAGE_PROPERTY_QUERY
local Result:DEVICE_SEEK_PENALTY_DESCRIPTOR
invoke GetVolumeHandleForFile, pFilePath
.if xax != 0
mov hVolume, xax
mov Result.IncursSeekPenalty, -1 ;Set error value
invoke GetFirstPhysicalDiskHandleForVolume, hVolume
.if xax != 0
mov hDisk, xax
mov Query.PropertyId, StorageDeviceSeekPenaltyProperty
mov Query.QueryType, PropertyStandardQuery
invoke DeviceIoControl, hDisk, IOCTL_STORAGE_QUERY_PROPERTY, \
addr Query, sizeof Query, addr Result, sizeof Result, \
addr dBytesWritten, NULL
invoke CloseHandle, hDisk
.endif
invoke CloseHandle, hVolume
movsx eax, Result.IncursSeekPenalty ;Prepare the return value
.if eax == 0 ;eax = TRUE, FALSE or -1 if failed
inc eax
.elseif eax != -1
xor eax, eax
.endif
.else
mov eax, -1
.endif
ret
IsFileOnSSD endp
I'm adding this file and project for reference for those who need such functionality.
Biterider