Skip to content

Commit d392999

Browse files
author
nahida-mono
committed
修复ssd检测逻辑
1 parent cda00ff commit d392999

File tree

3 files changed

+81
-28
lines changed

3 files changed

+81
-28
lines changed

src/Snap.Hutao.Remastered.Native.Packaging/Snap.Hutao.Remastered.Native.Packaging.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<NoPackageAnalysis>true</NoPackageAnalysis>
66

77
<PackageId>Snap.Hutao.Remastered.Native</PackageId>
8-
<Version>1.0.2</Version>
8+
<Version>1.0.3</Version>
99
<Authors>SnapHutaoRemasteringProject</Authors>
1010
<Description>Native x64 libraries for Snap.Hutao.Remastered</Description>
1111
<PackageTags>native;snap;hutao</PackageTags>

src/Snap.Hutao.Remastered.Native/HutaoNativePhysicalDrive.cpp

Lines changed: 80 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "pch.h"
22
#include "HutaoNativePhysicalDrive.h"
3+
#include "HutaoString.h"
34
#include <winioctl.h>
45

56
HRESULT __stdcall HutaoNativePhysicalDrive::IsPathOnSolidStateDrive(PCWSTR root, BOOL* isSSD) noexcept
@@ -9,39 +10,36 @@ HRESULT __stdcall HutaoNativePhysicalDrive::IsPathOnSolidStateDrive(PCWSTR root,
910
return E_POINTER;
1011
}
1112

12-
// Check if path is empty
1313
if (root[0] == L'\0')
1414
{
1515
return E_INVALIDARG;
1616
}
1717

18-
// Get drive letter (e.g., "C:\" -> "C:")
19-
wchar_t drive[4] = { L'C', L':', L'\\', L'\0' };
20-
if (root[1] == L':')
18+
wchar_t driveLetter = L'\0';
19+
size_t len = wcslen(root);
20+
21+
if (len >= 2 && root[1] == L':')
2122
{
22-
drive[0] = root[0];
23+
driveLetter = root[0];
2324
}
2425
else
2526
{
26-
// If not a valid drive path, return error
2727
return E_INVALIDARG;
2828
}
2929

30-
// Create drive path
3130
HutaoString drivePath = L"\\\\.\\";
32-
// 创建一个包含单个字符的字符串
33-
wchar_t driveChar[2] = { drive[0], L'\0' };
34-
drivePath += driveChar;
31+
wchar_t driveLetterStr[2] = { driveLetter, L'\0' };
32+
drivePath += driveLetterStr;
3533
drivePath += L":";
3634

37-
// Open drive
35+
// Open drive with read access
3836
HANDLE hDrive = CreateFileW(
3937
drivePath.Data(),
40-
0,
38+
GENERIC_READ,
4139
FILE_SHARE_READ | FILE_SHARE_WRITE,
4240
nullptr,
4341
OPEN_EXISTING,
44-
0,
42+
FILE_ATTRIBUTE_NORMAL,
4543
nullptr
4644
);
4745

@@ -50,7 +48,7 @@ HRESULT __stdcall HutaoNativePhysicalDrive::IsPathOnSolidStateDrive(PCWSTR root,
5048
return HRESULT_FROM_WIN32(GetLastError());
5149
}
5250

53-
// Get disk properties
51+
// Method 1: Check device type
5452
STORAGE_PROPERTY_QUERY query = {};
5553
query.PropertyId = StorageDeviceProperty;
5654
query.QueryType = PropertyStandardQuery;
@@ -76,11 +74,11 @@ HRESULT __stdcall HutaoNativePhysicalDrive::IsPathOnSolidStateDrive(PCWSTR root,
7674
return HRESULT_FROM_WIN32(GetLastError());
7775
}
7876

79-
// Allocate buffer large enough
77+
// Allocate buffer
8078
DWORD bufferSize = header.Size;
8179
if (bufferSize == 0)
8280
{
83-
bufferSize = sizeof(STORAGE_DEVICE_DESCRIPTOR) + 1024; // Default size
81+
bufferSize = sizeof(STORAGE_DEVICE_DESCRIPTOR) + 1024;
8482
}
8583

8684
BYTE* buffer = new BYTE[bufferSize];
@@ -102,29 +100,88 @@ HRESULT __stdcall HutaoNativePhysicalDrive::IsPathOnSolidStateDrive(PCWSTR root,
102100
nullptr
103101
);
104102

105-
CloseHandle(hDrive);
106-
107103
if (!result)
108104
{
109105
delete[] buffer;
106+
CloseHandle(hDrive);
110107
return HRESULT_FROM_WIN32(GetLastError());
111108
}
112109

113110
// Parse device descriptor
114111
STORAGE_DEVICE_DESCRIPTOR* descriptor = reinterpret_cast<STORAGE_DEVICE_DESCRIPTOR*>(buffer);
115112

116-
// Check media type
117-
// SSD is usually DeviceType == 0x0C (SEMICONDUCTOR_DRIVE)
118113
BOOL isSolidState = FALSE;
119114

120-
// Check device type: SSD is usually 0x0C (SEMICONDUCTOR_DRIVE)
121-
if (descriptor->DeviceType == 0x0C)
115+
// Check 1: Device type - SSD is usually 0x0C (SEMICONDUCTOR_DRIVE)
116+
// But some SSDs report as 0x00 (unknown) or 0x07 (FILE_DEVICE_DISK)
117+
if (descriptor->DeviceType == 0x0C) // SEMICONDUCTOR_DRIVE
122118
{
123119
isSolidState = TRUE;
124120
}
125-
// Could also check other flags, but DeviceType is most reliable
121+
else if (descriptor->DeviceType == 0x00 || descriptor->DeviceType == 0x07)
122+
{
123+
// Could be SSD, need additional checks
124+
// Method 2: Check for seek penalty property
125+
STORAGE_PROPERTY_QUERY seekPenaltyQuery = {};
126+
seekPenaltyQuery.PropertyId = StorageDeviceSeekPenaltyProperty;
127+
seekPenaltyQuery.QueryType = PropertyStandardQuery;
128+
129+
DEVICE_SEEK_PENALTY_DESCRIPTOR seekPenaltyDesc = {};
130+
DWORD seekBytesReturned = 0;
131+
132+
result = DeviceIoControl(
133+
hDrive,
134+
IOCTL_STORAGE_QUERY_PROPERTY,
135+
&seekPenaltyQuery,
136+
sizeof(seekPenaltyQuery),
137+
&seekPenaltyDesc,
138+
sizeof(seekPenaltyDesc),
139+
&seekBytesReturned,
140+
nullptr
141+
);
142+
143+
if (result)
144+
{
145+
// SSDs typically have no seek penalty (IncursSeekPenalty = FALSE)
146+
// HDDs typically have seek penalty (IncursSeekPenalty = TRUE)
147+
if (!seekPenaltyDesc.IncursSeekPenalty)
148+
{
149+
isSolidState = TRUE;
150+
}
151+
}
152+
153+
// Method 3: Check for TRIM support (optional)
154+
if (!isSolidState)
155+
{
156+
STORAGE_PROPERTY_QUERY trimQuery = {};
157+
trimQuery.PropertyId = StorageDeviceTrimProperty;
158+
trimQuery.QueryType = PropertyStandardQuery;
159+
160+
DEVICE_TRIM_DESCRIPTOR trimDesc = {};
161+
DWORD trimBytesReturned = 0;
162+
163+
result = DeviceIoControl(
164+
hDrive,
165+
IOCTL_STORAGE_QUERY_PROPERTY,
166+
&trimQuery,
167+
sizeof(trimQuery),
168+
&trimDesc,
169+
sizeof(trimDesc),
170+
&trimBytesReturned,
171+
nullptr
172+
);
173+
174+
if (result && trimDesc.TrimEnabled)
175+
{
176+
// Device supports TRIM, likely an SSD
177+
isSolidState = TRUE;
178+
}
179+
}
180+
}
126181

127182
delete[] buffer;
183+
CloseHandle(hDrive);
184+
128185
*isSSD = isSolidState;
129186
return S_OK;
130187
}

src/Snap.Hutao.Remastered.Native/HutaoNativeProcess.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,6 @@ HRESULT __stdcall HutaoNativeProcess::WaitForExit()
142142
return hr;
143143
}
144144

145-
// 获取退出码
146145
if (!::GetExitCodeProcess(m_processInfo.hProcess, &m_exitCode))
147146
{
148147
HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
@@ -169,10 +168,8 @@ HRESULT __stdcall HutaoNativeProcess::Kill()
169168
return hr;
170169
}
171170

172-
// 等待进程结束
173171
WaitForSingleObject(m_processInfo.hProcess, 5000);
174172

175-
// 获取退出码
176173
if (!::GetExitCodeProcess(m_processInfo.hProcess, &m_exitCode))
177174
{
178175
m_exitCode = 1;
@@ -296,7 +293,6 @@ HRESULT __stdcall HutaoNativeProcess::GetExitCodeProcess(BOOL* isRunning, uint*
296293
return S_OK;
297294
}
298295

299-
// 检查进程是否还在运行
300296
DWORD currentExitCode;
301297
if (!::GetExitCodeProcess(m_processInfo.hProcess, &currentExitCode))
302298
{

0 commit comments

Comments
 (0)