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.

334 lines
9.2 KiB

  1. /*
  2. Copyright (c) Microsoft Corporation
  3. */
  4. #include <stdio.h>
  5. #include <stdarg.h>
  6. #include "nt.h"
  7. #include "ntrtl.h"
  8. #include "nturtl.h"
  9. #include "windows.h"
  10. #include "delayimp.h"
  11. #include "strsafe.h"
  12. #include "sxsvc1.h"
  13. #define NUMBER_OF(x) (sizeof(x)/sizeof((x)[0]))
  14. typedef struct _SERVICE_CONTEXT {
  15. HANDLE ServiceHandle;
  16. SERVICE_STATUS ServiceStatus;
  17. } SERVICE_CONTEXT, *PSERVICE_CONTEXT;
  18. PVOID MemAlloc(SIZE_T n) { return HeapAlloc(GetProcessHeap(), 0, n); }
  19. VOID MemFree(PVOID p) { HeapFree(GetProcessHeap(), 0, p); }
  20. BOOL
  21. WINAPI
  22. DllEntry(
  23. HINSTANCE hInst,
  24. DWORD dwReason,
  25. PVOID pvReserved
  26. )
  27. {
  28. switch (dwReason)
  29. {
  30. case DLL_PROCESS_ATTACH:
  31. DisableThreadLibraryCalls(hInst);
  32. break;
  33. }
  34. return TRUE;
  35. }
  36. #if 0
  37. BOOL ChangePathExtensionW(PWSTR Buffer, SIZE_T BufferSize, PCWSTR NewExtension)
  38. {
  39. SIZE_T OldLength = 0;
  40. SIZE_T NewLength = 0;
  41. PWSTR OldExtension = NULL;
  42. SIZE_T NewExtensionLength = 0;
  43. SIZE_T OldExtensionLength = 0;
  44. SIZE_T Counter = 0;
  45. OldLength = wcslen(Buffer);
  46. if (NewExtension[0] == '.')
  47. {
  48. NewExtension += 1;
  49. }
  50. NewExtensionLength = wcslen(NewExtension);
  51. if ((NewExtensionLength + 1) >= BufferSize)
  52. {
  53. return FALSE;
  54. }
  55. for (Counter = 0; Counter != OldLength; ++Counter)
  56. {
  57. SIZE_T Index = (OldLength - 1 - Counter);
  58. if (Buffer[Index] == '.')
  59. {
  60. OldExtension = Buffer + Index + 1;
  61. break;
  62. }
  63. if (Buffer[Index] == '\\' || Buffer[Index] == '/')
  64. {
  65. break;
  66. }
  67. }
  68. if (OldExtension == NULL)
  69. {
  70. if (OldLength + 1 + NewExtensionLength >= BufferSize)
  71. {
  72. return FALSE;
  73. }
  74. Buffer[OldLength] = '.';
  75. CopyMemory(Buffer + OldLength + 1, NewExtension, NewExtensionLength * sizeof(WCHAR));
  76. Buffer[OldLength + 1 + NewExtensionLength + 1] = 0;
  77. return TRUE;
  78. }
  79. OldExtensionLength = wcslen(OldExtension);
  80. NewLength = OldLength - OldExtensionLength + NewExtensionLength;
  81. if (NewLength + 1 >= BufferSize)
  82. {
  83. return FALSE;
  84. }
  85. CopyMemory(Buffer + OldLength - OldExtensionLength, NewExtension, NewExtensionLength * sizeof(WCHAR));
  86. Buffer[OldLength - OldExtensionLength + NewExtensionLength] = 0;
  87. return TRUE;
  88. }
  89. #endif
  90. HMODULE GetMyModule(VOID)
  91. {
  92. return (HMODULE)&__ImageBase;
  93. }
  94. void GetMyFullPathW(PWSTR Buffer, DWORD BufferSize)
  95. {
  96. Buffer[0] = 0;
  97. GetModuleFileNameW(GetMyModule(), Buffer, BufferSize);
  98. }
  99. void strcatfW(PWSTR Buffer, SIZE_T n, PCWSTR Format, ...)
  100. {
  101. va_list Args;
  102. va_start(Args, Format);
  103. if (n != 0 && Buffer != NULL && Format != NULL)
  104. {
  105. SIZE_T i = wcslen(Buffer);
  106. if (i < n)
  107. {
  108. SIZE_T j = n - i;
  109. StringCchVPrintfW(Buffer + i, j, Format, Args);
  110. }
  111. Buffer[n - 1] = 0;
  112. }
  113. va_end(Args);
  114. }
  115. const STRING EmptyString = RTL_CONSTANT_STRING("");
  116. const STRING *
  117. DbgServiceControlToString(
  118. DWORD dw
  119. )
  120. {
  121. const STRING * String = &EmptyString;
  122. switch (dw)
  123. {
  124. #define CASE(x) case x: { const static STRING y = RTL_CONSTANT_STRING(#x); String = &y; } break;
  125. CASE(SERVICE_CONTROL_CONTINUE)
  126. CASE(SERVICE_CONTROL_INTERROGATE)
  127. CASE(SERVICE_CONTROL_NETBINDADD)
  128. CASE(SERVICE_CONTROL_NETBINDDISABLE)
  129. CASE(SERVICE_CONTROL_NETBINDENABLE)
  130. CASE(SERVICE_CONTROL_NETBINDREMOVE)
  131. CASE(SERVICE_CONTROL_PARAMCHANGE)
  132. CASE(SERVICE_CONTROL_PAUSE)
  133. CASE(SERVICE_CONTROL_SHUTDOWN)
  134. CASE(SERVICE_CONTROL_STOP)
  135. CASE(SERVICE_CONTROL_DEVICEEVENT)
  136. CASE(SERVICE_CONTROL_HARDWAREPROFILECHANGE)
  137. CASE(SERVICE_CONTROL_POWEREVENT)
  138. CASE(SERVICE_CONTROL_SESSIONCHANGE)
  139. #undef CASE
  140. }
  141. return String;
  142. }
  143. DWORD
  144. WINAPI
  145. ServiceHandlerEx(
  146. DWORD dwControl, // requested control code
  147. DWORD dwEventType, // event type
  148. LPVOID lpEventData, // event data
  149. LPVOID lpContext // user-defined context data
  150. )
  151. {
  152. BOOL CallSetStatus = FALSE;
  153. PSERVICE_CONTEXT ServiceContext = (PSERVICE_CONTEXT)lpContext;
  154. DbgPrint("sxsvc1: %Z\n", DbgServiceControlToString(dwControl));
  155. if (ServiceContext == NULL)
  156. {
  157. DbgPrint("sxsvc1: got null context\n");
  158. return (DWORD)-1;
  159. }
  160. switch (dwControl)
  161. {
  162. case SERVICE_CONTROL_CONTINUE:
  163. ServiceContext->ServiceStatus.dwCurrentState = SERVICE_RUNNING;
  164. CallSetStatus = TRUE;
  165. break;
  166. case SERVICE_CONTROL_INTERROGATE:
  167. CallSetStatus = TRUE;
  168. break;
  169. case SERVICE_CONTROL_NETBINDADD:
  170. break;
  171. case SERVICE_CONTROL_NETBINDDISABLE:
  172. break;
  173. case SERVICE_CONTROL_NETBINDENABLE:
  174. break;
  175. case SERVICE_CONTROL_NETBINDREMOVE:
  176. break;
  177. case SERVICE_CONTROL_PARAMCHANGE:
  178. break;
  179. case SERVICE_CONTROL_PAUSE:
  180. ServiceContext->ServiceStatus.dwCurrentState = SERVICE_PAUSED;
  181. CallSetStatus = TRUE;
  182. break;
  183. case SERVICE_CONTROL_SHUTDOWN:
  184. ServiceContext->ServiceStatus.dwCurrentState = SERVICE_STOPPED;
  185. CallSetStatus = TRUE;
  186. break;
  187. case SERVICE_CONTROL_STOP:
  188. ServiceContext->ServiceStatus.dwCurrentState = SERVICE_STOPPED;
  189. CallSetStatus = TRUE;
  190. break;
  191. case SERVICE_CONTROL_DEVICEEVENT:
  192. break;
  193. case SERVICE_CONTROL_HARDWAREPROFILECHANGE:
  194. break;
  195. case SERVICE_CONTROL_POWEREVENT:
  196. break;
  197. case SERVICE_CONTROL_SESSIONCHANGE:
  198. break;
  199. }
  200. if (CallSetStatus)
  201. {
  202. SetServiceStatus(ServiceContext->ServiceHandle, &ServiceContext->ServiceStatus);
  203. }
  204. return NO_ERROR;
  205. }
  206. VOID
  207. WINAPI
  208. ServiceMain(
  209. DWORD argc,
  210. PWSTR argv[]
  211. )
  212. {
  213. const static WCHAR MyFullPathFormat[] = L"MyFullPath: %ls: ";
  214. const static WCHAR CurrentActCtxFormat[] = L"CurrentActCtx: %p: ";
  215. HANDLE FileHandle = 0;
  216. SIZE_T Length = 0;
  217. SIZE_T i = 0;
  218. PWSTR MyFullPath = 0;
  219. PWSTR Buffer = 0;
  220. HANDLE CurrentActCtx = 0;
  221. DWORD BytesWritten = 0;
  222. PSERVICE_CONTEXT ServiceContext = 0;
  223. MyFullPath = (PWSTR)MemAlloc(MAX_PATH);
  224. if (MyFullPath == NULL)
  225. goto Exit;
  226. MyFullPath[0] = 0;
  227. GetMyFullPathW(MyFullPath, MAX_PATH);
  228. FileHandle = CreateFileW(L"C:\\sxsvc.log", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  229. if (FileHandle == INVALID_HANDLE_VALUE)
  230. {
  231. goto Exit;
  232. }
  233. Length = 0;
  234. if (argc != 0 && argv != NULL)
  235. {
  236. for (i = 0 ; i < argc ; i++ )
  237. {
  238. Length += wcslen(argv[i]) + 1;
  239. }
  240. }
  241. Length += wcslen(MyFullPath) + NUMBER_OF(MyFullPathFormat);
  242. Length += sizeof(PVOID) * 8 + NUMBER_OF(CurrentActCtxFormat);
  243. Length += 1;
  244. Buffer = (PWSTR)MemAlloc(Length * sizeof(WCHAR));
  245. if (Buffer == NULL)
  246. {
  247. goto Exit;
  248. }
  249. Buffer[0] = 0;
  250. strcatfW(Buffer, Length, MyFullPathFormat, MyFullPath);
  251. if (argc != 0 && argv != NULL)
  252. {
  253. for (i = 0 ; i < argc ; i++ )
  254. {
  255. strcatfW(Buffer, Length, L"%ls ", argv[i]);
  256. }
  257. }
  258. GetCurrentActCtx(&CurrentActCtx);
  259. strcatfW(Buffer, Length, CurrentActCtxFormat, CurrentActCtx);
  260. WriteFile(FileHandle, Buffer, wcslen(Buffer), &BytesWritten, NULL);
  261. #if DBG
  262. DbgPrint("sxsvc1: %ls\n", Buffer);
  263. #endif
  264. ServiceContext = (PSERVICE_CONTEXT)MemAlloc(sizeof(*ServiceContext));
  265. if (ServiceContext == NULL)
  266. {
  267. DbgPrint("sxsvc1: out of memory line %ld\n", (ULONG)__LINE__);
  268. }
  269. RtlZeroMemory(ServiceContext, sizeof(*ServiceContext));
  270. ServiceContext->ServiceHandle = RegisterServiceCtrlHandlerExW(ServiceName, ServiceHandlerEx, ServiceContext);
  271. if (ServiceContext->ServiceHandle == 0)
  272. {
  273. DbgPrint("sxsvc1: RegisterServiceCtrlHandlerExW failed 0x%lx\n", (ULONG)GetLastError());
  274. goto Exit;
  275. }
  276. ServiceContext->ServiceStatus.dwServiceType = ServiceTypeValue;
  277. ServiceContext->ServiceStatus.dwCurrentState = SERVICE_RUNNING;
  278. ServiceContext->ServiceStatus.dwControlsAccepted |= SERVICE_ACCEPT_STOP;
  279. ServiceContext->ServiceStatus.dwControlsAccepted |= SERVICE_ACCEPT_SHUTDOWN;
  280. ServiceContext->ServiceStatus.dwControlsAccepted |= SERVICE_ACCEPT_PAUSE_CONTINUE;
  281. ServiceContext->ServiceStatus.dwControlsAccepted |= SERVICE_ACCEPT_PARAMCHANGE;
  282. ServiceContext->ServiceStatus.dwControlsAccepted |= SERVICE_ACCEPT_SESSIONCHANGE;
  283. ServiceContext->ServiceStatus.dwWin32ExitCode = NO_ERROR;
  284. SetServiceStatus(ServiceContext->ServiceHandle, &ServiceContext->ServiceStatus);
  285. ServiceContext = NULL;
  286. Exit:
  287. if (FileHandle != NULL)
  288. CloseHandle(FileHandle);
  289. MemFree(Buffer);
  290. MemFree(MyFullPath);
  291. MemFree(ServiceContext);
  292. }
  293. #if 0
  294. int __cdecl wmain(int argc, wchar_t ** argv)
  295. {
  296. WCHAR Buffer[MAX_PATH];
  297. int i = 0;
  298. for ( i = 1 ; i < argc ; i += 2)
  299. {
  300. StringCchCopyW(Buffer, NUMBER_OF(Buffer), argv[i]);
  301. ChangePathExtensionW(Buffer, NUMBER_OF(Buffer), argv[i + 1]);
  302. printf("%ls\n", Buffer);
  303. }
  304. return 0;
  305. }
  306. #endif