Well, i we're working on a CPU Controller, which shows all CPU Data. I've managed to get Windows Version, Windows Service Pack, Processor Name, Processor Speed, Processor Identifier(Though Registry Vals).
But now i don't have any idea of how to get the processor Instructions, Caches, Video Card Information (Video Card Name, Available Memory, Total Memory), Southbridge Information (Ethernet Information)
Well, i've been loking on WinAPI but i get it very hard to work. I've looked over google 3 hours but nothing. :/ Any idea? :(
Have you looked at WMI ? This appears to suggest you can get SouthBridge info through WMI.
Gonna expand cppanda's answer a bit:
Concerning video cards, there's sometimes more than one in the system. The best way to get oodles n oodles of information on them is to use DirectX.
If it's meant to be compatible with Vista and up, you can use DXGI, which is cleaner and easier to use in my opinion.
First things first, you'll need to create a DXGI factory...
IDXGIFactory* DXGIFactoryPtr = 0;
HRESULT RetVal = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&DXGIFactoryPtr);
if (FAILED(RetVal)) {/*Error Checking*/;}
then use it to loop through each adapter...
unsigned short I = 0;
IDXGIAdapter* AdapterPtr = 0;
std::vector<IDXGIAdapter*> Adapters;
while (DXGIFactoryPtr->EnumAdapters(I, &AdapterPtr) != DXGI_ERROR_NOT_FOUND)
{
Adapters.push_back(AdapterPtr);
++I;
}
From here, you can see if Direct3D 10 is supported:
if (Adapters[I]->CheckInterfaceSupport(__uuidof(ID3D10Device), 0) == S_OK)
{ /*D3D10 is supported for this device*/; }
Enumerate attached outputs [I.E. Moniters], which could be useful for checking which resolutions are supported and such:
unsigned short J = 0;
IDXGIOutput* OutputPtr = 0;
std::vector<IDXGIOutput*> Outputs;
while (Adapter[I]->EnumOutputs(J, &OutputPtr) != DXGI_ERROR_NOT_FOUND)
{
Outputs.push_back(OutputPtr);
++J;
}
and get a description:
DXGI_ADAPTER_DESC AdapterDescription;
Adapter[I]->GetDesc(&AdapterDescription);
AdapterDescription has the fields Description, VenderId, DeviceId, SubSysId, Revision, DedicatedVideoMemory, DedicatedSystemMemory, SharedSystemMemory, and AdapterLuid.
AdapterLuid is a system specific unique identifier for the card, but all the others should be very obvious given the names.
Beyond that, it becomes vendor specific I think.
For DirectX 9, which is available for Windows 2000 up, it's a bit different. First, you have to create the core Direct3D9 object:
IDirect3D9* D3D9 = Direct3DCreate9(D3D_SDK_VERSION);
if (D3D9 == 0)
{ /* Error checking*/; }
Then get the adapter count:
unsigned short AdapterCount = (unsigned short)D3D9->GetAdapterCount();
Then loop through them, getting their identifiers:
D3DADAPTER_IDENTIFIER9* Identifiers = new D3DADAPTER_IDENTIFIER9[AdapterCount];
HRESULT RetVal = 0;
for (unsigned short I = 0; I < AdapterCount; ++I)
{
RetVal = D3D9->GetAdapterIdentifier(I, 0, &Identifiers[I]);
if (FAILED(RetVal))
{ /* Error checking*/; }
}
Again, most of the fields should be self explanitory. WHQLLevel is information on if and when Microsoft tested that driver's compatability with Windows, and for the most part can be safely ignored. Using close to the same method above, you can also acquire a device's capabilities using GetDeviceCaps, which would give you more information.
As cppanda said, you can use IDirect3DDevice9::GetAvailableTextureMem(), but that requires you to create the device before querying it. Anything the above two don't indicate require creating the device before retrieving it.
Hope that helps~
[Side note, a lot of this was pulled out of the DirectX SDK so code's theirs, not mine.]
Take a look at:
MEMORYSTATUSEX status;
GlobalMemoryStatusEx(&status);
For RAM and Virtual RAM
For video memory
vista:
CreateDXGIFactory API via GetProcAddress()
Below vista, d3d9 API
GetAvailableTextureMemory()
Well, the CPUID instruction gives a bit of info. Not all that you need, but it's a start.
Related
i am currently trying to make some sort of CPU usage overview for my DirectX program, but it seems that i am not able to get this information through PdhAddCounter().
My code looks like this:
status = PdhOpenQuery(NULL, 0, &m_queryHandle);
if(status != ERROR_SUCCESS)
{
m_canReadCpu = false;
}
status = PdhAddCounter(m_queryHandle, TEXT("\\Processor(_Total)\\% processor time"), 0, &m_counterHandle);
if(status != ERROR_SUCCESS)
{
m_canReadCpu = false;
}
After the PdhAddCounter call my status is = -1073738824, wich causes the program to fail.
Im using a Windows 7 64bit system, do i have to make something different in a 64bit environment?
Thanks for any help.
Remember: PdhAddCounter is locale sensible.
The response -1073738824 means PDH_CSTATUS_NO_OBJECT=0xC0000BB8. The api didn't find that string. Are you using a non-english OS?
If you need to do a Windows XP compatible application you need to use a workaround like this: http://en.verysource.com/code/3604946_1/platforminfo.cpp.html.
For Vista and Windows 7, 8,... you can use PdhAddEnglishCounter instead.
You may also want to use GetSystemTimes kernel32 API which will free you from the dependency on pdh.dll.
See my answer here.
I want to develop a virtual webcam driver which from User mode I'll pass image to it and it will display as webcam output.
I don't want to use DirectX filter and CSourceStream etc. Because they don't work on some programs which doesn't use DirectX for capturing webcam image.
I have to write a kernel mode device driver so.
Any ideas? I tried testcap from DDK samples, but it doesn't process image from user mode and doesn't get any input, just it displays 7 colors in webcam...
Any help would be greatly appreciated.
Thanks
Thank you all!
I tried code from here:
http://tmhare.mvps.org/downloads.htm (find Capture Source Filter)
It worked well when I compiled it in Yahoo, MSN, but it crashed AIM, Internet Explorer Flash Webcam, Firefox Flash webcam and Skype... I got crash in QueryInterface after 8 time call to that, I found it with tracing it with a lot of tricks..
Now I know, it crashes on 8th call to
HRESULT CVCamStream::QueryInterface(REFIID riid, void **ppv)
8th call when it reaches to last if, I mean:
return CSourceStream::QueryInterface(riid, ppv);
It's in 17th line of Filters.cpp
Why do you think I'm getting crash??
Thank you all for guiding me to find correct solution which is DirectShow, not driver
There are several APIs from Microsoft which provide access to image data.
Twain: Used for single image capture from scanners, etc.
WIA: This seems to have degenerated to a single image codec library.
VfW: A very old (Win16) API which really works only Video-File encoding/decoding, but has support for some video acquisition.
DirectShow: previously part in the DirectX SDK, currently in the Platform SDK. This is the place to go for current (general) streaming solutions.
Windows Media/Media Foundation: This seems more to be geared at video playback/reencoding.
Manufacturer Specific Libraries: Pylon/Halcon/Imaging Control/...
DirectShow specific :
To create image acquisition devices under windows, you have to provide either a device (driver) which implements the streamclasses interfaces (or newer Avstream) or you have to write a usermode COM object which has to be added to the VideoInputCategory enumerator.
The Avstream sample provides everything for a real image acquisition device. Only the lower layer for the actual device really is missing.
If you can design a device, you should either create it DCAM or UVC compatible. For both there are built-in drivers supplied by windows.
How to write a software source device :
You have to create a DirectShow filter which provides at least one output pin and register this under the VideoInputCategory. There may be several interfaces certain applications require from a capture application, but these depend on the application itself. Simple applications to try out filters are GraphEdit and AMCap which are supplied in the Plattform SDK.
Some code :
#include <InitGuid.h>
#include <streams.h>
const AMOVIESETUP_MEDIATYPE s_VideoPinType =
{
&MEDIATYPE_Video, // Major type
&MEDIATYPE_NULL // Minor type
};
const AMOVIESETUP_PIN s_VideoOutputPin =
{
L"Output", // Pin string name
FALSE, // Is it rendered
TRUE, // Is it an output
FALSE, // Can we have none
FALSE, // Can we have many
&CLSID_NULL, // Connects to filter
NULL, // Connects to pin
1, // Number of types
&s_VideoPinType // Pin details
};
const AMOVIESETUP_FILTER s_Filter =
{
&CLSID_MyFilter, // Filter CLSID
L"bla", // String name
MERIT_DO_NOT_USE, // Filter merit
1, // Number pins
&s_VideoOutputPin // Pin details
};
REGFILTER2 rf2;
rf2.dwVersion = 1;
rf2.dwMerit = MERIT_DO_NOT_USE;
rf2.cPins = 1;
rf2.rgPins = s_Filter.lpPin;
HRESULT hr = pFilterMapper->RegisterFilter( CLSID_MyFilter, _FriendlyName.c_str(), 0,
&CLSID_VideoInputDeviceCategory, _InstanceID.c_str(), &rf2 );
if( FAILED( hr ) )
{
return false;
}
std::wstring inputCat = GUIDToWString( CLSID_VideoInputDeviceCategory );
std::wstring regPath = L"CLSID\\" + inputCat + L"\\Instance";
win32_utils::CRegKey hKeyInstancesDir;
LONG rval = openKey( HKEY_CLASSES_ROOT, regPath, KEY_WRITE, hKeyInstancesDir );
if( rval == ERROR_SUCCESS )
{
win32_utils::CRegKey hKeyInstance;
rval = createKey( hKeyInstancesDir, _InstanceID, KEY_WRITE, hKeyInstance );
....
_InstanceID is a GUID created for this 'virtual device' entry.
You can not decide how other program would call your driver. Most of programs will use DirectShow. Some would use the win3.x technology VFW. Many new programs, including Windows XP's scanner and camera wizard, may call you via the WIA interface. If you do not want to implement all that, you need to at least provide the DirectShow interface via WDM and let vfwwdm32.dll gives you a VFW interface, or write your own VFW driver.
How to get the unique number (serial number/ID) for Processor (CPU), SCSI, Display, and IDE using C++ program other than WMI and asm code?
Since you mention WMI, I assume you are working on Windows. Lookup GetVolumeInformation().
On Windows you can get CPU info from the environment variable *PROCESSOR_** , you can parse the volume serial number from vol, the MAC address from route print
If you want to make it cross-platform (and if this is for software licensing) then an open source platform like Linux raises the problem to a whole new level anyway and requires a different approach. However you can still get a lot of the info by parsing the output from standard tools.
You really should consider WMI. In the old days, the BIOS would have been helpful but its all been replaced by the HAL.
CodeProject is always worth searching in cases like this.
How To Get Hardware Information
The below is the code I use to retrieve the hard drive serial for a game, so that cheaters are permanently banned (and they can't get back in without getting a new drive!):
string GetMachineID()
{
// LPCTSTR szHD = "C:\\"; // ERROR
string ss;
ss = "Err_StringIsNull";
UCHAR szFileSys[255],
szVolNameBuff[255];
DWORD dwSerial;
DWORD dwMFL;
DWORD dwSysFlags;
int error = 0;
bool success = GetVolumeInformation(LPCTSTR("C:\\"), (LPTSTR)szVolNameBuff,
255, &dwSerial,
&dwMFL, &dwSysFlags,
(LPTSTR)szFileSys,
255);
if (!success) {
ss = "Err_Not_Elevated";
}
std::stringstream errorStream;
errorStream << dwSerial;
return string(errorStream.str().c_str());
}
Although there is a potential bug whereupon if Windows is installed onto a drive other than C:\, this is an easy fix.
I need a way to determine whether the computer running my program is joined to any domain. It doesn't matter what specific domain it is part of, just whether it is connected to anything. I'm coding in vc++ against the Win32 API.
Straight from Microsoft:
How To Determine If a Windows NT/Windows 2000 Computer Is a Domain Member
This approach uses the Windows API. From the article summary:
This article describes how to
determine if a computer that is
running Windows NT 4.0 or Windows 2000
is a member of a domain, is a member
of a workgroup, or is a stand-alone
computer using the Local Security
Authority APIs.
The article also provides sample code for a small program that outputs whether the computer the program is running on is part of a domain, part of a workgroup, or a standalone computer.
I think the NetServerEnum function will help you in what you want; I would ask for the primary domain controllers with the SV_TYPE_DOMAIN_CTRL constant for servertype parameter. If you don't get any, then you're not in a domain.
The code in the MSDN sample is a little outdated. This is the function I came up with that works.
bool ComputerBelongsToDomain()
{
bool ret = false;
LSA_OBJECT_ATTRIBUTES objectAttributes;
LSA_HANDLE policyHandle;
NTSTATUS status;
PPOLICY_PRIMARY_DOMAIN_INFO info;
// Object attributes are reserved, so initialize to zeros.
ZeroMemory(&objectAttributes, sizeof(objectAttributes));
status = LsaOpenPolicy(NULL, &objectAttributes, GENERIC_READ | POLICY_VIEW_LOCAL_INFORMATION, &policyHandle);
if (!status)
{
status = LsaQueryInformationPolicy(policyHandle, PolicyPrimaryDomainInformation, (LPVOID*)&info);
if (!status)
{
if (info->Sid)
ret = true;
LsaFreeMemory(info);
}
LsaClose(policyHandle);
}
return ret;
}
Here is a dead simple approach I don't see mentioned.
TCHAR UserDnsDomain[128] = { 0 };
DWORD Result = 0;
Result = GetEnvironmentVariable("USERDNSDOMAIN", UserDnsDomain, sizeof(UserDnsDomain));
if (Result == 0 || Result >= sizeof(UserDnsDomain) || GetLastError() == ERROR_ENVVAR_NOT_FOUND)
{
return(FALSE); // Not logged in to a domain
}
This is predicated on the idea that if the user who is running this code is not currently logged in to a domain, then the USERDNSDOMAIN environment variable will be empty or unavailable. But there are some caveats you should think about.
Pros:
Very easy to implement.
99% reliable.
Cons:
May fail or return false results if the computer is domain joined, but the user executing this code is logged on to that computer with a local account.
May fail or return false results if the computer is domain joined, but network connectivity to a domain controller was unavailable at the time of logon/user logged on with cached credentials.
You can check the registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon for the value of 'CachePrimaryDomain'.
Avoid LSA which is a wrong method.
You must use DS api (2 lines of code)
what about from the name of the computer?
edit: this was a crapy 'answer' from way back. What I meant was cheching for the form domain\name in the computer name. That of course implies that you do know the name of the domain, it does not solves the issue of just knowing if the computer is in any domain.
As part of a JavaScript Profiler for IE 6/7 I needed to load a custom debugger that I created into IE. I got this working fine on XP, but couldn't get it working on Vista (full story here: http://damianblog.com/2008/09/09/tracejs-v2-rip/).
The call to GetProviderProcessData is failing on Vista. Anyone have any suggestions?
Thanks,
Damian
// Create the MsProgramProvider
IDebugProgramProvider2* pIDebugProgramProvider2 = 0;
HRESULT st = CoCreateInstance(CLSID_MsProgramProvider, 0, CLSCTX_ALL, IID_IDebugProgramProvider2, (void**)&pIDebugProgramProvider2);
if(st != S_OK) {
return st;
}
// Get the IDebugProgramNode2 instances running in this process
AD_PROCESS_ID processID;
processID.ProcessId.dwProcessId = GetCurrentProcessId();
processID.ProcessIdType = AD_PROCESS_ID_SYSTEM;
CONST_GUID_ARRAY engineFilter;
engineFilter.dwCount = 0;
PROVIDER_PROCESS_DATA processData;
st = pIDebugProgramProvider2->GetProviderProcessData(PFLAG_GET_PROGRAM_NODES|PFLAG_DEBUGGEE, 0, processID, engineFilter, &processData);
if(st != S_OK) {
ShowError(L"GPPD Failed", st);
pIDebugProgramProvider2->Release();
return st;
}
It would help to know what the error result was.
Possible problems I can think of:
If your getting permission denied, your most likely missing some requried Privilege in your ACL. New ones are sometimes not doceumented well, check the latest Platform SDK headers to see if any new ones that still out. It may be that under vista the Privilege is not assigned my default to your ACL any longer.
If your getting some sort of Not Found type error, then it may be 32bit / 64bit problem. Your debbugging API may only be available under 64bit COM on vista 64. The 32bit/64bit interoperation can be very confusing.
I'm not familiar with these interfaces, but unexpected failures in Vista may require being past a UAC prompt. Have you tried starting the debugger with admin privileges?