Leaked source code of windows server 2003
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.

705 lines
17 KiB

  1. /*--------------------------------------------------------------
  2. *
  3. * FILE: SKEYDLL.C
  4. *
  5. * PURPOSE: The file contains the SerialKeys DLL Functions
  6. *
  7. * CREATION: June 1994
  8. *
  9. * COPYRIGHT: Black Diamond Software (C) 1994
  10. *
  11. * AUTHOR: Ronald Moak
  12. *
  13. * $Header: %Z% %F% %H% %T% %I%
  14. *
  15. *------------------------------------------------------------*/
  16. #include "windows.h"
  17. #include "..\skeys\sk_dllif.h"
  18. #include "..\skeys\sk_dll.h"
  19. #include "..\skeys\sk_reg.h"
  20. #include "skeys.h"
  21. #include <malloc.h>
  22. #include "w95trace.c"
  23. #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
  24. #define RUNNINGEVENT TEXT("SkeysRunning")
  25. #define ONE_MINUTE (60 * 1000)
  26. static BOOL SerialKeysInstall(void);
  27. static BOOL IsSerialKeysRunning();
  28. static BOOL IsServiceStartAllowed();
  29. static BOOL WaitForServiceRunning();
  30. /*---------------------------------------------------------------
  31. *
  32. * FUNCTION int APIENTRY LibMain
  33. *
  34. * TYPE Global
  35. *
  36. * PURPOSE LibMain is called by Windows when
  37. * the DLL is initialized, Thread Attached, and other times.
  38. * Refer to SDK documentation, as to the different ways this
  39. * may be called.
  40. *
  41. * The LibMain function should perform additional initialization
  42. * tasks required by the DLL. In this example, no initialization
  43. * tasks are required. LibMain should return a value of 1 if
  44. * the initialization is successful.
  45. *
  46. * INPUTS
  47. *
  48. * RETURNS TRUE - Transfer Ok
  49. * FALSE- Transfer Failed
  50. *
  51. *---------------------------------------------------------------*/
  52. INT APIENTRY LibMain(HANDLE hInst, DWORD ul_reason_being_called, LPVOID lpReserved)
  53. {
  54. return 1;
  55. UNREFERENCED_PARAMETER(hInst);
  56. UNREFERENCED_PARAMETER(ul_reason_being_called);
  57. UNREFERENCED_PARAMETER(lpReserved);
  58. }
  59. /*---------------------------------------------------------------
  60. *
  61. * FUNCTION void SkeyGetRegistryValues()
  62. *
  63. * TYPE Global
  64. *
  65. * PURPOSE Reads the values from the registry into the
  66. * SerialKeys structure
  67. *
  68. * INPUTS None
  69. *
  70. * RETURNS None
  71. *
  72. *---------------------------------------------------------------*/
  73. static BOOL SkeyGetRegistryValues(HKEY hkey, LPSERIALKEYS psk)
  74. {
  75. LONG lErr;
  76. DWORD dwType;
  77. DWORD cbData;
  78. psk->iPortState = 0;
  79. psk->iActive = 0;
  80. psk->dwFlags = 0;
  81. cbData = sizeof(psk->dwFlags);
  82. lErr = RegQueryValueEx(
  83. hkey,
  84. REG_FLAGS,
  85. 0,
  86. &dwType,
  87. (LPBYTE)&psk->dwFlags,
  88. &cbData);
  89. if (ERROR_SUCCESS != lErr || dwType != REG_DWORD)
  90. {
  91. psk->dwFlags = 0;
  92. }
  93. psk->dwFlags |= SERKF_AVAILABLE;
  94. if (NULL != psk->lpszActivePort)
  95. {
  96. cbData = MAX_PATH * sizeof(*psk->lpszActivePort);
  97. lErr = RegQueryValueEx(
  98. hkey,
  99. REG_ACTIVEPORT,
  100. 0,
  101. &dwType,
  102. (LPBYTE)psk->lpszActivePort,
  103. &cbData);
  104. psk->lpszActivePort[ MAX_PATH - 1 ] = '\0'; // ports are all MAX_PATH tchars
  105. if (ERROR_SUCCESS != lErr || dwType != REG_SZ)
  106. {
  107. lstrcpy(psk->lpszActivePort, TEXT("COM1"));
  108. }
  109. }
  110. if (NULL != psk->lpszPort)
  111. {
  112. cbData = MAX_PATH * sizeof(*psk->lpszPort);
  113. lErr = RegQueryValueEx(
  114. hkey,
  115. REG_PORT,
  116. 0,
  117. &dwType,
  118. (LPBYTE)psk->lpszPort,
  119. &cbData);
  120. psk->lpszPort[ MAX_PATH - 1 ] = '\0'; // ports are all MAX_PATH tchars
  121. if (ERROR_SUCCESS != lErr || dwType != REG_SZ)
  122. {
  123. lstrcpy(psk->lpszPort, TEXT("COM1"));
  124. }
  125. }
  126. cbData = sizeof(psk->iBaudRate);
  127. lErr = RegQueryValueEx(
  128. hkey,
  129. REG_BAUD,
  130. 0,&dwType,
  131. (LPBYTE)&psk->iBaudRate,
  132. &cbData);
  133. if (ERROR_SUCCESS != lErr || dwType != REG_DWORD)
  134. {
  135. psk->iBaudRate = 300;
  136. }
  137. return TRUE;
  138. }
  139. /*---------------------------------------------------------------
  140. *
  141. * FUNCTION BOOL SkeyGetUserValues()
  142. *
  143. * TYPE Local
  144. *
  145. * PURPOSE Read the registery an collect the data for the current
  146. * user.
  147. *
  148. * RETURNS TRUE - User wants Serial Keys Enabled
  149. * FALSE- User wants Serial Keys Disabled
  150. *
  151. *---------------------------------------------------------------*/
  152. BOOL SkeyGetUserValues(LPSERIALKEYS psk)
  153. {
  154. BOOL fOk = FALSE;
  155. HKEY hkey;
  156. DWORD dwRet;
  157. DWORD dwDisposition;
  158. dwRet = RegCreateKeyEx( HKEY_CURRENT_USER,
  159. TEXT("Control Panel\\Accessibility\\SerialKeys"),
  160. 0,
  161. NULL, // CLASS NAME??
  162. 0, // by default is non-volatile
  163. KEY_READ,
  164. NULL, // default security descriptor
  165. &hkey,
  166. &dwDisposition); // yes we throw this away
  167. if (ERROR_SUCCESS == dwRet)
  168. {
  169. fOk = SkeyGetRegistryValues(hkey, psk);
  170. RegCloseKey(hkey);
  171. }
  172. if (fOk)
  173. {
  174. // Not available unless the service is running or this
  175. // user can start it
  176. if (IsSerialKeysRunning() || IsServiceStartAllowed())
  177. {
  178. psk->dwFlags |= SERKF_AVAILABLE;
  179. }
  180. else
  181. {
  182. psk->dwFlags &= ~SERKF_AVAILABLE;
  183. }
  184. }
  185. return(fOk);
  186. }
  187. /*---------------------------------------------------------------
  188. *
  189. * FUNCTION void SetRegistryValues()
  190. *
  191. * TYPE Global
  192. *
  193. * PURPOSE Writes the values in the SerialKeys structure to
  194. * the Registry.
  195. *
  196. * INPUTS None
  197. *
  198. * RETURNS None
  199. *
  200. *---------------------------------------------------------------*/
  201. static BOOL SkeySetRegistryValues(HKEY hkey, LPSERIALKEYS psk)
  202. {
  203. LONG lErr;
  204. BOOL fOk;
  205. DWORD dwFlags;
  206. dwFlags = psk->dwFlags | SERKF_AVAILABLE;
  207. lErr = RegSetValueEx( // Write dwFlags
  208. hkey,
  209. REG_FLAGS,
  210. 0,REG_DWORD,
  211. (CONST LPBYTE)&dwFlags,
  212. sizeof(DWORD));
  213. fOk = (ERROR_SUCCESS == lErr);
  214. if (fOk)
  215. {
  216. lErr = RegSetValueEx( // Write Active Port
  217. hkey,
  218. REG_ACTIVEPORT,
  219. 0,REG_SZ,
  220. (CONST LPBYTE) psk->lpszActivePort,
  221. (NULL == psk->lpszActivePort) ? 0 :
  222. (lstrlen(psk->lpszActivePort) + 1) *
  223. sizeof(*psk->lpszActivePort));
  224. fOk = (ERROR_SUCCESS == lErr);
  225. }
  226. if (fOk)
  227. {
  228. lErr = RegSetValueEx( // Write Active Port
  229. hkey,
  230. REG_PORT,
  231. 0,REG_SZ,
  232. (CONST LPBYTE)psk->lpszPort,
  233. (NULL == psk->lpszPort) ? 0 :
  234. (lstrlen(psk->lpszPort) + 1) * sizeof(*psk->lpszPort));
  235. fOk = (ERROR_SUCCESS == lErr);
  236. }
  237. if (fOk)
  238. {
  239. lErr = RegSetValueEx( // Write Active Port
  240. hkey,
  241. REG_BAUD,
  242. 0,REG_DWORD,
  243. (CONST LPBYTE) &psk->iBaudRate,
  244. sizeof(psk->iBaudRate));
  245. fOk = (ERROR_SUCCESS == lErr);
  246. }
  247. return fOk;
  248. }
  249. /*---------------------------------------------------------------
  250. *
  251. * FUNCTION void SetUserValues()
  252. *
  253. * TYPE Global
  254. *
  255. * PURPOSE This function writes out information to the
  256. * registry.
  257. *
  258. * INPUTS None
  259. *
  260. * RETURNS TRUE - Write Successful
  261. * FALSE- Write Failed
  262. *
  263. *---------------------------------------------------------------*/
  264. BOOL SkeySetUserValues(LPSERIALKEYS psk)
  265. {
  266. BOOL fOk = FALSE;
  267. HKEY hkey;
  268. DWORD dwRet;
  269. DWORD dwDisposition;
  270. dwRet = RegCreateKeyEx(
  271. HKEY_CURRENT_USER,
  272. TEXT("Control Panel\\Accessibility\\SerialKeys"),
  273. 0,
  274. NULL, // class name
  275. REG_OPTION_NON_VOLATILE,
  276. KEY_READ | KEY_WRITE,
  277. NULL, // default security descriptor
  278. &hkey,
  279. &dwDisposition); // yes we throw this away
  280. if (ERROR_SUCCESS == dwRet)
  281. {
  282. fOk = SkeySetRegistryValues(hkey, psk);
  283. RegCloseKey(hkey);
  284. }
  285. return(fOk);
  286. }
  287. #if 0 // This old code is no longer needed ////////////////////////////////////
  288. /*---------------------------------------------------------------
  289. *
  290. * FUNCTION BOOL IsSerialKeysInstalled();
  291. *
  292. * TYPE Local
  293. *
  294. * PURPOSE This function passes the information from the
  295. * Serial Keys application to the Server
  296. *
  297. * INPUTS None
  298. *
  299. * RETURNS TRUE - SerialKeys is Installed
  300. * FALSE- SerialKeys Not Installed
  301. *
  302. *---------------------------------------------------------------*/
  303. static BOOL IsSerialKeysInstalled()
  304. {
  305. SC_HANDLE schService = NULL;
  306. SC_HANDLE schSCManager = NULL;
  307. BOOL fOk = FALSE;
  308. //
  309. // Check if the Serial Keys Service is installed
  310. schSCManager = OpenSCManager
  311. (
  312. NULL, // machine (NULL == local)
  313. NULL, // database (NULL == default)
  314. SC_MANAGER_ALL_ACCESS // access required
  315. );
  316. if (NULL != schSCManager)
  317. {
  318. schService = OpenService(schSCManager, "SerialKeys", SERVICE_ALL_ACCESS);
  319. if (NULL != schService)
  320. {
  321. CloseServiceHandle(schService);
  322. fOk = TRUE;
  323. }
  324. CloseServiceHandle(schSCManager);
  325. }
  326. return fOk;
  327. }
  328. #endif ////////////////////////////////////////////////////////////////////////
  329. BOOL IsSerialKeysRunning()
  330. {
  331. BOOL fRunning = FALSE;
  332. HANDLE hEventSkeysServiceRunning;
  333. hEventSkeysServiceRunning = OpenEvent(SYNCHRONIZE, FALSE, RUNNINGEVENT);
  334. if (NULL != hEventSkeysServiceRunning)
  335. {
  336. DWORD dwWait;
  337. dwWait = WaitForSingleObject(hEventSkeysServiceRunning, 0);
  338. fRunning = (WAIT_OBJECT_0 == dwWait);
  339. CloseHandle(hEventSkeysServiceRunning);
  340. }
  341. return fRunning;
  342. }
  343. BOOL IsServiceStartAllowed()
  344. {
  345. BOOL fServiceStartAllowed = FALSE;
  346. SC_HANDLE schSCManager = NULL;
  347. schSCManager = OpenSCManager( // Open Service Manager
  348. NULL, // machine (NULL == local)
  349. NULL, // database (NULL == default)
  350. SC_MANAGER_CREATE_SERVICE); // access required
  351. if (NULL != schSCManager) // Did Open Service succeed?
  352. {
  353. CloseServiceHandle(schSCManager);
  354. fServiceStartAllowed = TRUE;
  355. }
  356. return fServiceStartAllowed;
  357. }
  358. BOOL SkeyServiceRequest(UINT uAction, LPSERIALKEYS psk, BOOL fWinIni)
  359. {
  360. BOOL fOk = FALSE;
  361. SKEYDLL SKeyDLL;
  362. DWORD bytesRead;
  363. if (IsSerialKeysRunning())
  364. {
  365. memset(&SKeyDLL, 0, sizeof(SKeyDLL));
  366. SKeyDLL.Message = uAction;
  367. if (psk->lpszActivePort != NULL)
  368. {
  369. strcpy(SKeyDLL.szActivePort,psk->lpszActivePort);
  370. }
  371. if (psk->lpszPort != NULL)
  372. {
  373. strcpy(SKeyDLL.szPort,psk->lpszPort);
  374. }
  375. SKeyDLL.dwFlags = psk->dwFlags | SERKF_AVAILABLE;
  376. SKeyDLL.iBaudRate = psk->iBaudRate;
  377. SKeyDLL.iPortState = psk->iPortState;
  378. SKeyDLL.iSave = fWinIni;
  379. fOk = CallNamedPipe(
  380. SKEY_NAME, // Pipe name
  381. &SKeyDLL,
  382. sizeof(SKeyDLL),
  383. &SKeyDLL,
  384. sizeof(SKeyDLL),
  385. &bytesRead,
  386. NMPWAIT_USE_DEFAULT_WAIT);
  387. if (fOk)
  388. {
  389. if (psk->lpszActivePort != NULL)
  390. {
  391. strcpy(psk->lpszActivePort,SKeyDLL.szActivePort);
  392. }
  393. if (psk->lpszPort != NULL)
  394. {
  395. strcpy(psk->lpszPort,SKeyDLL.szPort);
  396. }
  397. psk->dwFlags = SKeyDLL.dwFlags | SERKF_AVAILABLE;
  398. psk->iBaudRate = SKeyDLL.iBaudRate;
  399. psk->iPortState = SKeyDLL.iPortState;
  400. }
  401. }
  402. return fOk;
  403. }
  404. BOOL SkeyInitUser()
  405. {
  406. BOOL fOk;
  407. SERIALKEYS sk;
  408. TCHAR szActivePort[MAX_PATH]; // all ports are expected to be MAX_PATH tchars
  409. TCHAR szPort[MAX_PATH]; // all ports are expected to be MAX_PATH tchars
  410. memset(&sk, 0, sizeof(sk));
  411. sk.cbSize = sizeof(sk);
  412. sk.lpszActivePort = szActivePort;
  413. sk.lpszPort = szPort;
  414. fOk = SkeyGetUserValues(&sk);
  415. if (fOk)
  416. {
  417. fOk = SkeyServiceRequest(SPI_SETSERIALKEYS, &sk, FALSE);
  418. }
  419. return fOk;
  420. }
  421. /*---------------------------------------------------------------
  422. *
  423. * FUNCTION int APIENTRY SKEY_SystemParameterInfo
  424. *
  425. * TYPE Global
  426. *
  427. * PURPOSE This function passes the information from the
  428. * Serial Keys application to the Server
  429. *
  430. * INPUTS
  431. *
  432. * RETURNS TRUE - Transfer Ok
  433. * FALSE- Transfer Failed
  434. *
  435. *---------------------------------------------------------------*/
  436. BOOL APIENTRY SKEY_SystemParametersInfo(
  437. UINT uAction,
  438. UINT uParam,
  439. LPSERIALKEYS psk,
  440. BOOL fWinIni)
  441. {
  442. BOOL fOk;
  443. BOOL fStarted;
  444. fOk = ((uAction == SK_SPI_INITUSER) ||
  445. (NULL != psk && (0 != psk->cbSize)));
  446. if (fOk)
  447. {
  448. switch (uAction)
  449. {
  450. case SPI_SETSERIALKEYS:
  451. fOk = SkeySetUserValues(psk);
  452. if (fOk && (psk->dwFlags & SERKF_SERIALKEYSON) && IsServiceStartAllowed())
  453. {
  454. fOk = SerialKeysInstall();
  455. }
  456. if (fOk && IsSerialKeysRunning())
  457. {
  458. fOk = SkeyInitUser();
  459. }
  460. break;
  461. case SPI_GETSERIALKEYS:
  462. fOk = SkeyGetUserValues(psk);
  463. if (fOk && (psk->dwFlags & SERKF_SERIALKEYSON) &&
  464. !IsSerialKeysRunning() && IsServiceStartAllowed())
  465. {
  466. fOk = SerialKeysInstall();
  467. }
  468. if (fOk && IsSerialKeysRunning())
  469. {
  470. fOk = SkeyInitUser();
  471. }
  472. break;
  473. case SK_SPI_INITUSER:
  474. // give the service a chance to start
  475. fStarted = WaitForServiceRunning();
  476. if (!fStarted)
  477. {
  478. // service does not seem to be running
  479. // let's try to start it
  480. fOk = SkeyGetUserValues(psk);
  481. if (fOk && (psk->dwFlags & SERKF_SERIALKEYSON) &&
  482. !IsSerialKeysRunning() && IsServiceStartAllowed())
  483. {
  484. SerialKeysInstall();
  485. }
  486. if (IsSerialKeysRunning())
  487. {
  488. fOk = SkeyInitUser();
  489. }
  490. }
  491. break;
  492. default:
  493. fOk = FALSE; // No - Fail
  494. }
  495. }
  496. return fOk;
  497. }
  498. /*****************************************************************************/
  499. /* WaitForServiceRunning - wait up to one minute for the SerialKeys service
  500. * to signal it is ready. CreateEvent has been called by SKeys.exe before
  501. * this function is executed.
  502. */
  503. BOOL WaitForServiceRunning()
  504. {
  505. BOOL fOk = FALSE;
  506. HANDLE hEventSkeysServiceRunning = OpenEvent(SYNCHRONIZE, FALSE, RUNNINGEVENT);
  507. if (hEventSkeysServiceRunning)
  508. {
  509. DWORD dwWait = WaitForSingleObject(hEventSkeysServiceRunning, ONE_MINUTE);
  510. CloseHandle(hEventSkeysServiceRunning);
  511. fOk = (WAIT_OBJECT_0 == dwWait);
  512. }
  513. return fOk;
  514. }
  515. /****************************************************************************/
  516. BOOL SerialKeysInstall(void)
  517. {
  518. BOOL fStarted = FALSE;
  519. SERVICE_STATUS ssStatus;
  520. DWORD dwOldCheckPoint;
  521. TCHAR szFileName[MAX_PATH + 1];
  522. SC_HANDLE schService = NULL;
  523. SC_HANDLE schSCManager = NULL;
  524. schSCManager = OpenSCManager( // Open Service Manager
  525. NULL, // machine (NULL == local)
  526. NULL, // database (NULL == default)
  527. SC_MANAGER_ALL_ACCESS); // access required
  528. if (NULL != schSCManager) // Did Open Service succeed?
  529. {
  530. schService = OpenService(
  531. schSCManager ,
  532. __TEXT("SerialKeys"),
  533. SERVICE_ALL_ACCESS);
  534. if (NULL != schService)
  535. {
  536. // insure the serivce is auto-start
  537. ChangeServiceConfig(
  538. schService,
  539. SERVICE_WIN32_OWN_PROCESS,
  540. SERVICE_AUTO_START, // when to start service
  541. SERVICE_NO_CHANGE, // severity if service fails to start
  542. NULL, // pointer to service binary file name
  543. NULL, // pointer to load ordering group name
  544. NULL, // pointer to variable to get tag identifier
  545. NULL, // pointer to array of dependency names
  546. NULL, // pointer to account name of service
  547. NULL, // pointer to password for service account
  548. __TEXT("SerialKeys")); // name to display
  549. }
  550. else
  551. {
  552. if (!GetWindowsDirectory(szFileName, ARRAY_SIZE(szFileName)))
  553. return FALSE; // PREFIX #113665 don't use szFileName if call fails
  554. lstrcat(szFileName, __TEXT("\\system32\\skeys.exe"));
  555. // Is Service File installed?
  556. if (0xFFFFFFFF != GetFileAttributes(szFileName))
  557. {
  558. schService = CreateService(
  559. schSCManager, // SCManager database
  560. __TEXT("SerialKeys"), // name of service
  561. __TEXT("SerialKeys"), // name to display
  562. SERVICE_ALL_ACCESS, // desired access
  563. SERVICE_WIN32_OWN_PROCESS, // service type
  564. SERVICE_AUTO_START, // start type
  565. SERVICE_ERROR_NORMAL, // error control type
  566. szFileName, // service's binary
  567. NULL, // no load ordering group
  568. NULL, // no tag identifier
  569. NULL, // no dependencies
  570. NULL, // LocalSystem account
  571. NULL); // no password
  572. }
  573. }
  574. if (NULL != schService)
  575. {
  576. BOOL fOk = QueryServiceStatus(schService,&ssStatus);
  577. if (fOk && ssStatus.dwCurrentState != SERVICE_RUNNING)
  578. {
  579. static PTSTR pszArg = TEXT("F\0"); // force service to start
  580. PTSTR apszArg[] = {pszArg, NULL};
  581. if (StartService(schService, 1, apszArg))
  582. {
  583. while(fOk && ssStatus.dwCurrentState != SERVICE_RUNNING)
  584. {
  585. dwOldCheckPoint = ssStatus.dwCheckPoint;
  586. Sleep(max(ssStatus.dwWaitHint, 1000));
  587. fOk = QueryServiceStatus(schService,&ssStatus);
  588. fOk = (fOk && (dwOldCheckPoint >= ssStatus.dwCheckPoint));
  589. }
  590. }
  591. }
  592. fStarted = fOk && (ssStatus.dwCurrentState == SERVICE_RUNNING);
  593. CloseServiceHandle(schService);
  594. if (fStarted)
  595. {
  596. fStarted = WaitForServiceRunning();
  597. }
  598. }
  599. CloseServiceHandle(schSCManager);
  600. }
  601. return fStarted;
  602. }