Page 1 of 2

Exita vreo functie API care sa 'stie' despre sistem ?

Posted: 19 Oct 2009, 20:54
by mesajflaviu
Exista vreo functie API ( sau cel mai bine vreo clasa MFC !!! ) cu care sa se poata interoga lucruri mai deosebite despre sistem : de exemplu ce viteza are procesorul pe care ruleaza aplicatia , sau eventual din ce familie este , cat RAM exista pe masina , memoria video , etc. ?
Am vazut ca exista functii cu care se poate afla cate partitii exista si de ce tip sant ( fixe , de retea , optice , etc. ) si ce spatiu exista pe ele ( liber , ocupat ... ). Am cautat ceva asemanator pentru componentele ce le-am scris mai sus , dar ... n-am gasit ...

Re: Exita vreo functie API care sa 'stie' despre sistem ?

Posted: 19 Oct 2009, 21:24
by MrSmersh
GetSystemInfo http://msdn.microsoft.com/en-us/library ... S.85).aspx?
Si aici e lista de functii care dau info despre system http://msdn.microsoft.com/en-us/library ... S.85).aspx
Si cele mai multe info se obtin cu Windows Managment Instrumentation (WMI)http://msdn.microsoft.com/en-us/library ... S.85).aspx. Asta se poate pe unele OS mai vechi sa nu mearga tot si e si ceva mai ciudat putin de apelat.

Re: Exita vreo functie API care sa 'stie' despre sistem ?

Posted: 19 Oct 2009, 23:01
by Ovidiu Cucu
Pai dac-ar fi o functie sa stie totul despre sistem, celelalte s-ar supara nu-i asa? ;)

Cata memorie RAM este in sistem am spus aici.
Informatii despre procesor poti obtine cu instuctiunea de asamblare CPUID. Marius a scris un mic articol despre asta.

WMI e o biblioteca ce pretinde ca le stie pe toate, dar e destul de greoi. Poti porni sa intelegi cum se foloseste de la exemplele din MSDN (vezi link-ul dat de MrSmersh) sau de la acest FAQ. Ideal ar fi sa faci un wrapper "mai uman" peste WMI, altfel e curata scarpinare dupa cap. :)

Re: Exita vreo functie API care sa 'stie' despre sistem ?

Posted: 21 Oct 2009, 22:06
by mesajflaviu
Referitor la topic-ul [WinAPI] Cata memorie RAM este in sistem? , unde gasesc functia GlobalMemoryStatusEx , caci in VC6 am cautat-o in lung si in lat , dar n-am gasit-o ... in <winbase.h> exista numai GlobalMemoryStatus ... e vorba de o versiune mai noua a acestui fisier ?

Re: Exita vreo functie API care sa 'stie' despre sistem ?

Posted: 22 Oct 2009, 09:53
by Marius Bancila
Ce mesaje de eroare primesti? Din MSDN:

Code: Select all

Client
 Requires Windows Vista, Windows XP, or Windows 2000 Professional. 
Server
 Requires Windows Server 2008, Windows Server 2003, or Windows 2000 Server. 
Header
 Declared in Winbase.h; include Windows.h. 
Library
 Use Kernel32.lib. 
DLL
 Requires Kernel32.dll. 
Deci pe Win 2K si XP exista deja. Intrebarea e: ai instalat Platform SDK (sau Windows SDK cum se numeste mai nou)?

Re: Exita vreo functie API care sa 'stie' despre sistem ?

Posted: 22 Oct 2009, 13:43
by Ovidiu Cucu
Cel mai bine, asa cum a zis deja Marius, e sa faci download si sa instalez o versiune noua de Windows SDK.
Sunt multe alte functii pe care le gasesti in help/MSDN dar nu sunt continute in SDK-ul din VS6.0.
Alta cale, la carpeala, este sa apelezi LoadLibrary (sau GetModuleHandle) si GetProcAddress.

Code: Select all

#if _MSC_VER < 1300
typedef struct _MEMORYSTATUSEX 
{  
    DWORD dwLength;  
    DWORD dwMemoryLoad;  
    DWORDLONG ullTotalPhys;  
    DWORDLONG ullAvailPhys;  
    DWORDLONG ullTotalPageFile;  
    DWORDLONG ullAvailPageFile;  
    DWORDLONG ullTotalVirtual;  
    DWORDLONG ullAvailVirtual;  
    DWORDLONG ullAvailExtendedVirtual;
} MEMORYSTATUSEX, *LPMEMORYSTATUSEX;

typedef BOOL (WINAPI *pGMSEx)(LPMEMORYSTATUSEX);
#endif // MSC_VER < 1300

Code: Select all

    MEMORYSTATUSEX msex = {0};
    msex.dwLength = sizeof(MEMORYSTATUSEX);

#if _MSC_VER < 1300
    HMODULE hModule = ::GetModuleHandle(_T("Kernel32.dll"));
    pGMSEx pFn = (pGMSEx)::GetProcAddress(hModule, "GlobalMemoryStatusEx");
    if(NULL == pFn)
    {
        AfxMessageBox(_T("GlobalMemoryStatusEx function is not supported"));
        return;
    }
    BOOL bRet = pFn(&msex);    
#else
    BOOL bRet = ::GlobalMemoryStatusEx(&msex);
#endif // MSC_VER < 1300 

Re: Exita vreo functie API care sa 'stie' despre sistem ?

Posted: 22 Oct 2009, 18:59
by mesajflaviu
Ce mesaje de eroare primesti?
La compilare nu recunostea aceasta functie ::GlobalMemoryStatusEx ( "unknow identifier" ...)
insa am instalat un SDK nou dar inca nu recunoaste VC6 aceasta functie , trebuie sa mai sap sa vad de ce ...Am vazut ca in folder-ul SDK , fisierul WinBase.h are ::GlobalMemoryStatusEx , MEMORYSTATUSEX ...etc., am incercat sa-l includ simplu in proiect (#include "WinBase.h"), dar tot nu merge ...

Re: Exita vreo functie API care sa 'stie' despre sistem ?

Posted: 22 Oct 2009, 19:29
by Ovidiu Cucu
Trage mai intai un ochi in MSDN la WINVER.

Re: Exita vreo functie API care sa 'stie' despre sistem ?

Posted: 27 Oct 2009, 11:46
by mesajflaviu
Ca o alternativa la folosirea functiilor GlobalMemoryStatus si GlobalMemoryStatusEx , RAM-ul se mai poate citi si din registrii , din HKEY_LOCAL_MACHINE,Hardware\\ResourceMap\\System Resources\\Physical Memory din cheia .Translated . Am gasit undeva un model de citire si "descifrare" a marimii memoriei :

Code: Select all

	CString sRam = "unknow";

	const DWORD dwMBFactor = 0x00100000;

	struct _mi {
		LARGE_INTEGER Address;
		DWORD Length;
		DWORD Reserved;
	};

#define MI_LEN sizeof(struct _mi)

	typedef struct _phy_mem_info {
		DWORD BusCount;
		DWORD MemoryRangeCount;
		struct _mi* MemInfoPtr;
	}PHY_MEM_INFO;

	
	PHY_MEM_INFO* PhyMemInfo = new PHY_MEM_INFO;

	HKEY hKey;

	if(RegOpenKey(HKEY_LOCAL_MACHINE, "Hardware\\ResourceMap\\System Resources\\Physical Memory", &hKey) == ERROR_SUCCESS)
	{
		DWORD dwType = 0;
		LPBYTE lpData = NULL;

		if(RegQueryValueEx(hKey, ".Translated", 0, &dwType, NULL, &dwLength) == ERROR_SUCCESS)
		{
			lpData = (LPBYTE)malloc(dwLength);
			RegQueryValueEx(hKey, ".Translated", 0, &dwType, lpData, &dwLength);
		}

		DWORD BusCount = *(DWORD*)lpData;
		if(BusCount > 0)
		{
			LPBYTE p = lpData + 0x10;
			DWORD MemoryRangesCount = 0;
			for(DWORD i = 1; i <= BusCount; i++)
			{
				MemoryRangesCount += *(DWORD*)p;
				p = p + 0x8 + i * (*(DWORD*)p) * 0x10;
			}
			p = lpData + 0x10;

			PhyMemInfo->MemInfoPtr = (struct _mi*)malloc(MI_LEN * MemoryRangesCount);
			
			if(PhyMemInfo->MemInfoPtr != NULL)
			{
				LPBYTE pmi = NULL;
				struct _mi* ptr = PhyMemInfo->MemInfoPtr;
				for(DWORD x = 1; x <= BusCount; x++)
				{
					pmi = p + 0x8;
					
					for(DWORD j = 0; j < *(DWORD*)p; j++)
					{
						ptr->Address.LowPart = *(DWORD*)pmi;
						ptr->Address.HighPart = *(long*)(pmi + 0x4);
						ptr->Length = *(DWORD*)(pmi + 0x8);
						ptr++;
						pmi += MI_LEN;
					}

					p = p + 0x8 + i * (*(DWORD*)p) * 0x10;
				}

				PhyMemInfo->MemoryRangeCount = MemoryRangesCount;

				RegCloseKey(hKey);
				free(lpData);

				LARGE_INTEGER TotalSize = {0};

				for(DWORD k = 0; k < PhyMemInfo->MemoryRangeCount; k++)
					TotalSize.QuadPart += (PhyMemInfo->MemInfoPtr + k)->Length;

				delete []PhyMemInfo;
				
				sRam.Format("%d MB\n", TotalSize.QuadPart / dwMBFactor);
			}

		}
	}
care are rezultate la fel cu functiile mentionate mai sus. Intrebarea mea este : se poate converti codul C :

Code: Select all

lpData = (LPBYTE)malloc(dwLength);
.
.
.
free(lpData);
in cod C++ , prin folosirea operatorului new , in loc de malloc ?
Mie mi-a iesit o gogomanie de genu :

Code: Select all

lpData = new (LPBYTE)[sizeof(dwLength)];
.
.
.
delete []lpData;
la care am primit o eroare de genu :

Code: Select all

cannot convert from 'unsigned char ** ' to 'unsigned char *'

Re: Exita vreo functie API care sa 'stie' despre sistem ?

Posted: 27 Oct 2009, 12:16
by Viorel
Încearcă altfel:

Code: Select all

lpData = new BYTE[dwLength];

Re: Exita vreo functie API care sa 'stie' despre sistem ?

Posted: 27 Oct 2009, 13:53
by Ovidiu Cucu
Cum a scris deja Viorel, doar un pic mai detaliat:
  1. scoate sizeof-ul (nu era nici in codul initial), altfel o sa aloci sizeof(DWORD) bytes;
  2. lui new ii pasezi tipul si intoarce pointer la tip; deci scrii...
  3. Code: Select all

        LPBYTE lpData = NULL;
        //...
        lpData = new BYTE[dwLength];
Si o mica intrebare: gaselnita e interesanta dar pentru a intoarce total physical memory nu era suficient GlobalMemoryStatus(Ex)?

Re: Exita vreo functie API care sa 'stie' despre sistem ?

Posted: 27 Oct 2009, 21:39
by mesajflaviu
Viorel si Ovidiu , merge brici solutia voastra !!! Multumesc mult !
Si o mica intrebare: gaselnita e interesanta dar pentru a intoarce total physical memory nu era suficient GlobalMemoryStatus(Ex)?
Am evitat sa folosesc GlobalMemoryStatus sau GlobalMemoryStatusEx pentru ca : 1.GlobalMemoryStatus are limite
2.GlobalMemoryStatusEx nu functioneaza pe un sistem de operare Windows NT cu SP5 ... asa ca solutia aflarii RAM-ului din registrii mi se pare mai buna ... oricum am cosmetizat ceea ce am gasit pe net , iar in varianta finala poate fi o solutie alternativa la topic-ul [WinAPI] Cata memorie RAM este in sistem? ... poate ... :?:

Re: Exita vreo functie API care sa 'stie' despre sistem ?

Posted: 28 Oct 2009, 00:28
by Marius Bancila
mesajflaviu wrote:Am evitat sa folosesc GlobalMemoryStatus sau GlobalMemoryStatusEx pentru ca : 1.GlobalMemoryStatus are limite
2.GlobalMemoryStatusEx nu functioneaza pe un sistem de operare Windows NT cu SP5 ... asa ca solutia aflarii RAM-ului din registrii mi se pare mai buna ... oricum am cosmetizat ceea ce am gasit pe net , iar in varianta finala poate fi o solutie alternativa la topic-ul [WinAPI] Cata memorie RAM este in sistem? ... poate ... :?:
Ce sa zic, pune-te pe scris.

Re: Exita vreo functie API care sa 'stie' despre sistem ?

Posted: 28 Oct 2009, 08:09
by Ovidiu Cucu
Exista si alte alternative "via registry" la apeluri directe de funcii API. Un exemplu ar fi listarea proceselor despre care a curs un pic de cerneala aici.
Totusi, daca ar fi sa-l parafrazez pe MrSmersh: "Richter zis nashpa trecut API" :).

Doua mici observatii de ordin practic:
  1. Este greu de crezut ca exista cineva care foloseste NT4.0 pe un computer cu peste 4G RAM (dealtfel, NT-ul nici nu "vede" atata).
    Sa zicem totusi, vreun ciudat, dar...
  2. ...nu cred ca este garantat ca structurile alea tinute in registry sunt identice si la fel pe toate versinile de Windows.
Functiile API, chiar daca au mici probleme/limitari, cel putin sunt documentate.

Oricum, no problem, e bine ca sapi. Trebuie doar daca vrei intradevar "solutia universala", pe cat posibil, sa testezi pe toate sistemele posibile.

Re: Exita vreo functie API care sa 'stie' despre sistem ?

Posted: 28 Oct 2009, 10:41
by Ovidiu Cucu
mesajflaviu wrote:... solutia aflarii RAM-ului din registrii mi se pare mai buna ... oricum am cosmetizat ceea ce am gasit pe net , iar in varianta finala poate fi o solutie alternativa la topic-ul [WinAPI]Cata memorie RAM este in sistem? ... poate ... :?:
Poate, no problem.
Scrie o functie care sa functioneze, pune si-un link la articolul original (nu vreau sa fim acuzati de plagiat ;)), fa un reply la FAQ-ul cu pricina si se aproba.
De eventuale mici cosmetice ma ocup eu.