Source code of Windows XP (NT5)
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.

360 lines
9.4 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. sclgntfy.cxx
  5. Abstract:
  6. Notification dll for secondary logon service
  7. Author:
  8. Praerit Garg (Praeritg)
  9. Revision History:
  10. --*/
  11. #ifdef __cplusplus
  12. extern "C" {
  13. #endif
  14. #include <nt.h>
  15. #include <ntrtl.h>
  16. #include <nturtl.h>
  17. #ifdef __cplusplus
  18. }
  19. #endif
  20. #include <windows.h>
  21. #include <winwlx.h>
  22. #include "seclogon.h"
  23. #include <stdio.h>
  24. #include "sclgntfy.hxx"
  25. //
  26. // Some helpful tips about winlogon's notify events
  27. //
  28. // 1) The logoff and shutdown notifications are always done
  29. // synchronously regardless of the Asynchronous registry entry.
  30. //
  31. // 2) If you need to spawn child processes, you have to use
  32. // CreateProcessAsUser() otherwise the process will start
  33. // on winlogon's desktop (not the user's)
  34. //
  35. // 3) The logon notification comes before the user's network
  36. // connections are restored. If you need the user's persisted
  37. // net connections, use the StartShell event.
  38. //
  39. // 4) Don't put any UI up during either screen saver event.
  40. // These events are intended for background processing only.
  41. //
  42. HINSTANCE g_hDllInstance=NULL;
  43. #define NOTIFY_PATH TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\Notify\\sclgntfy")
  44. BOOL
  45. SlpCreateProcessWithLogon(
  46. ULONG LogonIdLowPart,
  47. LONG LogonIdHighPart
  48. );
  49. extern "C" void *__cdecl _alloca(size_t);
  50. BOOL
  51. SlpCreateProcessWithLogon(
  52. ULONG LogonIdLowPart,
  53. LONG LogonIdHighPart
  54. )
  55. /*++
  56. Routine Description:
  57. Arguments:
  58. Return Value:
  59. --*/
  60. {
  61. BOOL fOk = FALSE;
  62. DWORD dwResult;
  63. LPWSTR pwszBinding = NULL;
  64. RPC_BINDING_HANDLE hRPCBinding = NULL;
  65. SECL_BLOB sbNULL = { 0, NULL };
  66. SECL_SLI sli;
  67. SECL_SLRI slri;
  68. SECL_STRING ssNULL = { 0, 0, NULL };
  69. ZeroMemory(&sli, sizeof(sli));
  70. ZeroMemory(&slri, sizeof(slri));
  71. __try {
  72. sli.ulLogonIdLowPart = LogonIdLowPart;
  73. sli.lLogonIdHighPart = LogonIdHighPart;
  74. sli.ulProcessId = GetCurrentProcessId();
  75. sli.ssUsername = ssNULL;
  76. sli.ssDomain = ssNULL;
  77. sli.ssPassword = ssNULL;
  78. sli.ssApplicationName = ssNULL;
  79. sli.ssCommandLine = ssNULL;
  80. sli.ulCreationFlags = 0;
  81. sli.sbEnvironment = sbNULL;
  82. sli.ssCurrentDirectory = ssNULL;
  83. sli.ssTitle = ssNULL;
  84. sli.ssDesktop = ssNULL;
  85. // Make the RPC call:
  86. //
  87. dwResult = RpcStringBindingCompose
  88. (NULL,
  89. (unsigned short *)L"ncacn_np",
  90. NULL,
  91. (unsigned short *)L"\\PIPE\\" wszSeclogonSharedProcEndpointName,
  92. NULL,
  93. (unsigned short **)&pwszBinding);
  94. if (RPC_S_OK != dwResult) { __leave; }
  95. dwResult = RpcBindingFromStringBinding((unsigned short *)pwszBinding, &hRPCBinding);
  96. if (0 != dwResult) { __leave; }
  97. __try {
  98. SeclCreateProcessWithLogonW
  99. (hRPCBinding,
  100. &sli,
  101. &slri);
  102. }
  103. __except(EXCEPTION_EXECUTE_HANDLER) {
  104. dwResult = RpcExceptionCode();
  105. }
  106. if (0 != dwResult) { __leave; }
  107. fOk = (slri.ulErrorCode == NO_ERROR); // This function succeeds if the server's function succeeds
  108. if (!fOk) {
  109. //
  110. // If the server function failed, set the server's
  111. // returned eror code as this thread's error code
  112. //
  113. SetLastError(slri.ulErrorCode);
  114. }
  115. }
  116. __finally {
  117. if (NULL != pwszBinding) { RpcStringFree((unsigned short **)&pwszBinding); }
  118. if (NULL != hRPCBinding) { RpcBindingFree(&hRPCBinding); }
  119. }
  120. return(fOk);
  121. }
  122. //////////////////////////////// End Of File /////////////////////////////////
  123. BOOL WINAPI DllMain(HANDLE hInstance, ULONG dwReason, LPVOID lpReserved)
  124. //BOOL WINAPI LibMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
  125. {
  126. switch (dwReason)
  127. {
  128. case DLL_PROCESS_ATTACH:
  129. {
  130. // DisableThreadLibraryCalls (hInstance);
  131. g_hDllInstance = (HINSTANCE)hInstance;
  132. }
  133. break;
  134. }
  135. return TRUE;
  136. }
  137. //
  138. // WLEventLogon moved to recovery.cpp
  139. //
  140. VOID WLEventLogoff (PWLX_NOTIFICATION_INFO pInfo)
  141. {
  142. TOKEN_STATISTICS TokenStats;
  143. DWORD ReturnLength;
  144. LUID LogonId;
  145. STARTUPINFO si;
  146. PROCESS_INFORMATION pi;
  147. ZeroMemory(&si, sizeof(si));
  148. si.cb = sizeof(si);
  149. // OutputDebugString (TEXT("NOTIFY: Entering WLEventLogff.\r\n"));
  150. //
  151. // We are interested in this event.
  152. //
  153. //
  154. // We will basically call CreateProcessWithLogon
  155. // in a specially formed message such that secondary logon
  156. // service can cleanup processes associated with this
  157. // logon id.
  158. //
  159. if(GetTokenInformation(pInfo->hToken, TokenStatistics,
  160. (PVOID *)&TokenStats,
  161. sizeof(TOKEN_STATISTICS),
  162. &ReturnLength))
  163. {
  164. LogonId.HighPart = TokenStats.AuthenticationId.HighPart;
  165. LogonId.LowPart = TokenStats.AuthenticationId.LowPart;
  166. SlpCreateProcessWithLogon(
  167. LogonId.LowPart,
  168. LogonId.HighPart
  169. );
  170. }
  171. }
  172. VOID WLEventStartup (PWLX_NOTIFICATION_INFO pInfo)
  173. {
  174. // OutputDebugString (TEXT("NOTIFY: Entering WLEventStartup.\r\n"));
  175. }
  176. VOID WLEventShutdown (PWLX_NOTIFICATION_INFO pInfo)
  177. {
  178. // OutputDebugString (TEXT("NOTIFY: Entering WLEventShutdown.\r\n"));
  179. }
  180. VOID WLEventStartScreenSaver (PWLX_NOTIFICATION_INFO pInfo)
  181. {
  182. // OutputDebugString (TEXT("NOTIFY: Entering WLEventStartScreenSaver.\r\n"));
  183. }
  184. VOID WLEventStopScreenSaver (PWLX_NOTIFICATION_INFO pInfo)
  185. {
  186. // OutputDebugString (TEXT("NOTIFY: Entering WLEventStopScreenSaver.\r\n"));
  187. }
  188. VOID WLEventLock (PWLX_NOTIFICATION_INFO pInfo)
  189. {
  190. // OutputDebugString (TEXT("NOTIFY: Entering WLEventLock.\r\n"));
  191. }
  192. VOID WLEventUnlock (PWLX_NOTIFICATION_INFO pInfo)
  193. {
  194. // OutputDebugString (TEXT("NOTIFY: Entering WLEventUnlock.\r\n"));
  195. }
  196. VOID WLEventStartShell (PWLX_NOTIFICATION_INFO pInfo)
  197. {
  198. // OutputDebugString (TEXT("NOTIFY: Entering WLEventStartShell.\r\n"));
  199. }
  200. /////////////////////////////////////////////////////////////////////////////
  201. // DllRegisterServer - Adds entries to the system registry
  202. STDAPI DllRegisterServer(void)
  203. {
  204. HKEY hKey;
  205. LONG lResult;
  206. DWORD dwDisp, dwTemp;
  207. lResult = RegCreateKeyEx (HKEY_LOCAL_MACHINE, NOTIFY_PATH, 0, NULL,
  208. REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL,
  209. &hKey, &dwDisp);
  210. if (lResult != ERROR_SUCCESS)
  211. {
  212. return lResult;
  213. }
  214. DllRegisterServerEFS();
  215. RegSetValueEx (hKey, TEXT("Logoff"), 0, REG_SZ, (LPBYTE)TEXT("WLEventLogoff"),
  216. (lstrlen(TEXT("WLEventLogoff")) + 1) * sizeof(TCHAR));
  217. #if 0
  218. RegSetValueEx (hKey, TEXT("Logon"), 0, REG_SZ, (LPBYTE)TEXT("WLEventLogon"),
  219. (lstrlen(TEXT("WLEventLogon")) + 1) * sizeof(TCHAR));
  220. RegSetValueEx (hKey, TEXT("Startup"), 0, REG_SZ, (LPBYTE)TEXT("WLEventStartup"),
  221. (lstrlen(TEXT("WLEventStartup")) + 1) * sizeof(TCHAR));
  222. RegSetValueEx (hKey, TEXT("Shutdown"), 0, REG_SZ, (LPBYTE)TEXT("WLEventShutdown"),
  223. (lstrlen(TEXT("WLEventShutdown")) + 1) * sizeof(TCHAR));
  224. RegSetValueEx (hKey, TEXT("StartScreenSaver"), 0, REG_SZ, (LPBYTE)TEXT("WLEventStartScreenSaver"),
  225. (lstrlen(TEXT("WLEventStartScreenSaver")) + 1) * sizeof(TCHAR));
  226. RegSetValueEx (hKey, TEXT("StopScreenSaver"), 0, REG_SZ, (LPBYTE)TEXT("WLEventStopScreenSaver"),
  227. (lstrlen(TEXT("WLEventStopScreenSaver")) + 1) * sizeof(TCHAR));
  228. RegSetValueEx (hKey, TEXT("Lock"), 0, REG_SZ, (LPBYTE)TEXT("WLEventLock"),
  229. (lstrlen(TEXT("WLEventLock")) + 1) * sizeof(TCHAR));
  230. RegSetValueEx (hKey, TEXT("Unlock"), 0, REG_SZ, (LPBYTE)TEXT("WLEventUnlock"),
  231. (lstrlen(TEXT("WLEventUnlock")) + 1) * sizeof(TCHAR));
  232. RegSetValueEx (hKey, TEXT("StartShell"), 0, REG_SZ, (LPBYTE)TEXT("WLEventStartShell"),
  233. (lstrlen(TEXT("WLEventStartShell")) + 1) * sizeof(TCHAR));
  234. #endif
  235. dwTemp = 0;
  236. RegSetValueEx (hKey, TEXT("Impersonate"), 0, REG_DWORD, (LPBYTE)&dwTemp, sizeof(dwTemp));
  237. dwTemp = 1;
  238. RegSetValueEx (hKey, TEXT("Asynchronous"), 0, REG_DWORD, (LPBYTE)&dwTemp, sizeof(dwTemp));
  239. RegSetValueEx (hKey, TEXT("DllName"), 0, REG_EXPAND_SZ, (LPBYTE)TEXT("sclgntfy.dll"),
  240. (lstrlen(TEXT("sclgntfy.dll")) + 1) * sizeof(TCHAR));
  241. RegCloseKey (hKey);
  242. return S_OK;
  243. }
  244. /////////////////////////////////////////////////////////////////////////////
  245. // DllUnregisterServer - Removes entries from the system registry
  246. STDAPI DllUnregisterServer(void)
  247. {
  248. RegDeleteKey (HKEY_LOCAL_MACHINE, NOTIFY_PATH);
  249. return S_OK;
  250. }
  251. BOOL
  252. pLoadResourceString(
  253. IN UINT idMsg,
  254. OUT LPTSTR lpBuffer,
  255. IN int nBufferMax,
  256. IN LPTSTR lpDefault
  257. )
  258. {
  259. if ( lpBuffer == NULL || lpDefault == NULL ) {
  260. SetLastError(ERROR_INVALID_PARAMETER);
  261. return FALSE;
  262. }
  263. if ( g_hDllInstance == NULL ||
  264. !LoadString (g_hDllInstance,
  265. idMsg,
  266. lpBuffer,
  267. nBufferMax)) {
  268. wcscpy(lpBuffer, lpDefault);
  269. lpBuffer[nBufferMax-1] = L'\0';
  270. }
  271. return TRUE;
  272. }