2
0

RestartManager.pas 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. unit RestartManager;
  2. {
  3. Basic RestartManager API interface unit by Martijn Laan
  4. }
  5. interface
  6. uses
  7. ActiveX, Windows;
  8. procedure FreeRestartManagerLibrary;
  9. function InitRestartManagerLibrary: Boolean;
  10. function UseRestartManager: Boolean;
  11. const
  12. RM_SESSION_KEY_LEN = SizeOf(TGUID);
  13. CCH_RM_SESSION_KEY = RM_SESSION_KEY_LEN*2;
  14. CCH_RM_MAX_APP_NAME = 255;
  15. CCH_RM_MAX_SVC_NAME = 63;
  16. RM_INVALID_TS_SESSION = -1;
  17. RM_INVALID_PROCESS = -1;
  18. type
  19. RM_APP_TYPE = DWORD;
  20. const
  21. RmUnknownApp = 0;
  22. RmMainWindow = 1;
  23. RmOtherWindow = 2;
  24. RmService = 3;
  25. RmExplorer = 4;
  26. RmConsole = 5;
  27. RmCritical = 1000;
  28. type
  29. RM_SHUTDOWN_TYPE = DWORD;
  30. const
  31. RmForceShutdown = $01;
  32. RmShutdownOnlyRegistered = $10;
  33. //RM_APP_STATUS
  34. type
  35. RM_REBOOT_REASON = DWORD;
  36. const
  37. RmRebootReasonNone = $0;
  38. RmRebootReasonPermissionDenied = $1;
  39. RmRebootReasonSessionMismatch = $2;
  40. RmRebootReasonCriticalProcess = $4;
  41. RmRebootReasonCriticalService = $8;
  42. RmRebootReasonDetectedSelf = $10;
  43. type
  44. RM_UNIQUE_PROCESS = record
  45. dwProcessId: DWORD;
  46. ProcessStartTime: TFileTime;
  47. end;
  48. RM_PROCESS_INFO = record
  49. Process: RM_UNIQUE_PROCESS;
  50. strAppName: array[0..CCH_RM_MAX_APP_NAME] of WideChar;
  51. strServiceShortName: array[0..CCH_RM_MAX_SVC_NAME] of WideChar;
  52. ApplicationType: RM_APP_TYPE;
  53. AppStatus: ULONG;
  54. TSSessionId: DWORD;
  55. bRestartable: BOOL;
  56. end;
  57. //RM_FILTER_TRIGGER
  58. //RM_FILTER_ACTION
  59. //RM_FILTER_INFO
  60. //RM_WRITE_STATUS_CALLBACK
  61. var
  62. RmStartSession: function (pSessionHandle: LPDWORD; dwSessionFlags: DWORD; strSessionKey: LPWSTR): DWORD; stdcall;
  63. RmRegisterResources: function (dwSessionHandle: DWORD; nFiles: UINT; rgsFilenames: Pointer; nApplications: UINT; rgApplications: Pointer; nServices: UINT; rgsServiceNames: Pointer): DWORD; stdcall;
  64. RmGetList: function (dwSessionHandle: DWORD; pnProcInfoNeeded, pnProcInfo: PUINT; rgAffectedApps: Pointer; lpdwRebootReasons: LPDWORD): DWORD; stdcall;
  65. RmShutdown: function (dwSessionHandle: DWORD; lActionFlags: ULONG; fnStatus: Pointer): DWORD; stdcall;
  66. RmRestart: function (dwSessionHandle: DWORD; dwRestartFlags: DWORD; fnStatus: Pointer): DWORD; stdcall;
  67. RmEndSession: function (dwSessionHandle: DWORD): DWORD; stdcall;
  68. implementation
  69. //----------------------------------------------------------------------------------------------------------------------
  70. uses
  71. SysUtils, PathFunc;
  72. const
  73. restartmanagerlib = 'Rstrtmgr.dll';
  74. var
  75. RestartManagerLibrary: HMODULE;
  76. ReferenceCount: Integer; // We have to keep track of several load/unload calls.
  77. procedure FreeRestartManagerLibrary;
  78. begin
  79. if ReferenceCount > 0 then
  80. Dec(ReferenceCount);
  81. if (RestartManagerLibrary <> 0) and (ReferenceCount = 0) then
  82. begin
  83. FreeLibrary(RestartManagerLibrary);
  84. RestartManagerLibrary := 0;
  85. RmStartSession := nil;
  86. RmRegisterResources := nil;
  87. RmGetList := nil;
  88. RmShutdown := nil;
  89. RmRestart := nil;
  90. RmEndSession := nil;
  91. end;
  92. end;
  93. //----------------------------------------------------------------------------------------------------------------------
  94. function InitRestartManagerLibrary: Boolean;
  95. function GetSystemDir: String;
  96. var
  97. Buf: array[0..MAX_PATH-1] of Char;
  98. begin
  99. GetSystemDirectory(Buf, SizeOf(Buf) div SizeOf(Buf[0]));
  100. Result := StrPas(Buf);
  101. end;
  102. begin
  103. Inc(ReferenceCount);
  104. if RestartManagerLibrary = 0 then
  105. begin
  106. RestartManagerLibrary := LoadLibrary(PChar(AddBackslash(GetSystemDir) + restartmanagerlib));
  107. if RestartManagerLibrary <> 0 then
  108. begin
  109. RmStartSession := GetProcAddress(RestartManagerLibrary, 'RmStartSession');
  110. RmRegisterResources := GetProcAddress(RestartManagerLibrary, 'RmRegisterResources');
  111. RmGetList := GetProcAddress(RestartManagerLibrary, 'RmGetList');
  112. RmShutdown := GetProcAddress(RestartManagerLibrary, 'RmShutdown');
  113. RmRestart := GetProcAddress(RestartManagerLibrary, 'RmRestart');
  114. RmEndSession := GetProcAddress(RestartManagerLibrary, 'RmEndSession');
  115. end;
  116. end;
  117. Result := RestartManagerLibrary <> 0;
  118. end;
  119. //----------------------------------------------------------------------------------------------------------------------
  120. function UseRestartManager: Boolean;
  121. begin
  122. Result := RestartManagerLibrary <> 0;
  123. end;
  124. //----------------------------------------------------------------------------------------------------------------------
  125. initialization
  126. finalization
  127. while ReferenceCount > 0 do
  128. FreeRestartManagerLibrary;
  129. end.