Кодю на плюсиках. Есть вот такая функция: Code: int SetFirewallException(HWND alertwindow) { if (alertwindow != NULL) { if (BringWindowToTop(alertwindow)) { DWORD dwCurrentThread = GetCurrentThreadId(); DWORD dwFGTThread = GetWindowThreadProcessId(GetForegroundWindow(), NULL); AttachThreadInput(dwCurrentThread, dwFGTThread, TRUE); SetForegroundWindow(alertwindow); int x = 0; INPUT ip; ip.type = INPUT_KEYBOARD; ip.ki.wScan = 0; ip.ki.time = 0; ip.ki.dwExtraInfo = 0; for (; x < 6; x++){ ip.ki.wVk = 0x09; ip.ki.dwFlags = 0; SendInput(1, &ip, sizeof(INPUT)); ip.ki.dwFlags = KEYEVENTF_KEYUP; SendInput(1, &ip, sizeof(INPUT)); } if (x == 6){ ip.ki.wVk = 0x0D; ip.ki.dwFlags = 0; SendInput(1, &ip, sizeof(INPUT)); ip.ki.dwFlags = KEYEVENTF_KEYUP; SendInput(1, &ip, sizeof(INPUT)); } } else return 1; } else return 1; return 0; } При запуске приложения все срабатывает и исключение добавляется. Но есть одно маленькое но. По умолчанию в окошке брандмауэра отмечена только одна галочка (тестирую на десятке), что надо бы поправить. Если я переписываю функцию вот так: Code: int SetFirewallException(HWND alertwindow) { if (alertwindow != NULL) { if (BringWindowToTop(alertwindow)) { DWORD dwCurrentThread = GetCurrentThreadId(); DWORD dwFGTThread = GetWindowThreadProcessId(GetForegroundWindow(), NULL); AttachThreadInput(dwCurrentThread, dwFGTThread, TRUE); SetForegroundWindow(alertwindow); int x = 0; INPUT ip; ip.type = INPUT_KEYBOARD; ip.ki.wScan = 0; ip.ki.time = 0; ip.ki.dwExtraInfo = 0; for (; x < 4; x++){ ip.ki.wVk = 0x09; ip.ki.dwFlags = 0; SendInput(1, &ip, sizeof(INPUT)); ip.ki.dwFlags = KEYEVENTF_KEYUP; SendInput(1, &ip, sizeof(INPUT)); } if (x == 4){ ip.ki.wVk = 0x0D; ip.ki.dwFlags = 0; SendInput(1, &ip, sizeof(INPUT)); ip.ki.dwFlags = KEYEVENTF_KEYUP; SendInput(1, &ip, sizeof(INPUT)); } for (; x < 6; x++){ ip.ki.wVk = 0x09; ip.ki.dwFlags = 0; SendInput(1, &ip, sizeof(INPUT)); ip.ki.dwFlags = KEYEVENTF_KEYUP; SendInput(1, &ip, sizeof(INPUT)); } if (x == 6){ ip.ki.wVk = 0x0D; ip.ki.dwFlags = 0; SendInput(1, &ip, sizeof(INPUT)); ip.ki.dwFlags = KEYEVENTF_KEYUP; SendInput(1, &ip, sizeof(INPUT)); } } else return 1; } else return 1; return 0; } То магическим образом сразу нихрена не работает. То есть если заставить программу нажимать на галку, то все, капут. Так не каеф. Поможете нерадивому кодеру?
Не проще ли вместо всех этих извращений с эмуляцией ввода с клавиатуры просто сделать новую запись исключения брандмауэра в реестр?
Пфффффф, научить гуглить? https://social.technet.microsoft.co...-why-does-it-not-appear?forum=w7itprosecurity HKLM\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\FirewallRules
Ну хорошо, это возможно и даже вполне неплохая идея. Но как насчет перезагрузки? Для применения ведь придется перезагрузить пк? Или я не прав?
Ну, написал я, значит, что надо. Code: int SetFirewallExceptionByReg(const char* pathToExe) { string value = "v2.10|Action=Allow|Active=TRUE|Dir=In|Protocol=6|Profile=Private|Profile=Public|App="; value += Quotes(pathToExe); value += "|Name=run|Desc=run|Defer=User|"; cout << "value: " << value << endl; int res; HKEY hKey; res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\SharedAccess\\Parameters\\FirewallPolicy\\FirewallRules", 0, KEY_SET_VALUE, &hKey); cout << "res: " << res << endl; res = RegSetValueEx(hKey, "TCP Query User Run.exe", 0, REG_SZ, (BYTE*)value.c_str(), (DWORD) ((lstrlen(value.c_str())+1)*sizeof(TCHAR))); cout << "res 2: " << res << endl; RegCloseKey(hKey); } res выдает 5 - Access is denied. (Что есть печально) res 2 выдает 6 - The handle is invalid. (Что есть логично) Говорите, у вас работало? А как быть без админских прав? Пока что проект вполне прилично работал и без них, не хотелось впихивать повышение прав... Теперь извращение с эмуляцией ввода смотрится вполне прилично, по сравнению с неработающим примером. P.s. А что это за лабуда: "{302A64E1-C42D-4819-A94C-535740A8F0FF}"? Находилось в середине имени ключа в реестре. Если этот метод заработает, то имя не важно, или придется как-то такое вот лепить?
Гуглите UAC bypass, вроде до сих пор не закрыли эту дыру, даже в Win 10. Вроде имя может быть любым, и даже не обязательно уникальным. CLSID нужен.
Дык при чем тут UAC? Вроде же прав не хватает. У вас точно нет идей на счет эмуляции ввода? То есть вот это вот лепить надо - {302A64E1-C42D-4819-A94C-535740A8F0FF}. А где его брать или как он генерируется?
Если запущено под админом, то нехватка прав может быть только из-за UAC. В противном случае (под простым пользователем) правила добавлять не получится. Сейчас не помню, ответ должен быть в реестре.