Skip to content

Instantly share code, notes, and snippets.

@kizernis
Created April 21, 2023 17:19
Show Gist options
  • Save kizernis/6c4c3f7fc7cd0f376ed4cdcd67cd50a3 to your computer and use it in GitHub Desktop.
Save kizernis/6c4c3f7fc7cd0f376ed4cdcd67cd50a3 to your computer and use it in GitHub Desktop.
#include <winsock2.h>
#include "resource.h"
#ifndef _DEBUG
#pragma comment(linker, "/entry:_WinMain /nodefaultlib /subsystem:windows /filealign:512 /stack:65536,65536")
#pragma comment(linker, "/merge:.data=.text /merge:.rdata=.text /section:.text,ewrx /ignore:4078")
#endif
#define OPTION_BOTH 1
#define OPTION_MODEM 2
#define OPTION_ROUTER 3
int g_nOption;
PCSTR g_csCurrentStatus;
int g_nMessageLength, g_nPos;
char g_sMsgTmp[20];
#ifdef _DEBUG
PCSTR g_csModemHttpRequest = "GET / HTTP/1.0\nAuthorization: Basic YWRtaW46YWRtaW4=\nConnection: Close\n\n";
PCSTR g_csRouterHttpRequest = "GET / HTTP/1.0\nAuthorization: Basic YWRtaW46\nConnection: Close\n\n";
#else
PCSTR g_csModemHttpRequest = "GET /rebootinfo.cgi HTTP/1.0\nAuthorization: Basic YWRtaW46YWRtaW4=\nConnection: Close\n\n";
PCSTR g_csRouterHttpRequest = "GET /restart.cgi HTTP/1.0\nAuthorization: Basic YWRtaW46\nConnection: Close\n\n";
#endif
PCSTR g_csModemAddress = "192.168.1.1";
PCSTR g_csRouterAddress = "192.168.0.1";
HWND g_hWnd, g_hStatus;
BOOL g_bProcessing, g_bSuccess, g_bFirstDone;
#define TIMER_PROCESSING 1
UINT g_nTypingTimerId;
void CALLBACK BlinkingTimerProc(HWND hWnd, UINT nMsg, UINT nEventID, DWORD dwTime)
{
char sTmp[20];
int nLen = GetWindowText(g_hStatus, sTmp, 18);
if (sTmp[nLen - 1] == '_')
sTmp[nLen - 1] = '\0';
else
{ sTmp[nLen] = '_'; sTmp[nLen + 1] = '\0'; }
SetWindowText(g_hStatus, sTmp);
}
void CALLBACK TypingTimerProc(HWND hWnd, UINT nMsg, UINT nEventID, DWORD dwTime)
{
g_sMsgTmp[g_nPos - 1] = g_csCurrentStatus[g_nPos - 1];
g_sMsgTmp[g_nPos] = '_';
g_sMsgTmp[g_nPos + 1] = '\0';
SetWindowText(g_hStatus, g_sMsgTmp);
if (++g_nPos > g_nMessageLength)
KillTimer(NULL, g_nTypingTimerId);
}
void TypeStatusMessage(PCSTR csMessage)
{
g_csCurrentStatus = csMessage;
lstrcpy(&g_sMsgTmp[1], &csMessage[1]);
g_nMessageLength = lstrlen(csMessage); g_nPos = 1;
g_nTypingTimerId = SetTimer(NULL, 0, 30, TypingTimerProc);
}
DWORD WINAPI NegotiationThreadProc(PVOID pDummy)
{
BOOL bIsModem = (g_nOption == OPTION_MODEM) || (g_nOption == OPTION_BOTH && !g_bFirstDone);
PCSTR csHttpRequest = bIsModem ? g_csModemHttpRequest : g_csRouterHttpRequest;
PCSTR csAddress = bIsModem ? g_csModemAddress : g_csRouterAddress;
SOCKET s;
SOCKADDR_IN sa = { 0 };
int nBytes;
char sTmp[20];
if (INVALID_SOCKET == (s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)))
{ g_bSuccess = FALSE; g_bProcessing = FALSE; return 0; }
sa.sin_family = AF_INET;
sa.sin_port = htons(80);
sa.sin_addr.s_addr = inet_addr(csAddress);
if (connect(s, (struct sockaddr *)&sa, sizeof(SOCKADDR_IN)))
{ closesocket(s); g_bSuccess = FALSE; g_bProcessing = FALSE; return 0; }
if (SOCKET_ERROR == send(s, csHttpRequest, lstrlen(csHttpRequest), 0))
{ closesocket(s); g_bSuccess = FALSE; g_bProcessing = FALSE; return 0; }
nBytes = recv(s, sTmp, sizeof(sTmp), 0);
shutdown(s, SD_RECEIVE);
closesocket(s);
if (nBytes != sizeof(sTmp))
{ g_bSuccess = FALSE; g_bProcessing = FALSE; return 0; }
// HTTP/1.0 200 OK
if (sTmp[ 8] != ' '
|| sTmp[ 9] != '2'
|| sTmp[10] != '0'
|| sTmp[11] != '0'
|| sTmp[12] != ' ')
{
g_bSuccess = FALSE;
}
g_bProcessing = FALSE;
return 0;
}
void RestartDevice()
{
DWORD dwThreadId;
TypeStatusMessage("Processing...");
g_bProcessing = TRUE; g_bSuccess = TRUE;
SetTimer(g_hWnd, TIMER_PROCESSING, 25, NULL);
CreateThread(NULL, 0, NegotiationThreadProc, NULL, 0, &dwThreadId);
}
#define STATUS_HEIGHT 18
BOOL CALLBACK DlgProc(HWND hDlg, UINT nMsg, WPARAM wParam, LPARAM lParam)
{
switch (nMsg)
{
case WM_INITDIALOG:
g_hWnd = hDlg;
g_hStatus = GetDlgItem(hDlg, ID_LBL_STATUS);
SetWindowPos(hDlg, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
{
RECT rc;
GetClientRect(hDlg, &rc);
SetWindowPos(g_hStatus, NULL, 0, rc.bottom - STATUS_HEIGHT, rc.right, STATUS_HEIGHT, SWP_NOZORDER);
}
SetTimer(NULL, 0, 500, BlinkingTimerProc);
TypeStatusMessage("Ready.");
break;
case WM_TIMER:
if (g_bProcessing)
break;
if (g_nOption == OPTION_BOTH && !g_bFirstDone && g_bSuccess)
{
g_bFirstDone = TRUE;
RestartDevice();
}
else
{
KillTimer(g_hWnd, TIMER_PROCESSING);
if (!g_bSuccess)
TypeStatusMessage("Error.");
else
switch (g_nOption)
{
case OPTION_BOTH: TypeStatusMessage("Modem && router restarted."); break;
case OPTION_MODEM: TypeStatusMessage("Modem restarted."); break;
case OPTION_ROUTER: TypeStatusMessage("Router restarted."); break;
}
}
break;
case WM_COMMAND:
if (g_bProcessing || (HWND)lParam == NULL)
break;
switch (LOWORD(wParam))
{
case ID_BTN_BOTH: g_nOption = OPTION_BOTH; g_bFirstDone = FALSE; break;
case ID_BTN_MODEM: g_nOption = OPTION_MODEM; break;
case ID_BTN_ROUTER: g_nOption = OPTION_ROUTER; break;
}
RestartDevice();
break;
case WM_CLOSE:
EndDialog(hDlg, 0);
break;
default:
return FALSE;
}
return TRUE;
}
#ifdef _DEBUG
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, PSTR psCmdLine, int nShowCmd)
{
#else
void _WinMain(void)
{
HINSTANCE hInst = GetModuleHandle(NULL);
#endif
WSADATA wd;
WSAStartup(0x0101, &wd);
DialogBox(hInst, MAKEINTRESOURCE(ID_DLG_MAIN), HWND_DESKTOP, DlgProc);
WSACleanup();
#ifdef _DEBUG
return 0;
#else
ExitProcess(0);
#endif
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment