BOOL CNTServiceControlManager::EnumServices(DWORD dwServiceType, DWORD dwServiceState, void* pUserData, ENUM_SERVICES_PROC lpEnumServicesFunc) const
{
  //Validate our parameters
  ATLASSUME(m_hSCM != NULL);

  DWORD dwBytesNeeded;
  DWORD dwServices;
  DWORD dwResumeHandle = 0;
  BOOL bSuccess = EnumServicesStatus(m_hSCM, dwServiceType, dwServiceState, NULL, 0, &dwBytesNeeded, &dwServices, &dwResumeHandle);
  if (!bSuccess && GetLastError() == ERROR_MORE_DATA)
  {
    //Allocate some memory for the API
    ATL::CHeapPtr<BYTE> lpBuffer;
    if (!lpBuffer.Allocate(dwBytesNeeded))
    {
      SetLastError(ERROR_OUTOFMEMORY);
      return FALSE;
    }
  
    LPENUM_SERVICE_STATUS lpServices = reinterpret_cast<LPENUM_SERVICE_STATUS>(lpBuffer.m_pData);
    DWORD dwSize = 0;
    bSuccess = EnumServicesStatus(m_hSCM, dwServiceType, dwServiceState, (LPENUM_SERVICE_STATUS) lpServices, dwBytesNeeded, &dwSize, &dwServices, &dwResumeHandle);
    if (bSuccess)
    {
      BOOL bContinue = TRUE;
      for (DWORD i=0; i<dwServices && bContinue; i++)
        bContinue = lpEnumServicesFunc(pUserData, lpServices[i]);
    }
  }
  return bSuccess;
}
BOOL CNTScmService::QueryDescription(CString& sDescription) const
{
  //Validate our parameters
  ASSERT(m_hService != NULL);

  //Check to see if the function pointer is available
  if (m_lpfnQueryServiceConfig2 == NULL)
  {
    TRACE(_T("CNTScmService::QueryDescription, QueryServiceConfig2 function is not supported on this OS. You need to be running at least Windows 2000 to use this function\n"));
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return FALSE;
  }

  //Call through the function pointer
  DWORD dwBytesNeeded = 0;
  BOOL bSuccess = m_lpfnQueryServiceConfig2(m_hService, SERVICE_CONFIG_DESCRIPTION, NULL, 0, &dwBytesNeeded);
  if (!bSuccess && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
  {
    //Allocate some memory for the API
    ATL::CHeapPtr<BYTE> lpData;
    if (!lpData.Allocate(dwBytesNeeded))
    {
      SetLastError(ERROR_OUTOFMEMORY);
      return FALSE;
    }

    bSuccess = m_lpfnQueryServiceConfig2(m_hService, SERVICE_CONFIG_DESCRIPTION, lpData, dwBytesNeeded, &dwBytesNeeded);
    if (bSuccess)
      sDescription = (reinterpret_cast<LPSERVICE_DESCRIPTION>(lpData.m_pData))->lpDescription;
  }

  return bSuccess;
}
Exemple #3
0
BOOL CEnumerateSerial::UsingEnumPorts(CSimpleArray<UINT>& ports)
#endif
{
  //Make sure we clear out any elements which may already be in the array
#if defined CENUMERATESERIAL_USE_STL
  ports.clear();
#else
  ports.RemoveAll();
#endif  

  //Call the first time to determine the size of the buffer to allocate
  DWORD cbNeeded = 0;
  DWORD dwPorts = 0;
  EnumPorts(NULL, 1, NULL, 0, &cbNeeded, &dwPorts);

  //What will be the return value
  BOOL bSuccess = FALSE;

  //Allocate the buffer and recall
  ATL::CHeapPtr<BYTE> pPorts;
  if (pPorts.Allocate(cbNeeded))
  {
    bSuccess = EnumPorts(NULL, 1, pPorts, cbNeeded, &cbNeeded, &dwPorts);
    if (bSuccess)
    {
      PORT_INFO_1* pPortInfo = reinterpret_cast<PORT_INFO_1*>(pPorts.m_pData);
      for (DWORD i=0; i<dwPorts; i++)
      {
        //If it looks like "COMX" then
        //add it to the array which will be returned
        size_t nLen = _tcslen(pPortInfo->pName);
        if (nLen > 3)
        {
          if ((_tcsnicmp(pPortInfo->pName, _T("COM"), 3) == 0) && IsNumeric(&(pPortInfo->pName[3]), TRUE))
          {
            //Work out the port number
            int nPort = _ttoi(&(pPortInfo->pName[3]));
          #if defined CENUMERATESERIAL_USE_STL
            ports.push_back(nPort);
          #else
            ports.Add(nPort);
          #endif  
          }
        }

        pPortInfo++;
      }
    }
  }
  else
    SetLastError(ERROR_OUTOFMEMORY);        
  
  return bSuccess;
}
BOOL CNTScmService::QueryRequiredPrivileges(CNTServiceStringArray& privileges) const
{
  //Validate our parameters
  ATLASSERT(m_hService != NULL);

  //Empty our the array
#ifdef CNTSERVICE_MFC_EXTENSIONS
  privileges.RemoveAll();
#else
  privileges.clear();
#endif

  //Check to see if the function pointer is available
  if (m_lpfnQueryServiceConfig2 == NULL)
  {
    ATLTRACE(_T("CNTScmService::QueryRequiredPrivileges, QueryServiceConfig2 function is not supported on this OS. You need to be running at least Windows Vista / Windows 2008 to use this function\n"));
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return FALSE;
  }

  //Call through the function pointer
  DWORD dwBytesNeeded = 0;
  BOOL bSuccess = m_lpfnQueryServiceConfig2(m_hService, SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO, NULL, 0, &dwBytesNeeded);
  if (!bSuccess && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
  {
    //Allocate some memory for the API
    ATL::CHeapPtr<BYTE> lpBuffer;
    if (!lpBuffer.Allocate(dwBytesNeeded))
    {
      SetLastError(ERROR_OUTOFMEMORY);
      return FALSE;
    }

    bSuccess = m_lpfnQueryServiceConfig2(m_hService, SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO, lpBuffer, dwBytesNeeded, &dwBytesNeeded);
    if (bSuccess)
    {
      LPTSTR lpszStrings = reinterpret_cast<LPTSTR>(lpBuffer.m_pData);
      while (lpszStrings[0] != 0)
      {
      #ifdef CNTSERVICE_MFC_EXTENSIONS
        privileges.Add(lpszStrings);
      #else
        privileges.push_back(lpszStrings);
      #endif
        lpszStrings += (_tcslen(lpszStrings ) + 1);
      }
    }
  }

  return bSuccess;
}
BOOL CNTScmService::ChangeRequiredPrivileges(const CStringArray& privileges)
{
  //Validate our parameters
  ASSERT(m_hService != NULL);

  //Check to see if the function pointer is available
  if (m_lpfnChangeServiceConfig2 == NULL)
  {
    TRACE(_T("CNTScmService::ChangeRequiredPrivileges, ChangeServiceConfig2 function is not supported on this OS. You need to be running at least Windows Vista / Windows 2008 to use this function\n"));
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return FALSE;
  }

  //Work out the size of the buffer we will need
  DWORD dwSize = 0;
  INT_PTR nStrings = privileges.GetSize();
  for (INT_PTR i=0; i<nStrings; i++)
    dwSize += privileges.GetAt(i).GetLength() + 1; //1 extra for each NULL terminator

  //Need one second NULL for the double NULL at the end
  dwSize++;

  //Allocate some memory for the API
  ATL::CHeapPtr<TCHAR> lpBuffer;
  if (!lpBuffer.Allocate(dwSize))
  {
    SetLastError(ERROR_OUTOFMEMORY);
    return FALSE;
  }

  //Now copy the strings into the buffer
  int nCurOffset = 0;
  LPTSTR lpszString = lpBuffer.m_pData;
  for (INT_PTR i=0; i<nStrings; i++)
  {
    CString sText = privileges.GetAt(i);
    int nCurrentStringLength = sText.GetLength();
    _tcscpy_s(&lpszString[nCurOffset], nCurrentStringLength+1, sText);
    nCurOffset += (nCurrentStringLength + 1);
  }
  //Don't forgot to doubly NULL terminate
  lpszString[nCurOffset] = _T('\0');

  //Call through the function pointer
  SERVICE_REQUIRED_PRIVILEGES_INFO srpi;
  srpi.pmszRequiredPrivileges = lpBuffer.m_pData;
  return m_lpfnChangeServiceConfig2(m_hService, SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO, &srpi);
}
BOOL ComPortDiscovery::QueryDeviceDescription(HDEVINFO hDevInfoSet, SP_DEVINFO_DATA& devInfo, ATL::CHeapPtr<BYTE>& byFriendlyName)
{
	DWORD dwType = 0;
	DWORD dwSize = 0;
	//Query initially to get the buffer size required
	if (!SetupDiGetDeviceRegistryProperty(hDevInfoSet, &devInfo, SPDRP_DEVICEDESC, &dwType, NULL, 0, &dwSize))
	{
		if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
			return FALSE;
	}

#pragma warning(suppress: 6102)
	if (!byFriendlyName.Allocate(dwSize))
	{
		SetLastError(ERROR_OUTOFMEMORY);
		return FALSE;
	}

	return SetupDiGetDeviceRegistryProperty(hDevInfoSet, &devInfo, SPDRP_DEVICEDESC, &dwType, byFriendlyName.m_pData, dwSize, &dwSize) && (dwType == REG_SZ);
}
BOOL CNTServiceControlManager::EnumServices(DWORD dwServiceType, DWORD dwServiceState, LPCTSTR pszGroupName, void* pUserData, ENUM_SERVICES_PROC2 lpEnumServicesFunc) const
{
  //Check to see if the function pointer is available
  if (m_lpfnEnumServicesStatusEx == NULL)
  {
    ATLTRACE(_T("CNTServiceControlManager::EnumServices, EnumServicesStatusEx function is not supported on this OS. You need to be running at least Windows 2000 to use this function\n"));
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return FALSE;
  }

  DWORD dwBytesNeeded;
  DWORD dwServices;
  DWORD dwResumeHandle = 0;
  BOOL bSuccess = m_lpfnEnumServicesStatusEx(m_hSCM, SC_ENUM_PROCESS_INFO, dwServiceType, dwServiceState, NULL, 0, &dwBytesNeeded, &dwServices, &dwResumeHandle, pszGroupName);
  if (!bSuccess && GetLastError() == ERROR_MORE_DATA)
  {
    //Allocate some memory for the API
    ATL::CHeapPtr<BYTE> lpBuffer;
    if (!lpBuffer.Allocate(dwBytesNeeded))
    {
      SetLastError(ERROR_OUTOFMEMORY);
      return FALSE;
    }
  
    LPENUM_SERVICE_STATUS_PROCESS lpServices = reinterpret_cast<LPENUM_SERVICE_STATUS_PROCESS>(lpBuffer.m_pData);
    DWORD dwSize = 0;
    bSuccess = m_lpfnEnumServicesStatusEx(m_hSCM, SC_ENUM_PROCESS_INFO, dwServiceType, dwServiceState, reinterpret_cast<LPBYTE>(lpServices), dwBytesNeeded, &dwSize, &dwServices, &dwResumeHandle, pszGroupName);
    if (bSuccess)
    {
      BOOL bContinue = TRUE;
      for (DWORD i=0; i<dwServices && bContinue; i++)
        bContinue = lpEnumServicesFunc(pUserData, lpServices[i]);
    }
  }
  return bSuccess;
}
BOOL CEnumerateSerial::UsingRegistry(CSimpleArray<CString>& ports)
#endif
{
  //Make sure we clear out any elements which may already be in the array(s)
  ports.RemoveAll();

  //What will be the return value
  BOOL bSuccess = FALSE;

  HKEY hSERIALCOMM;
  if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("HARDWARE\\DEVICEMAP\\SERIALCOMM"), 0, KEY_QUERY_VALUE, &hSERIALCOMM) == ERROR_SUCCESS)
  {
		//Get the max value name and max value lengths
		DWORD dwMaxValueNameLen;
		DWORD dwMaxValueLen;
		DWORD dwQueryInfo = RegQueryInfoKey(hSERIALCOMM, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &dwMaxValueNameLen, &dwMaxValueLen, NULL, NULL);
		if (dwQueryInfo == ERROR_SUCCESS)
		{
			DWORD dwMaxValueNameSizeInChars = dwMaxValueNameLen + 1; //Include space for the NULL terminator
			DWORD dwMaxValueNameSizeInBytes = dwMaxValueNameSizeInChars * sizeof(TCHAR);
			DWORD dwMaxValueDataSizeInChars = dwMaxValueLen/sizeof(TCHAR) + 1; //Include space for the NULL terminator
			DWORD dwMaxValueDataSizeInBytes = dwMaxValueDataSizeInChars * sizeof(TCHAR);
		
			//Allocate some space for the value name and value data			
      ATL::CHeapPtr<TCHAR> szValueName;
      ATL::CHeapPtr<BYTE> byValue;
      if (szValueName.Allocate(dwMaxValueNameSizeInChars) && byValue.Allocate(dwMaxValueDataSizeInBytes))
      {
				bSuccess = TRUE;

				//Enumerate all the values underneath HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM
				DWORD dwIndex = 0;
				DWORD dwType;
				DWORD dwValueNameSize = dwMaxValueNameSizeInChars;
				DWORD dwDataSize = dwMaxValueDataSizeInBytes;
				memset(szValueName.m_pData, 0, dwMaxValueNameSizeInBytes);
				memset(byValue.m_pData, 0, dwMaxValueDataSizeInBytes);
				LONG nEnum = RegEnumValue(hSERIALCOMM, dwIndex, szValueName, &dwValueNameSize, NULL, &dwType, byValue, &dwDataSize);
				while (nEnum == ERROR_SUCCESS)
				{
					//If the value is of the correct type, then add it to the array
					if (dwType == REG_SZ)
					{
						TCHAR* szPort = reinterpret_cast<TCHAR*>(byValue.m_pData);
						ports.Add(szPort);	
					}

					//Prepare for the next time around
					dwValueNameSize = dwMaxValueNameSizeInChars;
					dwDataSize = dwMaxValueDataSizeInBytes;
					memset(szValueName.m_pData, 0, dwMaxValueNameSizeInBytes);
					memset(byValue.m_pData, 0, dwMaxValueDataSizeInBytes);
					++dwIndex;
					nEnum = RegEnumValue(hSERIALCOMM, dwIndex, szValueName, &dwValueNameSize, NULL, &dwType, byValue, &dwDataSize);
				}
      }
      else
		    SetLastError(ERROR_OUTOFMEMORY);
		}
		
		//Close the registry key now that we are finished with it    
    RegCloseKey(hSERIALCOMM);
    
    if (dwQueryInfo != ERROR_SUCCESS)
			SetLastError(dwQueryInfo);
  }
	
	return bSuccess;
}
BOOL CEnumerateSerial::UsingComDB(CSimpleArray<UINT>& ports)
#endif
{
  //Make sure we clear out any elements which may already be in the array(s)
  ports.RemoveAll();

  //What will be the return value
  BOOL bSuccess = FALSE;
  
  //Used to preserve the last error value
  DWORD dwLastError = ERROR_SUCCESS;

  //Get the function pointers to "ComDBOpen", "ComDBClose" & "ComDBGetCurrentPortUsage" in msports.dll
  HINSTANCE hMSPorts = LoadLibrary(_T("MSPORTS.DLL"));
  if (hMSPorts == NULL)
    return FALSE;

  COMDBOPEN* lpfnLPCOMDBOPEN = reinterpret_cast<COMDBOPEN*>(GetProcAddress(hMSPorts, "ComDBOpen"));
  COMDBCLOSE* lpfnLPCOMDBCLOSE = reinterpret_cast<COMDBCLOSE*>(GetProcAddress(hMSPorts, "ComDBClose"));
  COMDBGETCURRENTPORTUSAGE* lpfnCOMDBGETCURRENTPORTUSAGE = reinterpret_cast<COMDBGETCURRENTPORTUSAGE*>(GetProcAddress(hMSPorts, "ComDBGetCurrentPortUsage"));
  if ((lpfnLPCOMDBOPEN != NULL) && (lpfnLPCOMDBCLOSE != NULL) && (lpfnCOMDBGETCURRENTPORTUSAGE != NULL))
  {
    //First need to open up the DB
    HCOMDB hComDB;
    DWORD dwComOpen = lpfnLPCOMDBOPEN(&hComDB);
    if (dwComOpen == ERROR_SUCCESS)
    {
      //Work out the size of the buffer required
      DWORD dwMaxPortsReported = 0;
      DWORD dwPortUsage = lpfnCOMDBGETCURRENTPORTUSAGE(hComDB, NULL, 0, CDB_REPORT_BYTES, &dwMaxPortsReported);
      if (dwPortUsage == ERROR_SUCCESS)
      {
        //Allocate some heap space and recall the function
        ATL::CHeapPtr<BYTE> portBytes;
        if (portBytes.Allocate(dwMaxPortsReported))
        {
          bSuccess = TRUE;
          if (lpfnCOMDBGETCURRENTPORTUSAGE(hComDB, portBytes, dwMaxPortsReported, CDB_REPORT_BYTES, &dwMaxPortsReported) == ERROR_SUCCESS)
          {
            //Work thro the byte bit array for ports which are in use
            for (DWORD i=0; i<dwMaxPortsReported; i++)
            {
              if (portBytes[i])
                ports.Add(i + 1);
            }
          }
        }
        else
          SetLastError(ERROR_OUTOFMEMORY);        
      }
      else
				dwLastError = dwPortUsage;
    
      //Close the DB
      lpfnLPCOMDBCLOSE(hComDB);
    }
    else
			dwLastError = dwComOpen;
  }
  else
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);

  //Unload the msports dll
  FreeLibrary(hMSPorts);
  
  //Reinstate the last error
  if (dwLastError)
		SetLastError(dwLastError);
 
  return bSuccess;
}
Exemple #10
0
BOOL CEnumerateSerial::UsingSetupAPI2(CSimpleArray<UINT>& ports, CSimpleArray<CString>& sFriendlyNames)
#endif
{
  //Make sure we clear out any elements which may already be in the array(s)
  ports.RemoveAll();
  sFriendlyNames.RemoveAll();

  //Get the function pointers to "SetupDiGetClassDevs", "SetupDiGetClassDevs", "SetupDiEnumDeviceInfo", "SetupDiOpenDevRegKey" 
  //and "SetupDiDestroyDeviceInfoList" in setupapi.dll
  HINSTANCE hSetupAPI = LoadLibrary(_T("SETUPAPI.DLL"));
  if (hSetupAPI == NULL)
    return FALSE;

  SETUPDIOPENDEVREGKEY* lpfnLPSETUPDIOPENDEVREGKEY = reinterpret_cast<SETUPDIOPENDEVREGKEY*>(GetProcAddress(hSetupAPI, "SetupDiOpenDevRegKey"));
#ifdef _UNICODE
  SETUPDICLASSGUIDSFROMNAME* lpfnSETUPDICLASSGUIDSFROMNAME = reinterpret_cast<SETUPDICLASSGUIDSFROMNAME*>(GetProcAddress(hSetupAPI, "SetupDiClassGuidsFromNameW"));
  SETUPDIGETCLASSDEVS* lpfnSETUPDIGETCLASSDEVS = reinterpret_cast<SETUPDIGETCLASSDEVS*>(GetProcAddress(hSetupAPI, "SetupDiGetClassDevsW"));
  SETUPDIGETDEVICEREGISTRYPROPERTY* lpfnSETUPDIGETDEVICEREGISTRYPROPERTY = reinterpret_cast<SETUPDIGETDEVICEREGISTRYPROPERTY*>(GetProcAddress(hSetupAPI, "SetupDiGetDeviceRegistryPropertyW"));
#else
  SETUPDICLASSGUIDSFROMNAME* lpfnSETUPDICLASSGUIDSFROMNAME = reinterpret_cast<SETUPDICLASSGUIDSFROMNAME*>(GetProcAddress(hSetupAPI, "SetupDiClassGuidsFromNameA"));
  SETUPDIGETCLASSDEVS* lpfnSETUPDIGETCLASSDEVS = reinterpret_cast<SETUPDIGETCLASSDEVS*>(GetProcAddress(hSetupAPI, "SetupDiGetClassDevsA"));
  SETUPDIGETDEVICEREGISTRYPROPERTY* lpfnSETUPDIGETDEVICEREGISTRYPROPERTY = reinterpret_cast<SETUPDIGETDEVICEREGISTRYPROPERTY*>(GetProcAddress(hSetupAPI, "SetupDiGetDeviceRegistryPropertyA"));
#endif
  SETUPDIDESTROYDEVICEINFOLIST* lpfnSETUPDIDESTROYDEVICEINFOLIST = reinterpret_cast<SETUPDIDESTROYDEVICEINFOLIST*>(GetProcAddress(hSetupAPI, "SetupDiDestroyDeviceInfoList"));
  SETUPDIENUMDEVICEINFO* lpfnSETUPDIENUMDEVICEINFO = reinterpret_cast<SETUPDIENUMDEVICEINFO*>(GetProcAddress(hSetupAPI, "SetupDiEnumDeviceInfo"));

  if ((lpfnLPSETUPDIOPENDEVREGKEY == NULL) || (lpfnSETUPDICLASSGUIDSFROMNAME == NULL) || (lpfnSETUPDIDESTROYDEVICEINFOLIST == NULL) ||
      (lpfnSETUPDIENUMDEVICEINFO == NULL) || (lpfnSETUPDIGETCLASSDEVS == NULL) || (lpfnSETUPDIGETDEVICEREGISTRYPROPERTY == NULL))
  {
    //Unload the setup dll
    FreeLibrary(hSetupAPI);

    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);

    return FALSE;
  }
  
  //First need to convert the name "Ports" to a GUID using SetupDiClassGuidsFromName
  DWORD dwGuids = 0;
  lpfnSETUPDICLASSGUIDSFROMNAME(_T("Ports"), NULL, 0, &dwGuids);
  if (dwGuids == 0)
  {
		DWORD dwLastError = GetLastError();
  
    //Unload the setup dll
    FreeLibrary(hSetupAPI);
    
    SetLastError(dwLastError);

    return FALSE;
  }

  //Allocate the needed memory
  ATL::CHeapPtr<GUID> pGuids;
  if (!pGuids.Allocate(dwGuids))
  {
    //Unload the setup dll
    FreeLibrary(hSetupAPI);
    
    SetLastError(ERROR_OUTOFMEMORY);

    return FALSE;
  }

  //Call the function again
  if (!lpfnSETUPDICLASSGUIDSFROMNAME(_T("Ports"), pGuids, dwGuids, &dwGuids))
  {
		DWORD dwLastError = GetLastError();
  
    //Unload the setup dll
    FreeLibrary(hSetupAPI);
    
    SetLastError(dwLastError);

    return FALSE;
  }

  //Now create a "device information set" which is required to enumerate all the ports
  HDEVINFO hDevInfoSet = lpfnSETUPDIGETCLASSDEVS(pGuids, NULL, NULL, DIGCF_PRESENT);
  if (hDevInfoSet == INVALID_HANDLE_VALUE)
  {
		DWORD dwLastError = GetLastError();
  
    //Unload the setup dll
    FreeLibrary(hSetupAPI);
    
    SetLastError(dwLastError);

    return FALSE;
  }

  //Finally do the enumeration
  BOOL bMoreItems = TRUE;
  int nIndex = 0;
  SP_DEVINFO_DATA devInfo;
  while (bMoreItems)
  {
    //Enumerate the current device
    devInfo.cbSize = sizeof(SP_DEVINFO_DATA);
    bMoreItems = lpfnSETUPDIENUMDEVICEINFO(hDevInfoSet, nIndex, &devInfo);
    if (bMoreItems)
    {
      //Did we find a serial port for this device
      BOOL bAdded = FALSE;

      //Get the registry key which stores the ports settings
      HKEY hDeviceKey = lpfnLPSETUPDIOPENDEVREGKEY(hDevInfoSet, &devInfo, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE);
      if (hDeviceKey)
      {
        //Read in the name of the port
        TCHAR pszPortName[256];
        DWORD dwSize = sizeof(pszPortName);
        DWORD dwType = 0;
  	    if ((RegQueryValueEx(hDeviceKey, _T("PortName"), NULL, &dwType, reinterpret_cast<LPBYTE>(pszPortName), &dwSize) == ERROR_SUCCESS) && (dwType == REG_SZ))
        {
          //If it looks like "COMX" then
          //add it to the array which will be returned
          size_t nLen = _tcslen(pszPortName);
          if (nLen > 3)
          {
            if ((_tcsnicmp(pszPortName, _T("COM"), 3) == 0) && IsNumeric(&pszPortName[3], FALSE))
            {
              //Work out the port number
              int nPort = _ttoi(&pszPortName[3]);
              ports.Add(nPort);

              bAdded = TRUE;
            }
          }
        }

        //Close the key now that we are finished with it
        RegCloseKey(hDeviceKey);
      }

      //If the port was a serial port, then also try to get its friendly name
      if (bAdded)
      {
        TCHAR pszFriendlyName[256];
        DWORD dwSize = sizeof(pszFriendlyName);
        DWORD dwType = 0;
        if (lpfnSETUPDIGETDEVICEREGISTRYPROPERTY(hDevInfoSet, &devInfo, SPDRP_DEVICEDESC, &dwType, reinterpret_cast<PBYTE>(pszFriendlyName), dwSize, &dwSize) && (dwType == REG_SZ))
          sFriendlyNames.Add(pszFriendlyName);
        else
          sFriendlyNames.Add(_T(""));
      }
    }

    ++nIndex;
  }

  //Free up the "device information set" now that we are finished with it
  lpfnSETUPDIDESTROYDEVICEINFOLIST(hDevInfoSet);

  //Unload the setup dll
  FreeLibrary(hSetupAPI);

  //Return the success indicator
  return TRUE;
}
Exemple #11
0
BOOL CEnumerateSerial::UsingQueryDosDevice(CSimpleArray<UINT>& ports)
#endif
{
  //What will be the return value from this function (assume the worst)
  BOOL bSuccess = FALSE;

  //Make sure we clear out any elements which may already be in the array
  ports.RemoveAll();

  //Determine what OS we are running on
  OSVERSIONINFO osvi;
  osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  BOOL bGetVer = GetVersionEx(&osvi);

  //On NT use the QueryDosDevice API
  if (bGetVer && (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT))
  {
    //Use QueryDosDevice to look for all devices of the form COMx. Since QueryDosDevice does
    //not consitently report the required size of buffer, lets start with a reasonable buffer size
    //of 4096 characters and go from there
    int nChars = 4096;
    BOOL bWantStop = FALSE;
    while (nChars && !bWantStop)
    {
      ATL::CHeapPtr<TCHAR> szDevices;
      if (szDevices.Allocate(nChars))
      {
        DWORD dwChars = QueryDosDevice(NULL, szDevices, nChars);
        if (dwChars == 0)
        {
          DWORD dwError = GetLastError();
          if (dwError == ERROR_INSUFFICIENT_BUFFER)
          {
            //Expand the buffer and  loop around again
            nChars *= 2;
          }
          else
            bWantStop = TRUE;
        }
        else
        {
          bSuccess = TRUE;
          bWantStop = TRUE;
          size_t i=0;
          while (szDevices[i] != _T('\0'))
          {
            //Get the current device name
            TCHAR* pszCurrentDevice = &szDevices[i];

            //If it looks like "COMX" then
            //add it to the array which will be returned
            size_t nLen = _tcslen(pszCurrentDevice);
            if (nLen > 3)
            {
              if ((_tcsnicmp(pszCurrentDevice, _T("COM"), 3) == 0) && IsNumeric(&pszCurrentDevice[3], FALSE))
              {
                //Work out the port number
                int nPort = _ttoi(&pszCurrentDevice[3]);
                ports.Add(nPort);
              }
            }

            //Go to next device name
            i += (nLen + 1);
          }
        }
      }
      else
      {
        bWantStop = TRUE;
        SetLastError(ERROR_OUTOFMEMORY);        
      }
    }
  }
  else
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);

  return bSuccess;
}
Exemple #12
0
BOOL CEnumerateSerial::UsingSetupAPI2(CSimpleArray<UINT>& ports, CSimpleArray<CString>& friendlyNames)
#endif
{
  //Make sure we clear out any elements which may already be in the array(s)
#if defined CENUMERATESERIAL_USE_STL
  ports.clear();
  friendlyNames.clear();
#else
  ports.RemoveAll();
  friendlyNames.RemoveAll();
#endif  

  //Get the function pointers to "SetupDiGetClassDevs", "SetupDiGetClassDevs", "SetupDiEnumDeviceInfo", "SetupDiOpenDevRegKey" 
  //and "SetupDiDestroyDeviceInfoList" in setupapi.dll
  CAutoHModule setupAPI(LoadLibraryFromSystem32(_T("SETUPAPI.DLL")));
  if (setupAPI == NULL)
    return FALSE;

  SETUPDIOPENDEVREGKEY* lpfnLPSETUPDIOPENDEVREGKEY = reinterpret_cast<SETUPDIOPENDEVREGKEY*>(GetProcAddress(setupAPI, "SetupDiOpenDevRegKey"));
#if defined _UNICODE
  SETUPDICLASSGUIDSFROMNAME* lpfnSETUPDICLASSGUIDSFROMNAME = reinterpret_cast<SETUPDICLASSGUIDSFROMNAME*>(GetProcAddress(setupAPI, "SetupDiClassGuidsFromNameW"));
  SETUPDIGETCLASSDEVS* lpfnSETUPDIGETCLASSDEVS = reinterpret_cast<SETUPDIGETCLASSDEVS*>(GetProcAddress(setupAPI, "SetupDiGetClassDevsW"));
  SETUPDIGETDEVICEREGISTRYPROPERTY* lpfnSETUPDIGETDEVICEREGISTRYPROPERTY = reinterpret_cast<SETUPDIGETDEVICEREGISTRYPROPERTY*>(GetProcAddress(setupAPI, "SetupDiGetDeviceRegistryPropertyW"));
#else
  SETUPDICLASSGUIDSFROMNAME* lpfnSETUPDICLASSGUIDSFROMNAME = reinterpret_cast<SETUPDICLASSGUIDSFROMNAME*>(GetProcAddress(setupAPI, "SetupDiClassGuidsFromNameA"));
  SETUPDIGETCLASSDEVS* lpfnSETUPDIGETCLASSDEVS = reinterpret_cast<SETUPDIGETCLASSDEVS*>(GetProcAddress(setupAPI, "SetupDiGetClassDevsA"));
  SETUPDIGETDEVICEREGISTRYPROPERTY* lpfnSETUPDIGETDEVICEREGISTRYPROPERTY = reinterpret_cast<SETUPDIGETDEVICEREGISTRYPROPERTY*>(GetProcAddress(setupAPI, "SetupDiGetDeviceRegistryPropertyA"));
#endif
  SETUPDIDESTROYDEVICEINFOLIST* lpfnSETUPDIDESTROYDEVICEINFOLIST = reinterpret_cast<SETUPDIDESTROYDEVICEINFOLIST*>(GetProcAddress(setupAPI, "SetupDiDestroyDeviceInfoList"));
  SETUPDIENUMDEVICEINFO* lpfnSETUPDIENUMDEVICEINFO = reinterpret_cast<SETUPDIENUMDEVICEINFO*>(GetProcAddress(setupAPI, "SetupDiEnumDeviceInfo"));

  if ((lpfnLPSETUPDIOPENDEVREGKEY == NULL) || (lpfnSETUPDICLASSGUIDSFROMNAME == NULL) || (lpfnSETUPDIDESTROYDEVICEINFOLIST == NULL) ||
      (lpfnSETUPDIENUMDEVICEINFO == NULL) || (lpfnSETUPDIGETCLASSDEVS == NULL) || (lpfnSETUPDIGETDEVICEREGISTRYPROPERTY == NULL))
  {
    //Set the error to report
    setupAPI.m_dwError = ERROR_CALL_NOT_IMPLEMENTED;

    return FALSE;
  }
  
  //First need to convert the name "Ports" to a GUID using SetupDiClassGuidsFromName
  DWORD dwGuids = 0;
  lpfnSETUPDICLASSGUIDSFROMNAME(_T("Ports"), NULL, 0, &dwGuids);
  if (dwGuids == 0)
  {
    //Set the error to report
    setupAPI.m_dwError = GetLastError();

    return FALSE;
  }

  //Allocate the needed memory
  ATL::CHeapPtr<GUID> pGuids;
  if (!pGuids.Allocate(dwGuids))
  {
    //Set the error to report
    setupAPI.m_dwError = ERROR_OUTOFMEMORY;

    return FALSE;
  }

  //Call the function again
  if (!lpfnSETUPDICLASSGUIDSFROMNAME(_T("Ports"), pGuids, dwGuids, &dwGuids))
  {
    //Set the error to report
    setupAPI.m_dwError = GetLastError();

    return FALSE;
  }

  //Now create a "device information set" which is required to enumerate all the ports
  HDEVINFO hDevInfoSet = lpfnSETUPDIGETCLASSDEVS(pGuids, NULL, NULL, DIGCF_PRESENT);
  if (hDevInfoSet == INVALID_HANDLE_VALUE)
  {
    //Set the error to report
    setupAPI.m_dwError = GetLastError();

    return FALSE;
  }

  //Finally do the enumeration
  BOOL bMoreItems = TRUE;
  int nIndex = 0;
  SP_DEVINFO_DATA devInfo;
  while (bMoreItems)
  {
    //Enumerate the current device
    devInfo.cbSize = sizeof(SP_DEVINFO_DATA);
    bMoreItems = lpfnSETUPDIENUMDEVICEINFO(hDevInfoSet, nIndex, &devInfo);
    if (bMoreItems)
    {
      //Did we find a serial port for this device
      BOOL bAdded = FALSE;

      //Get the registry key which stores the ports settings
      HKEY hDeviceKey = lpfnLPSETUPDIOPENDEVREGKEY(hDevInfoSet, &devInfo, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE);
      if (hDeviceKey)
      {
        int nPort = 0;
        if (QueryRegistryPortName(hDeviceKey, nPort))
        {
        #if defined CENUMERATESERIAL_USE_STL
          ports.push_back(nPort);
        #else
          ports.Add(nPort);
        #endif  
          bAdded = TRUE;
        }

        //Close the key now that we are finished with it
        RegCloseKey(hDeviceKey);
      }

      //If the port was a serial port, then also try to get its friendly name
      if (bAdded)
      {
        TCHAR szFriendlyName[1024];
        szFriendlyName[0] = _T('\0');
        DWORD dwSize = sizeof(szFriendlyName);
        DWORD dwType = 0;
        if (lpfnSETUPDIGETDEVICEREGISTRYPROPERTY(hDevInfoSet, &devInfo, SPDRP_DEVICEDESC, &dwType, reinterpret_cast<PBYTE>(szFriendlyName), dwSize, &dwSize) && (dwType == REG_SZ))
        {
        #if defined CENUMERATESERIAL_USE_STL
          friendlyNames.push_back(szFriendlyName);
        #else
          friendlyNames.Add(szFriendlyName);
        #endif  
        }
        else
        {
        #if defined CENUMERATESERIAL_USE_STL
          friendlyNames.push_back(_T(""));
        #else
          friendlyNames.Add(_T(""));
        #endif  
        }
      }
    }

    ++nIndex;
  }

  //Free up the "device information set" now that we are finished with it
  lpfnSETUPDIDESTROYDEVICEINFOLIST(hDevInfoSet);

  //Return the success indicator
  return TRUE;
}
Exemple #13
0
BOOL CEnumerateSerial::UsingComDB(CSimpleArray<UINT>& ports)
#endif
{
  //Make sure we clear out any elements which may already be in the array(s)
#if defined CENUMERATESERIAL_USE_STL
  ports.clear();
#else
  ports.RemoveAll();
#endif  

  //What will be the return value from this function (assume the worst)
  BOOL bSuccess = FALSE;
  
  //Get the function pointers to "ComDBOpen", "ComDBClose" & "ComDBGetCurrentPortUsage" in msports.dll
  CAutoHModule msPorts(LoadLibraryFromSystem32(_T("MSPORTS.DLL")));
  if (msPorts == NULL)
    return FALSE;

  COMDBOPEN* lpfnLPCOMDBOPEN = reinterpret_cast<COMDBOPEN*>(GetProcAddress(msPorts, "ComDBOpen"));
  COMDBCLOSE* lpfnLPCOMDBCLOSE = reinterpret_cast<COMDBCLOSE*>(GetProcAddress(msPorts, "ComDBClose"));
  COMDBGETCURRENTPORTUSAGE* lpfnCOMDBGETCURRENTPORTUSAGE = reinterpret_cast<COMDBGETCURRENTPORTUSAGE*>(GetProcAddress(msPorts, "ComDBGetCurrentPortUsage"));
  if ((lpfnLPCOMDBOPEN != NULL) && (lpfnLPCOMDBCLOSE != NULL) && (lpfnCOMDBGETCURRENTPORTUSAGE != NULL))
  {
    //First need to open up the DB
    HCOMDB hComDB;
    DWORD dwComOpen = lpfnLPCOMDBOPEN(&hComDB);
    if (dwComOpen == ERROR_SUCCESS)
    {
      //Work out the size of the buffer required
      DWORD dwMaxPortsReported = 0;
      DWORD dwPortUsage = lpfnCOMDBGETCURRENTPORTUSAGE(hComDB, NULL, 0, CDB_REPORT_BYTES, &dwMaxPortsReported);
      if (dwPortUsage == ERROR_SUCCESS)
      {
        //Allocate some heap space and recall the function
        ATL::CHeapPtr<BYTE> portBytes;
        if (portBytes.Allocate(dwMaxPortsReported))
        {
          bSuccess = TRUE;
          if (lpfnCOMDBGETCURRENTPORTUSAGE(hComDB, portBytes, dwMaxPortsReported, CDB_REPORT_BYTES, &dwMaxPortsReported) == ERROR_SUCCESS)
          {
            //Work thro the byte bit array for ports which are in use
            for (DWORD i=0; i<dwMaxPortsReported; i++)
            {
              if (portBytes[i])
              {
              #if defined CENUMERATESERIAL_USE_STL
                ports.push_back(i + 1);
              #else
                ports.Add(i + 1);
              #endif
              }
            }
          }
        }
        else
          msPorts.m_dwError = ERROR_OUTOFMEMORY;
      }
      else
        msPorts.m_dwError = dwPortUsage;
    
      //Close the DB
      lpfnLPCOMDBCLOSE(hComDB);
    }
    else
			msPorts.m_dwError = dwComOpen;
  }
  else
    msPorts.m_dwError = ERROR_CALL_NOT_IMPLEMENTED;

  return bSuccess;
}
BOOL CNTEventLogSource::SetStringArrayIntoRegistry(ATL::CRegKey& key, LPCTSTR lpszEntry, const CNTServiceStringArray& array, DWORD* pLastError)
{   
  //Validate our input parameters
  ATLASSERT(lpszEntry != NULL);

  //Work out the size of the buffer we will need
#ifdef CNTSERVICE_MFC_EXTENSIONS
  int nSize = 0;
  INT_PTR nStrings = array.GetSize();
  for (INT_PTR i=0; i<nStrings; i++)
    nSize += array.GetAt(i).GetLength() + 1; //1 extra for each NULL terminator
#else
  CNTServiceStringArray::size_type nSize = 0;
  CNTServiceStringArray::size_type nStrings = array.size();
  for (CNTServiceStringArray::size_type i=0; i<nStrings; i++)
    nSize += array[i].length() + 1; //1 extra for each NULL terminator
#endif

  //Need one second NULL for the double NULL at the end
  nSize++;

  //Allocate some memory for the API
  ATL::CHeapPtr<TCHAR> lpBuffer;
  if (!lpBuffer.Allocate(nSize))
  {
    SetLastError(ERROR_OUTOFMEMORY);
    if (pLastError)
      *pLastError = ERROR_OUTOFMEMORY;
    return FALSE;
  }

  //Now copy the strings into the buffer
  LPTSTR lpszString = lpBuffer.m_pData;
#ifdef CNTSERVICE_MFC_EXTENSIONS
  int nCurOffset = 0;
  for (INT_PTR i=0; i<nStrings; i++)
#else
  CNTServiceStringArray::size_type nCurOffset = 0;
  for (CNTServiceStringArray::size_type i=0; i<nStrings; i++)
#endif
  {
    const CNTServiceString& sText = array[i];
  #ifdef CNTSERVICE_MFC_EXTENSIONS
    int nCurrentStringLength = sText.GetLength();
    _tcscpy_s(&lpszString[nCurOffset], nCurrentStringLength+1, sText);
  #else
    CNTServiceString::size_type nCurrentStringLength = sText.length();
    _tcscpy_s(&lpszString[nCurOffset], nCurrentStringLength+1, sText.c_str());
  #endif
    nCurOffset += (nCurrentStringLength + 1);
  }
  //Don't forgot to doubly NULL terminate
  lpszString[nCurOffset] = _T('\0');

  //Finally write it into the registry
  LONG lResult = key.SetMultiStringValue(lpszEntry, lpBuffer);
  BOOL bSuccess = (lResult == ERROR_SUCCESS);
  if (!bSuccess && pLastError)
    *pLastError = lResult;

  return bSuccess;
}
BOOL CNTEventLogSource::GetStringArrayFromRegistry(ATL::CRegKey& key, LPCTSTR lpszEntry, CNTServiceStringArray& array, DWORD* pLastError)
{
  //Validate our parameters
  ATLASSERT(lpszEntry != NULL);

  //What will be the return value from this function, assume the worst
  BOOL bSuccess = FALSE;

  //Empty the array before we go any further
#ifdef CNTSERVICE_MFC_EXTENSIONS
  array.RemoveAll();
#else
  array.clear();
#endif

  DWORD dwType = 0;
  ULONG nBytes = 0;
  LONG lResult = key.QueryValue(lpszEntry, &dwType, NULL, &nBytes);
  if (lResult == ERROR_SUCCESS)
  {
    //Allocate some memory for the API
    ATL::CHeapPtr<TCHAR> lpBuffer;
    ULONG nChars = nBytes / sizeof(TCHAR);
    if (nChars < 2) //Ensure we can handle an empty MULTI_SZ string
      nChars = 2;
    if (!lpBuffer.Allocate(nChars))
    {
      SetLastError(ERROR_OUTOFMEMORY);
      if (pLastError)
        *pLastError = ERROR_OUTOFMEMORY;
      return FALSE;
    }

    lResult = key.QueryMultiStringValue(lpszEntry, lpBuffer, &nChars);      
    if (lResult == ERROR_SUCCESS)
    {
      LPTSTR lpszStrings = lpBuffer.m_pData;
      while (lpszStrings[0] != 0)
      {
      #ifdef CNTSERVICE_MFC_EXTENSIONS
        array.Add(lpszStrings);
      #else
        array.push_back(lpszStrings);
      #endif
        lpszStrings += (_tcslen(lpszStrings) + 1);
      }

      bSuccess = TRUE;
    }
    else
    {
      if (pLastError)
        *pLastError = lResult;
    }
  }
  else
  {
    if (pLastError)
      *pLastError = lResult;
  }

  return bSuccess;
}