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.

168 lines
4.4 KiB

  1. /****************************************************************************/
  2. // mulogoff.c
  3. //
  4. // Copyright (C) 1997-1999 Microsoft Corp.
  5. /****************************************************************************/
  6. #ifdef _HYDRA_
  7. /*****************************************************************************
  8. *
  9. * ProcessLogoff
  10. *
  11. * Do _HYDRA_ specific logoff processing
  12. * Handle logoff processing still under the users profile.
  13. *
  14. * This is currently used to clean up auto created printers, but is
  15. * designed for future logoff processing services, such as notifying
  16. * a user global service controller to cancel per user services.
  17. *
  18. * ENTRY:
  19. * Param1 (input/output)
  20. * Comments
  21. *
  22. * EXIT:
  23. * STATUS_SUCCESS - no error
  24. *
  25. ****************************************************************************/
  26. VOID
  27. ProcessLogoff(
  28. PTERMINAL pTerm
  29. )
  30. {
  31. DWORD Error;
  32. BOOLEAN Result;
  33. DWORD RetVal;
  34. PWSTR pszTok;
  35. HANDLE hProcess, hThread;
  36. TCHAR lpOldDir[MAX_PATH];
  37. HANDLE uh;
  38. PWSTR pchData;
  39. PWINDOWSTATION pWS = pTerm->pWinStaWinlogon;
  40. if( !pTerm->UserLoggedOn ) {
  41. // Not logged on
  42. return;
  43. }
  44. /*
  45. * Notify the EXEC service that the user is
  46. * logging off.
  47. */
  48. CtxExecServerLogoff( pTerm );
  49. /*
  50. * See if there are logoff program(s) to run
  51. */
  52. pchData = AllocAndGetPrivateProfileString(
  53. APPLICATION_NAME,
  54. LOGOFFAPP_KEY,
  55. TEXT(""),
  56. NULL
  57. );
  58. if( !pchData ) {
  59. // No string
  60. return;
  61. }
  62. //
  63. // We must unlock the Window station to allow the
  64. // new process to attach
  65. //
  66. UnlockWindowStation( pTerm->pWinStaWinlogon->hwinsta );
  67. lpOldDir[0] = 0;
  68. //
  69. // Save the current directory, then set it to the user's profile
  70. // (so that chgcdm can write there...even if C2 High security.
  71. //
  72. if (GetCurrentDirectory(MAX_PATH, lpOldDir)) {
  73. if (pWS->UserProcessData.CurrentDirectory[0]) {
  74. SetCurrentDirectory(pWS->UserProcessData.CurrentDirectory);
  75. }
  76. }
  77. //
  78. // Handle multiple commands, for MS additions
  79. //
  80. pszTok = wcstok(pchData, TEXT(","));
  81. while (pszTok) {
  82. if (*pszTok == TEXT(' '))
  83. {
  84. while (*pszTok++ == TEXT(' '))
  85. ;
  86. }
  87. Result = StartSystemProcess(
  88. (LPTSTR)pszTok,
  89. APPLICATION_DESKTOP_NAME,
  90. HIGH_PRIORITY_CLASS | DETACHED_PROCESS,
  91. STARTF_USESHOWWINDOW, // Startup Flags
  92. NULL, // Environment
  93. FALSE, // fSaveHandle
  94. &hProcess,
  95. &hThread
  96. );
  97. if( Result ) {
  98. Error = WlxAssignShellProtection(
  99. pTerm,
  100. pTerm->pWinStaWinlogon->UserProcessData.UserToken,
  101. hProcess,
  102. hThread
  103. );
  104. if( Error == 0 ) {
  105. // Wait for it to complete
  106. RetVal = WaitForSingleObject( hProcess, LOGOFF_CMD_TIMEOUT );
  107. if( RetVal != 0 ) {
  108. //Logoff does not terminate process on timeout
  109. DbgPrint("ProcessLogoff: Result %d, Error %d waiting for logoff command\n",RetVal,GetLastError());
  110. }
  111. CloseHandle(hThread);
  112. CloseHandle( hProcess );
  113. }
  114. else {
  115. // We do not run it unless its under user security
  116. DbgPrint("ProcessLogoff: Error %d creating user protection\n",Error);
  117. TerminateProcess( hProcess, 0 );
  118. CloseHandle( hThread );
  119. CloseHandle( hProcess );
  120. }
  121. }
  122. else {
  123. DbgPrint("ProcessLogoff: Could process logoff command %d\n",GetLastError());
  124. }
  125. pszTok = wcstok(NULL, TEXT(","));
  126. }
  127. Free( pchData );
  128. //
  129. // Restore the old directory
  130. //
  131. if (lpOldDir[0]) {
  132. SetCurrentDirectory(lpOldDir);
  133. }
  134. //
  135. // Relock the WindowStation
  136. //
  137. LockWindowStation( pTerm->pWinStaWinlogon->hwinsta );
  138. return;
  139. }
  140. #endif