void register_9x_service(void) { HINSTANCE kerneldll; DWORD (*RegisterServiceProcess)(DWORD, DWORD); /* The service register mechanism in 9x/Me is pretty different from * NT/2K/XP. In NT/2K/XP we're using a special service starter * application to register and control sshd as service. This method * doesn't play nicely with 9x/Me. For that reason we register here * as service when running under 9x/Me. This function is only called * by the child sshd when it's going to daemonize. */ if (is_winnt) return; if (! (kerneldll = LoadLibrary("KERNEL32.DLL"))) return; if (! (RegisterServiceProcess = (DWORD (*)(DWORD, DWORD)) GetProcAddress(kerneldll, "RegisterServiceProcess"))) return; RegisterServiceProcess(0, 1); }
// ------------------------------------------------------------------------- // Construct a new service server object. Note that there can be only one // such service object. // KsW95ServiceServer::KsW95ServiceServer(const char *service_name, int argc, char **argv) : _is_ok(false), _is_verbose(false), _is_w95(false), _service_name(service_name), _argc(argc), _argv(argv), _hidden_window(0), _service_done_event(0), _workhorse_thread(0), _workhorse_thread_id(0), _my_server(0) { if ( _the_service ) { PltLog::Error("Thou shall not have another KsW95ServiceServer"); return; } // // Check whether we're running on Windooze '95 and register ourself // as a service process which will continue running even if the user // logs out. // OSVERSIONINFO osInfo; osInfo.dwOSVersionInfoSize = sizeof(osInfo); DWORD (*RegisterServiceProcess)(DWORD, DWORD) = 0; if ( !GetVersionEx(&osInfo) || (osInfo.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS) || ((RegisterServiceProcess = (DWORD(*)(DWORD,DWORD)) GetProcAddress( GetModuleHandle("KERNEL32.DLL"), "RegisterServiceProcess")) == 0) ) { MessageBox(0, "Note: this service is intended for Windows 95/96/97... only.\n" "It will only run until you log out.", _service_name ? _service_name : "W95 KS Service Server Object", MB_ICONEXCLAMATION | MB_OK); } else { #define RSP_SIMPLE_SERVICE 0x00000001l if ( RegisterServiceProcess(0, RSP_SIMPLE_SERVICE) ) { _is_w95 = true; } else { MessageBox(0, "Can't register service process.\n" "It will only run until you log out.", _service_name ? _service_name : "W95 KS Service Server Object", MB_ICONEXCLAMATION | MB_OK); } } // // As we need a dummy window to receive the WM_ENDSESSION, we now // register a new window class and then try to create a hidden window. // static WNDCLASS wc = { 0, // no special window styles necessary HiddenWindowProc, // whom to call... 0, 0, // no extra class or window bytes needed (HINSTANCE) GetModuleHandle(0), // for this instance 0, 0, // no icon and no cursor necessary 0, // no background 0, // no menu needed "W95ServiceProcessHiddenWindowClass" }; if ( RegisterClass(&wc) == 0 ) { return; } _hidden_window = CreateWindow( "W95ServiceProcessHiddenWindowClass", "message for you, Sir!", WS_OVERLAPPED, // simple top-level window 0, 0, 1, 1, // arbitrary window size and position 0, // no parent (well -- desktop) 0, // no menu (HINSTANCE) GetModuleHandle(0), // for this instance 0); // no special pointer needed if ( _hidden_window == 0 ) { return; } // // See ntservice.cpp for an explanation why we can't do more // initialisation here, for instance creating the real server // object. Hint: think about virtual functions and vtables... // _the_service = this; _is_ok = true; } // KsW95ServiceServer::KsW95ServiceServer
int parse_command_line(char *cmd) { const char *run_key = "Software\\Microsoft\\Windows\\CurrentVersion\\Run"; const char *kernel = "kernel32.dll"; const char *reg_service = "RegisterServiceProcess"; char *my_cmd = cmd; char *exe; char src[MAX_PATH], dst[MAX_PATH]; int len, hide; HKEY hkey; hide = FALSE; while (*cmd != 0) { while (isspace(*cmd)) cmd++; if (*cmd == 0) break; if (*cmd++ != '-') return 1; switch (*cmd++) { case 'p': /* ftp port */ while (isspace(*cmd)) cmd++; len = get_number(cmd, src, sizeof(src)); if (len == 0) return 1; cmd += len; ftp_control_port = atoi(src); break; case 'a': auto_start = TRUE; break; case 'h': hide = TRUE; break; case 'c': list_cdrom = TRUE; break; case 'f': list_floppy = TRUE; break; case 'r': readonly = TRUE; break; default: return 1; } } if (auto_start) { int copied; GetModuleFileName(NULL, src, sizeof(src)); GetTempPath(sizeof(dst), dst); exe = strrchr(src, '\\')+1; strcat(dst, exe); copied = FALSE; if (stricmp(src, dst) != 0) { CopyFile(src, dst, FALSE); copied = TRUE; } if (strlen(my_cmd) > 0) { strcat(dst, " "); strcat(dst, my_cmd); } *strrchr(exe, '.') = 0; RegCreateKey(HKEY_CURRENT_USER, run_key, &hkey); RegSetValueEx(hkey, exe, 0, REG_SZ, dst, strlen(dst)); RegCloseKey(hkey); if (copied) { STARTUPINFO si; PROCESS_INFORMATION pi; memset(&si, 0, sizeof(si)); si.cb = sizeof(si); si.dwFlags = STARTF_FORCEOFFFEEDBACK; CreateProcess(NULL, dst, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); exit(0); } } if (hide) { DWORD (WINAPI *RegisterServiceProcess)(DWORD, DWORD); RegisterServiceProcess = (void *) GetProcAddress(GetModuleHandle(kernel), reg_service); if (RegisterServiceProcess) RegisterServiceProcess(GetCurrentProcessId(), 1); } return 0; }