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.

910 lines
26 KiB

  1. //
  2. // Popup choices and install Timestamp driver.
  3. //
  4. // ShreeM (January 31, 1999)
  5. //
  6. // This command line based installation program does the following -
  7. // 1. TcEnumerateInterfaces.
  8. // 2. Display these interfaces to the user.
  9. // 3. Based on the user input - Plumb the registry.
  10. // 4. Ask the user if the service needs to be AUTO or MANUAL.
  11. //
  12. #define UNICODE
  13. #define INITGUID
  14. #include <windows.h>
  15. #include <stdio.h>
  16. #include <objbase.h>
  17. #include <wmium.h>
  18. #include <ntddndis.h>
  19. #include <qos.h>
  20. #include <qossp.h>
  21. #include <wtypes.h>
  22. #include <traffic.h>
  23. #include <tcerror.h>
  24. #include <tcguid.h>
  25. #include <winsock2.h>
  26. #include <ndisguid.h>
  27. #include <tlhelp32.h>
  28. #include <ntddpsch.h>
  29. #define LAST_COMPATIBLE_OS_VERSION 2050
  30. HANDLE hClient = NULL;
  31. ULONG ClientContext = 12;
  32. BOOLEAN WANlink = FALSE;
  33. #define REGKEY_SERVICES TEXT("System\\CurrentControlSet\\Services")
  34. #define REGKEY_PSCHED TEXT("System\\CurrentControlSet\\Services\\Psched")
  35. #define REGKEY_PSCHED_PARAMS TEXT("System\\CurrentControlSet\\Services\\Psched\\Parameters")
  36. #define REGKEY_PSCHED_PARAMS_ADAPTERS TEXT("System\\CurrentControlSet\\Services\\Psched\\Parameters\\Adapters")
  37. #define REGKEY_TIMESTMP TEXT("System\\CurrentControlSet\\Services\\TimeStmp")
  38. TCHAR Profiles[] = TEXT("LANTEST");
  39. TCHAR Lantest[] = TEXT("TokenBucketConformer\0TrafficShaper\0DRRSequencer\0TimeStmp");
  40. //
  41. // Function prototype
  42. //
  43. VOID ShutdownNT();
  44. VOID _stdcall NotifyHandler(
  45. HANDLE ClRegCtx,
  46. HANDLE ClIfcCtx,
  47. ULONG Event,
  48. HANDLE SubCode,
  49. ULONG BufSize,
  50. PVOID Buffer)
  51. {
  52. //
  53. // This function may get executed in a new thread, so we can't fire the events directly (because
  54. // it breaks some clients, like VB and IE.) To get around this, we'll fire off an APC in the origina
  55. // thread, which will handle the actual event firing.
  56. //
  57. OutputDebugString(TEXT("Notify called\n"));
  58. }
  59. //
  60. // Delete the service and cleanup Psched regkeys
  61. //
  62. BOOLEAN
  63. DeleteTimeStamp(PTC_IFC_DESCRIPTOR pIf);
  64. // Just delete the service (no psched stuff)
  65. VOID RemoveTimeStampService();
  66. void _cdecl main(
  67. INT argc,
  68. CHAR *argv[]
  69. )
  70. {
  71. TCI_CLIENT_FUNC_LIST ClientHandlerList;
  72. ULONG err;
  73. TCHAR SzBuf[MAX_PATH], *TBuffer, *KeyBuffer;
  74. ULONG i = 0, len = 0, j = 0, cb = 0, Number = 0, size = 0, interfaceid = 0;
  75. WCHAR servicetype, response;
  76. BYTE *Buffer;
  77. TC_IFC_DESCRIPTOR *pIf, WanIf;
  78. DWORD ret, Disposition, starttype, choice, InstallFlag = -1;
  79. HKEY hConfigKey, TimeStampKey;
  80. SC_HANDLE schService;
  81. SC_HANDLE schSCManager;
  82. BOOLEAN Success = FALSE;
  83. OSVERSIONINFO osversion;
  84. ClientHandlerList.ClNotifyHandler = NotifyHandler;
  85. ClientHandlerList.ClAddFlowCompleteHandler = NULL;
  86. ClientHandlerList.ClModifyFlowCompleteHandler = NULL;
  87. ClientHandlerList.ClDeleteFlowCompleteHandler = NULL;
  88. wprintf(TEXT("Installer for Time Stamp module 1.0 for Windows NT (c) Microsoft Corp.\n\n"));
  89. // check if the psched versions will be compatible before doing anything here.
  90. osversion.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
  91. osversion.dwBuildNumber = 0;
  92. GetVersionEx(&osversion);
  93. if (osversion.dwBuildNumber < LAST_COMPATIBLE_OS_VERSION) {
  94. wprintf(TEXT("Install ERROR!\nYour current Windows 2000 OS build number is %d.\n"), osversion.dwBuildNumber);
  95. wprintf(TEXT("To use the version of TIMESTMP in the QoS Tools CD, you will be required to upgrade \nto an OS build number of atleast 2050 or later.\n"));
  96. return;
  97. }
  98. wprintf(TEXT("Running this program will (un)install this module on one Interface at a time.\n"));
  99. wprintf(TEXT("You will the prompted for basic choices in the installation process.\n"));
  100. j = 0;
  101. get_again:
  102. wprintf(TEXT("[1] Install\n[2] Uninstall\n[3] Exit\n Your Choice:"));
  103. fflush(stdin);
  104. wscanf(TEXT("%d"), &choice);
  105. if (1 == choice) {
  106. InstallFlag = 1;
  107. } else if (2 == choice) {
  108. InstallFlag = 0;
  109. } else if (3 == choice) {
  110. return;
  111. } else if (j < 3) {
  112. j++;
  113. goto get_again;
  114. } else {
  115. return;
  116. }
  117. err = TcRegisterClient(
  118. CURRENT_TCI_VERSION,
  119. (HANDLE)UlongToPtr(ClientContext),
  120. &ClientHandlerList,
  121. &hClient
  122. );
  123. if (NO_ERROR != err) {
  124. hClient = NULL;
  125. wsprintf(SzBuf, TEXT("Error registering Client: %d - %d\n"), err, GetLastError());
  126. OutputDebugString(SzBuf);
  127. wprintf(TEXT("INSTALLER: QoS is not installed on this machine\n\n"));
  128. //
  129. // However, if it should be ok to Uninstall the Timestmp service using this easily.
  130. //
  131. if (0 == InstallFlag) {
  132. RemoveTimeStampService();
  133. }
  134. return;
  135. } else {
  136. OutputDebugString(TEXT("Registered Client:\n"));
  137. }
  138. size = 0;
  139. // Query Buffer Size required.
  140. err = TcEnumerateInterfaces(
  141. hClient,
  142. &size,
  143. (TC_IFC_DESCRIPTOR *)NULL
  144. );
  145. if (NO_ERROR != err) {
  146. wsprintf(SzBuf, TEXT("Error Enumerating Interfaces: %d - (size reqd. %d) \n"), err, size);
  147. OutputDebugString(SzBuf);
  148. } else {
  149. wsprintf(SzBuf, TEXT("Enumerating Interfaces works??? : %d - ITS OK!\n"), size);
  150. OutputDebugString(SzBuf);
  151. wprintf(TEXT("INSTALLER: QoS is either not installed on this machine\n\t OR \n"));
  152. wprintf(TEXT("None of the adapters are enabled for QoS\n"));
  153. //
  154. // However, if it should be ok to Uninstall the Timestmp service using this easily.
  155. //
  156. if (0 == InstallFlag) {
  157. RemoveTimeStampService();
  158. }
  159. wprintf(TEXT("Exiting...\n"));
  160. goto cleanup_no_free;
  161. }
  162. // if there are no interfaces (qos is not installed on this machine), get out.
  163. //
  164. if (!size) {
  165. wprintf(TEXT("INSTALLER: QoS is either not installed on this machine\n\t OR \n"));
  166. wprintf(TEXT("None of the adapters are enabled for QoS\n"));
  167. //
  168. // However, if it should be ok to Uninstall the Timestmp service using this easily.
  169. //
  170. if (0 == InstallFlag) {
  171. RemoveTimeStampService();
  172. }
  173. wprintf(TEXT("Exiting...\n"));
  174. goto cleanup_no_free;
  175. }
  176. // query the interfaces
  177. Buffer = malloc (size);
  178. err = TcEnumerateInterfaces(
  179. hClient,
  180. &size,
  181. (TC_IFC_DESCRIPTOR *)Buffer
  182. );
  183. if (NO_ERROR != err) {
  184. wsprintf(SzBuf, TEXT("Error Enumerating Interfaces: %d (size:%d)!\n"), err, size);
  185. OutputDebugString(SzBuf);
  186. //
  187. // However, if it should be ok to Uninstall the Timestmp service using this easily.
  188. //
  189. if (0 == InstallFlag) {
  190. RemoveTimeStampService();
  191. }
  192. wprintf(TEXT("Exiting...\n"));
  193. goto cleanup;
  194. } else {
  195. OutputDebugString(TEXT("OK, so we got the interfaces.\n"));
  196. }
  197. // Display the interfaces for the user.
  198. wprintf(TEXT("\nThe interfaces available for (un)installing time stamp module are - \n"));
  199. len = 0;
  200. for (i = 1; len < size ; i++) {
  201. pIf = (PTC_IFC_DESCRIPTOR)(Buffer + len);
  202. wprintf(TEXT("[%d]:%ws\n\t%ws\n"), i, pIf->pInterfaceName, pIf->pInterfaceID);
  203. // Move to next interface
  204. len += pIf->Length;
  205. if (NULL != wcsstr(pIf->pInterfaceName, L"WAN")) {
  206. wprintf(TEXT("Please disconnect WAN links before installing Timestmp\n"));
  207. goto cleanup;
  208. }
  209. }
  210. wprintf(TEXT("[%d]:NDISWANIP (the WAN Interface)\n"), i);
  211. // Try to get the interface ID thrice...
  212. j = 0;
  213. get_interfaceid:
  214. wprintf(TEXT("\nYour choice:"));
  215. fflush(stdin);
  216. wscanf(TEXT("%d"), &interfaceid);
  217. if (interfaceid < 1 || (interfaceid > i)) {
  218. j++;
  219. if (j > 2) {
  220. wprintf(TEXT("Invalid Choice - Exiting...\n"));
  221. goto cleanup;
  222. } else {
  223. wprintf(TEXT("Invalid choice - pick again\n"));
  224. goto get_interfaceid;
  225. }
  226. }
  227. // Get to the interface ID for the Interface selected.
  228. pIf = NULL;
  229. len = 0;
  230. if (i == interfaceid) {
  231. wprintf(TEXT("\nInterface selected for (un)installing Time Stamp - \nNdisWanIp\n\n\n"));
  232. WANlink = TRUE;
  233. pIf = NULL;
  234. } else {
  235. for (i = 1; i <= interfaceid ; i++) {
  236. pIf = (PTC_IFC_DESCRIPTOR)(Buffer + len);
  237. wprintf(TEXT("[%d]:%ws\n\t%ws\n"), i, pIf->pInterfaceName, pIf->pInterfaceID);
  238. if (i == interfaceid) {
  239. break;
  240. }
  241. // Move to next interface
  242. len += pIf->Length;
  243. }
  244. wprintf(TEXT("\nInterface selected for (un)installing Time Stamp - \n%ws\n\n\n"), pIf->pInterfaceName);
  245. }
  246. //
  247. // Branch here for Uninstall/Install.
  248. //
  249. if (InstallFlag == FALSE) {
  250. if (!DeleteTimeStamp(pIf)) {
  251. wprintf(TEXT("Delete TimeStamp Failed!\n"));
  252. }
  253. return;
  254. }
  255. //
  256. // This is the regular install path.
  257. //
  258. j = 0;
  259. get_servicetype:
  260. wprintf(TEXT("\nWould you like this service to be- [A]UTO, [M]ANUAL, [D]ISABLED:"));
  261. fflush(stdin);
  262. wscanf(TEXT("%[a-z]"), &servicetype);
  263. switch (towupper(servicetype)) {
  264. case TEXT('A'):
  265. wprintf(TEXT("\nYou have chosen AUTO start up option\n"));
  266. starttype = SERVICE_AUTO_START;
  267. break;
  268. case TEXT('D'):
  269. wprintf(TEXT("\nYou have chosen DISABLED start up option\n"));
  270. starttype = SERVICE_DISABLED;
  271. break;
  272. case TEXT('M'):
  273. wprintf(TEXT("\nYou have chosen MANUAL start up option"));
  274. starttype = SERVICE_DEMAND_START;
  275. break;
  276. default:
  277. if (j > 2) {
  278. wprintf(TEXT("\nIncorrect choice. Exiting...\n"));
  279. goto cleanup;
  280. } else {
  281. j++;
  282. wprintf(TEXT("\nInvalid - Choose again.\n"));
  283. goto get_servicetype;
  284. }
  285. break;
  286. }
  287. wprintf(TEXT("\n\n\n"));
  288. //
  289. // We have enough info to muck with the registry now.
  290. //
  291. // 1.1 open psched regkey and add profile
  292. ret = RegOpenKeyEx(
  293. HKEY_LOCAL_MACHINE,
  294. REGKEY_PSCHED_PARAMS,
  295. 0,
  296. KEY_ALL_ACCESS,
  297. &hConfigKey);
  298. if (ret !=ERROR_SUCCESS){
  299. wprintf(TEXT("Cant OPEN key\n"));
  300. goto cleanup;
  301. }
  302. ret = RegSetValueEx(
  303. hConfigKey,
  304. TEXT("Profiles"),
  305. 0,
  306. REG_MULTI_SZ,
  307. (LPBYTE)Profiles,
  308. sizeof(Profiles)
  309. );
  310. if (ret !=ERROR_SUCCESS){
  311. wprintf(TEXT("Cant SET Value:Profiles\n"));
  312. RegCloseKey(hConfigKey);
  313. goto cleanup;
  314. }
  315. ret = RegSetValueEx(
  316. hConfigKey,
  317. TEXT("LANTEST"),
  318. 0,
  319. REG_MULTI_SZ,
  320. (LPBYTE)Lantest,
  321. sizeof(Lantest)
  322. );
  323. if (ret !=ERROR_SUCCESS){
  324. wprintf(TEXT("Cant SET Value:LANTEST\n"));
  325. RegCloseKey(hConfigKey);
  326. goto cleanup;
  327. }
  328. RegCloseKey(hConfigKey);
  329. // 1.2 Open the adapters section and add the profile
  330. if (!WANlink) {
  331. KeyBuffer = malloc(sizeof(TCHAR) * (wcslen(pIf->pInterfaceID) + wcslen(REGKEY_PSCHED_PARAMS_ADAPTERS)));
  332. } else {
  333. KeyBuffer = malloc(sizeof(TCHAR) * (wcslen(TEXT("NdisWanIp")) + wcslen(REGKEY_PSCHED_PARAMS_ADAPTERS)));
  334. }
  335. wcscpy(KeyBuffer, REGKEY_PSCHED_PARAMS_ADAPTERS);
  336. wcscat(KeyBuffer, TEXT("\\"));
  337. if (!WANlink) {
  338. wcscat(KeyBuffer, pIf->pInterfaceID);
  339. } else {
  340. wcscat(KeyBuffer, TEXT("NdisWanIp"));
  341. }
  342. ret = RegOpenKeyEx(
  343. HKEY_LOCAL_MACHINE,
  344. KeyBuffer,
  345. 0,
  346. KEY_ALL_ACCESS,
  347. &hConfigKey);
  348. if (ret != ERROR_SUCCESS) {
  349. wprintf(TEXT("INSTALLER: Couldn't open Regkey for Adapter specific info\n"));
  350. free(KeyBuffer);
  351. RegCloseKey(hConfigKey);
  352. goto cleanup;
  353. }
  354. ret = RegSetValueEx(
  355. hConfigKey,
  356. TEXT("Profile"),
  357. 0,
  358. REG_SZ,
  359. (LPBYTE)Profiles,
  360. sizeof(Profiles)
  361. );
  362. if (ret !=ERROR_SUCCESS){
  363. wprintf(TEXT("Cant SET Value:LANTEST under PARAMETERS\\ADAPTERS\n"));
  364. free(KeyBuffer);
  365. RegCloseKey(hConfigKey);
  366. goto cleanup;
  367. }
  368. free(KeyBuffer);
  369. RegCloseKey(hConfigKey);
  370. // 2. throw in time stamp into the registry
  371. ret = RegCreateKeyEx(
  372. HKEY_LOCAL_MACHINE, // handle of an open key
  373. REGKEY_TIMESTMP, // address of subkey name
  374. 0, // reserved
  375. TEXT(""), // address of class string
  376. REG_OPTION_NON_VOLATILE, // special options flag
  377. KEY_ALL_ACCESS, // desired security access
  378. NULL, // address of key security structure
  379. &TimeStampKey, // address of buffer for opened handle
  380. &Disposition // address of disposition value buffer
  381. );
  382. if (ret != ERROR_SUCCESS) {
  383. wprintf(TEXT("Couldn't open Regkey to plumb time stamp module\n"));
  384. RegCloseKey(hConfigKey);
  385. goto cleanup;
  386. }
  387. if (Disposition == REG_OPENED_EXISTING_KEY) {
  388. wprintf(TEXT("Time Stamp module is already installed.\n\n\n\n"));
  389. RegCloseKey(hConfigKey);
  390. goto cleanup;
  391. }
  392. RegCloseKey(hConfigKey);
  393. // 3. Create the service...
  394. schSCManager = OpenSCManager(
  395. NULL, // machine (NULL == local)
  396. NULL, // database (NULL == default)
  397. SC_MANAGER_ALL_ACCESS // access required
  398. );
  399. if ( schSCManager ) {
  400. schService = CreateService(
  401. schSCManager, // SCManager database
  402. TEXT("TimeStmp"), // name of service
  403. TEXT("TimeStmp"), // name to display
  404. SERVICE_ALL_ACCESS, // desired access
  405. SERVICE_KERNEL_DRIVER, // service type
  406. starttype, // start type
  407. SERVICE_ERROR_NORMAL, // error control type
  408. TEXT("System32\\Drivers\\timestmp.sys"), // service's binary
  409. NULL, // no load ordering group
  410. NULL, // no tag identifier
  411. NULL, // BUGBUG: no depend upon PNP_TDI??
  412. NULL, // LocalSystem account
  413. NULL); // no password
  414. if (!schService) {
  415. // couldn't create it.
  416. wprintf(TEXT("Could NOT create Time Stamp service - %d"), GetLastError());
  417. goto cleanup;
  418. } else {
  419. wprintf(TEXT("\nThe service will start on reboot.\n"));
  420. Success = TRUE;
  421. }
  422. CloseServiceHandle(schService);
  423. CloseServiceHandle(schSCManager);
  424. } else {
  425. wprintf(TEXT("\nINSTALLER: Couldn't open Service Control Manager - Do you have access?\n"));
  426. }
  427. wprintf(TEXT("The Time Stamp module installation is complete.\n"));
  428. wprintf(TEXT("Please ensure that a copy of timestmp.sys exists in your\n"));
  429. wprintf(TEXT("\\system32\\drivers directory before you reboot.\n"));
  430. cleanup:
  431. // cleanup before getting out
  432. free(Buffer);
  433. cleanup_no_free:
  434. // deregister before bailing...
  435. err = TcDeregisterClient(hClient);
  436. if (NO_ERROR != err) {
  437. hClient = NULL;
  438. wsprintf(SzBuf, TEXT("Error DEregistering Client: %d - %d\n"), err, GetLastError());
  439. OutputDebugString(SzBuf);
  440. return;
  441. }
  442. if (Success) {
  443. ShutdownNT();
  444. }
  445. }
  446. //
  447. // Delete the service and cleanup Psched regkeys
  448. //
  449. BOOLEAN
  450. DeleteTimeStamp(PTC_IFC_DESCRIPTOR pIf)
  451. {
  452. SC_HANDLE schService;
  453. SC_HANDLE schSCManager;
  454. TCHAR *KBuffer;
  455. DWORD err;
  456. HKEY hKey;
  457. //
  458. // 1. Delete Timestamp service.
  459. //
  460. schSCManager = OpenSCManager(
  461. NULL, // machine (NULL == local)
  462. NULL, // database (NULL == default)
  463. SC_MANAGER_ALL_ACCESS // access required
  464. );
  465. if ( schSCManager ) {
  466. schService = OpenService(
  467. schSCManager, // handle to service control manager
  468. TEXT("TimeStmp"), // pointer to name of service to start
  469. SERVICE_ALL_ACCESS // type of access to service
  470. );
  471. if (!schService) {
  472. // couldn't open it.
  473. wprintf(TEXT("Could NOT open Time Stamp service - %d\n"), GetLastError());
  474. wprintf(TEXT("Deletion of Time Stamp Service was UNSUCCESSFUL\n"));
  475. //return FALSE;
  476. } else {
  477. if (!DeleteService(schService)) {
  478. wprintf(TEXT("\nThe deletion of Timestamp service has failed - error (%d).\n"), GetLastError());
  479. } else {
  480. wprintf(TEXT("\nThe service will NOT start on reboot.\n"));
  481. }
  482. }
  483. CloseServiceHandle(schService);
  484. CloseServiceHandle(schSCManager);
  485. } else {
  486. wprintf(TEXT("\nINSTALLER: Couldn't open Service Control Manager - Do you have access?\n"));
  487. }
  488. //
  489. // 2. Clean up psched registry.
  490. //
  491. err = RegOpenKeyEx(
  492. HKEY_LOCAL_MACHINE,
  493. REGKEY_PSCHED_PARAMS,
  494. 0,
  495. KEY_ALL_ACCESS,
  496. &hKey);
  497. if (err !=ERROR_SUCCESS){
  498. wprintf(TEXT("Cant OPEN key\n"));
  499. return FALSE;
  500. }
  501. err = RegDeleteValue(
  502. hKey,
  503. TEXT("Profiles")
  504. );
  505. if (err !=ERROR_SUCCESS){
  506. wprintf(TEXT("Cant Delete Value:Profiles\n"));
  507. RegCloseKey(hKey);
  508. return FALSE;
  509. }
  510. err = RegDeleteValue(
  511. hKey,
  512. TEXT("LANTEST")
  513. );
  514. if (err != ERROR_SUCCESS){
  515. wprintf(TEXT("Cant Delete Value:LANTEST\n"));
  516. RegCloseKey(hKey);
  517. return FALSE;
  518. }
  519. RegCloseKey(hKey);
  520. // 2.2 Clean up the adapter specific registry
  521. if (!WANlink) {
  522. KBuffer = malloc(sizeof(TCHAR) * (wcslen(pIf->pInterfaceID) + wcslen(REGKEY_PSCHED_PARAMS_ADAPTERS)));
  523. } else {
  524. KBuffer = malloc(sizeof(TCHAR) * (wcslen(TEXT("NdisWanIp")) + wcslen(REGKEY_PSCHED_PARAMS_ADAPTERS)));
  525. }
  526. wcscpy(KBuffer, REGKEY_PSCHED_PARAMS_ADAPTERS);
  527. wcscat(KBuffer, TEXT("\\"));
  528. if (!WANlink) {
  529. wcscat(KBuffer, pIf->pInterfaceID);
  530. } else {
  531. wcscat(KBuffer, TEXT("NdisWanIp"));
  532. }
  533. err = RegOpenKeyEx(
  534. HKEY_LOCAL_MACHINE,
  535. KBuffer,
  536. 0,
  537. KEY_ALL_ACCESS,
  538. &hKey);
  539. if (err != ERROR_SUCCESS) {
  540. wprintf(TEXT("INSTALLER: Couldn't open Regkey for Adapter specific info\n"));
  541. wprintf(TEXT("INSTALLER: CLEAN UP is partial\n"));
  542. free(KBuffer);
  543. return FALSE;
  544. }
  545. err = RegDeleteValue(
  546. hKey,
  547. TEXT("Profile")
  548. );
  549. if (err !=ERROR_SUCCESS){
  550. wprintf(TEXT("Cant Delete Value:LANTEST under PARAMETERS\\ADAPTERS\n"));
  551. wprintf(TEXT("INSTALLER: CLEAN UP is partial\n"));
  552. free(KBuffer);
  553. RegCloseKey(hKey);
  554. return FALSE;
  555. }
  556. free(KBuffer);
  557. RegCloseKey(hKey);
  558. wprintf(TEXT("The Time Stamp service is successfully deleted\n"));
  559. wprintf(TEXT("You need to reboot for the changes to take effect\n"));
  560. return TRUE;
  561. }
  562. // Just delete the service (no psched stuff)
  563. VOID RemoveTimeStampService(
  564. )
  565. {
  566. SC_HANDLE schService;
  567. SC_HANDLE schSCManager;
  568. TCHAR *KBuffer;
  569. DWORD err;
  570. HKEY hKey;
  571. //
  572. // 1. Delete Timestamp service.
  573. //
  574. schSCManager = OpenSCManager(
  575. NULL, // machine (NULL == local)
  576. NULL, // database (NULL == default)
  577. SC_MANAGER_ALL_ACCESS // access required
  578. );
  579. if ( schSCManager ) {
  580. schService = OpenService(
  581. schSCManager, // handle to service control manager
  582. TEXT("TimeStmp"), // pointer to name of service to start
  583. SERVICE_ALL_ACCESS // type of access to service
  584. );
  585. if (!schService) {
  586. // couldn't open it.
  587. wprintf(TEXT("Could NOT open Time Stamp service - %d\n"), GetLastError());
  588. wprintf(TEXT("Deletion of Time Stamp Service was UNSUCCESSFUL\n"));
  589. return;
  590. } else {
  591. if (!DeleteService(schService)) {
  592. wprintf(TEXT("\nThe deletion of Timestamp service has failed - error (%d).\n"), GetLastError());
  593. } else {
  594. wprintf(TEXT("\nThe service will NOT start on reboot.\n"));
  595. }
  596. }
  597. CloseServiceHandle(schService);
  598. CloseServiceHandle(schSCManager);
  599. } else {
  600. wprintf(TEXT("\nINSTALLER: Couldn't open Service Control Manager - Do you have access?\n"));
  601. }
  602. wprintf(TEXT("The Time Stamp service is successfully deleted\n"));
  603. wprintf(TEXT("You need to reboot for the changes to take effect\n"));
  604. return;
  605. }
  606. VOID ShutdownNT()
  607. {
  608. HANDLE hToken; // handle to process token
  609. TOKEN_PRIVILEGES tkp; // ptr. to token structure
  610. TCHAR SzBuf[MAX_PATH];
  611. BOOL fResult; // system shutdown flag
  612. INT nRet = IDYES;
  613. // Get the curren process token handle
  614. // so we can get shutdown privilege.
  615. if (!OpenProcessToken (GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
  616. wsprintf(SzBuf, TEXT("OpenProcessToken failed (%d)\n"), GetLastError());
  617. OutputDebugString(SzBuf);
  618. return;
  619. }
  620. // Get the LUID for shutdown privilege
  621. LookupPrivilegeValue (NULL, SE_SHUTDOWN_NAME,
  622. &tkp.Privileges[0].Luid);
  623. tkp.PrivilegeCount = 1; // one privilege to set
  624. tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  625. // Get shutdown privileges for this process
  626. AdjustTokenPrivileges (hToken,
  627. FALSE,
  628. &tkp,
  629. 0,
  630. (PTOKEN_PRIVILEGES) NULL,
  631. 0);
  632. // Cannot test the return value of AdjustTokenPrivileges
  633. if (GetLastError() != ERROR_SUCCESS) {
  634. wsprintf(SzBuf, TEXT("AdjustTokenPriviledges failed (%d)\n"), GetLastError());
  635. OutputDebugString(SzBuf);
  636. CloseHandle(hToken);
  637. return;
  638. }
  639. CloseHandle(hToken);
  640. /*if (!InitiateSystemShutdownEx(
  641. NULL,
  642. ,
  643. 0xffffff00,
  644. FALSE, //BOOL bForceAppsClosed,
  645. TRUE, //BOOL bRebootAfterShutdown,
  646. 0 //DWORD dwReason
  647. )) {*/
  648. //
  649. // OK, so how about a popup?
  650. //
  651. nRet = MessageBox (
  652. NULL,//hwndParent,
  653. TEXT("A reboot is required for TimeStamp Driver to get loaded. Please ensure that your %windir%\\system32\\driver's directory has a copy of timestmp.sys. Reboot now?"),
  654. TEXT("TIMESTAMP Driver Install Program"),
  655. MB_YESNO | MB_ICONEXCLAMATION
  656. );
  657. if (nRet == IDYES) {
  658. if (!ExitWindowsEx(EWX_REBOOT, 10)) {
  659. wsprintf(SzBuf, TEXT("InitializeShutdownEx failed (%d)\n"), GetLastError());
  660. OutputDebugString(SzBuf);
  661. } else {
  662. return;
  663. }
  664. }
  665. return;
  666. }