Windows: no Windows CE, no Windows 9x

Windows CE (_WINCE: WinMain() and its window, the command line made
into argv, the paths and functions it went without) and Windows 9x
(--install and --remove through the RunServices key of the registry,
which is what GetVersionEx() was asked for) are no longer built for.
--install and --remove use the Service Manager alone; Winsock 2.2 is
asked for, which WSAPoll() needs, rather than 1.1.

The service command of a configuration, deprecated, still does
nothing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Vladimir Dubrovin 2026-10-28 11:56:05 +03:00
parent fa3807c6f1
commit ed49f9ab77
12 changed files with 7 additions and 193 deletions

View File

@ -352,10 +352,6 @@ sudo launchctl unload /Library/LaunchDaemons/org.3proxy.3proxy.plist
- Support `--remove` as service
- Support for service START, STOP, PAUSE and CONTINUE commands (on PAUSE no new connection accepted, but active connections still in progress, on CONTINUE configuration is reloaded)
**Windows 95/98/ME:**
- Support `--install` as service
- Support `--remove` as service
### 7. Compilation
- MSVC (static)

View File

@ -739,8 +739,8 @@ the connection limit has been reached.
.br
.B service
.br
(deprecated). Indicates that 3proxy should behave as a Windows 95/98/NT/2000/XP
service; has no effect under Unix. Not required for 3proxy 0.6 and above. If
(deprecated). Indicates that 3proxy should behave as a Windows service;
has no effect under Unix. Not required for 3proxy 0.6 and above. If
you upgraded from a previous version of 3proxy, use --remove and --install
to reinstall the service.

View File

@ -45,11 +45,9 @@ void doschedule(void);
#ifdef _WIN32
OSVERSIONINFO osv;
int service = 0;
void cyclestep(void);
#ifndef _WINCE
SERVICE_STATUS_HANDLE hSrv;
DWORD dwCurrState;
int SetStatus( DWORD dwState, DWORD dwExitCode, DWORD dwProgress )
@ -105,7 +103,6 @@ void __stdcall ServiceMain(int argc, unsigned char* argv[] )
/* the last thing: the process may be ended once this is reported */
SetStatus( SERVICE_STOPPED, 0, 0 );
}
#endif
#else
@ -297,15 +294,7 @@ void cyclestep(void){
#ifndef _WINCE
int main(int argc, char * argv[]) {
#else
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow){
int argc;
char ** argv;
WNDCLASS wc;
HWND hwnd = 0;
#endif
int res = 0;
FILE * fp = NULL;
@ -315,31 +304,13 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int
WSADATA wd;
unsigned char tmpbuf[8192];
WSAStartup(MAKEWORD( 1, 1 ), &wd);
osv.dwOSVersionInfoSize = sizeof(osv);
GetVersionEx(&osv);
WSAStartup(MAKEWORD( 2, 2 ), &wd);
#endif
#ifdef _WINCE
argc = ceparseargs((char *)lpCmdLine);
argv = ceargv;
if(FindWindow(L"3proxy", L"3proxy")) return 0;
ZeroMemory(&wc,sizeof(wc));
wc.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
wc.hInstance=hInstance;
wc.hCursor=LoadCursor(NULL,IDC_ARROW);
wc.lpfnWndProc=DefWindowProc;
wc.style=CS_HREDRAW|CS_VREDRAW;
wc.lpszClassName=L"3proxy";
RegisterClass(&wc);
hwnd = CreateWindowEx(0,L"3proxy",L"3proxy",WS_VISIBLE|WS_POPUP,0,0,0,0,0,0,hInstance,0);
#endif
conf->stringtable = strings;
#ifdef _WIN32
#ifndef _WINCE
if((argc == 2 || argc == 3)&& !strcmp((char *)argv[1], "--install")) {
sprintf((char *)tmpbuf, "%s will be installed and started.\n"
@ -360,7 +331,7 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int
RETURN(103);
}
strcat((char *)tmpbuf, "\" --service");
if(osv.dwPlatformId == VER_PLATFORM_WIN32_NT){
{
SC_HANDLE sch;
if(!(sch = OpenSCManager(NULL, NULL, GENERIC_WRITE|SERVICE_START ))){
@ -376,33 +347,11 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int
RETURN(103);
}
}
else {
HKEY runsrv;
if(RegOpenKeyEx( HKEY_LOCAL_MACHINE,
"Software\\Microsoft\\Windows\\CurrentVersion\\RunServices",
0,
KEY_ALL_ACCESS,
&runsrv) != ERROR_SUCCESS){
perror("Failed to open registry");
RETURN(104);
}
if(RegSetValueEx( runsrv,
(LPCSTR)conf->stringtable[1],
0,
REG_EXPAND_SZ,
(BYTE *)tmpbuf,
(int)strlen((char *)tmpbuf)+1)!=ERROR_SUCCESS){
perror("Failed to set registry value");
RETURN(105);
}
}
return 0;
}
if((argc == 2 || argc == 3)&& !strcmp((char *)argv[1], "--remove")) {
if(osv.dwPlatformId == VER_PLATFORM_WIN32_NT){
{
SC_HANDLE sch;
if(!(sch = OpenSCManager(NULL, NULL, GENERIC_WRITE))){
@ -418,28 +367,12 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int
RETURN(108);
}
}
else {
HKEY runsrv;
if(RegOpenKeyEx( HKEY_LOCAL_MACHINE,
"Software\\Microsoft\\Windows\\CurrentVersion\\RunServices",
0,
KEY_ALL_ACCESS,
&runsrv) != ERROR_SUCCESS){
perror("Failed to open registry");
RETURN(109);
}
if(RegDeleteValue(runsrv, (LPCSTR)conf->stringtable[1]) != ERROR_SUCCESS){
perror("Failed to clear registry");
RETURN(110);
}
}
RETURN(0);
}
if(argc==3 && !strcmp(argv[2], "--service")){
service = 1;
argc = 2;
}
#endif
#endif
conf->conffile = strdup((argc==2)?argv[1]:(char*)DEFAULTCONFIG);
if(conf->conffile && *conf->conffile != '-') {
@ -472,7 +405,7 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int
written to is an error, not the end */
signal(SIGPIPE, SIG_IGN);
#endif
#if defined _WIN32 && !defined _WINCE
#ifdef _WIN32
if(service) logstdclose();
#endif
sysdnsinit(); /* the system's name servers and hosts, before a chroot too */
@ -532,7 +465,6 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int
#ifdef _WIN32
#ifndef _WINCE
if(service){
SERVICE_TABLE_ENTRY ste[] =
{
@ -545,7 +477,6 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int
}
}
else
#endif
{
cyclestep();
/* what is queued to the logs written */

View File

@ -523,52 +523,6 @@ int sockpoll(struct sockfuncs *sf, void *state, struct pollfd *fds, unsigned nfd
return res;
}
#ifdef _WINCE
static char cebuf[1024];
static char ceargbuf[256];
char * ceargv[32];
char * CEToUnicode (const char *str){
int i;
for(i=0; i<510 && str[i]; i++){
cebuf[(i*2)] = str[i];
cebuf[(i*2)+1] = 0;
}
cebuf[(i*2)] = 0;
cebuf[(i*2)+1] = 0;
return cebuf;
};
int cesystem(const char *str){
STARTUPINFO startupInfo = {0};
startupInfo.cb = sizeof(startupInfo);
PROCESS_INFORMATION processInformation;
return CreateProcessW((LPWSTR)CEToUnicode(str), NULL, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &startupInfo, &processInformation);
}
int ceparseargs(const char *str){
int argc = 0, i;
int space = 1;
for(i=0; i<250 && argc<30 && str[2*i]; i++){
ceargbuf[i] = str[2*i];
if(space && ceargbuf[i]!=' '&& ceargbuf[i]!='\t'&& ceargbuf[i]!='\r'&& ceargbuf[i]!='\n'){
ceargv[argc++] = ceargbuf + i;
space = 0;
}
else if(!space && (ceargbuf[i]==' ' || ceargbuf[i]=='\t' || ceargbuf[i]=='\r' || ceargbuf[i]=='\n')){
ceargbuf[i] = 0;
space = 1;
}
}
return argc;
}
#endif
int parsehost(int family, unsigned char *host, struct sockaddr *sa){
char *sp=NULL,*se=NULL;

View File

@ -194,11 +194,7 @@ static int startservice(void *service){
runningservices++;
_3proxy_mutex_unlock(&runningservices_mutex);
#ifdef _WIN32
#ifndef _WINCE
h = (HANDLE)_beginthreadex((LPSECURITY_ATTRIBUTES )NULL, 16384+conf->stacksize, (void *)startsrv, service, (DWORD)0, &thread);
#else
h = (HANDLE)CreateThread((LPSECURITY_ATTRIBUTES )NULL, 16384+conf->stacksize, (void *)startsrv, service, (DWORD)0, &thread);
#endif
if(h)CloseHandle(h);
else {
#else
@ -1871,20 +1867,12 @@ static int h_plugin(int argc, unsigned char **argv){
HINSTANCE hi;
FARPROC fp;
#ifdef _WINCE
hi = LoadLibraryW((LPCWSTR)CEToUnicode(argv[1]));
#else
hi = LoadLibrary((char *)argv[1]);
#endif
if(!hi) {
fprintf(stderr, "Failed to load %s, code %d\n", argv[1], (int)GetLastError());
return 1;
}
#ifdef _WINCE
fp = GetProcAddressW(hi, (LPCWSTR)CEToUnicode(argv[2]));
#else
fp = GetProcAddress(hi, (char *)argv[2]);
#endif
if(!fp) {
printf("%s not found in %s, code: %d\n", argv[2], argv[1], (int)GetLastError());
return 2;

View File

@ -17,9 +17,7 @@
#define _FIBER_H
#if defined _WIN32
#ifndef _WINCE
#define FIBER_WINDOWS
#endif
#elif defined __x86_64__ && defined __LP64__
#define FIBER_X86_64
#elif defined __aarch64__ && defined __LP64__

View File

@ -835,11 +835,7 @@ static void logstart(struct logger *lg){
}
lg->stop = 0;
#ifdef _WIN32
#ifndef _WINCE
h = (HANDLE)_beginthreadex((LPSECURITY_ATTRIBUTES )NULL, (unsigned)(65536 + lg->type->stacksize), (void *)logthread, (void *)lg, 0, &thread);
#else
h = (HANDLE)CreateThread((LPSECURITY_ATTRIBUTES )NULL, (unsigned)(65536 + lg->type->stacksize), (void *)logthread, (void *)lg, 0, &thread);
#endif
res = !h;
if(h) CloseHandle(h);
#else

View File

@ -19,7 +19,7 @@
#define LOOP_EPOLL
#elif !defined LOOP_POLL && (defined __APPLE__ || defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ || defined __DragonFly__)
#define LOOP_KQUEUE
#elif !defined LOOP_POLL && defined _WIN32 && !defined _WINCE
#elif !defined LOOP_POLL && defined _WIN32
#define LOOP_AFD
#elif !defined LOOP_POLL
#define LOOP_POLL

View File

@ -342,11 +342,7 @@ static int srvspawn(struct srvstart *s, SOCKET client_sock){
a loop given its client once counted */
if(!reused && !job){
#ifdef _WIN32
#ifndef _WINCE
h = (HANDLE)_beginthreadex((LPSECURITY_ATTRIBUTES )NULL, (unsigned)(16384 + srv->stacksize), (void *)threadfunc, (void *) newparam, 0, &thread);
#else
h = (HANDLE)CreateThread((LPSECURITY_ATTRIBUTES )NULL, (unsigned)(16384 + srv->stacksize), (void *)threadfunc, (void *) newparam, 0, &thread);
#endif
if (h) {
CloseHandle(h);
}

View File

@ -17,12 +17,8 @@
#include <fcntl.h>
#include <time.h>
#ifdef _WIN32
#ifndef _WINCE
#include <io.h>
#else
#include <sys/unistd.h>
#endif
#else
#include <unistd.h>
#ifndef O_BINARY
#define O_BINARY (0)

View File

@ -59,11 +59,7 @@
#ifdef _WIN32
#include <winsock2.h>
#include <sys/timeb.h>
#ifndef _WINCE
#include <io.h>
#else
#include <sys/unistd.h>
#endif
#include <process.h>
#define SASIZETYPE int
#define SHUT_RDWR SD_BOTH
@ -109,11 +105,7 @@
#define pthread_self GetCurrentThreadId
#define getpid GetCurrentProcessId
#define pthread_t unsigned
#ifndef _WINCE
#define daemonize() FreeConsole()
#else
#define daemonize()
#endif
#define socket(x, y, z) WSASocket(x, y, z, NULL, 0, 0)
#define accept(x, y, z) WSAAccept(x, y, z, NULL, 0)
#define ftruncate chsize
@ -649,14 +641,6 @@ int getopts(const char *s, struct sockoptset *opts);
void setopts(SOCKET s, const struct sockoptset *opts, int maxseg);
char * printopts(char *sep);
#ifdef _WINCE
char * CEToUnicode (const char *str);
int cesystem(const char *str);
int ceparseargs(const char *str);
extern char * ceargv[32];
#define system(S) cesystem(S)
#endif
#define WEBBANNERS 35

View File

@ -198,19 +198,9 @@ EXIT:
#ifdef STDMAIN
#ifndef _WINCE
int main (int argc, char** argv){
#else
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow){
int argc;
char ** argv;
WNDCLASS wc;
HWND hwnd = 0;
#endif
struct srvstart s;
int res;
#ifndef _WIN32
@ -218,21 +208,6 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int
struct clientparam *newparam;
#endif
#ifdef _WINCE
argc = ceparseargs((char *)lpCmdLine);
argv = ceargv;
if(FindWindow(lpCmdLine, lpCmdLine)) return 0;
ZeroMemory(&wc,sizeof(wc));
wc.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
wc.hInstance=hInstance;
wc.hCursor=LoadCursor(NULL,IDC_ARROW);
wc.lpfnWndProc=DefWindowProc;
wc.style=CS_HREDRAW|CS_VREDRAW;
wc.lpszClassName=lpCmdLine;
RegisterClass(&wc);
hwnd = CreateWindowEx(WS_EX_TOOLWINDOW,lpCmdLine,lpCmdLine,WS_VISIBLE|WS_POPUP,0,0,0,0,0,0,hInstance,0);
#endif
#ifdef _WIN32