Click here to Skip to main content
15,890,995 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Im querying WMI to get the hard disk information from my system. I'm then adding the information to an array. When the while loop is displayed each turn, the information is correct.

When i loop the array and print this, it always prints drive as Z but does print the correct amount of drives. Any Ideas please?

C++
struct DriveInfo
{
	char	*DriveLetter;
	int	nType;
};
vector< DriveInfo* >DriveList;


bool WMIReader::GetInfo( CMainDlg *pThis )
{
	char pBuffer[ 256 ];

	DriveInfo *FoundDrive  = new DriveInfo;
	ZeroMemory( FoundDrive, sizeof( DriveInfo ) );

	WMIReader *Reader = new WMIReader( );
	if( !Reader->Initialized ) { Reader->Initialized = Reader->Setup( ); }

	if( Reader->Initialized )
	{
		if( Reader->GetFirstDevice( L"Win32_LogicalDisk" ) )
		{
			while( Reader->GetNextDevice( ) )
			{
				Reader->ReadProperty( L"DeviceID", pBuffer );
				FoundDrive->DriveLetter = pBuffer;
				DriveList.push_back( FoundDrive );

				//Prints the drive letter correctly
				Tools.AppendWindowText( pThis->m_StatusWindow, "Volume: %s\\", FoundDrive->DriveLetter );
			}

			for( int i = 0; i < DriveList.size( ); ++i )
			{
				DriveInfo* CurrentDrive = DriveList.at( i );

				//Prints all drives as 'Z'
				Tools.AppendWindowText( pThis->m_StatusWindow, "Volume: %s\\", CurrentDrive->DriveLetter );
			}
		}
	}

	return true;
}
Posted

You have only one instance of DriveInfo and so whenever you assign a drive letter it updates every entry in the list which, of course, all point to that one DriveInfo.

In the while loop create a new DriveInfo for each drive found.

Alan.
 
Share this answer
 
Comments
Code-o-mat 13-May-12 16:44pm    
Good catch, i could have sworn i saw that "DriveInfo *FoundDrive = new DriveInfo;" inside the while loop...5 points for not missing the obvious like i did. :)
That is because here:
FoundDrive->DriveLetter = pBuffer;

you store a pointer at pBuffer. So each and every instance of DriveInfo will have a pointer in it's DriveLetter member at the very same buffer. This buffer, pBuffer is overwritten in each itearion of the while loop that iterates the drives, thus, after the loop, pBuffer will contain the very last drive letter (e.g. Z), and since each and every DriveInfo has a pointer at this buffer, they will all "report" this very last drive.

Try changing DriveLetter from char * to CString, or std::string, or at least allocate a new char buffer for every DriveInfo instance and copy the buffer into them. Or make it simply a char and copy that one particular letter from the buffer into them.
 
Share this answer
 
Thanks, I thought it musta been something small I missed!

Basically i applied your solution to come up with the following:


C++
struct DriveInfo
{
    char    DriveLetter[50];
    int     nType;
};
vector< DriveInfo* >DriveList;
DriveInfo *FoundDrive  = NULL;
bool WMIReader::GetInfo( CEngTechDlg *pThis )
{
	char pBuffer[ 256 ];

	FoundDrive = new DriveInfo;

	WMIReader *Reader = new WMIReader( );
	if( !Reader->Initialized ) { Reader->Initialized = Reader->Setup( ); }

	if( Reader->Initialized )
	{
		if( Reader->GetFirstDevice( L"Win32_LogicalDisk" ) )
		{
			while( Reader->GetNextDevice( ) )
			{
				Reader->ReadProperty( L"DeviceID", pBuffer );
				strcpy( FoundDrive->DriveLetter, pBuffer );

				DriveList.push_back( FoundDrive );

				FoundDrive = new DriveInfo;
				ZeroMemory( FoundDrive, sizeof( DriveInfo ) );
			}
			Reader->EndQuery( );

			for( int j = 0; j < DriveList.size( ); ++j )
			{
				DriveInfo* CurrentDrive = DriveList.at( j );
				Tools.AppendWindowText( pThis->m_StatusWindow, "Volume: %s\\", CurrentDrive->DriveLetter );
			}
		}
	}

	return true;
}



This came up with the following:


VB
Volume: D:\
Volume: E:\
Volume: T:\
Volume: U:\
Volume: V:\
Volume: W:\
Volume: X:\
Volume: Y:\
Volume: Z:\




Appreciate your help there. Thanks a lot.
 
Share this answer
 
Comments
Code-o-mat 13-May-12 16:40pm    
Pelase note that this way you are leaking some memory, the last instance of DriveInfo that gets allocated is never deleted. Even, if one of your if conditions yield false, or your while loop doesn't go through any iterations, the very first instance of DriveInfo will not be deleted. You also don't seem to delete WMIReader either. (I assume you free up the DriveInfo instances that you pushed into the vector at some place...)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900