Thread: small Diag app ideas....

  1. #1
    Registered User
    Join Date
    Nov 2007
    Posts
    22

    small Diag app ideas....

    Hi all,

    I would like to implement an application that will return some diagnostic information of the pc. Ideally i would like it to be run on some client machines on a network to display info such as:

    - Local admins
    - Disk Drives and space available (maybe &#37
    - CPU speed and type
    - RAM size and amount used
    - Last user logged on maybe?

    I guess it would be a series of simple reads from data held on the local machine. Also from some research i gather that i need to access the registry to get info like CPU type and speed.

    Can anyone steer me in the right direction, with maybe an example of a statement to return one of these pieces of data, or explain what to do to obtain them?

    Sorry if i was a bit vague, thanks in advance.

    baffa

    PS i would like preferable use C, C++ or java for this application

    thanks
    Last edited by baffa; 08-13-2008 at 05:20 PM.

  2. #2
    Registered User valaris's Avatar
    Join Date
    Jun 2008
    Location
    RING 0
    Posts
    507
    Lookup WinSocks for the network part, or write it in c#. For all that other information there may be some functions out there to do it, or perhaps it is stored in the registry as you said.

  3. #3
    Unregistered User Yarin's Avatar
    Join Date
    Jul 2007
    Posts
    2,158
    >> - CPU speed and type
    CPUID

  4. #4
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    Can anyone steer me in the right direction, with maybe an example of a statement to return one of these pieces of data, or explain what to do to obtain them?
    Here is some starter code that returns available C drive space and processor info from remote targeted workstation

    Code:
    #pragma comment( lib, "ws2_32.lib" )
    #pragma comment( lib, "advapi32.lib" )
    #pragma comment( lib, "mpr.lib" )
    
    #include <winsock2.h>
    #include <windows.h>
    #include <stdio.h>
    
    #define E32 ((double)4294967296.)
    
    typedef BOOL (WINAPI *P_GDFSE)(LPCTSTR,
    	PULARGE_INTEGER, 
    	PULARGE_INTEGER, PULARGE_INTEGER);
    
    // Emulates a 64 bits integer. Computations will actually be made on doubles.
    typedef struct int64s {
    	unsigned long Low, High;
    } int64t;
    
    void PrintError( LPCSTR str)
    {
    	LPVOID lpMessageBuffer;
    	int iError = GetLastError();
    	FormatMessage(
    		FORMAT_MESSAGE_ALLOCATE_BUFFER |
    		FORMAT_MESSAGE_FROM_SYSTEM,
    		NULL,
    		iError,
    		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 
    		(LPTSTR) &lpMessageBuffer,
    		0,
    		NULL
    		);
    	printf("%s: (%d) %s\n\n",str,iError,lpMessageBuffer);
    	LocalFree( lpMessageBuffer );
    }
    
    int MapDrive(char *DrvLetter, char *ComputerName, char *Share)
    {
    	NETRESOURCE nr;
    	char szName[256] = {0};
    	sprintf(szName,"\\\\%s\\%s",ComputerName, Share);
    	nr.dwScope = RESOURCE_CONNECTED;
    	nr.dwType = RESOURCETYPE_DISK;
    	nr.dwDisplayType = RESOURCEDISPLAYTYPE_SHARE;
    	nr.dwUsage = RESOURCEUSAGE_CONNECTABLE;
    	nr.lpLocalName = DrvLetter;
    	nr.lpRemoteName = szName;
    	nr.lpComment = NULL;
    	nr.lpProvider = NULL;
    	return WNetAddConnection2(&nr, NULL, NULL, CONNECT_UPDATE_PROFILE);
    }
    
    double AvailableDiskspace(char *Drive)
    {  
    	BOOL  fResult;
    	char  szDrive[4];
    	DWORD dwSectPerClust,
    		dwBytesPerSect,
    		dwFreeClusters,
    		dwTotalClusters;
    	double FreeMegs, TotalMegs;
    	P_GDFSE pGetDiskFreeSpaceEx = NULL;
    	int64t i64FreeBytesToCaller,
    				   i64TotalBytes,
    				   i64FreeBytes;
    	if (!(toupper(Drive[0]) >= 'A' && toupper(Drive[0]) <= 'Z')) return 0.0;
    	szDrive[0]=Drive[0];
    	szDrive[1]=':';
    	szDrive[2]='\\';
    	szDrive[3]='\0';
    	/*
    	   Use GetDiskFreeSpaceEx if available; otherwise, use
    	   GetDiskFreeSpace. Let's assume that we may have a Windows 95 workstation.
    	   Since GetDiskFreeSpaceEx is not in Windows 95, we
    	   dynamically link to it and only call it if it is present.  We 
    	   don't need to call LoadLibrary on KERNEL32.DLL because it is 
    	   already loaded into every Win32 process's address space.
    
    		Bottomline, this accounts for Win95 workstations.
    	*/ 
    	pGetDiskFreeSpaceEx = (P_GDFSE)GetProcAddress (
    		GetModuleHandle
    		("kernel32.dll"),
    		"GetDiskFreeSpaceExA");
    	if (pGetDiskFreeSpaceEx) {
    		fResult = pGetDiskFreeSpaceEx (szDrive,
    			(PULARGE_INTEGER)&i64FreeBytesToCaller,
    			(PULARGE_INTEGER)&i64TotalBytes,
    			(PULARGE_INTEGER)&i64FreeBytes);
    		if (fResult) 
    			return ((double)i64FreeBytesToCaller.High*E32 + i64FreeBytesToCaller.Low)/(1024*1024*1024);
    	}
    	else {
    		fResult = GetDiskFreeSpace (szDrive, 
    			&dwSectPerClust,
    			&dwBytesPerSect, 
    			&dwFreeClusters,
    			&dwTotalClusters);
    		if (fResult) {
    			/* force 64-bit math */ 
    			TotalMegs = (double)dwTotalClusters * dwSectPerClust * dwBytesPerSect / (1024*1024*1024);
    			return FreeMegs = (double)dwFreeClusters * dwSectPerClust * dwBytesPerSect / (1024*1024*1024);
    		}
    	}
    	return 0.0;
    } 
    
    BOOL ReadRegistryString(HKEY hKey, LPCTSTR szValueName, LPTSTR * lpszReturnValue)
    {
    	DWORD dwType = 0, dwDataSize = 0, dwBufferSize = 0;
    	if(RegQueryValueEx(hKey, szValueName, 0, &dwType, NULL, &dwDataSize ) != ERROR_SUCCESS) return  FALSE;
    	else if (dwType != REG_SZ) return FALSE;
    	dwBufferSize = dwDataSize + (1 * sizeof(CHAR));
    	if((*lpszReturnValue = (LPTSTR) malloc(dwBufferSize)) == NULL)
    		return FALSE;
    	if( RegQueryValueEx(hKey, szValueName, 0, &dwType, (LPBYTE) *lpszReturnValue, &dwDataSize ) != ERROR_SUCCESS)
    	{ 
    		free(*lpszReturnValue);
    		return FALSE;
    	}
    	else if (dwType != REG_SZ)
    	{
    		free(*lpszReturnValue);
    		return FALSE;
    	}
    	(*lpszReturnValue)[(dwBufferSize / sizeof(CHAR)) - 1] = '\0';
    	return TRUE;
    }
    
    int main(void)
    {
    	char szCDriveFreeSpace[24] = {0};
    	char szInputComputerName[] = {"RemotePC"};
    	char szShare[] = {"C$"};
    	/* Note: A T: drive must not be mapped prior to running this sample
    	   If it is, then change szMappedDrive to something other thant T:
    	*/   
    	char szMappedDrive[] = {"T:"};
    	WSADATA wsaData;
    	LPTSTR szReturnValue;
    	WORD wVersionRequested = MAKEWORD(2,2);
    	HKEY hKeyRemote, hKey;
    	/*  Note:  you must first verify that a remote target workstation is on the
    		network before proceeding.  I'd suggest using the ICMP helper lib to write a Ping function
    		to verify that the remote workstation is accessible.
    	*/
    	if(WSAStartup(wVersionRequested, &wsaData))
    	{
    		PrintError("WSAStartup failed");
    		return -1;
    	}
    	if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
    	{
    		printf("Could not find a usable version of Winsock.dll\n");
    		WSACleanup();
    		return -1;
    	}
    	else
    	{
    		printf("Winsock 2.2 dll is loaded\n");
    		if( MapDrive(szMappedDrive,szInputComputerName, szShare ) != NO_ERROR)
    			PrintError( "MapDrive failed");
    		else
    		{
    			sprintf(szCDriveFreeSpace, "%02.3fGb", AvailableDiskspace(szMappedDrive));
    			printf("Available drive space: %s\n", szCDriveFreeSpace);
    		}
    		WNetCancelConnection2(szMappedDrive, CONNECT_UPDATE_PROFILE,TRUE);                       
    	}
    	if(RegConnectRegistry(szInputComputerName, HKEY_LOCAL_MACHINE, &hKeyRemote) != ERROR_SUCCESS)
    	{
    		printf("RegconnectRegistry failed\n");
    		return -1;  
    	}   
    	if(RegOpenKeyEx(hKeyRemote, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0",
    		0,
    		KEY_READ,
    		&hKey) == ERROR_SUCCESS)
    	{
    		if( ReadRegistryString(hKey,"ProcessorNameString", &szReturnValue) == TRUE)
    		{
    			printf("The returned value is %s\n", szReturnValue);
    			RegCloseKey(hKey); 
    		}
    		else printf("ReadRegistryString failed\n");
    	}
    	RegCloseKey(hKeyRemote); 
    	return 0;
    }

  5. #5
    Registered User
    Join Date
    Apr 2007
    Posts
    137
    Just use standards apis for such basic things.
    All the code is in MSDN, as always.
    Copy-paste => done in 5 minutes...

  6. #6
    Registered User
    Join Date
    Mar 2005
    Location
    Mountaintop, Pa
    Posts
    1,058
    And don't forget usenet
    news://comp.os.ms-windows.programmer.win32

    This has been discussed many times on usenet

  7. #7
    Registered User
    Join Date
    Nov 2007
    Posts
    22
    hi gang,

    Thanks for all the suggestions, i will begin my coding conquest!! ha!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Project ideas.
    By Wraithan in forum A Brief History of Cprogramming.com
    Replies: 5
    Last Post: 04-25-2009, 03:29 PM
  2. non-MFC DLL with MFC app question.
    By Kempelen in forum Windows Programming
    Replies: 10
    Last Post: 08-20-2008, 07:11 AM
  3. yhatzee, small straight
    By uglyjack in forum C++ Programming
    Replies: 2
    Last Post: 06-13-2002, 03:09 AM
  4. Reading text in another app
    By Unregistered in forum C++ Programming
    Replies: 3
    Last Post: 03-12-2002, 09:45 AM
  5. Small app ideas
    By dirkduck in forum A Brief History of Cprogramming.com
    Replies: 4
    Last Post: 02-15-2002, 08:57 PM