Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

537 lines
12 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Function: main
  4. //
  5. // Arguments:
  6. // argc, argv: the passed in argument list.
  7. //
  8. // Description: This routine initializes the dfs server, and creates
  9. // a worker thread that will be responsible for periodic
  10. // work (such as scavenging and refreshing). It then calls
  11. // into the RPC code to start processing client requests.
  12. //
  13. //--------------------------------------------------------------------------
  14. #include <nt.h>
  15. #include <ntrtl.h>
  16. #include <nturtl.h>
  17. #include <windows.h>
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <stddef.h>
  21. #include <shellapi.h>
  22. #include <ole2.h>
  23. #include <activeds.h>
  24. #include <DfsServerLibrary.hxx>
  25. #include "ReferralServerLog.hxx"
  26. #include "ReferralServer.tmh"
  27. extern
  28. void
  29. SetReferralControl(WPP_CB_TYPE * Control);
  30. #define PRINTF printf
  31. DWORD
  32. DfsApiInit();
  33. extern
  34. void
  35. DfsApiShutDown(void);
  36. extern DFSSTATUS
  37. DfsServerStop(
  38. ULONG Flags );
  39. DFSSTATUS
  40. ProcessCommandLineArg( LPWSTR Arg );
  41. VOID
  42. ReferralServerUsage();
  43. VOID
  44. StartDfsService(
  45. DWORD dwNumServiceArgs,
  46. LPWSTR *lpServiceArgs);
  47. DFSSTATUS
  48. DfsStartupServer();
  49. VOID DfsSvcMsgProc(
  50. DWORD dwControl);
  51. static void
  52. UpdateServiceStatus(
  53. SERVICE_STATUS_HANDLE hService,
  54. SERVICE_STATUS *pSStatus,
  55. DWORD Status);
  56. VOID
  57. DfsSvcMsgProc(
  58. DWORD dwControl);
  59. SERVICE_STATUS ServiceStatus;
  60. SERVICE_STATUS_HANDLE hDfsService;
  61. const PWSTR wszDfsServiceName = L"DfsService";
  62. #define MAKEARG(x) \
  63. WCHAR Arg##x[] = L"/" L#x L":"; \
  64. LONG ArgLen##x = (sizeof(Arg##x) / sizeof(WCHAR)) - 1; \
  65. BOOLEAN fArg##x;
  66. #define SWITCH(x) \
  67. WCHAR Switch##x[] = L"/" L#x ; \
  68. BOOLEAN fSwitch##x;
  69. //
  70. // The arguments we accept at commandline.
  71. //
  72. MAKEARG(Name);
  73. SWITCH(L);
  74. SWITCH(D);
  75. SWITCH(M);
  76. SWITCH(NoService);
  77. SWITCH(Trace);
  78. ULONG Flags = DFS_LOCAL_NAMESPACE;
  79. #if defined (DFS_RUN_SERVICE)
  80. //+----------------------------------------------------------------------------
  81. //
  82. // Function: WinMain
  83. //
  84. // Synopsis: This guy will set up link to service manager and install
  85. // ServiceMain as the service's entry point. Hopefully, the service
  86. // control dispatcher will call ServiceMain soon thereafter.
  87. //
  88. // Arguments:
  89. //
  90. // Returns:
  91. //
  92. //-----------------------------------------------------------------------------
  93. int WinMain(
  94. HINSTANCE hInstance,
  95. HINSTANCE hPrevInstance,
  96. LPSTR lpszCmdLine,
  97. int nCmdShow)
  98. {
  99. UNREFERENCED_PARAMETER(hInstance);
  100. UNREFERENCED_PARAMETER(hPrevInstance);
  101. UNREFERENCED_PARAMETER(lpszCmdLine);
  102. UNREFERENCED_PARAMETER(nCmdShow);
  103. SERVICE_TABLE_ENTRYW aServiceEntry[2];
  104. LPWSTR *argvw;
  105. DFSSTATUS Status = ERROR_SUCCESS;
  106. int argcw = 0;
  107. int i;
  108. LPWSTR CommandLine;
  109. BOOL fConsole = TRUE;
  110. HANDLE StdOut = NULL;
  111. WPP_CB_TYPE *pLogger = NULL;
  112. pLogger = &WPP_CB[WPP_CTRL_NO(WPP_BIT_CLI_DRV)];
  113. WPP_INIT_TRACING(L"DfsReferralServer");
  114. SetReferralControl(pLogger);
  115. CommandLine = GetCommandLine();
  116. argvw = CommandLineToArgvW(CommandLine, &argcw);
  117. //
  118. // Process each argument on the command line.
  119. //
  120. for (i = 1; i < argcw; i++) {
  121. Status = ProcessCommandLineArg(argvw[i]);
  122. if (fArgName == TRUE && fSwitchL == TRUE)
  123. {
  124. PRINTF("/L and /Name: are mutually exclusive");
  125. Status = ERROR_INVALID_PARAMETER;
  126. }
  127. if (Status != ERROR_SUCCESS)
  128. {
  129. ReferralServerUsage();
  130. break;
  131. }
  132. }
  133. if (Status == ERROR_SUCCESS)
  134. {
  135. if (fSwitchNoService != TRUE)
  136. {
  137. aServiceEntry[0].lpServiceName = wszDfsServiceName;
  138. aServiceEntry[0].lpServiceProc = StartDfsService;
  139. aServiceEntry[1].lpServiceName = NULL;
  140. aServiceEntry[1].lpServiceProc = NULL;
  141. if (!StartServiceCtrlDispatcherW(aServiceEntry)) {
  142. return(GetLastError());
  143. }
  144. return(0);
  145. }
  146. else
  147. {
  148. Status = DfsStartupServer();
  149. while (Status == ERROR_SUCCESS)
  150. {
  151. Sleep(3000000);
  152. }
  153. PRINTF("DfsServer is exiting with status %x\n", Status);
  154. exit(0);
  155. }
  156. }
  157. WPP_CLEANUP();
  158. exit(1);
  159. }
  160. #if 0
  161. VOID
  162. __cdecl MyPrintf(
  163. LPSTR lpFmt,
  164. ...
  165. )
  166. {
  167. va_list base;
  168. va_start(base,lpFmt);
  169. wvsprintf(vrgchLibBuff, lpFmt, base);
  170. OutputDebugString(vrgchLibBuff);
  171. }
  172. #endif
  173. #else
  174. _cdecl
  175. main(
  176. int argc,
  177. char *argv[])
  178. {
  179. LPWSTR CommandLine;
  180. LPWSTR *argvw;
  181. DFSSTATUS Status = ERROR_SUCCESS;
  182. int argcw,i;
  183. SERVICE_TABLE_ENTRYW aServiceEntry[2];
  184. WPP_CB_TYPE *pLogger = NULL;
  185. pLogger = &WPP_CB[WPP_CTRL_NO(WPP_BIT_CLI_DRV)];
  186. WPP_INIT_TRACING(L"DfsReferralServer");
  187. SetReferralControl(pLogger);
  188. //
  189. // Get the command line in Unicode
  190. //
  191. CommandLine = GetCommandLine();
  192. argvw = CommandLineToArgvW(CommandLine, &argcw);
  193. //
  194. // Process each argument on the command line.
  195. //
  196. for (i = 1; i < argcw; i++) {
  197. Status = ProcessCommandLineArg(argvw[i]);
  198. if (fArgName == TRUE && fSwitchL == TRUE)
  199. {
  200. printf("/L and /Name: are mutually exclusive");
  201. Status = ERROR_INVALID_PARAMETER;
  202. }
  203. if (Status != ERROR_SUCCESS)
  204. {
  205. ReferralServerUsage();
  206. break;
  207. }
  208. }
  209. if (Status == ERROR_SUCCESS)
  210. {
  211. Status = DfsStartupServer();
  212. DFS_TRACE_HIGH(REFERRAL_SERVER,"ReferralServer Initialized with error %x", Status);
  213. while (Status == ERROR_SUCCESS)
  214. {
  215. Sleep(3000000);
  216. }
  217. }
  218. printf("DfsServer is exiting with status %x\n", Status);
  219. WPP_CLEANUP();
  220. exit(0);
  221. }
  222. #endif // DFS_NO_SERVICE
  223. DFSSTATUS
  224. DfsStartupServer()
  225. {
  226. DFSSTATUS Status = ERROR_SUCCESS;
  227. //
  228. // Initialize the server.
  229. //
  230. if (Flags & DFS_LOCAL_NAMESPACE)
  231. {
  232. Flags |= DFS_CREATE_DIRECTORIES;
  233. }
  234. Flags |= DFS_POST_EVENT_LOG;
  235. Status = DfsServerInitialize( Flags );
  236. if (Status == ERROR_SUCCESS) {
  237. //
  238. // initialize the DfS api.
  239. //
  240. Status = DfsApiInit();
  241. }
  242. return Status;
  243. }
  244. void
  245. DfsShutdownServer(void)
  246. {
  247. DfsApiShutDown();
  248. DfsServerStop(0);
  249. }
  250. //+-------------------------------------------------------------------------
  251. //
  252. // Function: ProcessCommandLineArg - process the command line
  253. //
  254. // Arguments: Arg - the argument to process
  255. //
  256. // Returns: Status
  257. // ERROR_SUCCESS on success
  258. // ERROR status code otherwise
  259. //
  260. //
  261. // Description: This routine inteprets the passed in argument and
  262. // sets appropriate flags with which the server should
  263. // be initialized.
  264. //
  265. //--------------------------------------------------------------------------
  266. DFSSTATUS
  267. ProcessCommandLineArg( LPWSTR Arg )
  268. {
  269. LONG ArgLen;
  270. DFSSTATUS Status = ERROR_SUCCESS;
  271. LPWSTR NameSpace;
  272. if (Arg == NULL) {
  273. Status = ERROR_INVALID_PARAMETER;
  274. }
  275. if (Status == ERROR_SUCCESS)
  276. {
  277. ArgLen = wcslen(Arg);
  278. if (_wcsnicmp(Arg, ArgName, ArgLenName) == 0)
  279. {
  280. fArgName = TRUE;
  281. NameSpace = &Arg[ArgLenName];
  282. if (wcslen(NameSpace) == 0)
  283. {
  284. Status = ERROR_INVALID_PARAMETER;
  285. }
  286. else {
  287. Status = DfsAddHandledNamespace( NameSpace, TRUE );
  288. }
  289. }
  290. else if (_wcsicmp(Arg, SwitchTrace) == 0)
  291. {
  292. fSwitchTrace = TRUE;
  293. }
  294. else if (_wcsicmp(Arg, SwitchL) == 0)
  295. {
  296. fSwitchL = TRUE;
  297. Flags |= DFS_LOCAL_NAMESPACE;
  298. }
  299. else if (_wcsicmp(Arg, SwitchNoService) == 0)
  300. {
  301. fSwitchNoService = TRUE;
  302. }
  303. else if (_wcsicmp(Arg, SwitchD) == 0)
  304. {
  305. Flags |= DFS_CREATE_DIRECTORIES;
  306. }
  307. else if (_wcsicmp(Arg, SwitchM) == 0)
  308. {
  309. Flags |= DFS_MIGRATE;
  310. }
  311. else {
  312. Status = STATUS_INVALID_PARAMETER;
  313. }
  314. }
  315. return Status;
  316. }
  317. //
  318. // Function: ReferralServerUsage. Usage printout for the referral server.
  319. //
  320. VOID
  321. ReferralServerUsage()
  322. {
  323. printf("Usage:\n");
  324. printf("/D - Create directories\n");
  325. printf("/L - Run on the local root server\n");
  326. printf("/M - Migrate existing DFS to allow multiple roots\n");
  327. printf("/Name:<Namespace> - Handle referrals to the specified namespace\n");
  328. printf("/NoService - Dont start as a service\n");
  329. printf("/trace - enable tracing\n");
  330. return;
  331. }
  332. //+----------------------------------------------------------------------------
  333. //
  334. // Function: StartDfsService
  335. //
  336. // Synopsis: Call back for DfsService service. This is called *once* by the
  337. // Service controller when the DfsService service is to be inited
  338. // This function is responsible for registering a message
  339. // handler function for the DfsService service.
  340. //
  341. // Arguments: Unused
  342. //
  343. // Returns: Nothing
  344. //
  345. //-----------------------------------------------------------------------------
  346. VOID
  347. StartDfsService(
  348. DWORD dwNumServiceArgs,
  349. LPWSTR *lpServiceArgs)
  350. {
  351. DFSSTATUS Status;
  352. UNREFERENCED_PARAMETER(dwNumServiceArgs);
  353. UNREFERENCED_PARAMETER(lpServiceArgs);
  354. hDfsService = RegisterServiceCtrlHandlerW( wszDfsServiceName,
  355. DfsSvcMsgProc);
  356. if (!hDfsService) {
  357. return;
  358. }
  359. ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
  360. ServiceStatus.dwCurrentState = SERVICE_STOPPED;
  361. ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
  362. ServiceStatus.dwWin32ExitCode = 0;
  363. ServiceStatus.dwServiceSpecificExitCode = 0;
  364. ServiceStatus.dwCheckPoint = 0;
  365. ServiceStatus.dwWaitHint = 1000 * 30;
  366. UpdateServiceStatus( hDfsService, &ServiceStatus, SERVICE_START_PENDING);
  367. Status = DfsStartupServer();
  368. if (Status == ERROR_SUCCESS)
  369. {
  370. UpdateServiceStatus( hDfsService, &ServiceStatus, SERVICE_RUNNING);
  371. }
  372. else {
  373. UpdateServiceStatus( hDfsService, &ServiceStatus, SERVICE_STOPPED);
  374. }
  375. return;
  376. }
  377. //+----------------------------------------------------------------------------
  378. //
  379. // Function: DfsSvcMsgProc
  380. //
  381. // Synopsis: Service-Message handler for DFSInit.
  382. //
  383. // Arguments: [dwControl] - the message
  384. //
  385. // Returns: nothing
  386. //
  387. //-----------------------------------------------------------------------------
  388. VOID
  389. DfsSvcMsgProc(DWORD dwControl)
  390. {
  391. switch(dwControl) {
  392. case SERVICE_CONTROL_STOP:
  393. //
  394. // dfsdev: need to do something to stop the service!
  395. //
  396. DfsShutdownServer();
  397. UpdateServiceStatus( hDfsService, &ServiceStatus, SERVICE_STOPPED);
  398. CoUninitialize();
  399. break;
  400. case SERVICE_INTERROGATE:
  401. UpdateServiceStatus( hDfsService, &ServiceStatus, ServiceStatus.dwCurrentState);
  402. break;
  403. default:
  404. break;
  405. }
  406. }
  407. //+----------------------------------------------------------------------------
  408. //
  409. // Function: UpdateServiceStatus
  410. //
  411. // Synopsis: Pushes a ServiceStatus to the service manager.
  412. //
  413. // Arguments: [hService] - handle returned from RegisterServiceCtrlHandler
  414. // [pSStatus] - pointer to service-status block
  415. // [Status] - The status to set.
  416. //
  417. // Returns: Nothing.
  418. //
  419. //-----------------------------------------------------------------------------
  420. static void
  421. UpdateServiceStatus(
  422. SERVICE_STATUS_HANDLE hService,
  423. SERVICE_STATUS *pSStatus,
  424. DWORD Status)
  425. {
  426. pSStatus->dwCurrentState = Status;
  427. if (Status == SERVICE_START_PENDING) {
  428. pSStatus->dwCheckPoint++;
  429. pSStatus->dwWaitHint = 1000;
  430. } else {
  431. pSStatus->dwCheckPoint = 0;
  432. pSStatus->dwWaitHint = 0;
  433. }
  434. SetServiceStatus(hService, pSStatus);
  435. }