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.

331 lines
8.1 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 2000-2000
  5. //
  6. // File: expperm.cpp
  7. //
  8. // Contents:
  9. //
  10. // History:
  11. //
  12. // Note:
  13. //---------------------------------------------------------------------------
  14. #include "pch.cpp"
  15. #include <tchar.h>
  16. #include <process.h>
  17. #include "lscommon.h"
  18. #include "debug.h"
  19. #include "globals.h"
  20. #include "db.h"
  21. #include "keypack.h"
  22. #include "clilic.h"
  23. #include "server.h"
  24. #define EXPIRE_THREAD_INITIAL_SLEEP (1000*60) /* 1 minute */
  25. //---------------------------------------------------------------------
  26. unsigned int WINAPI
  27. ExpirePermanentThread(void* ptr)
  28. {
  29. HANDLE hEvent=(HANDLE) ptr;
  30. DWORD dwStatus=ERROR_SUCCESS;
  31. LICENSEDCLIENT search_license;
  32. memset(&search_license,0,sizeof(search_license));
  33. //
  34. // Signal initializer thread we are ready
  35. //
  36. SetEvent(hEvent);
  37. DBGPrintf(
  38. DBG_INFORMATION,
  39. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  40. DBG_ALL_LEVEL,
  41. _TEXT("ExpirePermanent : ready...\n")
  42. );
  43. //
  44. // Give service chance to initialize
  45. //
  46. Sleep(EXPIRE_THREAD_INITIAL_SLEEP);
  47. //
  48. // Forever loop
  49. //
  50. while(1)
  51. {
  52. PTLSDbWorkSpace pDbWkSpace = NULL;
  53. LICENSEDCLIENT found_license;
  54. TLSLICENSEPACK search_keypack;
  55. TLSLICENSEPACK found_keypack;
  56. search_license.ftExpireDate = time(NULL);
  57. memset(&found_license,0,sizeof(found_license));
  58. memset(&search_keypack,0,sizeof(search_keypack));
  59. memset(&found_keypack,0,sizeof(found_keypack));
  60. if (!(ALLOCATEDBHANDLE(pDbWkSpace, g_EnumDbTimeout)))
  61. {
  62. goto do_sleep;
  63. }
  64. TLSDBLockKeyPackTable();
  65. TLSDBLockLicenseTable();
  66. CLEANUPSTMT;
  67. dwStatus = TLSDBLicenseEnumBeginEx(
  68. USEHANDLE(pDbWkSpace),
  69. TRUE,
  70. LSLICENSE_SEARCH_EXPIREDATE,
  71. &search_license,
  72. JET_bitSeekLE
  73. );
  74. if (ERROR_SUCCESS != dwStatus)
  75. {
  76. TLSDBUnlockLicenseTable();
  77. TLSDBUnlockKeyPackTable();
  78. FREEDBHANDLE(pDbWkSpace);
  79. goto do_sleep;
  80. }
  81. while (1)
  82. {
  83. dwStatus = TLSDBLicenseEnumNextEx(
  84. USEHANDLE(pDbWkSpace),
  85. TRUE, // bReverse
  86. TRUE, // bAnyRecord
  87. &found_license
  88. );
  89. if(dwStatus != ERROR_SUCCESS)
  90. {
  91. goto next_time;
  92. }
  93. //
  94. // See if this is the right product type
  95. //
  96. search_keypack.dwKeyPackId = found_license.dwKeyPackId;
  97. dwStatus = TLSDBKeyPackFind(
  98. USEHANDLE(pDbWkSpace),
  99. TRUE,
  100. LSKEYPACK_EXSEARCH_DWINTERNAL,
  101. &search_keypack,
  102. &found_keypack
  103. );
  104. if(dwStatus != ERROR_SUCCESS)
  105. {
  106. continue;
  107. }
  108. //
  109. // only check licenses that we reissue
  110. //
  111. if(found_keypack.ucAgreementType != LSKEYPACKTYPE_RETAIL &&
  112. found_keypack.ucAgreementType != LSKEYPACKTYPE_SELECT &&
  113. found_keypack.ucAgreementType != LSKEYPACKTYPE_FREE &&
  114. found_keypack.ucAgreementType != LSKEYPACKTYPE_OPEN )
  115. {
  116. continue;
  117. }
  118. UCHAR ucKeyPackStatus = found_keypack.ucKeyPackStatus &
  119. ~LSKEYPACKSTATUS_RESERVED;
  120. //
  121. // Don't check pending activation key pack
  122. //
  123. if(ucKeyPackStatus != LSKEYPACKSTATUS_ACTIVE)
  124. {
  125. continue;
  126. }
  127. //
  128. // Only check per-seat and concurrent
  129. //
  130. if ((_tcsnicmp(found_keypack.szProductId,
  131. TERMSERV_PRODUCTID_SKU,
  132. _tcslen(TERMSERV_PRODUCTID_SKU)) != 0)
  133. && (_tcsnicmp(found_keypack.szProductId,
  134. TERMSERV_PRODUCTID_CONCURRENT_SKU,
  135. _tcslen(TERMSERV_PRODUCTID_CONCURRENT_SKU)) != 0))
  136. {
  137. continue;
  138. }
  139. BEGIN_TRANSACTION(pDbWorkSpace);
  140. //
  141. // Return currently enumerated license.
  142. //
  143. dwStatus = TLSDBDeleteEnumeratedLicense(USEHANDLE(pDbWkSpace));
  144. if (dwStatus == ERROR_SUCCESS)
  145. {
  146. //
  147. // Adjust available license number.
  148. //
  149. dwStatus = TLSDBReturnLicenseToKeyPack(
  150. USEHANDLE(pDbWkSpace),
  151. found_license.dwKeyPackId,
  152. 1
  153. );
  154. }
  155. if (dwStatus == ERROR_SUCCESS)
  156. {
  157. COMMIT_TRANSACTION(pDbWkSpace);
  158. InterlockedIncrement(&g_lPermanentLicensesReturned);
  159. }
  160. else
  161. {
  162. ROLLBACK_TRANSACTION(pDbWkSpace);
  163. }
  164. }
  165. next_time:
  166. TLSDBLicenseEnumEnd(USEHANDLE(pDbWkSpace));
  167. TLSDBUnlockLicenseTable();
  168. TLSDBUnlockKeyPackTable();
  169. FREEDBHANDLE(pDbWkSpace);
  170. do_sleep:
  171. if (WAIT_OBJECT_0 == WaitForSingleObject(GetServiceShutdownHandle(),g_dwReissueExpireThreadSleep))
  172. {
  173. break;
  174. }
  175. DBGPrintf(
  176. DBG_INFORMATION,
  177. DBG_FACILITY_RPC,
  178. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  179. _TEXT("ExpirePermanent : woke up\n")
  180. );
  181. }
  182. //
  183. // Initializer function will close the event handle
  184. //
  185. return dwStatus;
  186. }
  187. //---------------------------------------------------------------------
  188. DWORD
  189. InitExpirePermanentThread()
  190. /*++
  191. ++*/
  192. {
  193. HANDLE hThread = NULL;
  194. unsigned int dwThreadId;
  195. HANDLE hEvent = NULL;
  196. DWORD dwStatus = ERROR_SUCCESS;
  197. HANDLE waithandles[2];
  198. //
  199. // Create a event for namedpipe thread to signal it is ready.
  200. //
  201. hEvent = CreateEvent(
  202. NULL,
  203. FALSE,
  204. FALSE, // non-signal
  205. NULL
  206. );
  207. if(hEvent == NULL)
  208. {
  209. dwStatus = GetLastError();
  210. goto cleanup;
  211. }
  212. hThread = (HANDLE)_beginthreadex(
  213. NULL,
  214. 0,
  215. ExpirePermanentThread,
  216. hEvent,
  217. 0,
  218. &dwThreadId
  219. );
  220. if(hThread == NULL)
  221. {
  222. dwStatus = GetLastError();
  223. goto cleanup;
  224. }
  225. waithandles[0] = hEvent;
  226. waithandles[1] = hThread;
  227. //
  228. // Wait 30 second for thread to complete initialization
  229. //
  230. dwStatus = WaitForMultipleObjects(
  231. sizeof(waithandles)/sizeof(waithandles[0]),
  232. waithandles,
  233. FALSE,
  234. 30*1000
  235. );
  236. if(dwStatus == WAIT_OBJECT_0)
  237. {
  238. //
  239. // thread is ready
  240. //
  241. dwStatus = ERROR_SUCCESS;
  242. }
  243. else
  244. {
  245. if(dwStatus == (WAIT_OBJECT_0 + 1))
  246. {
  247. //
  248. // Thread terminate abnormally
  249. //
  250. GetExitCodeThread(
  251. hThread,
  252. &dwStatus
  253. );
  254. }
  255. else
  256. {
  257. dwStatus = TLS_E_SERVICE_STARTUP_CREATE_THREAD;
  258. }
  259. }
  260. cleanup:
  261. if(hEvent != NULL)
  262. {
  263. CloseHandle(hEvent);
  264. }
  265. if(hThread != NULL)
  266. {
  267. CloseHandle(hThread);
  268. }
  269. return dwStatus;
  270. }