www.pudn.com > EnumSerial.rar > EnumSerial.cpp, change:2015-02-21,size:7542b


#include "stdafx.h" 
#include <Setupapi.h> 
#include "GlobalDef.h" 
#include "resource.h" 
#include "EnumSerial.h" 
#include "config.h" 
#include "debug.h" 
#include "CommonFuns.h" 
 
EnumSerial::EnumSerial(void) 
{ 
    //Initializing list 
    InitializeListHead(&serList); 
} 
EnumSerial::~EnumSerial(void) 
{ 
    //Empty list 
    RemoveAll(&serList); 
} 
void EnumSerial::RemoveAll(ListEntry *list) 
{ 
    //Empty list 
#if defined(_DEBUG) 
    int         i = 0; 
#endif 
    ListEntry   *node; 
    SSerInfo    *pInfo; 
    for(node = serList.Flink;node != &serList ;){ 
        pInfo   = CONTAINING_RECORD(node, SSerInfo, Link); 
        node    = node->Flink; 
        RemoveEntryList(&pInfo->Link); 
        delete  pInfo; 
#if defined(_DEBUG) 
        i ++; 
#endif 
    } 
#if defined(_DEBUG) 
    LDEGMSGW(DEBUG_LOG,(TEXT("@@RemoveAll():%d\r\n"),i)); 
#endif 
     
} 
ListEntry *EnumSerial::EnumSerialPorts(BOOL bIgnoreBusyPorts) 
{ 
    OSVERSIONINFO   vi; 
    int             startdex; 
    int             enddex; 
    ListEntry       *node; 
    SSerInfo        *pInfo; 
    RemoveAll(&serList); 
    vi.dwOSVersionInfoSize  = sizeof(vi); 
    if (!::GetVersionEx(&vi)) { 
        LDEGMSGW(DEBUG_LOG,(TEXT("@@GetVersionEx:ERROR(err=%d)\r\n"),GetLastError())); 
        return NULL; 
    } 
    // Handle windows 9x and NT4 specially 
    if (vi.dwMajorVersion < 5) { 
        if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT){ 
            EnumPortsWNt4(&serList); 
        } else { 
            EnumPortsW9x(&serList); 
        } 
    } else { 
        // Win2k and later support a standard API for 
        // enumerating hardware devices. 
        EnumPortsWdm(&serList); 
    } 
    for (node = serList.Flink; node != &serList; node = node->Flink) 
	{ 
        pInfo = CONTAINING_RECORD(node, SSerInfo, Link); 
		if (bIgnoreBusyPorts) { 
			// Only display ports that can be opened for read/write 
			HANDLE hCom = CreateFile(pInfo->strDevPath, 
				GENERIC_READ | GENERIC_WRITE, 
				0,    /* comm devices must be opened w/exclusive-access */ 
				NULL, /* no security attrs */ 
				OPEN_EXISTING, /* comm devices must use OPEN_EXISTING */ 
				0,    /* not overlapped I/O */ 
				NULL  /* hTemplate must be NULL for comm devices */ 
				); 
			if (hCom == INVALID_HANDLE_VALUE) { 
				// It can't be opened; remove it. 
                RemoveEntryList(&pInfo->Link); 
				delete pInfo;        
				continue; 
			} else { 
				// It can be opened! Close it and add it to the list 
				::CloseHandle(hCom); 
			} 
		} 
		// Come up with a name for the device. 
		// If there is no friendly name, use the port name. 
         
		if (0 == wcslen(pInfo->strFriendlyName)){ 
            wsprintf(pInfo->strFriendlyName,pInfo->strPortName); 
        } 
 
		// If there is no description, try to make one up from 
		// the friendly name. 
		if (0 == wcslen(pInfo->strPortDesc)) { 
			// If the port name is of the form "ACME Port (COM3)" 
			// then strip off the " (COM3)" 
            wsprintf(pInfo->strPortDesc,pInfo->strFriendlyName); 
            startdex    = FindStrW(0,pInfo->strPortDesc,wcslen(pInfo->strPortDesc),TEXT(" ("),wcslen(TEXT(" ("))); 
            enddex      = FindStrW(0,pInfo->strPortDesc,wcslen(pInfo->strPortDesc),TEXT(")"),wcslen(TEXT(")"))); 
			if (startdex > 0 && enddex == (wcslen(pInfo->strPortDesc) -1 )){ 
                memset(pInfo->strPortDesc,0,sizeof(pInfo->strPortDesc)); 
                memcpy(pInfo->strPortDesc,pInfo->strFriendlyName,startdex*sizeof(TCHAR)); 
            } 
		} 
	} 
    if(!IsListEmpty(&serList)) { 
        return &serList; 
    } else { 
        return NULL; 
    } 
} 
void EnumSerial::EnumPortsWdm(ListEntry *list) 
{ 
    SSerInfo    *psi; 
    HDEVINFO    hDevInfo        = INVALID_HANDLE_VALUE; 
    //BOOL        bRet            = FALSE; 
    GUID        *guidDev        = (GUID*) &GUID_CLASS_COMPORT; 
    BOOL        bOk             = TRUE; 
    DWORD       dwDetDataSize; 
    DWORD       err; 
    TCHAR       fname[256]; 
    TCHAR       strDevPath[256]; 
    TCHAR       desc[256]; 
    TCHAR       locinfo[256]; 
    BOOL        bSuccess; 
    BOOL        bUsbDevice; 
    SP_DEVICE_INTERFACE_DATA        ifcData; 
    SP_DEVICE_INTERFACE_DETAIL_DATA *pDetData; 
    SP_DEVINFO_DATA                 devdata; 
    hDevInfo = SetupDiGetClassDevs( guidDev, 
                                    NULL, 
                                    NULL, 
                                    DIGCF_PRESENT | DIGCF_DEVICEINTERFACE 
                                    ); 
    if(INVALID_HANDLE_VALUE == hDevInfo){ 
        LDEGMSGW(DEBUG_LOG,(TEXT("@@SetupDiGetClassDevs():ERROR(err=%d)\r\n"),GetLastError())); 
        return ; 
    } 
    dwDetDataSize       =   sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + 256; 
    pDetData            = (SP_DEVICE_INTERFACE_DETAIL_DATA*) new char[dwDetDataSize]; 
    ifcData.cbSize      = sizeof(SP_DEVICE_INTERFACE_DATA); 
    pDetData->cbSize    = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); 
    for (DWORD ii=0; bOk; ii++) { 
        bOk = SetupDiEnumDeviceInterfaces(hDevInfo,NULL, guidDev, ii, &ifcData); 
        if (bOk) { 
            // Got a device. Get the details. 
            devdata.cbSize = sizeof(SP_DEVINFO_DATA); 
            bOk = SetupDiGetDeviceInterfaceDetail(hDevInfo,&ifcData, pDetData, dwDetDataSize, NULL, &devdata); 
            if (bOk) { 
                wsprintf(strDevPath,pDetData->DevicePath); 
                bSuccess    = SetupDiGetDeviceRegistryProperty(hDevInfo, &devdata, SPDRP_FRIENDLYNAME, NULL,(PBYTE)fname, sizeof(fname), NULL); 
                bSuccess    = bSuccess && SetupDiGetDeviceRegistryProperty(hDevInfo, &devdata, SPDRP_DEVICEDESC, NULL,(PBYTE)desc, sizeof(desc), NULL); 
                bUsbDevice  = FALSE; 
                if (SetupDiGetDeviceRegistryProperty(hDevInfo, &devdata, SPDRP_LOCATION_INFORMATION, NULL,(PBYTE)locinfo, sizeof(locinfo), NULL)) { 
                    bUsbDevice = (_tcsncmp(locinfo, TEXT("USB"), 3)==0); 
                } 
                if (bSuccess) { 
                    psi = new SSerInfo(); 
                    wsprintf(psi->strDevPath,strDevPath); 
                    //si.strDevPath       = strDevPath; 
                    wsprintf(psi->strFriendlyName,fname); 
                    //si.strFriendlyName  = fname; 
                    wsprintf(psi->strPortDesc,desc); 
                    //si.strPortDesc      = desc; 
                    wsprintf(psi->strDevPath,strDevPath); 
                    psi->bUsbDevice       = bUsbDevice; 
                    //asi.Add(si); 
                    InsertTailList(list,&psi->Link); 
                } 
            } else { 
                LDEGMSGW(DEBUG_LOG,(TEXT("@@SetupDiGetDeviceInterfaceDetail():ERROR(err=%d)\r\n"),GetLastError())); 
            } 
        } else { 
            err = GetLastError(); 
            if (err != ERROR_NO_MORE_ITEMS) { 
                LDEGMSGW(DEBUG_LOG,(TEXT("err != ERROR_NO_MORE_ITEMS\r\n"))); 
            } 
        } 
    } 
    if (NULL != pDetData ) { 
        delete[] pDetData; 
    } 
    if (INVALID_HANDLE_VALUE != hDevInfo){  
        // must delete the returned device information set when it is no longer needed by calling 
        SetupDiDestroyDeviceInfoList(hDevInfo); 
        hDevInfo    = INVALID_HANDLE_VALUE; 
    } 
} 
 
void EnumSerial::EnumPortsWNt4      (ListEntry *) 
{ 
 
 
} 
void EnumSerial::EnumPortsW9x       (ListEntry *) 
{ 
 
 
} 
void EnumSerial::SearchPnpKeyW9x    (HKEY hkPnp, BOOL bUsbDevice,ListEntry *) 
{ 
 
 
}