Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C++ C Windows VC++
0 down vote favorite

 
hi guys i tried to find a sollution like windows os does when i install a multifunction printer (that has a scanner and fax and printers and .....) i want to access to those device on vc++ i did a snipet of code that allows me to get the list of available printers but i want to enumirate what a printer has like internal devices
 
example >> printer : hp xxy
 
has a scanner : zyw
 
has a fax : abc
 
---------------
 
printer : samsung
 
has a phone
 
has a fax : abc
 
---------------
 
code for colleciton of available printers
 
void outAllDevicesDrivers()
{
    //>> try to get all drivers of printers
    unsigned long level =6; // equivalent to DWORD
    DRIVER_INFO_6 * listOfDrivers;  // appropiete driver params
    unsigned long pointedSizeOfDriverInfo;
    unsigned long sizeOfDriverInfo;
    unsigned long sizeOfStructure;
    int result;
    EnumPrinterDrivers(
            NULL, //context of search local Drivers
            NULL, // Environment of search
            level,
            NULL ,// collection 
            0,    // the buffer
            &sizeOfDriverInfo,
            &sizeOfStructure
        );
    cout<<"the size of driver info "<<sizeOfDriverInfo<<endl;
    //>> allocating the required space
    if(sizeOfDriverInfo>0)
    {
        //cout<<"the number of collection "<<sizeOfDriverInfo/sizeof(DRIVER_INFO_6)<<endl;
    listOfDrivers=new DRIVER_INFO_6[sizeOfDriverInfo];
 
    result=EnumPrinterDrivers(
        NULL, //context of search local Drivers
        NULL, // Environment of search
        level,
        (LPBYTE)listOfDrivers ,// collection 
        sizeOfDriverInfo ,     // the buffer
        &sizeOfDriverInfo,
        &sizeOfStructure
    );
 

    if(result>0)
    {
        cout<<"the size of collection "<<sizeOfStructure<<endl;
        for(int index=0;index<sizeOfStructure;index++)
        // for(int index=sizeOfStructure-1;index>=0;index--) reverse loop 
        {
            cout<<" ------------------------------------------------------------- "<<endl;
                //wcout<<"Driver Name "<<listOfDrivers[index].<<endl;
            wcout<<"Driver Name "<<listOfDrivers[index].pName<<endl;
            wcout<<"Driver path "<<listOfDrivers[index].pDriverPath<<endl;
            //wcout<<"DriverType  "<<listOfDrivers[index].pDependentFiles<<endl;
            wcout<<"platform : "<<listOfDrivers[index].pEnvironment<<endl;
            if(listOfDrivers[index].pszHardwareID)
                wcout<<"HardWare ID : "<<listOfDrivers[index].pszHardwareID<<endl;
            if(listOfDrivers[index].dwlDriverVersion)
                wcout<<"Driver Version : "<<listOfDrivers[index].dwlDriverVersion<<endl;
            if(listOfDrivers[index].pConfigFile)
                wcout<<"Driver configuration : "<<listOfDrivers[index].pConfigFile<<endl;
            if(listOfDrivers[index].pDependentFiles)
                wcout<<"Driver dependecies  : "<<listOfDrivers[index].pDependentFiles<<endl;
            if(listOfDrivers[index].pszMfgName)
                wcout<<"Driver Manufacture  : "<<listOfDrivers[index].pszMfgName<<endl;
 
            cout<<""<<endl;
        }
 

    }
    //>>

        //for(int index=0;index

 

 
        //>> free the space 
        delete [] listOfDrivers;
}
 
}
 
is there any idea ?
 
i did this but i don't know what next
	//SetupDiGetClassDevs
	// GUID_DEVINTERFACE_IMAGE defined in ==> Wiaintfc.h
	// i think it extends from a handler 
	 HDEVINFO deviceHandler;
	 // data 
	SP_DEVINFO_DATA deviceInfoData;
	  unsigned long deviceCount=0; 
	 DEVPROPTYPE ulPropertyType;
	//DWORD size=0,propDataType=0;

	BYTE * propertyBuffer=0;
 
	/*
	DWORD Property;
	PDWORD PropertyRegDataType=NULL; //
	PBYTE PropertyBuffer=NULL;*/
	
	
	DWORD dataT=0;
	LPTSTR buffer=NULL;
	DWORD requiredSize;
 

	 deviceHandler= SetupDiGetClassDevsW(&GUID_DEVINTERFACE_VOLUME, NULL, NULL,DIGCF_ALLCLASSES);
		if(deviceHandler==INVALID_HANDLE_VALUE)
		{
			cout<<" handler error "<<endl;
		}
		//define size 
		deviceInfoData.cbSize=sizeof(SP_DEVINFO_DATA);
		// loop on the devices
		while(SetupDiEnumDeviceInfo(deviceHandler,deviceCount,&deviceInfoData))
		{
			++deviceCount;
			cout<<deviceCount<<endl;
 

									SetupDiGetDeviceRegistryProperty
									(
									deviceHandler,
									&deviceInfoData,
									SPDRP_DEVICEDESC,			// const property
									&dataT,		// in out NULL
									(PBYTE)buffer,//PropertyBuffer,     // in out NULL => required size
									requiredSize,//PropertyBufferSize, // in 0=========>
									&requiredSize
									);
									
								
 

			cout<<"required"<<requiredSize<<endl;
			
		
		
 

		}
 
		SetupDiDestroyDeviceInfoList(deviceHandler);
 

 
i have improved little bit the code inside the loop
 
if(	SetupDiGetDeviceRegistryProperty
									(
									deviceHandler,
									&deviceInfoData,
									SPDRP_DEVICEDESC,			// const property
									&dataT,		// in out NULL
									/**************/
									(BYTE*)buffer,//PropertyBuffer,     // in out NULL => required size
									sizeof(buffer),//PropertyBufferSize, // in 0=========>
									&requiredSize
									))
								{
								cout<<"required"<<requiredSize<<endl;
								cout<<buffer<<endl;
								_tprintf (TEXT("    Device Description: \"%s\"\n"), buffer);
								
								}
								else
								{
								cout<<" false \n"<<endl;
								}
i don't know but i don't see the scanner that is inside my printer
maybe i should change
 deviceHandler= SetupDiGetClassDevsW(NULL, TEXT("USB"),NULL, DIGCF_PRESENT|DIGCF_ALLCLASSES);
with other thing
 
and the result that gives me is
 
1
required50
0035F520
Device Description: "Concentrateur USB racine"
2
required50
0035F520
Device Description: "Concentrateur USB racine"
3
required50
0035F520
Device Description: "Concentrateur USB racine"
4
required50
0035F520
Device Description: "Concentrateur USB racine"
5
required50
0035F520
Device Description: "Concentrateur USB racine"
6
required50
0035F520
Device Description: "Concentrateur USB racine"
7
required50
0035F520
Device Description: "Concentrateur USB racine"
8
required54
0035F520
Device Description: "PÚriphÚrique USB composite"
9
required38
0035F520
Device Description: "HP Officejet J4660"
10
required66
0035F520
Device Description: "Prise en charge d?impression USB"
11
required52
0035F520
Device Description: "Officejet J4660 (DOT4USB)"
12
required54
0035F520
Device Description: "PÚriphÚrique USB composite"
13
required46
0035F520
Device Description: "PÚriphÚrique audio USB"
14
required52
0035F520
Device Description: "PÚriphÚrique d?entrÚe USB"
15
required52
0035F520
Device Description: "PÚriphÚrique d?entrÚe USB"
16
required52
0035F520
Device Description: "PÚriphÚrique d?entrÚe USB"
17
required54
0035F520
Device Description: "PÚriphÚrique USB composite"
18
required46
0035F520
Device Description: "PÚriphÚrique vidÚo USB"
007E5828
Appuyez sur une touche pour continuer...
Posted 8-Jan-13 7:44am
Edited 9-Jan-13 23:38pm
v3
Comments
Jochen Arndt at 8-Jan-13 13:50pm
   
You may try to use the Setup API:
Use SetupDiGetClassDevs() to access specific classes or just all classes and enumerate the devices with SetupDiEnumDeviceInfo(). Then get the properties like SPDRP_DEVICEDESC for each device and check for identical manufacturer and model sub strings.
 
Posted as comment because I don't know if this can be achieved this way. Getting the info will work, but the properties may not contain enough information to identify devices belonging to a specific printer.
merousoft at 9-Jan-13 13:19pm
   
i did what u told me but i don't know what next
Jochen Arndt at 9-Jan-13 13:38pm
   
You should pass 0 for the buffer size when requesting the size rather than passing the var requiredSize (it is usually not zero with the next call when there are multiple devices).
 
Then allocate the buffer for the property string and retrieve it:
buffer = new TCHAR[requiredSize / sizeof(TCHAR)];
SetupDiGetDeviceRegistryProperty(...);
cout<<buffer<<endl;
delete [] buffer;
buffer = NULL;
 
You may also use a buffer of fixed size (e.g. 512 wide chars / 1024 bytes; that should be enough for all strings).
 
Now you should have the description string printed (the same string as displayed in the hardware control panel).
merousoft at 10-Jan-13 5:22am
   
yea did it and i have a listing but what really what i'm looking for is to be able to deal with components example i have a printer that containts a scanner so i need to get access to this scanner provided by this printer
Jochen Arndt at 10-Jan-13 5:33am
   
In my first post i said that there may be not enough information to get what you want. But you should have a look on the hardware control panel to see how you scanner is listed there. Most information shown there can be retrieved using the Setup API. Besides the device description you may also get other properties like the user friendly name SPDRP_FRIENDLYNAME.
 
Finally you have to get the name, model, and manufacturere of your printer and check if other devices match in some way.
JackDingler at 8-Jan-13 14:42pm
   
Jochen is right. These devices are controlled by multiple drivers. A different driver for each function.
 
You'll need to iterate these different driver types separately.
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

You can do this by enumerating USB devices and reading its descriptors.
For USB devices the internal hierarchy is as follows -
Device ---contains--> Configuration --contains--> Interface --contains--> Endpoints.
 
For a multi-function device each function will have an interface each.
So any USB device having multiple interfaces is a multi-function device.
  Permalink  
Comments
merousoft at 10-Jan-13 4:50am
   
yea this is what i'm trying to do but how to get config is there any specifique method ? or is there any possibility to fetch devices from by category ?
«_Superman_» at 10-Jan-13 6:16am
   
Open the root hub and use DeviceIoControl to send IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION.
merousoft at 10-Jan-13 8:23am
   
is there any code snippet or example that shows this process ?
and if is there some methods to enumerate PnP manager ?
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

I don't think it's possible. The system can tell what printers exist, but not if they are also a scanner, etc. The most you can do, is notice that a scanner is also connected, and perhaps compare their names.
  Permalink  

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



Advertise | Privacy | Mobile
Web01 | 2.8.1411023.1 | Last Updated 10 Jan 2013
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100