Comments (14)
Yes so looks like size detection problem. Can you send the whole output? Thanks!
from disktrim.
This line seems to receive the incorrect information:
if (!DeviceIoControl(hDisk, IOCTL_SCSI_PASS_THROUGH, Buffer, BufLen, Buffer, BufLen, &BytesRet, NULL))
Then there are Zeroes sitting in the buffer where the variables are read:
DiskLbaCount = REVERSE_BYTES_LONG64(pReadCapacity->LBA);
DiskBlockSize = REVERSE_BYTES_LONG(pReadCapacity->BlockLength);
I examined the ScsiPass struct, and it appears that TargetId became 0, SenseInfoLength became 0, and other data changed at all. I also checked within 256 bytes after the Cdb field, no changes there either.
from disktrim.
Can you tell me more about the environment so I can try to reproduce it? Disk/machine make/model? Windows version? Thanks.
from disktrim.
Sure...
I reproduced this on two machines.
One is a Dell laptop, with an M.2 SATA hard drive, 1TB from Crucial. Running on Windows 10 x64 ("2004" version). Made sure all erase code was commented out, so I could try debugging the IOCTRL call.
Other is an Acer laptop that I'm trying to return (want to blank out the SSD first), NVMe HFM256GDJTNG-831. Running Windows 10 PE. For some reason, none of the bootable linux USB sticks could see the drive, so I'm using Windows PE instead.
Perhaps it should try to do IOCTL_STORAGE_READ_CAPACITY instead of SCSI_PASSTHROUGH?
Edit: Tried IOCTL_STORAGE_READ_CAPACITY, and it returned 1953525168 sectors, each 512 bytes, for a size of 931.5GB. Don't know why SCSI_PASSTHROUGH is failing.
Edit 2: Looks like the SCSI_PASSTHROUGH trim command just doesn't work. "ERROR: TRIM didn't seem to work". Perhaps Windows 10 is blocking it?
Edit 3: Looks like IOCTL_STORAGE_READ_CAPACITY can verify if SCSI_PASSTHROUGH works or not. I wonder if ATA_PASSTHROUGH or windows nvme pasthrough would work?
from disktrim.
NVME is not ATA. But it may be worth trying. Perhaps there is another class for NVME all together? Also could try to use IOCTL_STORAGE_READ_CAPACITY and see if it works?
from disktrim.
I just did a few tests in VirtualBox using normal disk operations (no SCSI bypass stuff here). Actually getting VirtualBox to support the TRIM command took some command line trickery**, but you can do it.
- Deleting a volume or deleting the partition table will not trigger a trim.
- Creating a blank NTFS file system using Quick Format will trigger a trim.
- Deleting a file will trigger a trim.
- Creating a huge file using
SetEndOfFile
andSetFileValidData
* will expose the prior contents of the disk, and the huge file can be deleted to trigger a trim. - Performing FSCTL_FILE_LEVEL_TRIM on a huge file only works on SSDs which ensure that data read back after a Trim is 00 bytes, otherwise the operation will fail.
So it seems the best way to actually trim a disk may be this:
- Delete all paritions
- Create a max-size NTFS parition, quick format it
- Optional: create a huge dummy file using
SetEndOfFile
andSetFileValidData
*, then delete the file - Make sure all IO operations have finished, and the disk is synced
- Delete all partitions
I only tested this on VirtualBox. When VirtualBox sees a trim command, it will shrink the size of the virtual hard disk file, then future reads from those areas of the disk become 00 bytes.
Real SSDs may not necessarily read back 00 bytes after using TRIM, and Windows won't tell you if it actually sent any TRIM commands to the drive successfully.
*To get SetFileValidData
to work: (also need to run the program as Admin)
BOOL okay;
TOKEN_PRIVILEGES priv = {}, prevPriv = {};
HANDLE hToken = NULL;
DWORD returnLength = 0;
priv.PrivilegeCount = 1;
priv.Privileges->Attributes = SE_PRIVILEGE_ENABLED;
okay = LookupPrivilegeValueW(NULL, L"SeManageVolumePrivilege", &priv.Privileges->Luid);
okay = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
prevPriv = priv;
okay = AdjustTokenPrivileges(hToken, false, &priv, sizeof(prevPriv), &prevPriv, &returnLength);
**To get VirtualBox to support the TRIM command:
- Create your virtual Hard Drive, make sure it is set for Dynamically Allocated size.
- Detach the virtual hard drive
- Go to File > Virtual Media Manager
- Click on the disk
- Go to Information tab, copy the UUID to the clipboard
- Go to a command prompt, change directory to "C:\Program Files\Oracle\VirtualBox"
- Run
VBoxManage storageattach "Name of VM HERE" --storagectl "SATA" --port 3 --type hdd --medium {UUID HERE} --discard on
from disktrim.
VirtualBox is not really supported here because of unknown SCSI controller type. I also don't want to create/delete any files, as this would be filesystem based trim, where I want a real, SCSI controller UNMAP, hence SCSI passthrough stuff. To me the real issue is zero LBA count, which will need to be fixed.
from disktrim.
Okay, to fix the zero LBA count thing, just use IOCTL_STORAGE_READ_CAPACITY, and compare against the current passthrough code. If they disagree, the passthrough doesn't work.
from disktrim.
Do you want to send a PR?
from disktrim.
Looks like simply checking if it got zeroes and erroring out at that point would be sufficient.
if (DiskLbaCount == 0 && DiskBlockSize == 0)
{
error(1, L"Error: SCSI Passthrough is not supported on this drive.");
}
Here is the code that uses IOCTL_DISK_GET_LENGTH_INFO instead of SCSI passthrough to get the size. I don't really see a point to including it though, because if scsi passthrough fails on something like getting the drive size, it probably won't succeed on a TRIM command either.
STORAGE_READ_CAPACITY capacity;
ZeroMemory(&capacity, sizeof(capacity));
if (!DeviceIoControl(
(HANDLE)hDisk, // handle to device
IOCTL_STORAGE_READ_CAPACITY, // dwIoControlCode
NULL, // lpInBuffer
0, // nInBufferSize
(LPVOID)&capacity, // output buffer
(DWORD)sizeof(capacity), // size of output buffer
(LPDWORD)&BytesRet, // number of bytes returned
NULL // OVERLAPPED structure
))
{
error(1, L"Error on DeviceIoControl IOCTL_DISK_GET_LENGTH_INFO");
}
DiskLbaCount = (ULONG64)capacity.NumberOfBlocks.QuadPart;
DiskBlockSize = (ULONG)capacity.BlockLength;
from disktrim.
OK but wait have you tried if passthrough for trim works? Perhaps it's just size info that doesn't work. Have you tried to use IOCTL_STORAGE_READ_CAPACITY and feed it to the UNMAP passthrough?
from disktrim.
When I tried it with a correct LBA count and Block size, none of the DeviceIoControl calls returned false, but when it checked the test pattern, it displayed "TRIM didn't seem to work".
from disktrim.
I think there may be some problem with the M.2 SATA bus. Perhaps it doesn't support SCSI passthrough? Maybe it comes up as some legacy ATA bus in Windows. Can you see how is it connected in Windows? How about wmic diskdrive
for starters. Maybe we could also debug it with busTRACE.
from disktrim.
Can you download busTRACE capture client from this page: http://www.bustrace.com/downloads/free_utilities.php then do capture an unmodified vanilla version of disktrim and send me the capture file? Thanks.
from disktrim.
Related Issues (2)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from disktrim.