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.

135 lines
3.8 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 2001.
  5. //
  6. // tscompat.cpp
  7. //
  8. // This module include functions that were introduced to replace missing
  9. // functions/functionality from Windows XP to Windows 2000.
  10. //
  11. // 10/11/2001 annah Created
  12. //
  13. //----------------------------------------------------------------------------
  14. #include "pch.h"
  15. #include "tscompat.h"
  16. #include "service.h"
  17. //----------------------------------------------------------------------------
  18. // Replacements for TS functions
  19. //----------------------------------------------------------------------------
  20. //
  21. // Copied from TS sources, as this function is not available on the
  22. // win2k wtsapi32.dll. The function has the same functionality as WTSQueryUserToken().
  23. //
  24. BOOL WINAPI _WTSQueryUserToken(/* in */ ULONG SessionId, /* out */ PHANDLE phToken)
  25. {
  26. BOOL IsTsUp = FALSE;
  27. BOOL Result, bHasPrivilege;
  28. ULONG ReturnLength;
  29. WINSTATIONUSERTOKEN Info;
  30. HANDLE hUserToken = NULL;
  31. SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
  32. // Do parameter Validation
  33. if (NULL == phToken) {
  34. SetLastError(ERROR_INVALID_PARAMETER);
  35. return(FALSE);
  36. }
  37. // If it is session 0, don't call winsta. Use GetCurrentUserToken instead.
  38. if (SessionId == 0)
  39. {
  40. hUserToken = GetCurrentUserTokenW(L"WinSta0",
  41. TOKEN_QUERY |
  42. TOKEN_DUPLICATE |
  43. TOKEN_ASSIGN_PRIMARY
  44. );
  45. if (hUserToken == NULL)
  46. return FALSE;
  47. else
  48. *phToken = hUserToken;
  49. }
  50. else // Non-zero sessions
  51. {
  52. // No one except TS has any idea about non-zero sessions. So, check if the TS is running.
  53. IsTsUp = _IsTerminalServiceRunning();
  54. if (IsTsUp)
  55. { // This is so that CSRSS can dup the handle to our process
  56. Info.ProcessId = LongToHandle(GetCurrentProcessId());
  57. Info.ThreadId = LongToHandle(GetCurrentThreadId());
  58. Result = WinStationQueryInformation(
  59. SERVERNAME_CURRENT,
  60. SessionId,
  61. WinStationUserToken,
  62. &Info,
  63. sizeof(Info),
  64. &ReturnLength
  65. );
  66. if( !Result )
  67. return FALSE;
  68. else
  69. *phToken = Info.UserToken ;
  70. }
  71. else
  72. { // TS is not running. So, set error for non-zero sessions: WINSTATION_NOT_FOUND.
  73. SetLastError(ERROR_CTX_WINSTATION_NOT_FOUND);
  74. return FALSE;
  75. }
  76. }
  77. return TRUE;
  78. }
  79. //
  80. // This function determines if the Terminal Service is currently Running.
  81. // Copied from TS sources, as it is required on the _WTSQueryUserToken() function.
  82. //
  83. BOOL _IsTerminalServiceRunning (VOID)
  84. {
  85. BOOL bReturn = FALSE;
  86. SC_HANDLE hServiceController;
  87. hServiceController = OpenSCManager(NULL, NULL, GENERIC_READ);
  88. if (hServiceController)
  89. {
  90. SC_HANDLE hTermServ ;
  91. hTermServ = OpenService(hServiceController, L"TermService", SERVICE_QUERY_STATUS);
  92. if (hTermServ)
  93. {
  94. SERVICE_STATUS tTermServStatus;
  95. if (QueryServiceStatus(hTermServ, &tTermServStatus))
  96. {
  97. bReturn = (tTermServStatus.dwCurrentState == SERVICE_RUNNING);
  98. }
  99. else
  100. {
  101. CloseServiceHandle(hTermServ);
  102. CloseServiceHandle(hServiceController);
  103. return FALSE;
  104. }
  105. CloseServiceHandle(hTermServ);
  106. }
  107. else
  108. {
  109. CloseServiceHandle(hServiceController);
  110. return FALSE;
  111. }
  112. CloseServiceHandle(hServiceController);
  113. }
  114. else
  115. {
  116. return FALSE;
  117. }
  118. return bReturn;
  119. }