Кресты / Говнокод #27437 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
_Return_type_success_(return != false) bool CEnumerateSerial::UsingCreateFile(_Inout_ CPortsArray& ports)
{
  //Reset the output parameter
  ports.clear();

  //Up to 255 COM ports are supported so we iterate through all of them seeing
  //if we can open them or if we fail to open them, get an access denied or general error error.
  //Both of these cases indicate that there is a COM port at that number. 
  for (UINT i=1; i<256; i++)
  {
    //Form the Raw device name
    ATL::CAtlString sPort;
    sPort.Format(_T("\\\\.\\COM%u"), i);

    //Try to open the port
    bool bSuccess = false;
    ATL::CHandle port(CreateFile(sPort, GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, nullptr));
    if (port == INVALID_HANDLE_VALUE)
    {
      const DWORD dwError = GetLastError();

      //Check to see if the error was because some other app had the port open or a general failure
      if ((dwError == ERROR_ACCESS_DENIED) || (dwError == ERROR_GEN_FAILURE) || (dwError == ERROR_SHARING_VIOLATION) || (dwError == ERROR_SEM_TIMEOUT))
        bSuccess = true;
    }
    else
    {
      //The port was opened successfully
      bSuccess = true;
    }

    //Add the port number to the array which will be returned
    if (bSuccess)
#pragma warning(suppress: 26489)
      ports.push_back(i);
  }

  //Return the success indicator
  return true;
}

некоторые джавамэны вот таким гордятся

> Internally the code provides 10 different ways (yes you read that right: Ten)

еще и выложено под ни с чем не совместимой лицензией

Запостил: gologub gologub, (Updated )

Комментарии (32) RSS

  • ну что, спойлернуть над каким странным утверджением надо задуматься?
    Ответить
    • Предупреждения вырубили и забыли на место вернуть?
      Ответить
      • нет, там всё гораздо проще, щас если гость не угадает - я вскрою и это приведёт к лавине и извержению одновременно
        Ответить
    • >//Check to see if the error was because some other app had the port open or a general failure
      выглядит как говно
      Ответить
      • Да ладно, этот код хотя бы дискетой не скрипит во время перечисления...
        Ответить
        • Если из ``ERROR_GEN_FAILURE`` следует ``bSuccess = true``, то я такой код ебал
          Извините
          Ответить
          • Ну, может, жизнь такая. Мало ли почему не открылся, но порт есть, пользователю надо показать - пусть сам решает. Может, у кого-то именно это значение вернуло.
            Ответить
    • вот это!
      но... если копнуть глубже окажется, что искаропки поддерживается up to 1024 и расширяемо до 4096, а если забить на "com name arbiter" то ∞

      а несчастный примат этот код 23 года вылизывал, а он оказался полной хуйней
      Ответить
      • приведи пример машины с 1024 ком портами

        Это какая-то станция для дайлап пула в крупном провайдере из 1999-го года?
        Ответить
          • Да и мобилки через USB ACM раньше тоже плодились почему-то, у меня что-то в духе COM23 было под конец.
            Ответить
          • Рискну предположить, что ваши USB устройства каждый раз регистрируют новый порт
            Старый можно удалить, если сказать show hidden devices

            Кто настолько старый, что помнит переменную
            DEVMGR_SHOW_NONPRESENT_DEVICES
            Ответить
      • А есть нормальный способ, кстати?

        Ну там через какое-нибудь setupapi запросить по классу "последовательный порт" или что-то подобное...
        Ответить
      • #define _WIN32_DCOM
        
        #include <iostream>
        #include <Windows.h>
        #include <wbemidl.h>
        #pragma comment(lib, "wbemuuid.lib")
        
        int main()
        {
        	if (FAILED(CoInitializeEx(nullptr, COINIT_MULTITHREADED)))
        	{
        		std::cerr << "Failed to init com" << std::endl;
        		return -1;
        	}
        	CoInitializeSecurity(
        		nullptr,
        		-1,
        		nullptr,
        		nullptr,
        		RPC_C_AUTHN_LEVEL_DEFAULT,
        		RPC_C_IMP_LEVEL_IMPERSONATE,
        		nullptr,
        		EOAC_NONE,
        		nullptr);
        
        	IWbemLocator* pLoc = nullptr;
        	HRESULT hr = CoCreateInstance(CLSID_WbemLocator, 0,
        	                              CLSCTX_INPROC_SERVER, IID_IWbemLocator, reinterpret_cast<LPVOID*>(&pLoc));
        	if (FAILED(hr))
        	{
        		std::cerr << "Failed to create com" << std::endl;
        		return -1;
        	}
        	IWbemServices* pSvc = nullptr;
        	hr = pLoc->ConnectServer(L"\\\\.\\root\\cimv2", NULL, NULL, NULL,
        	                         WBEM_FLAG_CONNECT_USE_MAX_WAIT, NULL, NULL, &pSvc);
        	if (FAILED(hr))
        	{
        		std::cerr << "Failed to connect" << std::endl;
        		return -1;
        	}
        	IEnumWbemClassObject* pEnum = nullptr;
        	hr = pSvc->CreateInstanceEnum(L"Win32_SerialPort", 0, nullptr, &pEnum);
        	if (FAILED(hr))
        	{
        		std::wcerr << L"Failed get query" << hr << std::endl;
        		return -1;
        	}
        	IWbemClassObject* pObj;
        	ULONG returned;
        	while (1)
        	{
        		pEnum->Next(WBEM_INFINITE, 1, &pObj, &returned);
        		if (returned)
        		{
        			VARIANT v;
        			pObj->Get(L"Name", 0, &v, nullptr, nullptr);
        			std::wcout << v.bstrVal;
        		}
        		else
        		{
        			break;
        		}
        	}
        }

        собирать под 14-й vc. Под 17-й нужно явно отключать strictString (с ним wbem не собирается, ссаный BSTR виноват) и с unicode строками

        Нужно сделать обработку ошибок, и завернуть наверное комы в ATL, но я пьяный
        Ответить
        • > но я пьяный

          Оно и видно... кто по трезвости полезет ворошить WMI голыми руками...
          Ответить
  • #include <iostream>
    #include <Windows.h>
    #include <sstream>
    
    int main()
    {
    	char buffer[MAX_PATH]{};
    	for (uint16_t i = 1; i <= 1024; i++)
    	{
    		std::stringstream name;
    		name << "COM" << i;
    		const std::string devName{name.str()};
    		if (QueryDosDeviceA(devName.c_str(), buffer, sizeof(buffer)) == 0)
    		{
    			const auto lastError = GetLastError();
    			if (lastError == ERROR_FILE_NOT_FOUND)
    			{
    				break;
    			}
    			std::cerr << "Error: " << lastError << std::endl;
    			return lastError;
    		}
    		std::cout << devName.c_str() << std::endl;
    	}
    	return 0;
    }
    // не работает старше 4
    Ответить
    • > break

      Заебись, с USB COM девайсами это в принципе не работает, я думаю? У них не меньше 5 и дырки в нумерации, емнип.
      Ответить
      • с дырками не рабоатет точно) нужно все проверять
        Ответить
    • О, а это можня уже через Ви-няпи нярмальным способом распарсить. Правда, это всё равно будет противняя куча RegOpenKey RegQueryValue RegNyaKawaii...
      Ответить
      • тащемто всё что угодно можно сдеоать через win32pi |(кроме WinRT), просто много буков получится. Что с реестром, что с WMI, очень много буков
        Ответить
        • WMI это же говно со скриптосахаром
          сервис может быть отключен
          или хуже, настроен неторопливо стартовать, когда ты туда полезешь
          или даже еще хуже, не успеть обновить список чтобы туда включить девайс, который ты только что воткнул
          Ответить
  • Зеленые комментарии кода в IDe выглядят как сарказм...
    Ответить

Добавить комментарий

Помни, guest, за тобой могут следить!

    А не использовать ли нам bbcode?


    8