Windows NT 4.0 source code leak
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.

460 lines
8.2 KiB

4 years ago
  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. system.cxx
  5. Abstract:
  6. This file contains the system dependent functions for Windows NT.
  7. Author:
  8. Steven Zeck (stevez) 07/01/91
  9. --*/
  10. extern "C" {
  11. #include <nt.h>
  12. #include <ntrtl.h>
  13. #include <nturtl.h>
  14. }
  15. #include <windef.h> // Base windows types
  16. #include <winbase.h>
  17. #include <winsvc.h>
  18. #include <lmcons.h> // LAN Manager common definitions
  19. #include <lmapibuf.h> // Buffer stuff
  20. #include <lmwksta.h> // Workstation class
  21. #include "core.hxx"
  22. int hDebugFile = 1; // use standard out by default
  23. TIME LoadTime; // time the locator loaded
  24. unsigned long LoadTimeinSecs;
  25. SERVICE_STATUS ServiceStatus;
  26. SERVICE_STATUS_HANDLE ServiceHandle;
  27. void
  28. SetStatus(
  29. )
  30. /*++
  31. Routine Description:
  32. Set the lanman service status.
  33. --*/
  34. {
  35. ASSERT(ServiceHandle);
  36. if (! SetServiceStatus( ServiceHandle, &ServiceStatus))
  37. ASSERT(!"SetServiceStatus");
  38. }
  39. void
  40. LocatorControl(
  41. IN DWORD opCode // function that we are to carry out.
  42. )
  43. /*++
  44. Routine Description:
  45. This function responses the service control requests.
  46. Arguments:
  47. opCode - Function that we are to carry out.
  48. --*/
  49. {
  50. RPC_STATUS status;
  51. switch(opCode) {
  52. case SERVICE_CONTROL_STOP:
  53. // Announce that the service is shutting down
  54. ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
  55. ServiceStatus.dwWaitHint = 3000;
  56. SetStatus();
  57. status = RpcMgmtStopServerListening(0);
  58. ASSERT(!status);
  59. break;
  60. case SERVICE_CONTROL_INTERROGATE:
  61. // Do nothing; the status gets announced below
  62. SetStatus();
  63. break ;
  64. }
  65. }
  66. void
  67. LocatorServiceMain(
  68. DWORD argc,
  69. LPTSTR *argv
  70. )
  71. /*++
  72. Routine Description:
  73. This is main function for the locator service.
  74. When we are started as a service, the service control creates a new
  75. thread and calls this function.
  76. Arguments:
  77. argc - argument count
  78. argv - vector of argument pointers
  79. RegKeyPath - registry path for this conponet.,
  80. --*/
  81. {
  82. LPTSTR *aSZParms = new LPSTR[argc+1];
  83. char *BadArg;
  84. // Make a Copy of the vector and 0 terminate.
  85. memcpy(aSZParms, argv, sizeof(LPSTR) * (int) argc);
  86. aSZParms[argc] = 0;
  87. BadArg = ProcessArgs(aSwitchs, ++aSZParms);
  88. // Set up the service info structure to indicate the status.
  89. ServiceStatus.dwServiceType = SERVICE_WIN32;
  90. ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
  91. ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
  92. ServiceStatus.dwWin32ExitCode = 0;
  93. ServiceStatus.dwCheckPoint = 0;
  94. ServiceStatus.dwWaitHint = 0;
  95. // Set up control handler
  96. if (! (ServiceHandle = RegisterServiceCtrlHandler (
  97. "locator", LocatorControl)))
  98. AbortServer("RegisterServiceCtrlHandler", (int) GetLastError());
  99. // Bail out on bad arguments.
  100. if (BadArg) {
  101. char errLine[500];
  102. ServiceStatus.dwWin32ExitCode = ERROR_INVALID_PARAMETER;
  103. AbortServer((SZ) strcat(strcpy(
  104. errLine, "Command Line Error: "), BadArg));
  105. }
  106. // Start the RPC server. We won't return until stopped.
  107. SetStatus();
  108. StartServer();
  109. ServiceStatus.dwCurrentState = SERVICE_RUNNING;
  110. SetStatus();
  111. RpcMgmtWaitServerListen();
  112. ServiceStatus.dwCurrentState = SERVICE_STOPPED;
  113. SetStatus();
  114. }
  115. void
  116. SystemInit (
  117. )
  118. /*++
  119. Routine Description:
  120. System dependent initialization, Initialize data structures
  121. for Windows NT based operation.
  122. --*/
  123. {
  124. NTSTATUS status;
  125. void * pThreadHandle;
  126. DWORD ThreadID;
  127. UICHAR Buffer[200];
  128. int cbSelfName;
  129. static SERVICE_TABLE_ENTRY ServiceEntry [] = {
  130. "locator", (LPSERVICE_MAIN_FUNCTION) LocatorServiceMain, 0, 0
  131. };
  132. NtQuerySystemTime(&LoadTime);
  133. RtlTimeToSecondsSince1980(&LoadTime, &LoadTimeinSecs);
  134. if (! fService)
  135. *cout << "Microsoft RPC Locator Starting..\n";
  136. // Get the name of this work station into global buffer.
  137. WKSTA_INFO_100 *WorkInfo;
  138. NET_API_STATUS NetStatus = NetWkstaGetInfo(NIL, 100, (LPBYTE *) &WorkInfo);
  139. if (NetStatus)
  140. {
  141. #ifdef DEBUGRPC
  142. DbgPrint("RPC Locator: NetWkstaGetInfo returned %lu\n", NetStatus);
  143. DbgBreakPoint();
  144. #endif
  145. AbortServer("netwkstaGetInfo failed", NetStatus);
  146. }
  147. if (0 == WorkInfo->wki100_computername)
  148. {
  149. #ifdef DEBUGRPC
  150. DbgPrint("RPC Locator: NetWkstaGetInfo returned null computer name\n");
  151. DbgBreakPoint();
  152. #endif
  153. AbortServer("null computer name");
  154. }
  155. // put self name in global place
  156. Buffer[0] = 0;
  157. CatUZ(CatUZ(Buffer, (PUZ) L"\\\\"), (PUZ) WorkInfo->wki100_computername);
  158. SelfName = (PUZ) NewCopy(Buffer, (LenUZ(Buffer)+1)*sizeof(UICHAR));
  159. DomainName = (PUZ) NewCopy(WorkInfo->wki100_langroup,
  160. (LenUZ((PUZ) WorkInfo->wki100_langroup)+1)*sizeof(UICHAR));
  161. if (!SelfName || !DomainName)
  162. AbortServer("Out of Memory");
  163. status = NetApiBufferFree((LPBYTE) WorkInfo);
  164. ASSERT(!status);
  165. DLIST(2, "My workstation name: " << SelfName << nl);
  166. pThreadHandle = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) QueryProcess, 0, 0, &ThreadID);
  167. if (!pThreadHandle)
  168. AbortServer("CreateThread", (int) GetLastError());
  169. // Start the RPC service now if not running under the service controller.
  170. if (!fService)
  171. {
  172. StartServer();
  173. RpcMgmtWaitServerListen();
  174. return;
  175. }
  176. // Call (give this thread) to the service controller.
  177. StartServiceCtrlDispatcher(ServiceEntry);
  178. }
  179. void
  180. AbortServer(
  181. IN SZ szReason,
  182. IN int code
  183. )
  184. /*++
  185. Routine Description:
  186. Die a graceful death for the server.
  187. Arguments:
  188. szReason - Text message for death
  189. code - option error code
  190. --*/
  191. {
  192. ServiceStatus.dwCurrentState = SERVICE_STOPPED;
  193. ServiceStatus.dwServiceSpecificExitCode = code;
  194. if (code)
  195. ServiceStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
  196. if (fService && ServiceHandle)
  197. SetStatus();
  198. *cout << "Locator Aborting: " << szReason;
  199. if (code)
  200. *cout << ": " << code;
  201. else
  202. code = -1;
  203. *cout << nl;
  204. ExitProcess(code);
  205. }
  206. unsigned long
  207. CurrentTime (
  208. )
  209. /*++
  210. Routine Description:
  211. Return the current time in seconds.
  212. Returns:
  213. The time.
  214. --*/
  215. {
  216. TIME time;
  217. ULONG seconds;
  218. // QUERY the current time; this time is in some funky Nt specific
  219. // format and scale & Convert it into seconds since 1980.
  220. NtQuerySystemTime(&time);
  221. RtlTimeToSecondsSince1980(&time, &seconds);
  222. return(seconds);
  223. }
  224. unsigned long
  225. CurrentTimeMS (
  226. )
  227. /*++
  228. Routine Description:
  229. Return the current time in 1000th of a second.
  230. Returns:
  231. The time.
  232. --*/
  233. {
  234. TIME time;
  235. unsigned long TimeinSecs;
  236. // QUERY the current time; this time is in some funky Nt specific
  237. // format and scale (1/10,000). Form the delta between the load
  238. // time and the current time.
  239. NtQuerySystemTime(&time);
  240. RtlTimeToSecondsSince1980(&time, &TimeinSecs);
  241. /*
  242. Alpha Compiler Chokes Here
  243. return( RtlLargeIntegerSubtract(*(PLARGE_INTEGER) &time,
  244. *(PLARGE_INTEGER) &LoadTime).LowPart / 10);
  245. */
  246. return(TimeinSecs - LoadTimeinSecs);
  247. }
  248. // *** Misc helper functions *** //
  249. void
  250. DEBUG_STREAM::FlushBuffer(
  251. )
  252. /*++
  253. Routine Description:
  254. Dump a buffer to the dug console.
  255. Arguments:
  256. --*/
  257. {
  258. if (fService) {
  259. base[pptr-base] = 0;
  260. #if DBG
  261. DbgPrint(base);
  262. #endif
  263. }
  264. else
  265. _write(hDebugFile, base, pptr-base);
  266. }
  267. void
  268. CONSOLE_STREAM::FlushBuffer(
  269. )
  270. /*++
  271. Routine Description:
  272. Dump a buffer to the console.
  273. Arguments:
  274. --*/
  275. {
  276. if (fService)
  277. ((DEBUG_STREAM *)this)->DEBUG_STREAM::FlushBuffer();
  278. else
  279. _write(1, base, pptr-base);
  280. }
  281. #if DBG
  282. int AssertHeap(
  283. )
  284. /*++
  285. Routine Description:
  286. Call the NT Rtl runtime functions to check the heap.
  287. Returns:
  288. TRUE if the heap is NOT corrupted.
  289. --*/
  290. {
  291. static BOOL fHeapTrashed;
  292. if (!fHeapTrashed) {
  293. fHeapTrashed = RtlValidateHeap( RtlProcessHeap(), 0, NULL ) == 0;
  294. }
  295. return(!fHeapTrashed);
  296. }
  297. #endif // DBG