storport for Windows 2003 with SMART support

Hi to all developers,

we, as many others, wondered why there is no SMART support on Windows 2003 Server with storport AHCI drivers like StorAhci. For us it was time to investigate into this topic lately. The results have been uploaded to Sourceforge with some example source code for demonstration. This should be a resource to every interested developer out there.

Today we released two patched versions of the storport driver for Windows 2003. The first version patches the storport driver of the leaked Windows Server 2003 source code archive. The second version patches storport of Windows 7 and uses it in combination with ntoskrn7.sys, which is sort of a self compiled extender library for ntoskrnl.exe to add support for missing functions called by Windows 7 storport.

Because there is a limitation on posting external links for new users we replaced the https with hxxps.

To download the files and the ReadMe go to hxxps://sourceforge.net/projects/storpor…-support/files/
If you are interested in the reversing process visit hxxps://storport-win2003-smart-support.sourceforge.io/

We hope this will be a valuable resource to you all. Have fun!
Greets Kai Schtrom

@schtrom :
Welcome to the Win-RAID Forum! I got to know you already as developer of an Openfabrics Alliance NVMe driver for W2k3.
Since Windows 2003 is an outdated Operating System, I have moved your contribution into this Sub-Forum about XP/W2k/W2k3.
Enjoy the Forum!
Dieter (alias Fernando)

Thanks Fernando! I enjoyed the forum threads on Win-Raid, especially the Windows 2003 / XP on newer hardware thread. I am a passive reader for many years now. Keep up the brilliant work and thanks for the move into the right sub-forum.

Thank you for fixing it and writing such an extensive and thorough step-by-step guide, Kai!

While you’re at it, there are still 2 issues with storahci that I’ve been trying to fix:

- Only first drive is shown in ATA device and SMART of AIDA64 even with storport.w7
Except for NVMe drives, when a device is shown in ATA is also in SMART page as well, so you can test it in a VM.


- STANDBY IMMEDIATE command is not sent to SSDs:
Excerpt from entrypts.c:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 
        case SRB_FUNCTION_SHUTDOWN: {
//This request is for the device to flush device data from adapter cache.
//The miniport driver must hold on to the shutdown request until no data remains in the HBA's internal cache for the target logical unit and,
//then, complete the shutdown request.
PATA_DEVICE_PARAMETERS deviceParameters = &adapterExtension->PortExtension[Srb->PathId]->DeviceExtension->DeviceParameters;
BOOLEAN sendStandby = (IsDumpHiberMode(adapterExtension) || IsDumpCrashMode(adapterExtension));
 
deviceParameters->StateFlags.SystemPoweringDown = TRUE;
if (adapterExtension->PortExtension[Srb->PathId]->DeviceExtension->SupportedCommands.SetDateAndTime == 0x1) {
IssueSetDateAndTimeCommand(adapterExtension->PortExtension[Srb->PathId], sendStandby);
processIO = TRUE;
} else if (sendStandby) {
//in dump mode, this is the last Srb sent after SYNC CACHE, spin down the disk
PAHCI_SRB_EXTENSION srbExtension = GetSrbExtension(Srb);
srbExtension->AtaFunction = ATA_FUNCTION_ATA_COMMAND;
SetCommandReg((&srbExtension->TaskFile.Current), IDE_COMMAND_STANDBY_IMMEDIATE);
processIO = TRUE;
} else {
Srb->SrbStatus = SRB_STATUS_SUCCESS;
StorPortNotification(RequestComplete, AdapterExtension, Srb);
}
 
break;
}
 

Forcing sendStandby to 1, fixes it "somehow", but here are the results on my system with 6 SSDs:

- port0 - fails
- port1 - fails
- port2 - fails
- port3 - fails
- port4 - OK
- port5 - OK

Hi daniel_k,

I have updated the sources today and fixed two problems. I solved the logon screen instant reboot bug if a CD-/DVD-ROM drive is connected and implemented the START STOP UNIT command.

Now to your problems. The first problem where you only see drive 0 is definitely fixed since version 1.0. This should work also with the patched Windows 7 storport driver. I did some tests with the trial version of AIDA64 and see all drives with the patched drivers. The STANDBY IMMEDIATE command should now work in version 1.1. I included a writeup in the tutorial section what was fixed exactly for you to read. If you still have problems I think it could be platform specific stuff.

Thanks for your help and support!
Kai Schtrom

Thank you, Kai!

Will certainly try the patches later and report my findings.

@schtrom Hi, I downloaded source and seems like "typedef ULONG NODE_REQUIREMENT; " is missing in ntoskrn7.c. When I added it, I can compile it under XP and 2003 32bit target environment without problem.

When I tried it to compile 2003 x64 I receive many errors. Any updates on this project for x64?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
 
path contains nonexistant c:\windows\system32\openssh\, removing
BUILD: Compile and Link for AMD64
BUILD: Loading c:\winddk\7600.16385.1\build.dat...
BUILD: Computing Include file dependencies:
BUILD: Start time: Fri Sep 24 22:15:03 2021
BUILD: Examining c:\users\administrator\desktop\src directory for files to compile.
c:\users\administrator\desktop\src Invalidating OACR warning log for 'root:amd64fre'
- 2 source files (747 lines)
BUILD: Saving c:\winddk\7600.16385.1\build.dat...
BUILD: Compiling c:\users\administrator\desktop\src directory
Configuring OACR for 'root:amd64fre' - <OACR on>
_NT_TARGET_VERSION SET TO WS03
Compiling - ntoskrn7.c
Building Library - objfre_wnet_amd64\amd64\ntoskrn7.lib
BUILD: Linking for c:\users\administrator\desktop\src directory
_NT_TARGET_VERSION SET TO WS03
Compiling resources - ntoskrn7.rc
Linking Executable - objfre_wnet_amd64\amd64\ntoskrn7.sys
1>errors in directory c:\users\administrator\desktop\src
1>c:\users\administrator\desktop\src\ntoskrn7.exp : error LNK2001: unresolved external symbol _EtwEventEnabled_k7@12
1>c:\users\administrator\desktop\src\ntoskrn7.exp : error LNK2001: unresolved external symbol _EtwProviderEnabled_k7@20
1>c:\users\administrator\desktop\src\ntoskrn7.exp : error LNK2001: unresolved external symbol _EtwRegister_k7@16
1>c:\users\administrator\desktop\src\ntoskrn7.exp : error LNK2001: unresolved external symbol _EtwUnregister_k7@8
1>c:\users\administrator\desktop\src\ntoskrn7.exp : error LNK2001: unresolved external symbol _EtwWrite_k7@24
1>c:\users\administrator\desktop\src\ntoskrn7.exp : error LNK2001: unresolved external symbol _IoConnectInterruptEx_k7@4
1>c:\users\administrator\desktop\src\ntoskrn7.exp : error LNK2001: unresolved external symbol _IoDisconnectInterruptEx_k7@4
1>c:\users\administrator\desktop\src\ntoskrn7.exp : error LNK2001: unresolved external symbol _IoGetAffinityInterrupt_k7@8
1>c:\users\administrator\desktop\src\ntoskrn7.exp : error LNK2001: unresolved external symbol _IoGetDevicePropertyData_k7@32
1>c:\users\administrator\desktop\src\ntoskrn7.exp : error LNK2001: unresolved external symbol _KeGetCurrentProcessorNumberEx_k7@4
1>c:\users\administrator\desktop\src\ntoskrn7.exp : error LNK2001: unresolved external symbol _KeQueryActiveGroupCount_k7@0
1>c:\users\administrator\desktop\src\ntoskrn7.exp : error LNK2001: unresolved external symbol _KeQueryActiveProcessorCountEx_k7@4
1>c:\users\administrator\desktop\src\ntoskrn7.exp : error LNK2001: unresolved external symbol _KeQueryGroupAffinity_k7@4
1>c:\users\administrator\desktop\src\ntoskrn7.exp : error LNK2001: unresolved external symbol _KeQueryHighestNodeNumber_k7@0
1>c:\users\administrator\desktop\src\ntoskrn7.exp : error LNK2001: unresolved external symbol _KeQueryLogicalProcessorRelationship_k7@16
1>c:\users\administrator\desktop\src\ntoskrn7.exp : error LNK2001: unresolved external symbol _KeQueryNodeActiveAffinity_k7@12
1>c:\users\administrator\desktop\src\ntoskrn7.exp : error LNK2001: unresolved external symbol _KeSetTargetProcessorDpcEx_k7@8
1>c:\users\administrator\desktop\src\ntoskrn7.exp : error LNK2001: unresolved external symbol _MmAllocateContiguousMemorySpecifyCacheNode_k7@36
1>c:\users\administrator\desktop\src\ntoskrn7.exp : error LNK2001: unresolved external symbol _PoEndDeviceBusy_k7@4
1>c:\users\administrator\desktop\src\ntoskrn7.exp : error LNK2001: unresolved external symbol _PoStartDeviceBusy_k7@4
1>c:\users\administrator\desktop\src\objfre_wnet_amd64\amd64\ntoskrn7.sys : error LNK1120: 20 unresolved externals
BUILD: Finish time: Fri Sep 24 22:15:03 2021
BUILD: Done
 
6 files compiled - 1 Warning
1 library built
1 executable built - 21 Errors
 

Hi George King, I never investigated into x64 stuff on Windows XP and 2003 Server, because most say some drivers are unstable on x64. I myself only use Windows Server 2003 x86, because you can not compile 16 bit DOS programs on the x64 platform at all.

I’ve been using XP64 since it first came out on my old Athlon64. No issues with stability. The only problem was that a lack of driver support when it was new. Now same problem, because it is too old.

I tried this out on XP64 with storport 6.1.7601.23403. One SSD, one HDD, and one NVME. Using CrystalDisk8.9.0a/HWiNFO640/GSmartControl0.90

Both storahci based drivers shows SMART data with the modified storport on XP64. I was testing NVMe SMART at the same time.

@schtrom @daniel_k
How does SMART work for NVMe drives? On windows 7x64 SMART is displayed, while on XP64 it is not. Both using the same version of CrystalDisk8.3.0, the same version of samsung nvme driver, the same version of storport (with msi/smart/ntoskrn8 modification for XP64). Works in one, but not the other…

And for more fun, HWiNFO is able to get SMART data on XP64 using samsung driver or schtrom’s server2k3 OFA1.3


1
2
3
4
5
6
7
8
9
10
 
XP64 storport 6.1.7601.23403(msi/SMART) 
Crystal/HWinFO/GSmart
SATA AMD 1.2.1.402 Yes/Yes/Yes
SATA StorAHCI schtrom 1.0_20200928 Yes/Yes**/Yes
SATA storahci 6.2.9200.16384 Yes/Yes/Yes
 
NVME schtrom w2k3 OFA1.3 No/Yes/No
NVME win7.23403 No/No/No
NVME Samsung EXEcrash*/Yes/No
**when started HWi BSOD0x51(0x04,0x01,..., changed to other driver for test, no BSOD when changed back) Maybe a fluke do to changing the drivers constantly during test?
 
1
2
3
4
5
6
7
8
9
10
 
XP64 storport 6.1.7601.23403(msi)
Crystal/HWinFO/GSmart
SATA AMD 1.2.1.402 Yes/Yes/Yes
SATA StorAHCI schtrom 1.0_20200928 No/1stSATA/Yes
SATA storahci 6.2.9200.16384 No/1stSATA/Yes
 
NVME schtrom w2k3 OFA1.3 No/Yes/No
NVME win7.23403 No/No/No
NVME Samsung EXEcrash*/Yes/No
*Crystal8.3.0 last version to work with Samsung NVME driver on XP, newer ones crash)
 
1
2
3
4
5
6
7
8
9
 
Win7x64 6.1.7601.23403 (default)
Crystal/HWinFO/GSmart
SATA AMD 1.2.1.402 Yes/Yes/Yes
SATA Win7msahci Yes/Yes/Yes
 
NVME win7stornvme No/No/No
NVME Samsung Yes/Yes/No
NVME OFA1.3 error
NVME OFA1.5 error
 



@George_King
If anyone wants to try, here is where you would need to make the change on storport 6.1.7601.23403. I used schtrom's mod for 6.1.7601.17514 as guide.
1
2
3
4
5
6
7
8
 

x86 storport 6.1.7601.23403
@10302 75 36 -> 90 90
@1030E 75 2A -> 90 90
 
x64 storport 6.1.7601.23403
@192D5 75 36 -> 90 90
@192DE 75 2D -> 90 90
 


x86 storport 6.1.7601.23403


x64 storport 6.1.7601.23403

Had a random thought while I was working on something else. Looking over the source code for Crystal, it looks like it handles things differently depending on what version of windows it runs under.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
 
CAtaSmart::CAtaSmart()
{
BOOL bosVersionInfoEx;
ZeroMemory(&m_Os, sizeof(OSVERSIONINFOEX));
m_Os.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
if(!(bosVersionInfoEx = GetVersionEx((OSVERSIONINFO *)&m_Os)))
{
m_Os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx((OSVERSIONINFO *)&m_Os);
}
 
m_FlagAtaPassThrough = FALSE;
m_FlagAtaPassThroughSmart = FALSE;
m_FlagNVMeStorageQuery = FALSE;
 
if (m_Os.dwMajorVersion >= 10)
{
m_FlagAtaPassThrough = TRUE;
m_FlagAtaPassThroughSmart = TRUE;
m_FlagNVMeStorageQuery = TRUE;
}
else if(m_Os.dwMajorVersion >= 6 || (m_Os.dwMajorVersion == 5 && m_Os.dwMinorVersion == 2))
{
m_FlagAtaPassThrough = TRUE;
m_FlagAtaPassThroughSmart = TRUE;
}
else if(m_Os.dwMajorVersion == 5 && m_Os.dwMinorVersion == 1)
{
CString cstr;
cstr = m_Os.szCSDVersion;
cstr.Replace(_T("Service Pack "), _T(""));
if(_tstoi(cstr) >= 2)
{
m_FlagAtaPassThrough = TRUE;
m_FlagAtaPassThroughSmart = TRUE;
}
}
 


With depency walker you can see it calls GetVersionExW. I found an old copy of Microsoft Application Verifier and set HighVersionLie to trick the software.
http://wp.xin.at/wp-content/uploads/2019...ifier-32-bit.7z
http://wp.xin.at/wp-content/uploads/2019...ifier-64-bit.7z

On XP64/samsungNVME, i set it to think it was running on windows 7 and window 10 versions. No change, still no SMART. On Win7x64/samsungNVME with a working SMART, I set it to think it was on XP. No change, still shows SMART.

Thanks to @Andalu for pointing out that it works when wbemprox.dll is temporarily removed from system32. (No size info for NVMe, but all the SMART is there with no crash.

Long story short, to make Crystal Disk Info work: in DiskInfo32 or DiskInfo64, find where “\ \ . \ r o o t \ c i m v 2” is with hex editor and change it to something like “\ \ . \ r o o t \ n o w m i”.

630069006D00760032 -> 6E006F0077006D0069