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.

212 lines
5.9 KiB

  1. /*---------------------------------------------------------------------------
  2. File: RebootUtils.cpp
  3. Comments: Utility functions used to reboot a remote computer.
  4. (c) Copyright 1999, Mission Critical Software, Inc., All Rights Reserved
  5. Proprietary and confidential to Mission Critical Software, Inc.
  6. REVISION LOG ENTRY
  7. Revision By: Christy Boles
  8. Revised on 02/15/99 11:22:10
  9. ---------------------------------------------------------------------------
  10. */
  11. #include "Stdafx.h"
  12. #include <stdio.h>
  13. #include <winreg.h>
  14. #include <lm.h>
  15. #include <lmwksta.h>
  16. #include <lmapibuf.h>
  17. #include "RebootU.h"
  18. #include "EaLen.hpp"
  19. // ===========================================================================
  20. /* Function : GetPrivilege
  21. Description : This function gives the requested privilege on the requested
  22. computer.
  23. */
  24. // ===========================================================================
  25. BOOL // ret-TRUE if successful.
  26. GetPrivilege(
  27. WCHAR const * sMachineW, // in -NULL or machine name
  28. LPCWSTR pPrivilege // in -privilege name such as SE_SHUTDOWN_NAME
  29. )
  30. {
  31. BOOL bRc=FALSE; // boolean return code.
  32. HANDLE hToken=INVALID_HANDLE_VALUE; // process token.
  33. DWORD rcOs, rcOs2; // OS return code.
  34. WCHAR const * sEpName; // API EP name if failure.
  35. WKSTA_INFO_100 * pWkstaInfo; // Workstation info
  36. struct
  37. {
  38. TOKEN_PRIVILEGES tkp; // token privileges.
  39. LUID_AND_ATTRIBUTES x[3]; // room for several.
  40. } token;
  41. sEpName = L"OpenProcessToken";
  42. rcOs = OpenProcessToken( GetCurrentProcess(),
  43. TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
  44. &hToken )
  45. ? 0 : GetLastError();
  46. if ( !rcOs )
  47. {
  48. memset( &token, 0, sizeof token );
  49. sEpName = L"LookupPrivilegeValue";
  50. bRc = LookupPrivilegeValue( sMachineW,
  51. pPrivilege,
  52. &token.tkp.Privileges[0].Luid
  53. );
  54. if ( !bRc )
  55. {
  56. rcOs = GetLastError();
  57. }
  58. else
  59. {
  60. token.tkp.PrivilegeCount = 1;
  61. token.tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  62. sEpName = L"AdjustTokenPrivileges";
  63. AdjustTokenPrivileges( hToken, FALSE, &token.tkp, 0, NULL, 0 );
  64. rcOs = GetLastError();
  65. }
  66. }
  67. if ( hToken != INVALID_HANDLE_VALUE )
  68. {
  69. CloseHandle( hToken );
  70. hToken = INVALID_HANDLE_VALUE;
  71. }
  72. // If we had any error, try NetWkstaGetInfo.
  73. // If NetWkstaGetInfo fails, then use it's error condition instead.
  74. if ( rcOs )
  75. {
  76. pWkstaInfo = NULL,
  77. rcOs2 = NetWkstaGetInfo(
  78. const_cast<WCHAR *>(sMachineW),
  79. 100,
  80. (BYTE **) &pWkstaInfo );
  81. if ( pWkstaInfo )
  82. {
  83. NetApiBufferFree( pWkstaInfo );
  84. }
  85. if ( rcOs2 )
  86. {
  87. rcOs = rcOs2;
  88. sEpName = L"NetWkstaGetInfo";
  89. }
  90. }
  91. if ( !rcOs )
  92. {
  93. bRc = TRUE;
  94. }
  95. else
  96. {
  97. bRc = FALSE;
  98. SetLastError(rcOs);
  99. }
  100. return bRc;
  101. }
  102. // ===========================================================================
  103. /* Function : ComputerShutDown
  104. Description : This function shutsdown/restarts the given computer.
  105. */
  106. // ===========================================================================
  107. DWORD
  108. ComputerShutDown(
  109. WCHAR const * pComputerName, // in - computer to reboot
  110. WCHAR const * pMessage, // in - message to display in NT shutdown dialog
  111. DWORD delay, // in - delay, in seconds
  112. DWORD bRestart, // in - flag, whether to reboot or just shutdown
  113. BOOL bNoChange // in - flag, whether to really do it
  114. )
  115. {
  116. BOOL bSuccess = FALSE;
  117. WCHAR wcsMsg[LEN_ShutdownMessage];
  118. WCHAR wcsComputerName[LEN_Computer];
  119. DWORD rc = 0;
  120. WKSTA_INFO_100 * localMachine;
  121. WKSTA_INFO_100 * targetMachine;
  122. if ( pMessage )
  123. {
  124. wcscpy(wcsMsg,pMessage);
  125. }
  126. else
  127. {
  128. wcsMsg[0] = 0;
  129. }
  130. if ( pComputerName && *pComputerName )
  131. {
  132. if ( pComputerName[0] != L'\\' )
  133. {
  134. wsprintf(wcsComputerName,L"\\\\%s",pComputerName);
  135. }
  136. else
  137. {
  138. wcscpy(wcsComputerName,pComputerName);
  139. }
  140. // Get the name of the local machine
  141. rc = NetWkstaGetInfo(NULL,100,(LPBYTE*)&localMachine);
  142. if (! rc )
  143. {
  144. rc = NetWkstaGetInfo(wcsComputerName,100,(LPBYTE*)&targetMachine);
  145. }
  146. if ( ! rc )
  147. {
  148. // Get the privileges needed to shutdown a machine
  149. if ( !_wcsicmp(wcsComputerName + 2, localMachine->wki100_computername) )
  150. {
  151. bSuccess = GetPrivilege(wcsComputerName, (LPCWSTR)SE_SHUTDOWN_NAME);
  152. }
  153. else
  154. {
  155. bSuccess = GetPrivilege(wcsComputerName, (LPCWSTR)SE_REMOTE_SHUTDOWN_NAME);
  156. }
  157. if ( ! bSuccess )
  158. {
  159. rc = GetLastError();
  160. }
  161. }
  162. }
  163. else
  164. {
  165. // Computer name not specified - the is the local machine
  166. wcsComputerName[0] = 0;
  167. bSuccess = GetPrivilege(NULL, (LPCWSTR)SE_SHUTDOWN_NAME);
  168. if ( ! bSuccess )
  169. {
  170. rc = GetLastError();
  171. }
  172. }
  173. if ( bSuccess && ! bNoChange )
  174. {
  175. bSuccess = InitiateSystemShutdown( wcsComputerName,
  176. wcsMsg,
  177. delay,
  178. TRUE,
  179. bRestart
  180. );
  181. if ( !bSuccess )
  182. {
  183. rc = GetLastError();
  184. }
  185. }
  186. return rc;
  187. }