|
Can you check the reply from the DeviceIOControl function and also other API's? If it is failing, use GetLastError and see if it is privilege related issue.
Good luck
Saneesh
Saneesh
|
|
|
|
|
:(My Code is running normally in XP system, but it cannot detect any infotmation in Vista, it seems the funcion can not be supported by Vista system. There is any another way to use SMART Function in Vista? Thanks a lot!
Mywork_007
|
|
|
|
|
Hi,
The problem in Vista is because of strict user permission (as far as i could understand). The command is should be supported by device driver for the hard drive. Once i figure out how to do it, i will update it on CP. Thanks
for looking at it. Don't know any other way to do it. Actually i never gets that much time on Vista.
Thanks,
Saneesh
Saneesh
|
|
|
|
|
Hi, Thanks for your reply.
I have run my program as administrator, so i think is not user permission issue. and i have use the Function(GetLastError())to get the errorcode, it return 50. I will still trace this issue. Thanks a lot!
Mywork_007
|
|
|
|
|
Please let me know if you can make it work in Vista. I could not even make a successful call to CreateFile because of permission issue.
Saneesh
Saneesh
|
|
|
|
|
sorry, I can not make it work in Vista due to the DeviceIoControl Fialed.
But the CreateFile Function is successed in Vista. For Permission issue, you can set UAC in control panel or ren the executable file to the name which contain the character "Install" or "setup" to improve the access rights.
Also I can not find the description of the IOCTL code(SMART_GET_VERSION) in the latest WDK documentation for Vista, but I can find it in before version what used for XP. so it seems this function is not supported by Visat yet, but there have not any indication to tell us whether there have another way to solve this.
Thanks a lot!
Mywork_007
|
|
|
|
|
For Permission issue, you can set UAC in control panel or ren the executable file to the name which contain the character "Install" or "setup" to improve the access rights.
... or just right-click on the exe and pick "Run as administrator".
This will also be easier to handle with the upcoming Visual Studio 2008, that will support an embedded UAC manifest file to automatically tell Vista what privilege level the application needs. It will be a simple C++ project setting to tell it needs admin rights.
|
|
|
|
|
There is a problem with the way you are enumerating the fixed drives in ReadSMARTValuesForAllDrives(). Let me explain...
First, keep in mind that the first fixed drive is at index 0, the second at index 1, the third at index 2, and so on. They will always be in sequence, not in some semi-random order such as "1, 3, 4, 8...".
Also, there is not necessarily a one-to-one correlation between the drive letters and the hard drives physically present in the system. For example, the drive at physical index 0 may contain two logical drives (partitions) mounted as drive letters "C:" and "D:", so referencing them as physical drives 0 and 1 will not work correctly.
As a further example, consider my own system: I have two physical drives installed in the machine, with a single partition on each, mounted as drive letters "C:" and "G:". So, looking at your code:
<br />
case DRIVE_FIXED:<br />
ucDriveIndex=ucT2-2;<br />
if(ReadSMARTInfo(ucDriveIndex))<br />
m_ucDrivesWithInfo++;<br />
m_ucDrives++;<br />
break;<br />
As you can see, it will attempt to load data for drive 0 ( ucT2 == 2, ucDriveIndex == 0 ) and drive 4 ( ucT2 == 6, ucDriveIndex == 4 ). And since the system only recognizes physical hard drives 0 and 1, this code will fail to display information for the second drive.
The solution is to not enumerate the list of logical drives, but the actual physical drives instead, e.g.:
<br />
BOOL CSmartReader::ReadSMARTValuesForAllDrives()<br />
{<br />
static const BYTE MAX_DRIVES = 32;<br />
<br />
for( BYTE ucIndex = 0; ucIndex < MAX_DRIVES; ucIndex++ )<br />
{<br />
if( ReadSMARTInfo( ucIndex ) )<br />
m_ucDrivesWithInfo++;<br />
}<br />
<br />
return TRUE;<br />
}<br />
Of course, this breaks m_ucDrives completely, but you could easily update it inside the ReadSMARTInfo() function instead, e.g.:
<br />
BOOL CSmartReader::ReadSMARTInfo(BYTE ucDriveIndex)<br />
{<br />
...code...<br />
<br />
if(hDevice!=INVALID_HANDLE_VALUE)<br />
{<br />
m_ucDrives++;<br />
<br />
...more code...<br />
}<br />
Hope this helps!
- NL
*Real* programmers use "copy con:progname.exe"!
|
|
|
|
|
Hi,
Thanks for pointing it out.
Saneesh
Saneesh
|
|
|
|
|
it shows the cache memory buffer as 32kb instead of 16MB
also many values are 0
|
|
|
|
|
Can you send me the screen shot of your hdd information to saneesh8@hotmail.com
Saneesh
|
|
|
|
|
Also I have meet this issue, the problem is seems that the vista cann't support the function of SMART_RCV_DRIVE_DATA. when you call deviceiocontrol the return value is 50. Tks!
Mywork_007
|
|
|
|
|
Hi,
The problem in Vista is because of strict user permission (as far as i could understand). The command is should be supported by device driver for the hard drive. Once i figure out how to do it, i will update it on CP. Thanks
for looking at it.
Thanks,
Saneesh
Saneesh
|
|
|
|
|
Does this work on external storage arrays or SANs connected via FIBER, just curious because SANS simply present a LUN that is a virtual representation of disk space, and the operating system just sees the space as an additional drive, no matter how many disks the virtual space is stripped across at the san layer.
I will not be in the office for a few days, but when I get there I have a Hitachi Tagmastore SAN dedicated for testing I will try it out on and send the results to you if you are interested.
|
|
|
|
|
Hi,
Most of the time, this will work only on real hard drives present in the system. It wont even work on USB hard drives because the driver wont support it ??. Please try it and let me know the results.
Thanks,
Saneesh
|
|
|
|
|
hello sir ji
i double checked it
it is corupt
thanks
Girish Sharma
|
|
|
|
|
Which one is corrupted?? Both or only one? I just checked and found both are working.
Saneesh
|
|
|
|
|
Hi,
Why the threshold values always are zero? Anather application for HDD control has another values.
|
|
|
|
|
Is it 0 for all of them??? or of just one of the parameters?
Saneesh
|
|
|
|
|
The threshold values for some attributes may be 0. It is right. But it is 0 for all attributes! I can't understand why it is so
Help me, please!
|
|
|
|
|
When u compare the other values with the output from the other program u used, are they same? and only threshold is 0? May be there is some information / the index may be different for your particular model and my code is not checking for that. Can you debug the follwing code and see that you are getting? from function BOOL CSmartReader::ReadSMARTAttributes(HANDLE hDevice,UCHAR ucDriveIndex)
bRet=DeviceIoControl(hDevice,SMART_RCV_DRIVE_DATA,&stCIP,sizeof(stCIP),szAttributes,sizeof(ST_ATAOUTPARAM) + READ_ATTRIBUTE_BUFFER_SIZE - 1,&dwRet,NULL);
if(bRet)
{
pT1=(PBYTE)(((ST_ATAOUTPARAM*)szAttributes)->bBuffer);
for(ucT1=0;ucT1<30;++ucT1)
{
pT2=(PDWORD)&pT1[2+ucT1*12+5];
pT3=&pT1[2+ucT1*12];
pT3[INDEX_ATTRIB_RAW+2]=pT3[INDEX_ATTRIB_RAW+3]=pT3[INDEX_ATTRIB_RAW+4]=pT3[INDEX_ATTRIB_RAW+5]=pT3[INDEX_ATTRIB_RAW+6]=0;
if(pT3[0]!=0)
{
pSmartValues=GetSMARTValue(ucDriveIndex,pT3[0]);
if(pSmartValues)
pSmartValues->m_dwThreshold=pT2[0];
}
}
}
return bRet;
Saneesh
|
|
|
|
|
Hello, Saneesh! Sorry for my long silence.
I debug your specified code and look it's result.
After execution the following step
pSmartValues=GetSMARTValue(ucDriveIndex,pT3[0]);
the pSmartValues.m_dwThreshold is 4294967295. But the pT2[0] value is always 0, so after assignment statement pSmartValues->m_dwThreshold=pT2[0] the pSmartValues.m_dwThreshold value is 0 too.
So, can you help me to understand the pT2 variable meaning?
|
|
|
|
|
Looking at Section 2.6 of the SFF 8035i Revision 2 SMART Specification, titled "SMART Read Attribute Thresholds", the buffer beginning at OutParams.stCOP.bBuffer contains a 512 byte structure. This structure contains, among other things, a collection of smaller structures which include the threshold data. These structures are easily coded as something like this:
<br />
#define SMART_MAX_ATTRIBUTES 30<br />
#define SMART_MAX_THRESHOLDS 30<br />
<br />
#pragma pack( push, 1 )// Structures must be aligned on a single-byte boundary!<br />
typedef struct<br />
{<br />
BYTE ucId;<br />
BYTE ucValue;<br />
BYTE ucReserved[10];<br />
<br />
} SMART_THRESHOLD_INFO, *LPSMART_THRESHOLD_INFO;<br />
<br />
typedef struct<br />
{<br />
WORD wRevision;<br />
SMART_THRESHOLD_INFO arThresholds[ SMART_MAX_THRESHOLDS ];<br />
BYTE ucReserved[18];<br />
BYTE ucVendorSpecific[131];<br />
BYTE ucChecksum;<br />
<br />
} SMART_THRESHOLDS, *LPSMART_THRESHOLDS;<br />
#pragma pack( pop )<br />
With these structures in hand, we can modify the "Read Thresholds" code to be a bit easier to follow...
<br />
LPSMART_THRESHOLDS pThresholds = (LPSMART_THRESHOLDS)OutParams.stCOP.bBuffer;<br />
<br />
for( ucT1 = 0; ucT1 < SMART_MAX_THRESHOLDS; ucT1++ )<br />
{<br />
SMART_THRESHOLD_INFO& info = pThresholds->arThresholds[ ucT1 ];<br />
<br />
if( info.ucId != 0 )<br />
{<br />
pSmartValues = GetSMARTValue( ucDriveIndex, info.ucId );<br />
<br />
if( pSmartValues )<br />
pSmartValues->m_dwThreshold = info.ucValue;<br />
}<br />
}<br />
This same approach could, of course, be applied to the code which reads the attributes in as well. I'll leave that as an exercise for the reader...
Hope this helps!
- NL
*Real* programmers use "copy con:progname.exe"!
|
|
|
|
|
I tried your executable on a server with 2 HDD's using a RAID controller. And actually I was hoping to see 2 hdd's status accoording to SMART protocol, but I just get one. I understand that the OS sees only one hdd ( actually 2 parallel RAID1 ), so is there a way to achieve that, or is there some kind of an api needed delivered by the manufacturer?
Thank you!
**We are an example of helping each other**
|
|
|
|
|
Hi,
I never tried/see it like the way you have described. Well the way to open the drive is in "wsprintf(szT1,"\\\\.\\PHYSICALDRIVE%d",ucDriveIndex);
hDevice=CreateFile(szT1,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_SYSTEM,NULL);".
If the device driver can see it, i guess a different PHYSICALDRIVE should make it work. Does it shows up as two different HDD in control panel.
Which drive's data are you getting?
Saneesh
|
|
|
|