/****************************************************************************/ // mulogoff.c // // Copyright (C) 1997-1999 Microsoft Corp. /****************************************************************************/ #ifdef _HYDRA_ /***************************************************************************** * * ProcessLogoff * * Do _HYDRA_ specific logoff processing * Handle logoff processing still under the users profile. * * This is currently used to clean up auto created printers, but is * designed for future logoff processing services, such as notifying * a user global service controller to cancel per user services. * * ENTRY: * Param1 (input/output) * Comments * * EXIT: * STATUS_SUCCESS - no error * ****************************************************************************/ VOID ProcessLogoff( PTERMINAL pTerm ) { DWORD Error; BOOLEAN Result; DWORD RetVal; PWSTR pszTok; HANDLE hProcess, hThread; TCHAR lpOldDir[MAX_PATH]; HANDLE uh; PWSTR pchData; PWINDOWSTATION pWS = pTerm->pWinStaWinlogon; if( !pTerm->UserLoggedOn ) { // Not logged on return; } /* * Notify the EXEC service that the user is * logging off. */ CtxExecServerLogoff( pTerm ); /* * See if there are logoff program(s) to run */ pchData = AllocAndGetPrivateProfileString( APPLICATION_NAME, LOGOFFAPP_KEY, TEXT(""), NULL ); if( !pchData ) { // No string return; } // // We must unlock the Window station to allow the // new process to attach // UnlockWindowStation( pTerm->pWinStaWinlogon->hwinsta ); lpOldDir[0] = 0; // // Save the current directory, then set it to the user's profile // (so that chgcdm can write there...even if C2 High security. // if (GetCurrentDirectory(MAX_PATH, lpOldDir)) { if (pWS->UserProcessData.CurrentDirectory[0]) { SetCurrentDirectory(pWS->UserProcessData.CurrentDirectory); } } // // Handle multiple commands, for MS additions // pszTok = wcstok(pchData, TEXT(",")); while (pszTok) { if (*pszTok == TEXT(' ')) { while (*pszTok++ == TEXT(' ')) ; } Result = StartSystemProcess( (LPTSTR)pszTok, APPLICATION_DESKTOP_NAME, HIGH_PRIORITY_CLASS | DETACHED_PROCESS, STARTF_USESHOWWINDOW, // Startup Flags NULL, // Environment FALSE, // fSaveHandle &hProcess, &hThread ); if( Result ) { Error = WlxAssignShellProtection( pTerm, pTerm->pWinStaWinlogon->UserProcessData.UserToken, hProcess, hThread ); if( Error == 0 ) { // Wait for it to complete RetVal = WaitForSingleObject( hProcess, LOGOFF_CMD_TIMEOUT ); if( RetVal != 0 ) { //Logoff does not terminate process on timeout DbgPrint("ProcessLogoff: Result %d, Error %d waiting for logoff command\n",RetVal,GetLastError()); } CloseHandle(hThread); CloseHandle( hProcess ); } else { // We do not run it unless its under user security DbgPrint("ProcessLogoff: Error %d creating user protection\n",Error); TerminateProcess( hProcess, 0 ); CloseHandle( hThread ); CloseHandle( hProcess ); } } else { DbgPrint("ProcessLogoff: Could process logoff command %d\n",GetLastError()); } pszTok = wcstok(NULL, TEXT(",")); } Free( pchData ); // // Restore the old directory // if (lpOldDir[0]) { SetCurrentDirectory(lpOldDir); } // // Relock the WindowStation // LockWindowStation( pTerm->pWinStaWinlogon->hwinsta ); return; } #endif