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.

592 lines
15 KiB

  1. /*--------------------------------------------------------------
  2. *
  3. * FILE: SK_DLL.C
  4. *
  5. * PURPOSE: The file contains the Functions responsible for
  6. * managing information passed between SerialKeys
  7. * and the SerialKeys DLL
  8. *
  9. * CREATION: June 1994
  10. *
  11. * COPYRIGHT: Black Diamond Software (C) 1994
  12. *
  13. * AUTHOR: Ronald Moak
  14. *
  15. * NOTES:
  16. *
  17. * This file, and all others associated with it contains trade secrets
  18. * and information that is proprietary to Black Diamond Software.
  19. * It may not be copied copied or distributed to any person or firm
  20. * without the express written permission of Black Diamond Software.
  21. * This permission is available only in the form of a Software Source
  22. * License Agreement.
  23. *
  24. * $Header: %Z% %F% %H% %T% %I%
  25. *
  26. *--- Includes ---------------------------------------------------------*/
  27. #include <process.h>
  28. #include "windows.h"
  29. #include "w95trace.h"
  30. #include "sk_defs.h"
  31. #include "sk_reg.h"
  32. #include "sk_dll.h"
  33. #include "sk_dllif.h"
  34. #include <malloc.h>
  35. #ifdef DEBUG
  36. void dbg_Output(LPSTR Header)
  37. {
  38. DBPRINTF(Header);
  39. DBPRINTF(TEXT("-- dwFlags (%d) iBaudRate (%d) Save (%d) iPortState (%d)\r\n"), SKeyDLL.dwFlags,SKeyDLL.iBaudRate,SKeyDLL.iSave,SKeyDLL.iPortState);
  40. DBPRINTF(TEXT("-- ActivePort (%s) Port (%s)\r\n"),SKeyDLL.szActivePort,SKeyDLL.szPort);
  41. }
  42. #define DBG_DUMP(Header) dbg_Output(Header)
  43. #else
  44. #define DBG_DUMP(Header)
  45. #endif
  46. // Defines --------------------------------------------------
  47. // Local Function Prototypes ---------------------------------
  48. static void CleanUpDLL();
  49. static void GetCurrentValues();
  50. static void GetNewValues();
  51. static void ProcessDLL();
  52. static BOOL ReadDLL();
  53. static void __cdecl ServiceDLL(VOID *notUsed);
  54. static BOOL WriteDLL();
  55. // Local Variables --------------------------------------------------
  56. static OVERLAPPED OverLapRd; // Overlapped structure for reading.
  57. static SKEYDLL SKeyDLL; // Input buffer for pipe.
  58. static BOOL fExitDLL; // Set Exit Flag
  59. static BOOL fDoneDLL = TRUE;
  60. static HANDLE hPipeDLL;
  61. static HANDLE hThreadDLL;
  62. /*---------------------------------------------------------------
  63. *
  64. * Global Functions
  65. *
  66. /*---------------------------------------------------------------
  67. *
  68. * FUNCTION BOOL DoneDLL()
  69. *
  70. * TYPE Global
  71. *
  72. * PURPOSE Returns the state of the DLL Thread
  73. *
  74. * INPUTS None
  75. *
  76. * RETURNS TRUE - DLL Thread not running
  77. * FALSE - DLL Thread Is running
  78. *
  79. *---------------------------------------------------------------*/
  80. BOOL DoneDLL()
  81. {
  82. return(fDoneDLL);
  83. }
  84. //-----------------------------------------------------------------------------
  85. // CreateSd
  86. //
  87. // Creates a SECURITY_DESCRIPTOR with an authenticated user DACL and the
  88. // rights specified by ulRights.
  89. //
  90. // Caller must call free() on the returned buffer if not NULL.
  91. //
  92. PSECURITY_DESCRIPTOR
  93. CreateSd(unsigned long ulRights)
  94. {
  95. PSECURITY_DESCRIPTOR pSd = NULL;
  96. PSID psidAuthentUser;
  97. SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
  98. // Make a SID for a local administrator
  99. if (AllocateAndInitializeSid(&NtAuthority, 2,
  100. SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS,
  101. 0, 0, 0, 0, 0, 0,
  102. &psidAuthentUser))
  103. {
  104. // Calculate the size of and allocate a buffer for the DACL, we need
  105. // this value independently of the total alloc size for ACL init.
  106. ULONG cbAclSize = sizeof (ACL)
  107. + (sizeof (ACCESS_ALLOWED_ACE) - sizeof (ULONG))
  108. + GetLengthSid(psidAuthentUser);
  109. pSd = malloc(SECURITY_DESCRIPTOR_MIN_LENGTH + cbAclSize);
  110. if (pSd)
  111. {
  112. ACL *pAcl = (ACL *)((BYTE *)pSd + SECURITY_DESCRIPTOR_MIN_LENGTH);
  113. if ( !InitializeAcl(pAcl, cbAclSize, ACL_REVISION)
  114. || !AddAccessAllowedAce(pAcl, ACL_REVISION, ulRights, psidAuthentUser)
  115. || !InitializeSecurityDescriptor(pSd, SECURITY_DESCRIPTOR_REVISION)
  116. || !SetSecurityDescriptorDacl(pSd, TRUE, pAcl, FALSE))
  117. {
  118. free(pSd); // error!
  119. pSd = NULL;
  120. }
  121. }
  122. FreeSid(psidAuthentUser);
  123. }
  124. return pSd;
  125. }
  126. /*---------------------------------------------------------------
  127. *
  128. * FUNCTION BOOL InitDLL()
  129. *
  130. * TYPE Global
  131. *
  132. * PURPOSE This function creates a thread that monitors when an
  133. * application uses the DLL to Get or Set the state
  134. * of Serial Keys.
  135. *
  136. * INPUTS None
  137. *
  138. * RETURNS TRUE - Init ok & Thread installed
  139. * FALSE- Thread failed
  140. *
  141. *---------------------------------------------------------------*/
  142. BOOL InitDLL()
  143. {
  144. DWORD Id;
  145. PSECURITY_DESCRIPTOR pSD;
  146. SECURITY_ATTRIBUTES sa;
  147. DBPRINTF(TEXT("InitDLL()\r\n"));
  148. hPipeDLL = INVALID_HANDLE_VALUE;
  149. hThreadDLL = NULL;
  150. fExitDLL = FALSE;
  151. pSD = CreateSd(FILE_CREATE_PIPE_INSTANCE|GENERIC_READ|GENERIC_WRITE);
  152. if (!pSD)
  153. return(FALSE);
  154. sa.nLength = sizeof(SECURITY_ATTRIBUTES);
  155. sa.bInheritHandle = TRUE;
  156. sa.lpSecurityDescriptor = pSD;
  157. hPipeDLL = CreateNamedPipe(
  158. SKEY_NAME, // Pipe name
  159. PIPE_ACCESS_DUPLEX, // 2 way pipe.
  160. PIPE_TYPE_MESSAGE |
  161. PIPE_READMODE_MESSAGE |
  162. PIPE_WAIT,
  163. 1, // Maximum instance limit.
  164. 0, // Buffer sizes.
  165. 0,
  166. 1000 * 30, // Specify time out.
  167. &sa); // Default securities specified.
  168. free(pSD);
  169. if (INVALID_HANDLE_VALUE == hPipeDLL)
  170. {
  171. hPipeDLL = NULL;
  172. DBPRINTF(TEXT("Unable to Create DLL Named Pipe\r\n"));
  173. return FALSE;
  174. }
  175. fDoneDLL = FALSE; // Clear Thread Done Flag
  176. // Generate thread to handle DLL processing;
  177. hThreadDLL = (HANDLE)CreateThread( // Start Service Thread
  178. 0,
  179. 0,
  180. (LPTHREAD_START_ROUTINE) ServiceDLL,
  181. 0,0,&Id); // argument to thread
  182. if (NULL == hThreadDLL)
  183. {
  184. DBPRINTF(TEXT("Unable to Create DLL Thread\r\n"));
  185. CleanUpDLL();
  186. return FALSE;
  187. }
  188. return(TRUE);
  189. }
  190. /*---------------------------------------------------------------
  191. *
  192. * FUNCTION void SuspendDLL()
  193. *
  194. * TYPE Global
  195. *
  196. * PURPOSE The function is called to Pause the thread
  197. * reading and processing data coming from the comm port.
  198. *
  199. * INPUTS None
  200. *
  201. * RETURNS None
  202. *
  203. *---------------------------------------------------------------*/
  204. void SuspendDLL()
  205. {
  206. if (NULL != hThreadDLL)
  207. {
  208. SuspendThread(hThreadDLL);
  209. }
  210. }
  211. /*---------------------------------------------------------------
  212. *
  213. * FUNCTION void ResumeDLL()
  214. *
  215. * TYPE Global
  216. *
  217. * PURPOSE The function is called to resume the Paused thread.
  218. *
  219. * INPUTS None
  220. *
  221. * RETURNS None
  222. *
  223. *---------------------------------------------------------------*/
  224. void ResumeDLL()
  225. {
  226. if (NULL != hThreadDLL)
  227. {
  228. ResumeThread(hThreadDLL);
  229. }
  230. }
  231. /*---------------------------------------------------------------
  232. *
  233. * FUNCTION void TerminateDLL()
  234. *
  235. * TYPE Global
  236. *
  237. * PURPOSE This function is called to Terminate the DLL Process
  238. *
  239. * INPUTS None
  240. *
  241. * RETURNS None
  242. *
  243. *---------------------------------------------------------------*/
  244. void TerminateDLL()
  245. {
  246. DWORD bytesRead;
  247. DBPRINTF(TEXT("TerminateDLL()\r\n"));
  248. if (fDoneDLL)
  249. return;
  250. fExitDLL = TRUE; // Set Exit Flag
  251. CallNamedPipe // Trigger the DLL to Shutdown
  252. (
  253. SKEY_NAME, // Pipe name
  254. &SKeyDLL, sizeof(SKeyDLL),
  255. &SKeyDLL, sizeof(SKeyDLL),
  256. &bytesRead, NMPWAIT_NOWAIT
  257. );
  258. }
  259. /*---------------------------------------------------------------
  260. *
  261. * Local Functions
  262. *
  263. /*---------------------------------------------------------------
  264. *
  265. * FUNCTION static void CleanUpDLL()
  266. *
  267. * TYPE Local
  268. *
  269. * PURPOSE This function cleans up file handles and misc stuff
  270. * when the thread is terminated.
  271. *
  272. * INPUTS None
  273. *
  274. * RETURNS None
  275. *
  276. *---------------------------------------------------------------*/
  277. static void CleanUpDLL()
  278. {
  279. BOOL Stat;
  280. DBPRINTF(TEXT("CleanUpDLL()\r\n"));
  281. // Close Pipe Handle
  282. if (NULL != hPipeDLL)
  283. {
  284. Stat = CloseHandle(hPipeDLL);
  285. DBPRINTF_IF(Stat,TEXT("Unable to Close DLL Pipe\r\n"));
  286. }
  287. // Close Thread Handle
  288. if (NULL != hThreadDLL)
  289. {
  290. Stat = CloseHandle(hThreadDLL);
  291. DBPRINTF_IF(Stat,TEXT("Unable to Close DLL Thread\r\n"));
  292. }
  293. hPipeDLL = NULL;
  294. hThreadDLL = NULL;
  295. fDoneDLL = TRUE; // Set Thread Done Flag
  296. DBPRINTF(TEXT("DLL Service Processing Done\r\n"));
  297. }
  298. /*---------------------------------------------------------------
  299. *
  300. * FUNCTION void _CRTAPI1 ServiceDLL()
  301. *
  302. * TYPE Local
  303. *
  304. * PURPOSE This function is a thread that monitors when an
  305. * application uses the DLL to Get or Set the state
  306. * of Serial Keys.
  307. *
  308. * INPUTS None
  309. *
  310. * RETURNS None
  311. *
  312. *---------------------------------------------------------------*/
  313. static void __cdecl ServiceDLL(VOID *notUsed)
  314. {
  315. DWORD retCode;
  316. DWORD bytesRead;
  317. DWORD bytesWritten;
  318. DBPRINTF(TEXT("SericeDLL()\r\n"));
  319. while (TRUE)
  320. {
  321. if (!ConnectNamedPipe(hPipeDLL,NULL))
  322. {
  323. ExitThread(0);
  324. return;
  325. }
  326. if (fExitDLL) // Is the Service Done?
  327. { // Yes - Close Down Service
  328. CleanUpDLL(); // Close Handles Etc.
  329. ExitThread(0); // Exit The Thread
  330. return;
  331. }
  332. retCode = ReadFile( // Read Message
  333. hPipeDLL,
  334. &SKeyDLL,
  335. sizeof(SKeyDLL),
  336. &bytesRead,
  337. NULL);
  338. if (!retCode) // Pipe is Broken Try & reconnect
  339. continue;
  340. ProcessDLL(); // Yes - Process incoming buffer
  341. retCode = WriteFile( // Write Message
  342. hPipeDLL,
  343. &SKeyDLL,
  344. sizeof(SKeyDLL),
  345. &bytesWritten,
  346. NULL);
  347. if (!retCode) // Pipe is Broken Try & reconnect
  348. continue;
  349. DisconnectNamedPipe(hPipeDLL);
  350. }
  351. }
  352. /*---------------------------------------------------------------
  353. *
  354. * FUNCTION void ProcessDLL()
  355. *
  356. * TYPE Local
  357. *
  358. * PURPOSE This function process the input buffer received from
  359. * the DLL.
  360. *
  361. * INPUTS None
  362. *
  363. * RETURNS None
  364. *
  365. *---------------------------------------------------------------*/
  366. static void ProcessDLL()
  367. {
  368. DWORD dwService;
  369. DBPRINTF(TEXT("ProcessDLL()\r\n"));
  370. dwService = SC_CHANGE_COMM;
  371. switch (SKeyDLL.Message) // Validate Message
  372. {
  373. case SPI_GETSERIALKEYS:
  374. if (skCurKey.dwFlags & SERKF_ACTIVE) // Are We Disabled?
  375. GetCurrentValues(); // No - Send the actual Values
  376. else
  377. GetNewValues(); // Yes - Send the Proposed values
  378. DBG_DUMP("---Info Sent");
  379. return;
  380. case SPI_SETSERIALKEYS:
  381. DBG_DUMP("---Info Received");
  382. if ((SKeyDLL.dwFlags & SERKF_SERIALKEYSON) && // Are We Truning on &
  383. (SKeyDLL.dwFlags & SERKF_AVAILABLE)) // Is SerialKeys Available
  384. {
  385. if (!(skCurKey.dwFlags & SERKF_ACTIVE)) // Are We Disabled?
  386. {
  387. dwService = SC_ENABLE_SKEY; // Yes - Turn SKeys On
  388. DBPRINTF(TEXT("Turn Serial Key On\r\n"));
  389. }
  390. }
  391. if (!(SKeyDLL.dwFlags & SERKF_SERIALKEYSON) && // Are We Truning off &
  392. (SKeyDLL.dwFlags & SERKF_AVAILABLE)) // Is SerialKeys Available
  393. {
  394. if (skCurKey.dwFlags & SERKF_ACTIVE) // Are We Active?
  395. {
  396. dwService = SC_DISABLE_SKEY; // Yes - Turn SKeys Off
  397. DBPRINTF(TEXT("Turn Serial Key Off\r\n"));
  398. }
  399. }
  400. skNewKey.iBaudRate = SKeyDLL.iBaudRate;
  401. skNewKey.dwFlags = SKeyDLL.dwFlags;
  402. // Ensure that the strings we've just read off the named pipe
  403. // are NUL-terminated before we use them.
  404. // (All port strings are MAX_PATH long - see sk_dllif.h, sk_defs.h)
  405. SKeyDLL.szActivePort[ MAX_PATH - 1 ] = '\0';
  406. SKeyDLL.szPort[ MAX_PATH - 1 ] = '\0';
  407. #ifdef UNICODE
  408. MultiByteToWideChar(
  409. CP_ACP, 0, SKeyDLL.szActivePort, -1,
  410. skNewKey.lpszActivePort, MAX_PATH);
  411. MultiByteToWideChar(
  412. CP_ACP, 0, SKeyDLL.szPort, -1,
  413. skNewKey.lpszPort, MAX_PATH);
  414. // Just in case either of the above fail (due to insufficient
  415. // buffer or other reason), forcibly NUL-terminate.
  416. skNewKey.lpszActivePort[ MAX_PATH - 1 ] = '\0';
  417. skNewKey.lpszPort[ MAX_PATH - 1 ] = '\0';
  418. #else
  419. lstrcpy(skNewKey.lpszActivePort,SKeyDLL.szActivePort);
  420. lstrcpy(skNewKey.lpszPort,SKeyDLL.szPort);
  421. #endif
  422. if (*skNewKey.lpszPort == 0)
  423. {
  424. lstrcpy(skNewKey.lpszPort, skNewKey.lpszActivePort);
  425. }
  426. // the calling dll is now responsible for saving the
  427. // settings because it's running in the user context
  428. // and can access HKEY_CURRENT_USER. Here we're
  429. // running as a service (as the system) and have
  430. // no HKEY_CURRENT_USER
  431. DoServiceCommand(dwService);
  432. Sleep(1000); // Sleep 1 Sec to set values
  433. if (SKeyDLL.dwFlags & SERKF_SERIALKEYSON) // Are We Truning on
  434. GetCurrentValues(); // Yes - Send the actual Values
  435. else
  436. GetNewValues(); // No - Send the Proposed values
  437. DBG_DUMP("---Info Sent");
  438. break;
  439. default:
  440. return;
  441. }
  442. }
  443. /*---------------------------------------------------------------
  444. *
  445. * FUNCTION void GetCurrentValues()
  446. *
  447. * TYPE Local
  448. *
  449. * PURPOSE
  450. *
  451. *
  452. * INPUTS None
  453. *
  454. * RETURNS None
  455. *
  456. *---------------------------------------------------------------*/
  457. static void GetCurrentValues()
  458. {
  459. DBPRINTF(TEXT("GetCurrentValues()\r\n"));
  460. #ifdef UNICODE
  461. WideCharToMultiByte(
  462. CP_ACP, 0, skCurKey.lpszActivePort, -1,
  463. SKeyDLL.szActivePort, sizeof(SKeyDLL.szActivePort), NULL, NULL);
  464. WideCharToMultiByte(
  465. CP_ACP, 0, skCurKey.lpszPort, -1,
  466. SKeyDLL.szPort, sizeof(SKeyDLL.szPort), NULL, NULL);
  467. #else
  468. lstrcpy(SKeyDLL.szActivePort,skCurKey.lpszActivePort);
  469. lstrcpy(SKeyDLL.szPort,skCurKey.lpszPort);
  470. #endif
  471. SKeyDLL.dwFlags = skCurKey.dwFlags;
  472. SKeyDLL.iBaudRate = skCurKey.iBaudRate;
  473. SKeyDLL.iPortState = skCurKey.iPortState;
  474. }
  475. /*---------------------------------------------------------------
  476. *
  477. * FUNCTION void GetNewValues()
  478. *
  479. * TYPE Local
  480. *
  481. * PURPOSE
  482. *
  483. *
  484. * INPUTS None
  485. *
  486. * RETURNS None
  487. *
  488. *---------------------------------------------------------------*/
  489. static void GetNewValues()
  490. {
  491. DBPRINTF(TEXT("GetNewValues()\r\n"));
  492. // FEATURE a-jimhar 04-03-96 this next line is suspect. May need to
  493. // change 'skCurKey.dwFlags' to 'skNewKey.dwFlags. This is either
  494. // a mistake or was done to always return the current flags.
  495. SKeyDLL.dwFlags = skCurKey.dwFlags;
  496. SKeyDLL.iBaudRate = skNewKey.iBaudRate;
  497. SKeyDLL.iPortState = skNewKey.iPortState;
  498. #ifdef UNICODE
  499. WideCharToMultiByte(
  500. CP_ACP, 0, skNewKey.lpszActivePort, -1,
  501. SKeyDLL.szActivePort, sizeof(SKeyDLL.szActivePort), NULL, NULL);
  502. WideCharToMultiByte(
  503. CP_ACP, 0, skNewKey.lpszPort, -1,
  504. SKeyDLL.szPort, sizeof(SKeyDLL.szPort), NULL, NULL);
  505. #else
  506. lstrcpy(SKeyDLL.szActivePort,skNewKey.lpszActivePort);
  507. lstrcpy(SKeyDLL.szPort,skNewKey.lpszPort);
  508. #endif
  509. }