/*++ Copyright (c) 1992-1993 Microsoft Corporation Module Name: ExpStart.c Abstract: Contains ExportDirStartRepl(). Author: John Rogers (JohnRo) 10-Feb-1992 Environment: User mode only. Requires ANSI C extensions: slash-slash comments, long external names. Tab size is set to 4. Revision History: 09-Feb-1992 JohnRo Created this routine to allow dynamic role changes. 05-Mar-1992 JohnRo Changed interface to match new service controller. 06-Mar-1992 JohnRo Avoid starting RPC server too soon. 22-Mar-1992 JohnRo Added more debug output. 01-Apr-1992 JohnRo Up the stack size, just to be on the safe side. Avoid assertion if export startup fails. 09-Jul-1992 JohnRo RAID 10503: srv mgr: repl dialog doesn't come up. Use PREFIX_ equates. 19-Aug-1992 JohnRo RAID 2115: repl svc should wait while stopping or changing role. 11-Mar-1993 JohnRo RAID 12100: stopping repl sometimes goes into infinite loop. 02-Apr-1993 JohnRo Use NetpKdPrint() where possible. 24-May-1993 JohnRo RAID 10587: repl could deadlock with changed NetpStopRpcServer(), so just call ExitProcess() instead. --*/ // These must be included first: #include // CreateThread(), DWORD, etc. #include // IN, NET_API_STATUS, etc. // These may be included in any order: #include // My prototype. #include // DBGSTATIC, NetpKdPrint(), FORMAT_ equates. #include // PREFIX_ equates. #include // IF_DEBUG(). #include // ReplGlobalMasterThreadHandle. #include // ERROR_ and NO_ERROR equates. #define MASTER_STACK_SIZE (24 * 1024) /* BUGBUG: Wild guess! */ // Start replicating (exporting). Wait for master thread to startup. // Called when service starts or user does NetReplSetInfo() and changes role. NET_API_STATUS ExportDirStartRepl ( IN BOOL ServiceIsStarting ) { NET_API_STATUS ApiStatus; DWORD EventTriggered; DWORD ThreadID; LPVOID ThreadParm; // NULL if service is starting; // non-NULL if role is changing. HANDLE WaitHandles[3]; IF_DEBUG( MASTER ) { NetpKdPrint(( PREFIX_REPL_MASTER "ExportDirStartRepl: beginning...\n" )); } // Reset events in case we've ever been running before. (VOID) ResetEvent( ReplGlobalExportStartupEvent ); (VOID) ResetEvent( ReplGlobalMasterTerminateEvent ); if (ServiceIsStarting) { ThreadParm = NULL; } else { ThreadParm = (LPVOID) & ApiStatus; // any non-NULL addr will do. } // // Start up master thread. // ReplGlobalMasterThreadHandle = CreateThread( NULL, MASTER_STACK_SIZE, ReplMasterMain, ThreadParm, 0, &ThreadID); // // Handle error starting thread. // if (ReplGlobalMasterThreadHandle == NULL) { ApiStatus = (NET_API_STATUS) GetLastError(); NetpAssert( ApiStatus != NO_ERROR ); ReplFinish( ApiStatus ); return (ApiStatus); } // // Wait for master to setup. // WaitHandles[0] = ReplGlobalMasterTerminateEvent; // terminate WaitHandles[1] = ReplGlobalExportStartupEvent; // master success WaitHandles[2] = ReplGlobalMasterThreadHandle; // master died #define DUMP_WAIT_HANDLES( array, total ) \ { \ DWORD index; \ for (index=0; index