1) Services and Registry are not part of the core Apache operations,
so registry.c and service.c are moved into Apache.exe - assuring
the service control layers of NT and 95 are truly isolated.
2) Isolation can't be complete, we need to know when the mpm is
fully initialized. A new pointer to a no-arg function returning
void is provided for this purpose, ap_mpm_init_complete. It is
only called if overridden with a non-NULL value prior to invoking
apache_main.
3) Control+C, Control+Break are handled on both WinNT and Win9x.
4) The window close, logoff and shutdown events are handled on WinNT.
5) The beginnings of a Win95 service startup are provided, -k startservice
but this is horribly incomplete since Win95 will NOT report shutdown.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@85235
13f79535-47bb-0310-9956-
ffa450edef68
SOURCE=.\os\win32\main_win32.c
# End Source File
+# Begin Source File
+
+SOURCE=.\os\win32\registry.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\os\win32\service.c
+# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
+# Begin Source File
+
+SOURCE=.\os\win32\registry.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\os\win32\service.h
+# End Source File
# End Group
# Begin Group "Resource Files"
# Begin Source File
SOURCE=.\os\win32\apache.rc
+
+!IF "$(CFG)" == "Apache - Win32 Release"
+
+!ELSEIF "$(CFG)" == "Apache - Win32 Debug"
+
+!ENDIF
+
# End Source File
# End Group
# End Target
regerror @364
ap_send_error_response @365
ap_start_shutdown @366
- send_signal_to_service @367
+; send_signal_to_service @367
ap_read_config @368
ap_server_pre_read_config @369
ap_server_post_read_config @370
ap_setup_prelinked_modules @371
- RemoveService @372
- InstallService @373
- isValidService @374
- service_main @375
- isProcessService @376
- ap_registry_get_server_root @377
- ap_registry_get_service_conf @378
+; RemoveService @372
+; InstallService @373
+; isValidService @374
+; service_main @375
+; isProcessService @376
+; ap_registry_get_server_root @377
+; ap_registry_get_service_conf @378
ap_hook_pre_connection @379
ap_hook_post_read_request @380
ap_hook_log_transaction @381
ap_run_http_method @394
ap_bread_core @395
ap_bwrite_core @396
+ ap_mpm_init_complete @397
# End Source File
# Begin Source File
-SOURCE=.\os\win32\registry.c
-# End Source File
-# Begin Source File
-
SOURCE=.\main\rfc1413.c
# End Source File
# Begin Source File
-SOURCE=.\os\win32\service.c
-# End Source File
-# Begin Source File
-
SOURCE=.\main\util.c
# End Source File
# Begin Source File
# End Source File
# Begin Source File
-SOURCE=.\os\win32\registry.h
-# End Source File
-# Begin Source File
-
SOURCE=.\include\rfc1413.h
# End Source File
# Begin Source File
-SOURCE=.\os\win32\service.h
-# End Source File
-# Begin Source File
-
SOURCE=.\include\util_cfgtree.h
# End Source File
# Begin Source File
# End Source File
# Begin Source File
-SOURCE=.\os\win32\registry.c
-# End Source File
-# Begin Source File
-
SOURCE=.\main\rfc1413.c
# End Source File
# Begin Source File
-SOURCE=.\os\win32\service.c
-# End Source File
-# Begin Source File
-
SOURCE=.\main\util.c
# End Source File
# Begin Source File
# End Source File
# Begin Source File
-SOURCE=.\os\win32\registry.h
-# End Source File
-# Begin Source File
-
SOURCE=.\include\rfc1413.h
# End Source File
# Begin Source File
-SOURCE=.\os\win32\service.h
-# End Source File
-# Begin Source File
-
SOURCE=.\include\util_cfgtree.h
# End Source File
# Begin Source File
server_rec *ap_read_config(process_rec *process, ap_pool_t *temp_pool, const char *config_name);
void ap_post_config_hook(ap_pool_t *pconf, ap_pool_t *plog, ap_pool_t *ptemp, server_rec *s);
void ap_child_init_hook(ap_pool_t *pchild, server_rec *s);
+void ap_run_pre_config(ap_pool_t *p, ap_pool_t *plog, ap_pool_t *ptemp);
void ap_register_hooks(module *m);
void ap_hook_deregister_all(void);
regerror @364
ap_send_error_response @365
ap_start_shutdown @366
- send_signal_to_service @367
+; send_signal_to_service @367
ap_read_config @368
ap_server_pre_read_config @369
ap_server_post_read_config @370
ap_setup_prelinked_modules @371
- RemoveService @372
- InstallService @373
- isValidService @374
- service_main @375
- isProcessService @376
- ap_registry_get_server_root @377
- ap_registry_get_service_conf @378
+; RemoveService @372
+; InstallService @373
+; isValidService @374
+; service_main @375
+; isProcessService @376
+; ap_registry_get_server_root @377
+; ap_registry_get_service_conf @378
ap_hook_pre_connection @379
ap_hook_post_read_request @380
ap_hook_log_transaction @381
ap_run_http_method @394
ap_bread_core @395
ap_bwrite_core @396
+ ap_mpm_init_complete @397
#define USE_MMAP_SCOREBOARD
#define HAVE_CANONICAL_FILENAME
#define HAVE_DRIVE_LETTERS
-#define HAVE_SENDFILE
+#define HAVE_SENDFILE_UNKNOWN
typedef int uid_t;
typedef int gid_t;
ap_pool_t *g_pHookPool;
#ifdef WIN32
-API_EXPORT_NONSTD(int) apache_main(int argc, char *argv[])
+API_EXPORT(int) apache_main(int argc, char *argv[])
#else
-API_EXPORT_NONSTD(int) main(int argc, char *argv[])
+API_EXPORT(int) main(int argc, char *argv[])
#endif
{
int c;
#include "ap_config.h"
#include "ap_listen.h"
#include "mpm_default.h"
-#include "service.h"
+//#include "service.h"
#include "iol_socket.h"
#include "winnt.h"
ap_lock_t *start_mutex;
int my_pid;
int parent_pid;
+typedef void (CALLBACK *ap_completion_t)();
+API_VAR_EXPORT ap_completion_t ap_mpm_init_complete = NULL;
static ap_status_t socket_cleanup(void *sock)
{
/* Create child process
* Should only be one in this version of Apache for WIN32
*/
- service_set_status(SERVICE_START_PENDING);
+ //service_set_status(SERVICE_START_PENDING);
while (remaining_children_to_start--) {
if (create_process(pconf, process_handles, process_kill_events,
¤t_live_processes) < 0) {
goto die_now;
}
}
- service_set_status(SERVICE_RUNNING);
+ //service_set_status(SERVICE_RUNNING);
restart_pending = shutdown_pending = 0;
}
ap_log_pid(pconf, ap_pid_fname);
- service_set_status(SERVICE_START_PENDING);
+ //service_set_status(SERVICE_START_PENDING);
/* Create shutdown event, apPID_shutdown, where PID is the parent
* Apache process ID. Shutdown is signaled by 'apache -k shutdown'.
exit(1);
}
CleanNullACL((void *)sa);
-
+
+ if (ap_mpm_init_complete)
+ ap_mpm_init_complete();
+
/* Create the start mutex, apPID, where PID is the parent Apache process ID.
* Ths start mutex is used during a restart to prevent more than one
* child process from entering the accept loop at once.
CloseHandle(restart_event);
CloseHandle(shutdown_event);
- service_set_status(SERVICE_STOPPED);
+ //service_set_status(SERVICE_STOPPED);
return 1;
}
#include "registry.h"
#include "ap_mpm.h"
+typedef void (CALLBACK *ap_completion_t)();
+API_VAR_IMPORT ap_completion_t ap_mpm_init_complete;
+
static struct
{
int (*main_fn)(int, char **);
static int ap_start_service(SC_HANDLE);
static int ap_stop_service(SC_HANDLE);
+static void CALLBACK report_service95_running()
+{
+ FreeConsole();
+
+ /* We do this only once, ever */
+ ap_mpm_init_complete = NULL;
+}
+
+int service95_main(int (*main_fn)(int, char **), int argc, char **argv )
+{
+ HINSTANCE hkernel;
+ DWORD (WINAPI *RegisterServiceProcess)(DWORD, DWORD);
+
+ /* Obtain a handle to the kernel library */
+ hkernel = LoadLibrary("KERNEL32.DLL");
+ if (!hkernel)
+ return -1;
+
+ /* Find the RegisterServiceProcess function */
+ RegisterServiceProcess = (DWORD (WINAPI *)(DWORD, DWORD))
+ GetProcAddress(hkernel, "RegisterServiceProcess");
+ if (RegisterServiceProcess == NULL)
+ return -1;
+
+ /* Register this process as a service */
+ if (!RegisterServiceProcess((DWORD)NULL, 1))
+ return -1;
+
+ /* Eliminate the console for the remainer of the service session */
+ ap_mpm_init_complete = report_service95_running;
+
+ /* Run the service */
+ globdat.exit_status = main_fn(argc, argv);
+
+ /* When the service quits, remove it from the
+ system service table */
+ RegisterServiceProcess((DWORD)NULL, 0);
+
+ /* Free the kernel library */
+ // Worthless, methinks, since it won't be reclaimed
+ // FreeLibrary(hkernel);
+
+ /* We have to quit right here to avoid an invalid page fault */
+ // But, this is worth experimenting with!
+ return (globdat.exit_status);
+}
+
int service_main(int (*main_fn)(int, char **), int argc, char **argv )
{
SERVICE_TABLE_ENTRY dispatchTable[] =
chdir(buf);
}
+static void CALLBACK report_service_started()
+{
+ ReportStatusToSCMgr(
+ SERVICE_RUNNING, // service state
+ NO_ERROR, // exit code
+ 0); // wait hint
+
+ /* This is only reported once, ever! */
+ ap_mpm_init_complete = NULL;
+}
+
void __stdcall service_main_fn(DWORD argc, LPTSTR *argv)
{
int i, new_argc;
NO_ERROR, // exit code
3000); // wait hint
+ ap_mpm_init_complete = report_service_started;
+
service_cd();
/* Fetch server_conf from the registry