/* Minimal Civetweb HTTP server that runs as a standalone process. It accepts form input via HTTP, sends it to a Named Pipe, reads the result from CWP-2 application, and returns it in the browser. */ #include "civetweb.h" #include #include #define PIPE_NAME "\\\\.\\pipe\\CWP-2" #define FORM_FIELD_NAME "user_input" static HANDLE hPipe = INVALID_HANDLE_VALUE; static HANDLE hMutexClient = NULL; // Connects to the named pipe, with retry if needed static BOOL ensure_pipe_connected() { if (hPipe != INVALID_HANDLE_VALUE) { return TRUE; } hPipe = CreateFileA(PIPE_NAME, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); return (hPipe != INVALID_HANDLE_VALUE); } // Sends data to the named pipe and receives a response void send_to_pipe(const char *input, char *output, size_t out_size) { memset(output, 0, out_size); DWORD bytesWritten = 0, bytesRead = 0; if (!ensure_pipe_connected()) { snprintf(output, out_size, "Pipe connection failed."); return; } BOOL success = WriteFile(hPipe, input, (DWORD)strlen(input), &bytesWritten, NULL); if (!success) { CloseHandle(hPipe); hPipe = INVALID_HANDLE_VALUE; snprintf(output, out_size, "Write to pipe failed."); return; } FlushFileBuffers(hPipe); success = ReadFile(hPipe, output, (DWORD)(out_size - 1), &bytesRead, NULL); if (!success) { CloseHandle(hPipe); hPipe = INVALID_HANDLE_VALUE; snprintf(output, out_size, "Read from pipe failed."); return; } output[bytesRead] = '\0'; } int handle_request(struct mg_connection *conn, void *cbdata) { char input[256] = { 0 }; char result[512] = { 0 }; if (mg_get_request_info(conn)->request_method && strcmp(mg_get_request_info(conn)->request_method, "POST") == 0) { char post_data[1024] = { 0 }; int read_len = mg_read(conn, post_data, sizeof(post_data)-1); if (read_len > 0) { post_data[read_len] = '\0'; mg_get_var(post_data, read_len, FORM_FIELD_NAME, input, sizeof(input)); } send_to_pipe(input, result, sizeof(result)); } mg_printf(conn, "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n" "Code Wizard Pro 2" "" "" "" "" "
" "
CODE
" "
EEPROM
" "
" "
" "
" "
" "" "" "
" "
" "" "
" "
" "" "" "
" "
" "
" "
" "

EEPROM functionality is under development.

" "
" "", FORM_FIELD_NAME, input, result); return 1; } int main(void) { const char *options[] = { "listening_ports", "49374", NULL }; struct mg_callbacks callbacks; memset(&callbacks, 0, sizeof(callbacks)); // Check for existence of server mutex HANDLE hMutexServer = OpenMutexA(SYNCHRONIZE, FALSE, "Global\\CWP-2 Server"); if (hMutexServer == NULL) { MessageBoxA(NULL, "Warning: CWP-2 Server is not running.", "CWP-2 Client", MB_OK | MB_ICONWARNING); } else { CloseHandle(hMutexServer); } // Create client mutex hMutexClient = CreateMutexA(NULL, FALSE, "Global\\CWP-2 Client"); struct mg_context *ctx = mg_start(&callbacks, NULL, options); mg_set_request_handler(ctx, "/", handle_request, NULL); printf("Server running on http://localhost:49374\nPress Enter to exit.\n"); getchar(); mg_stop(ctx); if (hPipe != INVALID_HANDLE_VALUE) { CloseHandle(hPipe); } if (hMutexClient != NULL) { CloseHandle(hMutexClient); } return 0; }