//+------------------------------------------------------------------------- // // Function: main // // Arguments: // argc, argv: the passed in argument list. // // Description: This routine initializes the dfs server, and creates // a worker thread that will be responsible for periodic // work (such as scavenging and refreshing). It then calls // into the RPC code to start processing client requests. // //-------------------------------------------------------------------------- #include #include #include #include #include #include #include #include #include #include #include #include "ReferralServerLog.hxx" #include "ReferralServer.tmh" extern void SetReferralControl(WPP_CB_TYPE * Control); #define PRINTF printf DWORD DfsApiInit(); extern void DfsApiShutDown(void); extern DFSSTATUS DfsServerStop( ULONG Flags ); DFSSTATUS ProcessCommandLineArg( LPWSTR Arg ); VOID ReferralServerUsage(); VOID StartDfsService( DWORD dwNumServiceArgs, LPWSTR *lpServiceArgs); DFSSTATUS DfsStartupServer(); VOID DfsSvcMsgProc( DWORD dwControl); static void UpdateServiceStatus( SERVICE_STATUS_HANDLE hService, SERVICE_STATUS *pSStatus, DWORD Status); VOID DfsSvcMsgProc( DWORD dwControl); SERVICE_STATUS ServiceStatus; SERVICE_STATUS_HANDLE hDfsService; const PWSTR wszDfsServiceName = L"DfsService"; #define MAKEARG(x) \ WCHAR Arg##x[] = L"/" L#x L":"; \ LONG ArgLen##x = (sizeof(Arg##x) / sizeof(WCHAR)) - 1; \ BOOLEAN fArg##x; #define SWITCH(x) \ WCHAR Switch##x[] = L"/" L#x ; \ BOOLEAN fSwitch##x; // // The arguments we accept at commandline. // MAKEARG(Name); SWITCH(L); SWITCH(D); SWITCH(M); SWITCH(NoService); SWITCH(Trace); ULONG Flags = DFS_LOCAL_NAMESPACE; #if defined (DFS_RUN_SERVICE) //+---------------------------------------------------------------------------- // // Function: WinMain // // Synopsis: This guy will set up link to service manager and install // ServiceMain as the service's entry point. Hopefully, the service // control dispatcher will call ServiceMain soon thereafter. // // Arguments: // // Returns: // //----------------------------------------------------------------------------- int WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) { UNREFERENCED_PARAMETER(hInstance); UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpszCmdLine); UNREFERENCED_PARAMETER(nCmdShow); SERVICE_TABLE_ENTRYW aServiceEntry[2]; LPWSTR *argvw; DFSSTATUS Status = ERROR_SUCCESS; int argcw = 0; int i; LPWSTR CommandLine; BOOL fConsole = TRUE; HANDLE StdOut = NULL; WPP_CB_TYPE *pLogger = NULL; pLogger = &WPP_CB[WPP_CTRL_NO(WPP_BIT_CLI_DRV)]; WPP_INIT_TRACING(L"DfsReferralServer"); SetReferralControl(pLogger); CommandLine = GetCommandLine(); argvw = CommandLineToArgvW(CommandLine, &argcw); // // Process each argument on the command line. // for (i = 1; i < argcw; i++) { Status = ProcessCommandLineArg(argvw[i]); if (fArgName == TRUE && fSwitchL == TRUE) { PRINTF("/L and /Name: are mutually exclusive"); Status = ERROR_INVALID_PARAMETER; } if (Status != ERROR_SUCCESS) { ReferralServerUsage(); break; } } if (Status == ERROR_SUCCESS) { if (fSwitchNoService != TRUE) { aServiceEntry[0].lpServiceName = wszDfsServiceName; aServiceEntry[0].lpServiceProc = StartDfsService; aServiceEntry[1].lpServiceName = NULL; aServiceEntry[1].lpServiceProc = NULL; if (!StartServiceCtrlDispatcherW(aServiceEntry)) { return(GetLastError()); } return(0); } else { Status = DfsStartupServer(); while (Status == ERROR_SUCCESS) { Sleep(3000000); } PRINTF("DfsServer is exiting with status %x\n", Status); exit(0); } } WPP_CLEANUP(); exit(1); } #if 0 VOID __cdecl MyPrintf( LPSTR lpFmt, ... ) { va_list base; va_start(base,lpFmt); wvsprintf(vrgchLibBuff, lpFmt, base); OutputDebugString(vrgchLibBuff); } #endif #else _cdecl main( int argc, char *argv[]) { LPWSTR CommandLine; LPWSTR *argvw; DFSSTATUS Status = ERROR_SUCCESS; int argcw,i; SERVICE_TABLE_ENTRYW aServiceEntry[2]; WPP_CB_TYPE *pLogger = NULL; pLogger = &WPP_CB[WPP_CTRL_NO(WPP_BIT_CLI_DRV)]; WPP_INIT_TRACING(L"DfsReferralServer"); SetReferralControl(pLogger); // // Get the command line in Unicode // CommandLine = GetCommandLine(); argvw = CommandLineToArgvW(CommandLine, &argcw); // // Process each argument on the command line. // for (i = 1; i < argcw; i++) { Status = ProcessCommandLineArg(argvw[i]); if (fArgName == TRUE && fSwitchL == TRUE) { printf("/L and /Name: are mutually exclusive"); Status = ERROR_INVALID_PARAMETER; } if (Status != ERROR_SUCCESS) { ReferralServerUsage(); break; } } if (Status == ERROR_SUCCESS) { Status = DfsStartupServer(); DFS_TRACE_HIGH(REFERRAL_SERVER,"ReferralServer Initialized with error %x", Status); while (Status == ERROR_SUCCESS) { Sleep(3000000); } } printf("DfsServer is exiting with status %x\n", Status); WPP_CLEANUP(); exit(0); } #endif // DFS_NO_SERVICE DFSSTATUS DfsStartupServer() { DFSSTATUS Status = ERROR_SUCCESS; // // Initialize the server. // if (Flags & DFS_LOCAL_NAMESPACE) { Flags |= DFS_CREATE_DIRECTORIES; } Flags |= DFS_POST_EVENT_LOG; Status = DfsServerInitialize( Flags ); if (Status == ERROR_SUCCESS) { // // initialize the DfS api. // Status = DfsApiInit(); } return Status; } void DfsShutdownServer(void) { DfsApiShutDown(); DfsServerStop(0); } //+------------------------------------------------------------------------- // // Function: ProcessCommandLineArg - process the command line // // Arguments: Arg - the argument to process // // Returns: Status // ERROR_SUCCESS on success // ERROR status code otherwise // // // Description: This routine inteprets the passed in argument and // sets appropriate flags with which the server should // be initialized. // //-------------------------------------------------------------------------- DFSSTATUS ProcessCommandLineArg( LPWSTR Arg ) { LONG ArgLen; DFSSTATUS Status = ERROR_SUCCESS; LPWSTR NameSpace; if (Arg == NULL) { Status = ERROR_INVALID_PARAMETER; } if (Status == ERROR_SUCCESS) { ArgLen = wcslen(Arg); if (_wcsnicmp(Arg, ArgName, ArgLenName) == 0) { fArgName = TRUE; NameSpace = &Arg[ArgLenName]; if (wcslen(NameSpace) == 0) { Status = ERROR_INVALID_PARAMETER; } else { Status = DfsAddHandledNamespace( NameSpace, TRUE ); } } else if (_wcsicmp(Arg, SwitchTrace) == 0) { fSwitchTrace = TRUE; } else if (_wcsicmp(Arg, SwitchL) == 0) { fSwitchL = TRUE; Flags |= DFS_LOCAL_NAMESPACE; } else if (_wcsicmp(Arg, SwitchNoService) == 0) { fSwitchNoService = TRUE; } else if (_wcsicmp(Arg, SwitchD) == 0) { Flags |= DFS_CREATE_DIRECTORIES; } else if (_wcsicmp(Arg, SwitchM) == 0) { Flags |= DFS_MIGRATE; } else { Status = STATUS_INVALID_PARAMETER; } } return Status; } // // Function: ReferralServerUsage. Usage printout for the referral server. // VOID ReferralServerUsage() { printf("Usage:\n"); printf("/D - Create directories\n"); printf("/L - Run on the local root server\n"); printf("/M - Migrate existing DFS to allow multiple roots\n"); printf("/Name: - Handle referrals to the specified namespace\n"); printf("/NoService - Dont start as a service\n"); printf("/trace - enable tracing\n"); return; } //+---------------------------------------------------------------------------- // // Function: StartDfsService // // Synopsis: Call back for DfsService service. This is called *once* by the // Service controller when the DfsService service is to be inited // This function is responsible for registering a message // handler function for the DfsService service. // // Arguments: Unused // // Returns: Nothing // //----------------------------------------------------------------------------- VOID StartDfsService( DWORD dwNumServiceArgs, LPWSTR *lpServiceArgs) { DFSSTATUS Status; UNREFERENCED_PARAMETER(dwNumServiceArgs); UNREFERENCED_PARAMETER(lpServiceArgs); hDfsService = RegisterServiceCtrlHandlerW( wszDfsServiceName, DfsSvcMsgProc); if (!hDfsService) { return; } ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; ServiceStatus.dwCurrentState = SERVICE_STOPPED; ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; ServiceStatus.dwWin32ExitCode = 0; ServiceStatus.dwServiceSpecificExitCode = 0; ServiceStatus.dwCheckPoint = 0; ServiceStatus.dwWaitHint = 1000 * 30; UpdateServiceStatus( hDfsService, &ServiceStatus, SERVICE_START_PENDING); Status = DfsStartupServer(); if (Status == ERROR_SUCCESS) { UpdateServiceStatus( hDfsService, &ServiceStatus, SERVICE_RUNNING); } else { UpdateServiceStatus( hDfsService, &ServiceStatus, SERVICE_STOPPED); } return; } //+---------------------------------------------------------------------------- // // Function: DfsSvcMsgProc // // Synopsis: Service-Message handler for DFSInit. // // Arguments: [dwControl] - the message // // Returns: nothing // //----------------------------------------------------------------------------- VOID DfsSvcMsgProc(DWORD dwControl) { switch(dwControl) { case SERVICE_CONTROL_STOP: // // dfsdev: need to do something to stop the service! // DfsShutdownServer(); UpdateServiceStatus( hDfsService, &ServiceStatus, SERVICE_STOPPED); CoUninitialize(); break; case SERVICE_INTERROGATE: UpdateServiceStatus( hDfsService, &ServiceStatus, ServiceStatus.dwCurrentState); break; default: break; } } //+---------------------------------------------------------------------------- // // Function: UpdateServiceStatus // // Synopsis: Pushes a ServiceStatus to the service manager. // // Arguments: [hService] - handle returned from RegisterServiceCtrlHandler // [pSStatus] - pointer to service-status block // [Status] - The status to set. // // Returns: Nothing. // //----------------------------------------------------------------------------- static void UpdateServiceStatus( SERVICE_STATUS_HANDLE hService, SERVICE_STATUS *pSStatus, DWORD Status) { pSStatus->dwCurrentState = Status; if (Status == SERVICE_START_PENDING) { pSStatus->dwCheckPoint++; pSStatus->dwWaitHint = 1000; } else { pSStatus->dwCheckPoint = 0; pSStatus->dwWaitHint = 0; } SetServiceStatus(hService, pSStatus); }