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.

4554 lines
117 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. pack.c
  5. Abstract:
  6. Author:
  7. Arthur Hanson (arth) 06-Jan-1995
  8. Revision History:
  9. Jeff Parham (jeffparh) 05-Dec-1995
  10. o Added new fields to purchase record to support secure certificates.
  11. o Unified per server purchase model with per seat purchase model for
  12. secure certificates; per server model still done in the traditional
  13. manner for non-secure certificates (for backwards compatibility).
  14. o Removed assertion on LicenseAdd() failure. LicenseAdd() may
  15. legitimately fail under certain circumstances.
  16. o Fixed bug wherein a memory allocation failure in the LLS routines
  17. would result in a corrupt data file (which would AV the server when
  18. it was thereafter read). (Bug #14072.)
  19. o Added SaveAll() function analogous to LoadAll().
  20. o Added support for extended user data packing/unpacking. This was
  21. done to save the SUITE_USE flag across restarts of the service.
  22. o Removed user table parameters from unpack routines that didn't use
  23. them.
  24. o Fixed ServerServiceListUnpack() to subtract out old values only when
  25. they were previously added to the MasterServiceTable. This fixes
  26. problems with the MaxSessionCount and HighMark tallies getting skewed.
  27. --*/
  28. #include <stdlib.h>
  29. #include <nt.h>
  30. #include <ntrtl.h>
  31. #include <nturtl.h>
  32. #include <windows.h>
  33. #include <tstr.h>
  34. #include <dsgetdc.h>
  35. #include "llsapi.h"
  36. #include "debug.h"
  37. #include "llsutil.h"
  38. #include "llssrv.h"
  39. #include "mapping.h"
  40. #include "msvctbl.h"
  41. #include "svctbl.h"
  42. #include "perseat.h"
  43. #include "purchase.h"
  44. #include "server.h"
  45. #include "service.h"
  46. #include "llsrpc_s.h"
  47. #include "lsapi_s.h"
  48. #include "llsdbg_s.h"
  49. #include "repl.h"
  50. #include "pack.h"
  51. #include "llsevent.h"
  52. #include "certdb.h"
  53. #include "llsrtl.h"
  54. #include <strsafe.h> //include last
  55. int __cdecl MServiceRecordCompare(const void *arg1, const void *arg2);
  56. BOOL ValidateDN(LPTSTR pszDN);
  57. static HANDLE PurchaseFile = NULL;
  58. RTL_CRITICAL_SECTION MappingFileLock;
  59. RTL_CRITICAL_SECTION UserFileLock;
  60. /////////////////////////////////////////////////////////////////////////
  61. // License List
  62. //
  63. /////////////////////////////////////////////////////////////////////////
  64. VOID
  65. LicenseListUnpackOld (
  66. ULONG LicenseServiceTableSize,
  67. PPACK_LICENSE_SERVICE_RECORD LicenseServices,
  68. ULONG LicenseTableSize,
  69. PPACK_LICENSE_PURCHASE_RECORD_0 Licenses
  70. )
  71. /*++
  72. Routine Description:
  73. Arguments:
  74. Return Value:
  75. --*/
  76. {
  77. NTSTATUS Status = STATUS_SUCCESS;
  78. ULONG i;
  79. PPACK_LICENSE_PURCHASE_RECORD_0 pLicense;
  80. #if DBG
  81. if (TraceFlags & TRACE_FUNCTION_TRACE)
  82. dprintf(TEXT("LicenseListUnpackOld: Service[%lu] License[%lu]\n"), LicenseServiceTableSize, LicenseTableSize);
  83. #endif
  84. //
  85. // Walk services table, adding any new services to our local table.
  86. // Fix up the index pointers to match our local services.
  87. //
  88. RtlAcquireResourceExclusive(&LicenseListLock, TRUE);
  89. for (i = 0; i < LicenseTableSize; i++) {
  90. pLicense = &Licenses[i];
  91. if (pLicense->Service < LicenseServiceTableSize)
  92. Status = LicenseAdd(LicenseServices[pLicense->Service].ServiceName, TEXT("Microsoft"), pLicense->NumberLicenses, 0, pLicense->Admin, pLicense->Comment, pLicense->Date, LLS_LICENSE_MODE_ALLOW_PER_SEAT, 0, TEXT("None"), 0, NULL );
  93. else {
  94. ASSERT(FALSE);
  95. }
  96. if (Status != STATUS_SUCCESS) {
  97. #ifdef DBG
  98. dprintf(TEXT("LicenseAdd failed: 0x%lX\n"), Status);
  99. #endif
  100. // ASSERT(FALSE);
  101. }
  102. }
  103. RtlReleaseResource(&LicenseListLock);
  104. } // LicenseListUnpackOld
  105. /////////////////////////////////////////////////////////////////////////
  106. VOID
  107. LicenseListStringsUnpackOld (
  108. ULONG LicenseServiceTableSize,
  109. PPACK_LICENSE_SERVICE_RECORD LicenseServices,
  110. ULONG LicenseServiceStringSize,
  111. LPTSTR LicenseServiceStrings,
  112. ULONG LicenseTableSize,
  113. PPACK_LICENSE_PURCHASE_RECORD_0 Licenses,
  114. ULONG LicenseStringSize,
  115. LPTSTR LicenseStrings
  116. )
  117. /*++
  118. Routine Description:
  119. Arguments:
  120. Return Value:
  121. --*/
  122. {
  123. ULONG i;
  124. PPACK_LICENSE_SERVICE_RECORD pSvc;
  125. PPACK_LICENSE_PURCHASE_RECORD_0 pLicense;
  126. TCHAR *pStr;
  127. UNREFERENCED_PARAMETER(LicenseServiceStringSize);
  128. UNREFERENCED_PARAMETER(LicenseStringSize);
  129. #if DBG
  130. if (TraceFlags & TRACE_FUNCTION_TRACE)
  131. dprintf(TEXT("LicenseListStringsUnpack\n"));
  132. #endif
  133. //
  134. // First do license service strings
  135. //
  136. pStr = LicenseServiceStrings;
  137. for (i = 0; i < LicenseServiceTableSize; i++) {
  138. pSvc = &LicenseServices[i];
  139. pSvc->ServiceName = pStr;
  140. //
  141. // Move to end of current string
  142. //
  143. while (*pStr != TEXT('\0'))
  144. pStr++;
  145. // now go past ending NULL
  146. pStr++;
  147. }
  148. //
  149. // Now do license purchase strings
  150. //
  151. pStr = LicenseStrings;
  152. for (i = 0; i < LicenseTableSize; i++) {
  153. pLicense = &Licenses[i];
  154. pLicense->Admin = pStr;
  155. //
  156. // Move to end of current string
  157. //
  158. while (*pStr != TEXT('\0'))
  159. pStr++;
  160. // now go past ending NULL
  161. pStr++;
  162. pLicense->Comment = pStr;
  163. //
  164. // Move to end of current string
  165. //
  166. while (*pStr != TEXT('\0'))
  167. pStr++;
  168. // now go past ending NULL
  169. pStr++;
  170. }
  171. } // LicenseListStringsUnpackOld
  172. /////////////////////////////////////////////////////////////////////////
  173. VOID
  174. LicenseListLoadOld()
  175. /*++
  176. Routine Description:
  177. Arguments:
  178. None.
  179. Return Value:
  180. None.
  181. --*/
  182. {
  183. BOOL ret;
  184. DWORD Version, DataSize;
  185. NTSTATUS Status = STATUS_SUCCESS;
  186. HANDLE hFile = NULL;
  187. ULONG LicenseServiceTableSize;
  188. PPACK_LICENSE_SERVICE_RECORD LicenseServices = NULL;
  189. ULONG LicenseServiceStringSize;
  190. LPTSTR LicenseServiceStrings = NULL;
  191. ULONG LicenseTableSize;
  192. PPACK_LICENSE_PURCHASE_RECORD_0 Licenses = NULL;
  193. ULONG LicenseStringSize;
  194. LPTSTR LicenseStrings = NULL;
  195. LICENSE_FILE_HEADER_0 FileHeader;
  196. DWORD BytesRead;
  197. #if DBG
  198. if (TraceFlags & (TRACE_FUNCTION_TRACE | TRACE_DATABASE))
  199. dprintf(TEXT("LLS TRACE: LicenseListLoad\n"));
  200. #endif
  201. //
  202. // Check if we already have file open
  203. //
  204. if (PurchaseFile != NULL) {
  205. CloseHandle(PurchaseFile);
  206. PurchaseFile = NULL;
  207. }
  208. //
  209. // If nothing to load then get-out
  210. //
  211. if (!FileExists(LicenseFileName))
  212. goto LicenseListLoadExit;
  213. //
  214. // Check the init header
  215. //
  216. Version = DataSize = 0;
  217. PurchaseFile = LlsFileCheck(LicenseFileName, &Version, &DataSize );
  218. if (PurchaseFile == NULL) {
  219. Status = GetLastError();
  220. goto LicenseListLoadExit;
  221. }
  222. if ((Version != LICENSE_FILE_VERSION_0) || (DataSize != sizeof(LICENSE_FILE_HEADER_0))) {
  223. Status = STATUS_FILE_INVALID;
  224. goto LicenseListLoadExit;
  225. }
  226. //
  227. // The init header checks out, so load the license header and data blocks
  228. //
  229. hFile = PurchaseFile;
  230. ret = ReadFile(hFile, &FileHeader, sizeof(LICENSE_FILE_HEADER_0), &BytesRead, NULL);
  231. LicenseServiceTableSize = 0;
  232. LicenseServiceStringSize = 0;
  233. LicenseTableSize = 0;
  234. LicenseStringSize = 0;
  235. if (ret) {
  236. //
  237. // Run through and allocate space to read data blocks into
  238. //
  239. if (FileHeader.LicenseServiceTableSize != 0) {
  240. LicenseServiceTableSize = FileHeader.LicenseServiceTableSize / sizeof(PACK_LICENSE_SERVICE_RECORD);
  241. LicenseServices = MIDL_user_allocate(FileHeader.LicenseServiceTableSize);
  242. if ( LicenseServices == NULL ) {
  243. Status = STATUS_NO_MEMORY;
  244. goto LicenseListLoadExit;
  245. }
  246. }
  247. if (FileHeader.LicenseServiceStringSize != 0) {
  248. LicenseServiceStringSize = FileHeader.LicenseServiceStringSize / sizeof(TCHAR);
  249. LicenseServiceStrings = MIDL_user_allocate(FileHeader.LicenseServiceStringSize);
  250. if ( LicenseServiceStrings == NULL ) {
  251. Status = STATUS_NO_MEMORY;
  252. goto LicenseListLoadExit;
  253. }
  254. }
  255. if (FileHeader.LicenseTableSize != 0) {
  256. LicenseTableSize = FileHeader.LicenseTableSize / sizeof(PACK_LICENSE_PURCHASE_RECORD);
  257. Licenses = MIDL_user_allocate(FileHeader.LicenseTableSize);
  258. if ( Licenses == NULL ) {
  259. Status = STATUS_NO_MEMORY;
  260. goto LicenseListLoadExit;
  261. }
  262. }
  263. if (FileHeader.LicenseStringSize != 0) {
  264. LicenseStringSize = FileHeader.LicenseStringSize / sizeof(TCHAR);
  265. LicenseStrings = MIDL_user_allocate(FileHeader.LicenseStringSize);
  266. if ( LicenseStrings == NULL ) {
  267. Status = STATUS_NO_MEMORY;
  268. goto LicenseListLoadExit;
  269. }
  270. }
  271. }
  272. if (ret && (FileHeader.LicenseServiceTableSize != 0) )
  273. ret = ReadFile(hFile, LicenseServices, FileHeader.LicenseServiceTableSize, &BytesRead, NULL);
  274. if (ret && (FileHeader.LicenseServiceStringSize != 0) )
  275. ret = ReadFile(hFile, LicenseServiceStrings, FileHeader.LicenseServiceStringSize, &BytesRead, NULL);
  276. if (ret && (FileHeader.LicenseTableSize != 0) )
  277. ret = ReadFile(hFile, Licenses, FileHeader.LicenseTableSize, &BytesRead, NULL);
  278. if (ret && (FileHeader.LicenseStringSize != 0) )
  279. ret = ReadFile(hFile, LicenseStrings, FileHeader.LicenseStringSize, &BytesRead, NULL);
  280. if (!ret) {
  281. Status = GetLastError();
  282. goto LicenseListLoadExit;
  283. }
  284. //
  285. // Decrypt the data
  286. //
  287. Status = DeBlock(LicenseServices, FileHeader.LicenseServiceTableSize);
  288. if (Status == STATUS_SUCCESS)
  289. Status = DeBlock(LicenseServiceStrings, FileHeader.LicenseServiceStringSize);
  290. if (Status == STATUS_SUCCESS)
  291. Status = DeBlock(Licenses, FileHeader.LicenseTableSize);
  292. if (Status == STATUS_SUCCESS)
  293. Status = DeBlock(LicenseStrings, FileHeader.LicenseStringSize);
  294. if (Status != STATUS_SUCCESS)
  295. goto LicenseListLoadExit;
  296. //
  297. // Unpack the string data
  298. //
  299. LicenseListStringsUnpackOld( LicenseServiceTableSize, LicenseServices,
  300. LicenseServiceStringSize, LicenseServiceStrings,
  301. LicenseTableSize, Licenses,
  302. LicenseStringSize, LicenseStrings );
  303. //
  304. // Unpack the license data
  305. //
  306. LicenseListUnpackOld( LicenseServiceTableSize, LicenseServices, LicenseTableSize, Licenses );
  307. LicenseListLoadExit:
  308. // Note: Don't close the License Purchase File (keep it locked).
  309. //
  310. // Run through our tables and clean them up
  311. //
  312. if (LicenseServices != NULL)
  313. MIDL_user_free(LicenseServices);
  314. if (LicenseServiceStrings != NULL)
  315. MIDL_user_free(LicenseServiceStrings);
  316. if (Licenses != NULL)
  317. MIDL_user_free(Licenses);
  318. if (LicenseStrings != NULL)
  319. MIDL_user_free(LicenseStrings);
  320. //
  321. // If there was an error log it.
  322. //
  323. if (Status != STATUS_SUCCESS)
  324. LogEvent(LLS_EVENT_LOAD_LICENSE, 0, NULL, Status);
  325. } // LicenseListLoadOld
  326. /////////////////////////////////////////////////////////////////////////
  327. NTSTATUS
  328. LicenseListPack (
  329. ULONG *pLicenseServiceTableSize,
  330. PPACK_LICENSE_SERVICE_RECORD *pLicenseServices,
  331. ULONG *pLicenseTableSize,
  332. PPACK_LICENSE_PURCHASE_RECORD *pLicenses,
  333. ULONG *pPerServerLicenseServiceTableSize,
  334. PPACK_LICENSE_SERVICE_RECORD *pPerServerLicenseServices
  335. )
  336. /*++
  337. Routine Description:
  338. Arguments:
  339. Return Value:
  340. --*/
  341. {
  342. NTSTATUS Status = STATUS_SUCCESS;
  343. PPACK_LICENSE_SERVICE_RECORD LicenseServices = NULL;
  344. PPACK_LICENSE_PURCHASE_RECORD Licenses = NULL;
  345. ULONG i;
  346. ULONG TotalRecords = 0;
  347. PLICENSE_SERVICE_RECORD pLicenseService;
  348. PLICENSE_PURCHASE_RECORD pLicense;
  349. PPACK_LICENSE_SERVICE_RECORD PerServerLicenseServices = NULL;
  350. PLICENSE_SERVICE_RECORD pPerServerLicenseService;
  351. #if DBG
  352. if (TraceFlags & TRACE_FUNCTION_TRACE)
  353. dprintf(TEXT("LLS TRACE: LicenseListPack\n"));
  354. #endif
  355. ASSERT(pLicenseServices != NULL);
  356. ASSERT(pLicenseServiceTableSize != NULL);
  357. *pLicenseServices = NULL;
  358. *pLicenseServiceTableSize = 0;
  359. ASSERT(pLicenses != NULL);
  360. ASSERT(pLicenseTableSize != NULL);
  361. *pLicenses = NULL;
  362. *pLicenseTableSize = 0;
  363. ASSERT(pPerServerLicenseServices != NULL);
  364. ASSERT(pPerServerLicenseServiceTableSize != NULL);
  365. *pPerServerLicenseServices = NULL;
  366. *pPerServerLicenseServiceTableSize = 0;
  367. //////////////////////////////////////////////////////////////////
  368. //
  369. // Do License Service Table First
  370. //
  371. TotalRecords = LicenseServiceListSize;
  372. //
  373. // Make sure there is anything to replicate
  374. //
  375. if (TotalRecords > 0) {
  376. //
  377. // Create our buffer to hold all of the garbage
  378. //
  379. LicenseServices = MIDL_user_allocate(TotalRecords * sizeof(PACK_LICENSE_SERVICE_RECORD));
  380. if (LicenseServices == NULL) {
  381. ASSERT(FALSE);
  382. return STATUS_NO_MEMORY;
  383. }
  384. //
  385. // Fill in the buffer - walk the License Services tree
  386. //
  387. for (i = 0; i < LicenseServiceListSize; i++) {
  388. pLicenseService = LicenseServiceList[i];
  389. //
  390. // Make index match table in it's current state
  391. //
  392. pLicenseService->Index = i;
  393. LicenseServices[i].ServiceName = pLicenseService->ServiceName;
  394. LicenseServices[i].NumberLicenses = pLicenseService->NumberLicenses;
  395. }
  396. }
  397. *pLicenseServices = LicenseServices;
  398. *pLicenseServiceTableSize = TotalRecords;
  399. //////////////////////////////////////////////////////////////////
  400. //
  401. // Now Do Per Server License Service Table
  402. //
  403. TotalRecords = PerServerLicenseServiceListSize;
  404. //
  405. // Make sure there is anything to replicate
  406. //
  407. if (TotalRecords > 0)
  408. {
  409. //
  410. // Create our buffer to hold all of the garbage
  411. //
  412. PerServerLicenseServices = MIDL_user_allocate(TotalRecords * sizeof(PACK_LICENSE_SERVICE_RECORD));
  413. if (PerServerLicenseServices == NULL)
  414. {
  415. ASSERT(FALSE);
  416. //
  417. // Clean up already alloc'd information
  418. //
  419. if (LicenseServices != NULL)
  420. MIDL_user_free(LicenseServices);
  421. *pLicenseServices = NULL;
  422. *pLicenseServiceTableSize = 0;
  423. return STATUS_NO_MEMORY;
  424. }
  425. //
  426. // Fill in the buffer - walk the Per Server License Services tree
  427. //
  428. for (i = 0; i < PerServerLicenseServiceListSize; i++)
  429. {
  430. pPerServerLicenseService = PerServerLicenseServiceList[i];
  431. //
  432. // Make index match table in it's current state
  433. //
  434. pPerServerLicenseService->Index = i;
  435. PerServerLicenseServices[i].ServiceName = pPerServerLicenseService->ServiceName;
  436. PerServerLicenseServices[i].NumberLicenses = pPerServerLicenseService->NumberLicenses;
  437. }
  438. }
  439. *pPerServerLicenseServices = PerServerLicenseServices;
  440. *pPerServerLicenseServiceTableSize = TotalRecords;
  441. //////////////////////////////////////////////////////////////////
  442. //
  443. // Now Do License Purchase Records
  444. //
  445. TotalRecords = PurchaseListSize;
  446. //
  447. // Make sure there is anything to replicate
  448. //
  449. if (TotalRecords > 0) {
  450. //
  451. // Create our buffer to hold all of the garbage
  452. //
  453. Licenses = MIDL_user_allocate(TotalRecords * sizeof(PACK_LICENSE_PURCHASE_RECORD));
  454. if (Licenses == NULL) {
  455. ASSERT(FALSE);
  456. //
  457. // Clean up already alloc'd information
  458. //
  459. if (LicenseServices != NULL)
  460. MIDL_user_free(LicenseServices);
  461. if (PerServerLicenseServices != NULL)
  462. MIDL_user_free(PerServerLicenseServices);
  463. *pLicenseServices = NULL;
  464. *pLicenseServiceTableSize = 0;
  465. *pPerServerLicenseServices = NULL;
  466. *pPerServerLicenseServiceTableSize = 0;
  467. return STATUS_NO_MEMORY;
  468. }
  469. //
  470. // Fill in the buffer - walk the License Purchase tree
  471. //
  472. for (i = 0; i < PurchaseListSize; i++) {
  473. pLicense = &PurchaseList[i];
  474. //
  475. // License Service table index is fixed-up to what we need
  476. //
  477. Licenses[i].Service = ( pLicense->AllowedModes & 1 ) ? pLicense->Service->Index
  478. : 0xFFFFFFFF;
  479. Licenses[i].NumberLicenses = pLicense->NumberLicenses;
  480. Licenses[i].Date = pLicense->Date;
  481. Licenses[i].Admin = pLicense->Admin;
  482. Licenses[i].Comment = pLicense->Comment;
  483. Licenses[i].PerServerService = ( pLicense->AllowedModes & 2 ) ? pLicense->PerServerService->Index
  484. : 0xFFFFFFFF;
  485. Licenses[i].AllowedModes = pLicense->AllowedModes;
  486. Licenses[i].CertificateID = pLicense->CertificateID;
  487. Licenses[i].Source = pLicense->Source;
  488. Licenses[i].ExpirationDate = pLicense->ExpirationDate;
  489. Licenses[i].MaxQuantity = pLicense->MaxQuantity;
  490. Licenses[i].Vendor = pLicense->Vendor;
  491. memcpy( Licenses[i].Secrets, pLicense->Secrets, LLS_NUM_SECRETS * sizeof( *pLicense->Secrets ) );
  492. }
  493. }
  494. *pLicenses = Licenses;
  495. *pLicenseTableSize = TotalRecords;
  496. return Status;
  497. } // LicenseListPack
  498. /////////////////////////////////////////////////////////////////////////
  499. VOID
  500. LicenseListUnpack (
  501. ULONG LicenseServiceTableSize,
  502. PPACK_LICENSE_SERVICE_RECORD LicenseServices,
  503. ULONG LicenseTableSize,
  504. PPACK_LICENSE_PURCHASE_RECORD Licenses,
  505. ULONG PerServerLicenseServiceTableSize,
  506. PPACK_LICENSE_SERVICE_RECORD PerServerLicenseServices
  507. )
  508. /*++
  509. Routine Description:
  510. Arguments:
  511. Return Value:
  512. --*/
  513. {
  514. NTSTATUS Status = STATUS_SUCCESS;
  515. ULONG i;
  516. PPACK_LICENSE_PURCHASE_RECORD pLicense;
  517. LPTSTR ServiceName;
  518. #if DBG
  519. if (TraceFlags & TRACE_FUNCTION_TRACE)
  520. dprintf(TEXT("LicenseListUnpack: Service[%lu] PerServerService[%lu] License[%lu]\n"), LicenseServiceTableSize, PerServerLicenseServiceTableSize, LicenseTableSize);
  521. #endif
  522. //
  523. // Walk services table, adding any new services to our local table.
  524. // Fix up the index pointers to match our local services.
  525. //
  526. RtlAcquireResourceExclusive(&LicenseListLock, TRUE);
  527. for (i = 0; i < LicenseTableSize; i++)
  528. {
  529. pLicense = &Licenses[i];
  530. ServiceName = NULL;
  531. if ( pLicense->AllowedModes & LLS_LICENSE_MODE_ALLOW_PER_SERVER )
  532. {
  533. if ( pLicense->PerServerService < PerServerLicenseServiceTableSize )
  534. {
  535. ServiceName = PerServerLicenseServices[ pLicense->PerServerService ].ServiceName;
  536. }
  537. else
  538. {
  539. ASSERT( FALSE );
  540. }
  541. }
  542. if ( ( NULL == ServiceName ) && ( pLicense->AllowedModes & LLS_LICENSE_MODE_ALLOW_PER_SEAT ) )
  543. {
  544. if ( pLicense->Service < LicenseServiceTableSize )
  545. {
  546. ServiceName = LicenseServices[ pLicense->Service ].ServiceName;
  547. }
  548. else
  549. {
  550. ASSERT( FALSE );
  551. }
  552. }
  553. if ( NULL == ServiceName )
  554. {
  555. ASSERT( FALSE );
  556. }
  557. else
  558. {
  559. Status = LicenseAdd( ServiceName, pLicense->Vendor, pLicense->NumberLicenses, pLicense->MaxQuantity, pLicense->Admin, pLicense->Comment, pLicense->Date, pLicense->AllowedModes, pLicense->CertificateID, pLicense->Source, pLicense->ExpirationDate, pLicense->Secrets );
  560. if (Status != STATUS_SUCCESS)
  561. {
  562. #ifdef DBG
  563. dprintf(TEXT("LicenseAdd failed: 0x%lX\n"), Status);
  564. #endif
  565. // ASSERT(FALSE);
  566. }
  567. }
  568. if (i % 100 == 0) ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, NSERVICEWAITHINT);
  569. }
  570. RtlReleaseResource(&LicenseListLock);
  571. } // LicenseListUnpack
  572. /////////////////////////////////////////////////////////////////////////
  573. NTSTATUS
  574. LicenseListStringsPack (
  575. ULONG LicenseServiceTableSize,
  576. PPACK_LICENSE_SERVICE_RECORD LicenseServices,
  577. ULONG *pLicenseServiceStringSize,
  578. LPTSTR *pLicenseServiceStrings,
  579. ULONG LicenseTableSize,
  580. PPACK_LICENSE_PURCHASE_RECORD Licenses,
  581. ULONG *pLicenseStringSize,
  582. LPTSTR *pLicenseStrings,
  583. ULONG PerServerLicenseServiceTableSize,
  584. PPACK_LICENSE_SERVICE_RECORD PerServerLicenseServices,
  585. ULONG *pPerServerLicenseServiceStringSize,
  586. LPTSTR *pPerServerLicenseServiceStrings
  587. )
  588. /*++
  589. Routine Description:
  590. Arguments:
  591. Return Value:
  592. --*/
  593. {
  594. NTSTATUS Status = STATUS_SUCCESS;
  595. ULONG i;
  596. ULONG StringSize;
  597. PPACK_LICENSE_SERVICE_RECORD pSvc;
  598. PPACK_LICENSE_PURCHASE_RECORD pLicense;
  599. LPTSTR LicenseServiceStrings = NULL;
  600. LPTSTR LicenseStrings = NULL;
  601. TCHAR *pStr;
  602. LPTSTR PerServerLicenseServiceStrings = NULL;
  603. HRESULT hr;
  604. #if DBG
  605. if (TraceFlags & TRACE_FUNCTION_TRACE)
  606. dprintf(TEXT("LicenseListStringsPack\n"));
  607. #endif
  608. ASSERT(pLicenseServiceStrings != NULL);
  609. ASSERT(pLicenseServiceStringSize != NULL);
  610. *pLicenseServiceStrings = NULL;
  611. *pLicenseServiceStringSize = 0;
  612. ASSERT(pLicenseStrings != NULL);
  613. ASSERT(pLicenseStringSize != NULL);
  614. *pLicenseStrings = NULL;
  615. *pLicenseStringSize = 0;
  616. ASSERT(pPerServerLicenseServiceStrings != NULL);
  617. ASSERT(pPerServerLicenseServiceStringSize != NULL);
  618. *pPerServerLicenseServiceStrings = NULL;
  619. *pPerServerLicenseServiceStringSize = 0;
  620. //////////////////////////////////////////////////////////////////
  621. //
  622. // Do License Service Strings
  623. //
  624. //
  625. // First walk the list adding up string sizes - to calculate our buff size
  626. //
  627. StringSize = 0;
  628. for (i = 0; i < LicenseServiceTableSize; i++) {
  629. pSvc = &LicenseServices[i];
  630. StringSize = StringSize + lstrlen(pSvc->ServiceName) + 1;
  631. }
  632. //
  633. // Make sure there is anything to replicate
  634. //
  635. if (StringSize > 0) {
  636. //
  637. // Create our buffer to hold all of the garbage
  638. //
  639. LicenseServiceStrings = MIDL_user_allocate(StringSize * sizeof(TCHAR));
  640. if (LicenseServiceStrings == NULL) {
  641. ASSERT(FALSE);
  642. return STATUS_NO_MEMORY;
  643. }
  644. //
  645. // Fill in the buffer
  646. //
  647. pStr = LicenseServiceStrings;
  648. for (i = 0; i < LicenseServiceTableSize; i++) {
  649. pSvc = &LicenseServices[i];
  650. hr = StringCchCopy(pStr, StringSize, pSvc->ServiceName);
  651. ASSERT(SUCCEEDED(hr));
  652. pStr = &pStr[lstrlen(pSvc->ServiceName) + 1];
  653. }
  654. }
  655. *pLicenseServiceStrings = LicenseServiceStrings;
  656. *pLicenseServiceStringSize = StringSize;
  657. //////////////////////////////////////////////////////////////////
  658. //
  659. // Do Per Server License Service Strings
  660. //
  661. //
  662. // First walk the list adding up string sizes - to calculate our buff size
  663. //
  664. StringSize = 0;
  665. for (i = 0; i < PerServerLicenseServiceTableSize; i++) {
  666. pSvc = &PerServerLicenseServices[i];
  667. StringSize = StringSize + lstrlen(pSvc->ServiceName) + 1;
  668. }
  669. //
  670. // Make sure there is anything to replicate
  671. //
  672. if (StringSize > 0) {
  673. //
  674. // Create our buffer to hold all of the garbage
  675. //
  676. PerServerLicenseServiceStrings = MIDL_user_allocate(StringSize * sizeof(TCHAR));
  677. if (PerServerLicenseServiceStrings == NULL)
  678. {
  679. ASSERT(FALSE);
  680. //
  681. // Clean up already alloc'd information
  682. //
  683. if (LicenseServiceStrings != NULL)
  684. MIDL_user_free(LicenseServiceStrings);
  685. *pLicenseServiceStrings = NULL;
  686. *pLicenseServiceStringSize = 0;
  687. return STATUS_NO_MEMORY;
  688. }
  689. //
  690. // Fill in the buffer
  691. //
  692. pStr = PerServerLicenseServiceStrings;
  693. for (i = 0; i < PerServerLicenseServiceTableSize; i++)
  694. {
  695. pSvc = &PerServerLicenseServices[i];
  696. hr = StringCchCopy(pStr, StringSize, pSvc->ServiceName);
  697. ASSERT(SUCCEEDED(hr));
  698. pStr = &pStr[lstrlen(pSvc->ServiceName) + 1];
  699. }
  700. }
  701. *pPerServerLicenseServiceStrings = PerServerLicenseServiceStrings;
  702. *pPerServerLicenseServiceStringSize = StringSize;
  703. //////////////////////////////////////////////////////////////////
  704. //
  705. // Now Do License Purchase Strings
  706. //
  707. //
  708. // First walk the list adding up string sizes - to calculate our buff size
  709. //
  710. StringSize = 0;
  711. for (i = 0; i < LicenseTableSize; i++) {
  712. pLicense = &Licenses[i];
  713. StringSize = StringSize + lstrlen(pLicense->Vendor) + 1;
  714. StringSize = StringSize + lstrlen(pLicense->Admin) + 1;
  715. StringSize = StringSize + lstrlen(pLicense->Comment) + 1;
  716. StringSize = StringSize + lstrlen(pLicense->Source) + 1;
  717. }
  718. //
  719. // Make sure there is anything to replicate
  720. //
  721. if (StringSize > 0) {
  722. //
  723. // Create our buffer to hold all of the garbage
  724. //
  725. LicenseStrings = MIDL_user_allocate(StringSize * sizeof(TCHAR));
  726. if (LicenseStrings == NULL) {
  727. ASSERT(FALSE);
  728. //
  729. // Clean up already alloc'd information
  730. //
  731. if (LicenseServiceStrings != NULL)
  732. MIDL_user_free(LicenseServiceStrings);
  733. if (PerServerLicenseServiceStrings != NULL)
  734. MIDL_user_free(PerServerLicenseServiceStrings);
  735. *pLicenseServiceStrings = NULL;
  736. *pLicenseServiceStringSize = 0;
  737. *pPerServerLicenseServiceStrings = NULL;
  738. *pPerServerLicenseServiceStringSize = 0;
  739. return STATUS_NO_MEMORY;
  740. }
  741. //
  742. // Fill in the buffer
  743. //
  744. pStr = LicenseStrings;
  745. for (i = 0; i < LicenseTableSize; i++) {
  746. pLicense = &Licenses[i];
  747. hr = StringCchCopy(pStr, StringSize, pLicense->Vendor);
  748. ASSERT(SUCCEEDED(hr));
  749. pStr = &pStr[lstrlen(pLicense->Vendor) + 1];
  750. hr = StringCchCopy(pStr, StringSize, pLicense->Admin);
  751. ASSERT(SUCCEEDED(hr));
  752. pStr = &pStr[lstrlen(pLicense->Admin) + 1];
  753. hr = StringCchCopy(pStr, StringSize, pLicense->Comment);
  754. ASSERT(SUCCEEDED(hr));
  755. pStr = &pStr[lstrlen(pLicense->Comment) + 1];
  756. hr = StringCchCopy(pStr, StringSize, pLicense->Source);
  757. ASSERT(SUCCEEDED(hr));
  758. pStr = &pStr[lstrlen(pLicense->Source) + 1];
  759. }
  760. }
  761. *pLicenseStrings = LicenseStrings;
  762. *pLicenseStringSize = StringSize;
  763. return Status;
  764. } // LicenseListStringsPack
  765. /////////////////////////////////////////////////////////////////////////
  766. VOID
  767. LicenseListStringsUnpack (
  768. ULONG LicenseServiceTableSize,
  769. PPACK_LICENSE_SERVICE_RECORD LicenseServices,
  770. ULONG LicenseServiceStringSize,
  771. LPTSTR LicenseServiceStrings,
  772. ULONG LicenseTableSize,
  773. PPACK_LICENSE_PURCHASE_RECORD Licenses,
  774. ULONG LicenseStringSize,
  775. LPTSTR LicenseStrings,
  776. ULONG PerServerLicenseServiceTableSize,
  777. PPACK_LICENSE_SERVICE_RECORD PerServerLicenseServices,
  778. ULONG PerServerLicenseServiceStringSize,
  779. LPTSTR PerServerLicenseServiceStrings
  780. )
  781. /*++
  782. Routine Description:
  783. Arguments:
  784. Return Value:
  785. --*/
  786. {
  787. ULONG i;
  788. PPACK_LICENSE_SERVICE_RECORD pSvc;
  789. PPACK_LICENSE_PURCHASE_RECORD pLicense;
  790. TCHAR *pStr;
  791. UNREFERENCED_PARAMETER(LicenseServiceStringSize);
  792. UNREFERENCED_PARAMETER(LicenseStringSize);
  793. UNREFERENCED_PARAMETER(PerServerLicenseServiceStringSize);
  794. #if DBG
  795. if (TraceFlags & TRACE_FUNCTION_TRACE)
  796. dprintf(TEXT("LicenseListStringsUnpack\n"));
  797. #endif
  798. //
  799. // First do per seat license service strings
  800. //
  801. pStr = LicenseServiceStrings;
  802. for (i = 0; i < LicenseServiceTableSize; i++) {
  803. pSvc = &LicenseServices[i];
  804. pSvc->ServiceName = pStr;
  805. //
  806. // Move to end of current string
  807. //
  808. while (*pStr != TEXT('\0'))
  809. pStr++;
  810. // now go past ending NULL
  811. pStr++;
  812. }
  813. //
  814. // Then do per server license service strings
  815. //
  816. pStr = PerServerLicenseServiceStrings;
  817. for (i = 0; i < PerServerLicenseServiceTableSize; i++) {
  818. pSvc = &PerServerLicenseServices[i];
  819. pSvc->ServiceName = pStr;
  820. //
  821. // Move to end of current string
  822. //
  823. while (*pStr != TEXT('\0'))
  824. pStr++;
  825. // now go past ending NULL
  826. pStr++;
  827. }
  828. //
  829. // Now do license purchase strings
  830. //
  831. pStr = LicenseStrings;
  832. for (i = 0; i < LicenseTableSize; i++) {
  833. pLicense = &Licenses[i];
  834. pLicense->Vendor = pStr;
  835. //
  836. // Move to end of current string
  837. //
  838. while (*pStr != TEXT('\0'))
  839. pStr++;
  840. // now go past ending NULL
  841. pStr++;
  842. pLicense->Admin = pStr;
  843. //
  844. // Move to end of current string
  845. //
  846. while (*pStr != TEXT('\0'))
  847. pStr++;
  848. // now go past ending NULL
  849. pStr++;
  850. pLicense->Comment = pStr;
  851. //
  852. // Move to end of current string
  853. //
  854. while (*pStr != TEXT('\0'))
  855. pStr++;
  856. // now go past ending NULL
  857. pStr++;
  858. pLicense->Source = pStr;
  859. //
  860. // Move to end of current string
  861. //
  862. while (*pStr != TEXT('\0'))
  863. pStr++;
  864. // now go past ending NULL
  865. pStr++;
  866. }
  867. } // LicenseListStringsUnpack
  868. /////////////////////////////////////////////////////////////////////////
  869. VOID
  870. LicenseListLoad()
  871. /*++
  872. Routine Description:
  873. Arguments:
  874. None.
  875. Return Value:
  876. None.
  877. --*/
  878. {
  879. BOOL ret;
  880. DWORD Version, DataSize;
  881. NTSTATUS Status = STATUS_SUCCESS;
  882. HANDLE hFile = NULL;
  883. ULONG LicenseServiceTableSize;
  884. PPACK_LICENSE_SERVICE_RECORD LicenseServices = NULL;
  885. ULONG LicenseServiceStringSize;
  886. LPTSTR LicenseServiceStrings = NULL;
  887. ULONG PerServerLicenseServiceTableSize = 0;
  888. PPACK_LICENSE_SERVICE_RECORD PerServerLicenseServices = NULL;
  889. ULONG PerServerLicenseServiceStringSize = 0;
  890. LPTSTR PerServerLicenseServiceStrings = NULL;
  891. ULONG LicenseTableSize;
  892. PPACK_LICENSE_PURCHASE_RECORD Licenses = NULL;
  893. ULONG LicenseStringSize;
  894. LPTSTR LicenseStrings = NULL;
  895. LICENSE_FILE_HEADER FileHeader;
  896. DWORD BytesRead;
  897. #if DBG
  898. if (TraceFlags & (TRACE_FUNCTION_TRACE | TRACE_DATABASE))
  899. dprintf(TEXT("LLS TRACE: LicenseListLoad\n"));
  900. #endif
  901. //
  902. // Check if we already have file open
  903. //
  904. if (PurchaseFile != NULL) {
  905. CloseHandle(PurchaseFile);
  906. PurchaseFile = NULL;
  907. }
  908. //
  909. // If nothing to load then get-out
  910. //
  911. if (!FileExists(LicenseFileName))
  912. goto LicenseListLoadExit;
  913. //
  914. // Check the init header
  915. //
  916. Version = DataSize = 0;
  917. PurchaseFile = LlsFileCheck(LicenseFileName, &Version, &DataSize );
  918. if (PurchaseFile == NULL) {
  919. Status = GetLastError();
  920. goto LicenseListLoadExit;
  921. }
  922. if ( ( Version == LICENSE_FILE_VERSION_0 ) && ( DataSize == sizeof(LICENSE_FILE_HEADER_0) ) ) {
  923. CloseHandle(PurchaseFile);
  924. PurchaseFile = NULL;
  925. LicenseListLoadOld();
  926. return;
  927. }
  928. if ( ( Version != LICENSE_FILE_VERSION ) || ( DataSize != sizeof(LICENSE_FILE_HEADER) ) ) {
  929. Status = STATUS_FILE_INVALID;
  930. goto LicenseListLoadExit;
  931. }
  932. //
  933. // The init header checks out, so load the license header and data blocks
  934. //
  935. hFile = PurchaseFile;
  936. ret = ReadFile(hFile, &FileHeader, sizeof(LICENSE_FILE_HEADER), &BytesRead, NULL);
  937. LicenseServiceTableSize = 0;
  938. LicenseServiceStringSize = 0;
  939. LicenseTableSize = 0;
  940. LicenseStringSize = 0;
  941. if (ret) {
  942. //
  943. // Run through and allocate space to read data blocks into
  944. //
  945. if (FileHeader.LicenseServiceTableSize != 0) {
  946. LicenseServiceTableSize = FileHeader.LicenseServiceTableSize / sizeof(PACK_LICENSE_SERVICE_RECORD);
  947. LicenseServices = MIDL_user_allocate(FileHeader.LicenseServiceTableSize);
  948. if ( LicenseServices == NULL ) {
  949. Status = STATUS_NO_MEMORY;
  950. goto LicenseListLoadExit;
  951. }
  952. }
  953. if (FileHeader.LicenseServiceStringSize != 0) {
  954. LicenseServiceStringSize = FileHeader.LicenseServiceStringSize / sizeof(TCHAR);
  955. LicenseServiceStrings = MIDL_user_allocate(FileHeader.LicenseServiceStringSize);
  956. if ( LicenseServiceStrings == NULL ) {
  957. Status = STATUS_NO_MEMORY;
  958. goto LicenseListLoadExit;
  959. }
  960. }
  961. if (FileHeader.LicenseServiceTableSize != 0) {
  962. PerServerLicenseServiceTableSize = FileHeader.PerServerLicenseServiceTableSize / sizeof(PACK_LICENSE_SERVICE_RECORD);
  963. PerServerLicenseServices = MIDL_user_allocate(FileHeader.PerServerLicenseServiceTableSize);
  964. if ( PerServerLicenseServices == NULL ) {
  965. Status = STATUS_NO_MEMORY;
  966. goto LicenseListLoadExit;
  967. }
  968. }
  969. if (FileHeader.PerServerLicenseServiceStringSize != 0) {
  970. PerServerLicenseServiceStringSize = FileHeader.PerServerLicenseServiceStringSize / sizeof(TCHAR);
  971. PerServerLicenseServiceStrings = MIDL_user_allocate(FileHeader.PerServerLicenseServiceStringSize);
  972. if ( PerServerLicenseServiceStrings == NULL ) {
  973. Status = STATUS_NO_MEMORY;
  974. goto LicenseListLoadExit;
  975. }
  976. }
  977. if (FileHeader.LicenseTableSize != 0) {
  978. LicenseTableSize = FileHeader.LicenseTableSize / sizeof(PACK_LICENSE_PURCHASE_RECORD);
  979. Licenses = MIDL_user_allocate(FileHeader.LicenseTableSize);
  980. if ( Licenses == NULL ) {
  981. Status = STATUS_NO_MEMORY;
  982. goto LicenseListLoadExit;
  983. }
  984. }
  985. if (FileHeader.LicenseStringSize != 0) {
  986. LicenseStringSize = FileHeader.LicenseStringSize / sizeof(TCHAR);
  987. LicenseStrings = MIDL_user_allocate(FileHeader.LicenseStringSize);
  988. if ( LicenseStrings == NULL ) {
  989. Status = STATUS_NO_MEMORY;
  990. goto LicenseListLoadExit;
  991. }
  992. }
  993. }
  994. if (ret && (FileHeader.LicenseServiceTableSize != 0) )
  995. ret = ReadFile(hFile, LicenseServices, FileHeader.LicenseServiceTableSize, &BytesRead, NULL);
  996. if (ret && (FileHeader.LicenseServiceStringSize != 0) )
  997. ret = ReadFile(hFile, LicenseServiceStrings, FileHeader.LicenseServiceStringSize, &BytesRead, NULL);
  998. if (ret && (FileHeader.PerServerLicenseServiceTableSize != 0) )
  999. ret = ReadFile(hFile, PerServerLicenseServices, FileHeader.PerServerLicenseServiceTableSize, &BytesRead, NULL);
  1000. if (ret && (FileHeader.PerServerLicenseServiceStringSize != 0) )
  1001. ret = ReadFile(hFile, PerServerLicenseServiceStrings, FileHeader.PerServerLicenseServiceStringSize, &BytesRead, NULL);
  1002. if (ret && (FileHeader.LicenseTableSize != 0) )
  1003. ret = ReadFile(hFile, Licenses, FileHeader.LicenseTableSize, &BytesRead, NULL);
  1004. if (ret && (FileHeader.LicenseStringSize != 0) )
  1005. ret = ReadFile(hFile, LicenseStrings, FileHeader.LicenseStringSize, &BytesRead, NULL);
  1006. if (!ret) {
  1007. Status = GetLastError();
  1008. goto LicenseListLoadExit;
  1009. }
  1010. //
  1011. // Decrypt the data
  1012. //
  1013. Status = DeBlock(LicenseServices, FileHeader.LicenseServiceTableSize);
  1014. if (Status == STATUS_SUCCESS)
  1015. Status = DeBlock(LicenseServiceStrings, FileHeader.LicenseServiceStringSize);
  1016. if (Status == STATUS_SUCCESS)
  1017. Status = DeBlock(PerServerLicenseServices, FileHeader.PerServerLicenseServiceTableSize);
  1018. if (Status == STATUS_SUCCESS)
  1019. Status = DeBlock(PerServerLicenseServiceStrings, FileHeader.PerServerLicenseServiceStringSize);
  1020. if (Status == STATUS_SUCCESS)
  1021. Status = DeBlock(Licenses, FileHeader.LicenseTableSize);
  1022. if (Status == STATUS_SUCCESS)
  1023. Status = DeBlock(LicenseStrings, FileHeader.LicenseStringSize);
  1024. if (Status != STATUS_SUCCESS)
  1025. goto LicenseListLoadExit;
  1026. //
  1027. // Unpack the string data
  1028. //
  1029. LicenseListStringsUnpack( LicenseServiceTableSize, LicenseServices,
  1030. LicenseServiceStringSize, LicenseServiceStrings,
  1031. LicenseTableSize, Licenses,
  1032. LicenseStringSize, LicenseStrings,
  1033. PerServerLicenseServiceTableSize, PerServerLicenseServices,
  1034. PerServerLicenseServiceStringSize, PerServerLicenseServiceStrings
  1035. );
  1036. //
  1037. // Unpack the license data
  1038. //
  1039. LicenseListUnpack( LicenseServiceTableSize, LicenseServices, LicenseTableSize, Licenses, PerServerLicenseServiceTableSize, PerServerLicenseServices );
  1040. LicenseListLoadExit:
  1041. // Note: Don't close the License Purchase File (keep it locked).
  1042. //
  1043. // Run through our tables and clean them up
  1044. //
  1045. if (LicenseServices != NULL)
  1046. MIDL_user_free(LicenseServices);
  1047. if (LicenseServiceStrings != NULL)
  1048. MIDL_user_free(LicenseServiceStrings);
  1049. if (PerServerLicenseServices != NULL)
  1050. MIDL_user_free(PerServerLicenseServices);
  1051. if (PerServerLicenseServiceStrings != NULL)
  1052. MIDL_user_free(PerServerLicenseServiceStrings);
  1053. if (Licenses != NULL)
  1054. MIDL_user_free(Licenses);
  1055. if (LicenseStrings != NULL)
  1056. MIDL_user_free(LicenseStrings);
  1057. //
  1058. // If there was an error log it.
  1059. //
  1060. if (Status != STATUS_SUCCESS)
  1061. LogEvent(LLS_EVENT_LOAD_LICENSE, 0, NULL, Status);
  1062. } // LicenseListLoad
  1063. /////////////////////////////////////////////////////////////////////////
  1064. NTSTATUS
  1065. LicenseListSave()
  1066. /*++
  1067. Routine Description:
  1068. Arguments:
  1069. None.
  1070. Return Value:
  1071. None.
  1072. --*/
  1073. {
  1074. BOOL ret = TRUE;
  1075. NTSTATUS Status = STATUS_SUCCESS;
  1076. HANDLE hFile = NULL;
  1077. ULONG LicenseServiceTableSize;
  1078. PPACK_LICENSE_SERVICE_RECORD LicenseServices = NULL;
  1079. ULONG LicenseServiceStringSize;
  1080. LPTSTR LicenseServiceStrings = NULL;
  1081. ULONG PerServerLicenseServiceTableSize;
  1082. PPACK_LICENSE_SERVICE_RECORD PerServerLicenseServices = NULL;
  1083. ULONG PerServerLicenseServiceStringSize;
  1084. LPTSTR PerServerLicenseServiceStrings = NULL;
  1085. ULONG LicenseTableSize;
  1086. PPACK_LICENSE_PURCHASE_RECORD Licenses = NULL;
  1087. ULONG LicenseStringSize;
  1088. LPTSTR LicenseStrings = NULL;
  1089. LICENSE_FILE_HEADER FileHeader;
  1090. DWORD BytesWritten;
  1091. #if DBG
  1092. if (TraceFlags & (TRACE_FUNCTION_TRACE | TRACE_DATABASE))
  1093. dprintf(TEXT("LLS TRACE: LicenseListSave\n"));
  1094. #endif
  1095. RtlAcquireResourceExclusive(&LicenseListLock, TRUE);
  1096. //
  1097. // Check if we already have file open
  1098. //
  1099. if (PurchaseFile != NULL) {
  1100. CloseHandle(PurchaseFile);
  1101. PurchaseFile = NULL;
  1102. }
  1103. //
  1104. // If nothing to save then get-out
  1105. //
  1106. if ( (LicenseServiceListSize == 0) && (PerServerLicenseServiceListSize == 0) )
  1107. goto LicenseListSaveExit;
  1108. //
  1109. // Pack the license data
  1110. //
  1111. Status = LicenseListPack( &LicenseServiceTableSize, &LicenseServices, &LicenseTableSize, &Licenses, &PerServerLicenseServiceTableSize, &PerServerLicenseServices );
  1112. if (Status != STATUS_SUCCESS)
  1113. goto LicenseListSaveExit;
  1114. //
  1115. // Now pack the String data
  1116. //
  1117. Status = LicenseListStringsPack( LicenseServiceTableSize, LicenseServices,
  1118. &LicenseServiceStringSize, &LicenseServiceStrings,
  1119. LicenseTableSize, Licenses,
  1120. &LicenseStringSize, &LicenseStrings,
  1121. PerServerLicenseServiceTableSize, PerServerLicenseServices,
  1122. &PerServerLicenseServiceStringSize, &PerServerLicenseServiceStrings );
  1123. if (Status != STATUS_SUCCESS)
  1124. goto LicenseListSaveExit;
  1125. //
  1126. // Fill out the file header - sizes are byte sizes
  1127. //
  1128. FileHeader.LicenseServiceTableSize = LicenseServiceTableSize * sizeof(PACK_LICENSE_SERVICE_RECORD);
  1129. FileHeader.LicenseServiceStringSize = LicenseServiceStringSize * sizeof(TCHAR);
  1130. FileHeader.PerServerLicenseServiceTableSize = PerServerLicenseServiceTableSize * sizeof(PACK_LICENSE_SERVICE_RECORD);
  1131. FileHeader.PerServerLicenseServiceStringSize = PerServerLicenseServiceStringSize * sizeof(TCHAR);
  1132. FileHeader.LicenseTableSize = LicenseTableSize * sizeof(PACK_LICENSE_PURCHASE_RECORD);
  1133. FileHeader.LicenseStringSize = LicenseStringSize * sizeof(TCHAR);
  1134. //
  1135. // Encrypt the data before saving it out.
  1136. //
  1137. Status = EBlock(LicenseServices, FileHeader.LicenseServiceTableSize);
  1138. if (Status == STATUS_SUCCESS)
  1139. Status = EBlock(LicenseServiceStrings, FileHeader.LicenseServiceStringSize);
  1140. if (Status == STATUS_SUCCESS)
  1141. Status = EBlock(PerServerLicenseServices, FileHeader.PerServerLicenseServiceTableSize);
  1142. if (Status == STATUS_SUCCESS)
  1143. Status = EBlock(PerServerLicenseServiceStrings, FileHeader.PerServerLicenseServiceStringSize);
  1144. if (Status == STATUS_SUCCESS)
  1145. Status = EBlock(Licenses, FileHeader.LicenseTableSize);
  1146. if (Status == STATUS_SUCCESS)
  1147. Status = EBlock(LicenseStrings, FileHeader.LicenseStringSize);
  1148. if (Status != STATUS_SUCCESS)
  1149. goto LicenseListSaveExit;
  1150. //
  1151. // Save out the header record
  1152. //
  1153. PurchaseFile = LlsFileInit(LicenseFileName, LICENSE_FILE_VERSION, sizeof(LICENSE_FILE_HEADER) );
  1154. if (PurchaseFile == NULL) {
  1155. Status = GetLastError();
  1156. goto LicenseListSaveExit;
  1157. }
  1158. //
  1159. // Now write out all the data blocks
  1160. //
  1161. hFile = PurchaseFile;
  1162. ret = WriteFile(hFile, &FileHeader, sizeof(LICENSE_FILE_HEADER), &BytesWritten, NULL);
  1163. if (ret && (LicenseServices != NULL) && (FileHeader.LicenseServiceTableSize != 0))
  1164. ret = WriteFile(hFile, LicenseServices, FileHeader.LicenseServiceTableSize, &BytesWritten, NULL);
  1165. if (ret && (LicenseServiceStrings != NULL) && (FileHeader.LicenseServiceStringSize != 0))
  1166. ret = WriteFile(hFile, LicenseServiceStrings, FileHeader.LicenseServiceStringSize, &BytesWritten, NULL);
  1167. if (ret && (PerServerLicenseServices != NULL) && (FileHeader.PerServerLicenseServiceTableSize != 0))
  1168. ret = WriteFile(hFile, PerServerLicenseServices, FileHeader.PerServerLicenseServiceTableSize, &BytesWritten, NULL);
  1169. if (ret && (PerServerLicenseServiceStrings != NULL) && (FileHeader.PerServerLicenseServiceStringSize != 0))
  1170. ret = WriteFile(hFile, PerServerLicenseServiceStrings, FileHeader.PerServerLicenseServiceStringSize, &BytesWritten, NULL);
  1171. if (ret && (Licenses != NULL) && (FileHeader.LicenseTableSize != 0))
  1172. ret = WriteFile(hFile, Licenses, FileHeader.LicenseTableSize, &BytesWritten, NULL);
  1173. if (ret && (LicenseStrings != NULL) && (FileHeader.LicenseStringSize != 0))
  1174. ret = WriteFile(hFile, LicenseStrings, FileHeader.LicenseStringSize, &BytesWritten, NULL);
  1175. if (!ret)
  1176. Status = GetLastError();
  1177. LicenseListSaveExit:
  1178. RtlReleaseResource(&LicenseListLock);
  1179. // Note: Don't close the License Purchase File (keep it locked).
  1180. if (hFile != NULL)
  1181. FlushFileBuffers(hFile);
  1182. //
  1183. // Run through our tables and clean them up
  1184. //
  1185. if (LicenseServices != NULL)
  1186. MIDL_user_free(LicenseServices);
  1187. if (LicenseServiceStrings != NULL)
  1188. MIDL_user_free(LicenseServiceStrings);
  1189. if (PerServerLicenseServices != NULL)
  1190. MIDL_user_free(PerServerLicenseServices);
  1191. if (PerServerLicenseServiceStrings != NULL)
  1192. MIDL_user_free(PerServerLicenseServiceStrings);
  1193. if (Licenses != NULL)
  1194. MIDL_user_free(Licenses);
  1195. if (LicenseStrings != NULL)
  1196. MIDL_user_free(LicenseStrings);
  1197. //
  1198. // If there was an error log it.
  1199. //
  1200. if (Status != STATUS_SUCCESS)
  1201. LogEvent(LLS_EVENT_SAVE_LICENSE, 0, NULL, Status);
  1202. return Status;
  1203. } // LicenseListSave
  1204. /////////////////////////////////////////////////////////////////////////
  1205. // Mapping List
  1206. //
  1207. /////////////////////////////////////////////////////////////////////////
  1208. NTSTATUS
  1209. MappingListPack (
  1210. ULONG *pMappingUserTableSize,
  1211. PPACK_MAPPING_USER_RECORD *pMappingUsers,
  1212. ULONG *pMappingTableSize,
  1213. PPACK_MAPPING_RECORD *pMappings
  1214. )
  1215. /*++
  1216. Routine Description:
  1217. Arguments:
  1218. Return Value:
  1219. --*/
  1220. {
  1221. NTSTATUS Status = STATUS_SUCCESS;
  1222. PPACK_MAPPING_USER_RECORD MappingUsers = NULL;
  1223. PPACK_MAPPING_RECORD Mappings = NULL;
  1224. ULONG i, j, k;
  1225. ULONG TotalRecords = 0;
  1226. PMAPPING_RECORD pMapping;
  1227. #if DBG
  1228. if (TraceFlags & TRACE_FUNCTION_TRACE)
  1229. dprintf(TEXT("LLS TRACE: MappingListPack\n"));
  1230. #endif
  1231. ASSERT(pMappingUsers != NULL);
  1232. ASSERT(pMappingUserTableSize != NULL);
  1233. *pMappingUsers = NULL;
  1234. *pMappingUserTableSize = 0;
  1235. ASSERT(pMappings != NULL);
  1236. ASSERT(pMappingTableSize != NULL);
  1237. *pMappings = NULL;
  1238. *pMappingTableSize = 0;
  1239. //////////////////////////////////////////////////////////////////
  1240. //
  1241. // Do Mapping User Table First
  1242. //
  1243. TotalRecords = 0;
  1244. //
  1245. // Make sure there is anything to replicate
  1246. //
  1247. for (i = 0; i < MappingListSize; i++)
  1248. TotalRecords += MappingList[i]->NumMembers;
  1249. if (TotalRecords > 0) {
  1250. //
  1251. // Create our buffer to hold all of the garbage
  1252. //
  1253. MappingUsers = MIDL_user_allocate(TotalRecords * sizeof(PACK_MAPPING_USER_RECORD));
  1254. if (MappingUsers == NULL) {
  1255. ASSERT(FALSE);
  1256. return STATUS_NO_MEMORY;
  1257. }
  1258. //
  1259. // Fill in the buffer - walk the Mapping tree
  1260. //
  1261. k = 0;
  1262. for (i = 0; i < MappingListSize; i++) {
  1263. pMapping = MappingList[i];
  1264. for (j = 0; j < pMapping->NumMembers; j++) {
  1265. MappingUsers[k].Mapping = i;
  1266. MappingUsers[k].Name = pMapping->Members[j];
  1267. k++;
  1268. }
  1269. }
  1270. }
  1271. *pMappingUsers = MappingUsers;
  1272. *pMappingUserTableSize = TotalRecords;
  1273. //////////////////////////////////////////////////////////////////
  1274. //
  1275. // Now Do Mapping Records
  1276. //
  1277. TotalRecords = MappingListSize;
  1278. //
  1279. // Make sure there is anything to replicate
  1280. //
  1281. if (TotalRecords > 0) {
  1282. //
  1283. // Create our buffer to hold all of the garbage
  1284. //
  1285. Mappings = MIDL_user_allocate(TotalRecords * sizeof(PACK_MAPPING_RECORD));
  1286. if (Mappings == NULL) {
  1287. ASSERT(FALSE);
  1288. //
  1289. // Clean up already alloc'd information
  1290. //
  1291. if (MappingUsers != NULL)
  1292. MIDL_user_free(MappingUsers);
  1293. *pMappingUsers = NULL;
  1294. *pMappingUserTableSize = 0;
  1295. return STATUS_NO_MEMORY;
  1296. }
  1297. //
  1298. // Fill in the buffer - walk the License Purchase tree
  1299. //
  1300. for (i = 0; i < MappingListSize; i++) {
  1301. pMapping = MappingList[i];
  1302. Mappings[i].Name = pMapping->Name;
  1303. Mappings[i].Comment = pMapping->Comment;
  1304. Mappings[i].Licenses = pMapping->Licenses;
  1305. }
  1306. }
  1307. *pMappings = Mappings;
  1308. *pMappingTableSize = TotalRecords;
  1309. return Status;
  1310. } // MappingListPack
  1311. /////////////////////////////////////////////////////////////////////////
  1312. VOID
  1313. MappingListUnpack (
  1314. ULONG MappingUserTableSize,
  1315. PPACK_MAPPING_USER_RECORD MappingUsers,
  1316. ULONG MappingTableSize,
  1317. PPACK_MAPPING_RECORD Mappings
  1318. )
  1319. /*++
  1320. Routine Description:
  1321. Arguments:
  1322. Return Value:
  1323. --*/
  1324. {
  1325. ULONG i;
  1326. PPACK_MAPPING_USER_RECORD pUsr;
  1327. PPACK_MAPPING_RECORD pMapping;
  1328. PMAPPING_RECORD pMap;
  1329. #if DBG
  1330. if (TraceFlags & TRACE_FUNCTION_TRACE)
  1331. dprintf(TEXT("MappingListUnpack: Mappings[%lu] TotalUsers[%lu]\n"), MappingTableSize, MappingUserTableSize);
  1332. #endif
  1333. RtlAcquireResourceExclusive(&MappingListLock, TRUE);
  1334. //
  1335. // Add the Mappings first
  1336. //
  1337. for (i = 0; i < MappingTableSize; i++) {
  1338. pMapping = &Mappings[i];
  1339. pMap = MappingListAdd(pMapping->Name, pMapping->Comment, pMapping->Licenses,NULL);
  1340. if (i % 100 == 0) ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, NSERVICEWAITHINT);
  1341. }
  1342. //
  1343. // Now add the users to the mappings...
  1344. //
  1345. for (i = 0; i < MappingUserTableSize; i++) {
  1346. pUsr = &MappingUsers[i];
  1347. pMap = NULL;
  1348. if (pUsr->Mapping < MappingTableSize)
  1349. pMap = MappingUserListAdd(Mappings[pUsr->Mapping].Name, pUsr->Name);
  1350. #if DBG
  1351. if (pMap == NULL) {
  1352. dprintf(TEXT("pMap: 0x%lX pUsr->Mapping: %lu MappingTableSize: %lu\n"), pMap, pUsr->Mapping, MappingTableSize);
  1353. ASSERT(FALSE);
  1354. }
  1355. #endif
  1356. if (i % 100 == 0) ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, NSERVICEWAITHINT);
  1357. }
  1358. RtlReleaseResource(&MappingListLock);
  1359. } // MappingListUnpack
  1360. /////////////////////////////////////////////////////////////////////////
  1361. NTSTATUS
  1362. MappingListStringsPack (
  1363. ULONG MappingUserTableSize,
  1364. PPACK_MAPPING_USER_RECORD MappingUsers,
  1365. ULONG *pMappingUserStringSize,
  1366. LPTSTR *pMappingUserStrings,
  1367. ULONG MappingTableSize,
  1368. PPACK_MAPPING_RECORD Mappings,
  1369. ULONG *pMappingStringSize,
  1370. LPTSTR *pMappingStrings
  1371. )
  1372. /*++
  1373. Routine Description:
  1374. Arguments:
  1375. Return Value:
  1376. --*/
  1377. {
  1378. NTSTATUS Status = STATUS_SUCCESS;
  1379. ULONG i;
  1380. ULONG StringSize;
  1381. PPACK_MAPPING_USER_RECORD pUsr;
  1382. PPACK_MAPPING_RECORD pMapping;
  1383. LPTSTR MappingUserStrings = NULL;
  1384. LPTSTR MappingStrings = NULL;
  1385. TCHAR *pStr;
  1386. HRESULT hr;
  1387. #if DBG
  1388. if (TraceFlags & TRACE_FUNCTION_TRACE)
  1389. dprintf(TEXT("MappingListStringsPack\n"));
  1390. #endif
  1391. ASSERT(pMappingUserStrings != NULL);
  1392. ASSERT(pMappingUserStringSize != NULL);
  1393. *pMappingUserStrings = NULL;
  1394. *pMappingUserStringSize = 0;
  1395. ASSERT(pMappingStrings != NULL);
  1396. ASSERT(pMappingStringSize != NULL);
  1397. *pMappingStrings = NULL;
  1398. *pMappingStringSize = 0;
  1399. //////////////////////////////////////////////////////////////////
  1400. //
  1401. // Do Mapping User Strings
  1402. //
  1403. //
  1404. // First walk the list adding up string sizes - to calculate our buff size
  1405. //
  1406. StringSize = 0;
  1407. for (i = 0; i < MappingUserTableSize; i++) {
  1408. pUsr = &MappingUsers[i];
  1409. StringSize = StringSize + lstrlen(pUsr->Name) + 1;
  1410. }
  1411. //
  1412. // Make sure there is anything to replicate
  1413. //
  1414. if (StringSize > 0) {
  1415. //
  1416. // Create our buffer to hold all of the garbage
  1417. //
  1418. MappingUserStrings = MIDL_user_allocate(StringSize * sizeof(TCHAR));
  1419. if (MappingUserStrings == NULL) {
  1420. ASSERT(FALSE);
  1421. return STATUS_NO_MEMORY;
  1422. }
  1423. //
  1424. // Fill in the buffer
  1425. //
  1426. pStr = MappingUserStrings;
  1427. for (i = 0; i < MappingUserTableSize; i++) {
  1428. pUsr = &MappingUsers[i];
  1429. hr = StringCchCopy(pStr, StringSize, pUsr->Name);
  1430. ASSERT(SUCCEEDED(hr));
  1431. pStr = &pStr[lstrlen(pUsr->Name) + 1];
  1432. }
  1433. }
  1434. *pMappingUserStrings = MappingUserStrings;
  1435. *pMappingUserStringSize = StringSize;
  1436. //////////////////////////////////////////////////////////////////
  1437. //
  1438. // Now Do Mapping Strings
  1439. //
  1440. //
  1441. // First walk the list adding up string sizes - to calculate our buff size
  1442. //
  1443. StringSize = 0;
  1444. for (i = 0; i < MappingTableSize; i++) {
  1445. pMapping = &Mappings[i];
  1446. StringSize = StringSize + lstrlen(pMapping->Name) + 1;
  1447. StringSize = StringSize + lstrlen(pMapping->Comment) + 1;
  1448. }
  1449. //
  1450. // Make sure there is anything to replicate
  1451. //
  1452. if (StringSize > 0) {
  1453. //
  1454. // Create our buffer to hold all of the garbage
  1455. //
  1456. MappingStrings = MIDL_user_allocate(StringSize * sizeof(TCHAR));
  1457. if (MappingStrings == NULL) {
  1458. ASSERT(FALSE);
  1459. //
  1460. // Clean up already alloc'd information
  1461. //
  1462. if (MappingUserStrings != NULL)
  1463. MIDL_user_free(MappingUserStrings);
  1464. *pMappingUserStrings = NULL;
  1465. *pMappingUserStringSize = 0;
  1466. return STATUS_NO_MEMORY;
  1467. }
  1468. //
  1469. // Fill in the buffer
  1470. //
  1471. pStr = MappingStrings;
  1472. for (i = 0; i < MappingTableSize; i++) {
  1473. pMapping = &Mappings[i];
  1474. hr = StringCchCopy(pStr, StringSize, pMapping->Name);
  1475. ASSERT(SUCCEEDED(hr));
  1476. pStr = &pStr[lstrlen(pMapping->Name) + 1];
  1477. hr = StringCchCopy(pStr, StringSize, pMapping->Comment);
  1478. ASSERT(SUCCEEDED(hr));
  1479. pStr = &pStr[lstrlen(pMapping->Comment) + 1];
  1480. }
  1481. }
  1482. *pMappingStrings = MappingStrings;
  1483. *pMappingStringSize = StringSize;
  1484. return Status;
  1485. } // MappingListStringsPack
  1486. /////////////////////////////////////////////////////////////////////////
  1487. VOID
  1488. MappingListStringsUnpack (
  1489. ULONG MappingUserTableSize,
  1490. PPACK_MAPPING_USER_RECORD MappingUsers,
  1491. ULONG MappingUserStringSize,
  1492. LPTSTR MappingUserStrings,
  1493. ULONG MappingTableSize,
  1494. PPACK_MAPPING_RECORD Mappings,
  1495. ULONG MappingStringSize,
  1496. LPTSTR MappingStrings
  1497. )
  1498. /*++
  1499. Routine Description:
  1500. Arguments:
  1501. Return Value:
  1502. --*/
  1503. {
  1504. ULONG i;
  1505. PPACK_MAPPING_USER_RECORD pUsr;
  1506. PPACK_MAPPING_RECORD pMapping;
  1507. TCHAR *pStr;
  1508. UNREFERENCED_PARAMETER(MappingUserStringSize);
  1509. UNREFERENCED_PARAMETER(MappingStringSize);
  1510. #if DBG
  1511. if (TraceFlags & TRACE_FUNCTION_TRACE)
  1512. dprintf(TEXT("MappingListStringsUnpack\n"));
  1513. #endif
  1514. //
  1515. // First do license service strings
  1516. //
  1517. pStr = MappingUserStrings;
  1518. for (i = 0; i < MappingUserTableSize; i++) {
  1519. pUsr = &MappingUsers[i];
  1520. pUsr->Name = pStr;
  1521. //
  1522. // Move to end of current string
  1523. //
  1524. while (*pStr != TEXT('\0'))
  1525. pStr++;
  1526. // now go past ending NULL
  1527. pStr++;
  1528. }
  1529. //
  1530. // Now do license purchase strings
  1531. //
  1532. pStr = MappingStrings;
  1533. for (i = 0; i < MappingTableSize; i++) {
  1534. pMapping = &Mappings[i];
  1535. pMapping->Name = pStr;
  1536. //
  1537. // Move to end of current string
  1538. //
  1539. while (*pStr != TEXT('\0'))
  1540. pStr++;
  1541. // now go past ending NULL
  1542. pStr++;
  1543. pMapping->Comment = pStr;
  1544. //
  1545. // Move to end of current string
  1546. //
  1547. while (*pStr != TEXT('\0'))
  1548. pStr++;
  1549. // now go past ending NULL
  1550. pStr++;
  1551. }
  1552. } // MappingListStringsUnpack
  1553. /////////////////////////////////////////////////////////////////////////
  1554. VOID
  1555. MappingListLoad()
  1556. /*++
  1557. Routine Description:
  1558. Arguments:
  1559. None.
  1560. Return Value:
  1561. None.
  1562. --*/
  1563. {
  1564. BOOL ret;
  1565. DWORD Version, DataSize;
  1566. NTSTATUS Status = STATUS_SUCCESS;
  1567. HANDLE hFile = NULL;
  1568. ULONG MappingUserTableSize;
  1569. PPACK_MAPPING_USER_RECORD MappingUsers = NULL;
  1570. ULONG MappingUserStringSize;
  1571. LPTSTR MappingUserStrings = NULL;
  1572. ULONG MappingTableSize;
  1573. PPACK_MAPPING_RECORD Mappings = NULL;
  1574. ULONG MappingStringSize;
  1575. LPTSTR MappingStrings = NULL;
  1576. MAPPING_FILE_HEADER FileHeader;
  1577. DWORD BytesRead;
  1578. #if DBG
  1579. if (TraceFlags & (TRACE_FUNCTION_TRACE | TRACE_DATABASE))
  1580. dprintf(TEXT("LLS TRACE: MappingListLoad\n"));
  1581. #endif
  1582. RtlEnterCriticalSection(&MappingFileLock);
  1583. //
  1584. // If nothing to load then get-out
  1585. //
  1586. if (!FileExists(MappingFileName))
  1587. goto MappingListLoadExit;
  1588. //
  1589. // Check the init header
  1590. //
  1591. Version = DataSize = 0;
  1592. hFile = LlsFileCheck(MappingFileName, &Version, &DataSize );
  1593. if (hFile == NULL) {
  1594. Status = GetLastError();
  1595. goto MappingListLoadExit;
  1596. }
  1597. if ((Version != MAPPING_FILE_VERSION) || (DataSize != sizeof(MAPPING_FILE_HEADER))) {
  1598. Status = STATUS_FILE_INVALID;
  1599. goto MappingListLoadExit;
  1600. }
  1601. //
  1602. // The init header checks out, so load the license header and data blocks
  1603. //
  1604. ret = ReadFile(hFile, &FileHeader, sizeof(MAPPING_FILE_HEADER), &BytesRead, NULL);
  1605. MappingUserTableSize = 0;
  1606. MappingUserStringSize = 0;
  1607. MappingTableSize = 0;
  1608. MappingStringSize = 0;
  1609. if (ret) {
  1610. //
  1611. // Run through and allocate space to read data blocks into
  1612. //
  1613. if (FileHeader.MappingUserTableSize != 0) {
  1614. MappingUserTableSize = FileHeader.MappingUserTableSize / sizeof(PACK_MAPPING_USER_RECORD);
  1615. MappingUsers = MIDL_user_allocate(FileHeader.MappingUserTableSize);
  1616. if ( MappingUsers == NULL ) {
  1617. Status = STATUS_NO_MEMORY;
  1618. goto MappingListLoadExit;
  1619. }
  1620. }
  1621. if (FileHeader.MappingUserStringSize != 0) {
  1622. MappingUserStringSize = FileHeader.MappingUserStringSize / sizeof(TCHAR);
  1623. MappingUserStrings = MIDL_user_allocate(FileHeader.MappingUserStringSize);
  1624. if ( MappingUserStrings == NULL ) {
  1625. Status = STATUS_NO_MEMORY;
  1626. goto MappingListLoadExit;
  1627. }
  1628. }
  1629. if (FileHeader.MappingTableSize != 0) {
  1630. MappingTableSize = FileHeader.MappingTableSize / sizeof(PACK_MAPPING_RECORD);
  1631. Mappings = MIDL_user_allocate(FileHeader.MappingTableSize);
  1632. if ( Mappings == NULL ) {
  1633. Status = STATUS_NO_MEMORY;
  1634. goto MappingListLoadExit;
  1635. }
  1636. }
  1637. if (FileHeader.MappingStringSize != 0) {
  1638. MappingStringSize = FileHeader.MappingStringSize / sizeof(TCHAR);
  1639. MappingStrings = MIDL_user_allocate(FileHeader.MappingStringSize);
  1640. if ( MappingStrings == NULL ) {
  1641. Status = STATUS_NO_MEMORY;
  1642. goto MappingListLoadExit;
  1643. }
  1644. }
  1645. }
  1646. if (ret && (FileHeader.MappingUserTableSize != 0) )
  1647. ret = ReadFile(hFile, MappingUsers, FileHeader.MappingUserTableSize, &BytesRead, NULL);
  1648. if (ret && (FileHeader.MappingUserStringSize != 0) )
  1649. ret = ReadFile(hFile, MappingUserStrings, FileHeader.MappingUserStringSize, &BytesRead, NULL);
  1650. if (ret && (FileHeader.MappingTableSize != 0) )
  1651. ret = ReadFile(hFile, Mappings, FileHeader.MappingTableSize, &BytesRead, NULL);
  1652. if (ret && (FileHeader.MappingStringSize != 0) )
  1653. ret = ReadFile(hFile, MappingStrings, FileHeader.MappingStringSize, &BytesRead, NULL);
  1654. if (!ret) {
  1655. Status = GetLastError();
  1656. goto MappingListLoadExit;
  1657. }
  1658. //
  1659. // Decrypt the data
  1660. //
  1661. Status = DeBlock(MappingUsers, FileHeader.MappingUserTableSize);
  1662. if (Status == STATUS_SUCCESS)
  1663. Status = DeBlock(MappingUserStrings, FileHeader.MappingUserStringSize);
  1664. if (Status == STATUS_SUCCESS)
  1665. Status = DeBlock(Mappings, FileHeader.MappingTableSize);
  1666. if (Status == STATUS_SUCCESS)
  1667. Status = DeBlock(MappingStrings, FileHeader.MappingStringSize);
  1668. if (Status != STATUS_SUCCESS)
  1669. goto MappingListLoadExit;
  1670. //
  1671. // Unpack the string data
  1672. //
  1673. MappingListStringsUnpack( MappingUserTableSize, MappingUsers,
  1674. MappingUserStringSize, MappingUserStrings,
  1675. MappingTableSize, Mappings,
  1676. MappingStringSize, MappingStrings );
  1677. //
  1678. // Unpack the data
  1679. //
  1680. MappingListUnpack( MappingUserTableSize, MappingUsers, MappingTableSize, Mappings );
  1681. MappingListLoadExit:
  1682. if (hFile != NULL)
  1683. CloseHandle(hFile);
  1684. RtlLeaveCriticalSection(&MappingFileLock);
  1685. //
  1686. // Run through our tables and clean them up
  1687. //
  1688. if (MappingUsers != NULL)
  1689. MIDL_user_free(MappingUsers);
  1690. if (MappingUserStrings != NULL)
  1691. MIDL_user_free(MappingUserStrings);
  1692. if (Mappings != NULL)
  1693. MIDL_user_free(Mappings);
  1694. if (MappingStrings != NULL)
  1695. MIDL_user_free(MappingStrings);
  1696. //
  1697. // If there was an error log it.
  1698. //
  1699. if (Status != STATUS_SUCCESS)
  1700. LogEvent(LLS_EVENT_LOAD_MAPPING, 0, NULL, Status);
  1701. } // MappingListLoad
  1702. /////////////////////////////////////////////////////////////////////////
  1703. NTSTATUS
  1704. MappingListSave()
  1705. /*++
  1706. Routine Description:
  1707. Arguments:
  1708. None.
  1709. Return Value:
  1710. None.
  1711. --*/
  1712. {
  1713. BOOL ret = TRUE;
  1714. NTSTATUS Status = STATUS_SUCCESS;
  1715. HANDLE hFile = NULL;
  1716. ULONG MappingUserTableSize;
  1717. PPACK_MAPPING_USER_RECORD MappingUsers = NULL;
  1718. ULONG MappingUserStringSize;
  1719. LPTSTR MappingUserStrings = NULL;
  1720. ULONG MappingTableSize;
  1721. PPACK_MAPPING_RECORD Mappings = NULL;
  1722. ULONG MappingStringSize;
  1723. LPTSTR MappingStrings = NULL;
  1724. MAPPING_FILE_HEADER FileHeader;
  1725. DWORD BytesWritten;
  1726. #if DBG
  1727. if (TraceFlags & (TRACE_FUNCTION_TRACE | TRACE_DATABASE))
  1728. dprintf(TEXT("LLS TRACE: MappingListSave\n"));
  1729. #endif
  1730. RtlEnterCriticalSection(&MappingFileLock);
  1731. RtlAcquireResourceExclusive(&MappingListLock, TRUE);
  1732. //
  1733. // If nothing to save then get-out
  1734. //
  1735. if (MappingListSize == 0)
  1736. goto MappingListSaveExit;
  1737. //
  1738. // Pack the data
  1739. //
  1740. Status = MappingListPack( &MappingUserTableSize, &MappingUsers, &MappingTableSize, &Mappings );
  1741. if (Status != STATUS_SUCCESS)
  1742. goto MappingListSaveExit;
  1743. //
  1744. // Now pack the String data
  1745. //
  1746. Status = MappingListStringsPack( MappingUserTableSize, MappingUsers,
  1747. &MappingUserStringSize, &MappingUserStrings,
  1748. MappingTableSize, Mappings,
  1749. &MappingStringSize, &MappingStrings );
  1750. if (Status != STATUS_SUCCESS)
  1751. goto MappingListSaveExit;
  1752. //
  1753. // Fill out the file header - sizes are byte sizes
  1754. //
  1755. FileHeader.MappingUserTableSize = MappingUserTableSize * sizeof(PACK_MAPPING_USER_RECORD);
  1756. FileHeader.MappingUserStringSize = MappingUserStringSize * sizeof(TCHAR);
  1757. FileHeader.MappingTableSize = MappingTableSize * sizeof(PACK_MAPPING_RECORD);
  1758. FileHeader.MappingStringSize = MappingStringSize * sizeof(TCHAR);
  1759. //
  1760. // Encrypt the data before saving it out.
  1761. //
  1762. Status = EBlock(MappingUsers, FileHeader.MappingUserTableSize);
  1763. if (Status == STATUS_SUCCESS)
  1764. Status = EBlock(MappingUserStrings, FileHeader.MappingUserStringSize);
  1765. if (Status == STATUS_SUCCESS)
  1766. Status = EBlock(Mappings, FileHeader.MappingTableSize);
  1767. if (Status == STATUS_SUCCESS)
  1768. Status = EBlock(MappingStrings, FileHeader.MappingStringSize);
  1769. if (Status != STATUS_SUCCESS)
  1770. goto MappingListSaveExit;
  1771. //
  1772. // Save out the header record
  1773. //
  1774. hFile = LlsFileInit(MappingFileName, MAPPING_FILE_VERSION, sizeof(MAPPING_FILE_HEADER) );
  1775. if (hFile == NULL) {
  1776. Status = GetLastError();
  1777. goto MappingListSaveExit;
  1778. }
  1779. //
  1780. // Now write out all the data blocks
  1781. //
  1782. ret = WriteFile(hFile, &FileHeader, sizeof(MAPPING_FILE_HEADER), &BytesWritten, NULL);
  1783. if (ret && (MappingUsers != NULL) && (FileHeader.MappingUserTableSize != 0))
  1784. ret = WriteFile(hFile, MappingUsers, FileHeader.MappingUserTableSize, &BytesWritten, NULL);
  1785. if (ret && (MappingUserStrings != NULL) && (FileHeader.MappingUserStringSize != 0))
  1786. ret = WriteFile(hFile, MappingUserStrings, FileHeader.MappingUserStringSize, &BytesWritten, NULL);
  1787. if (ret && (Mappings != NULL) && (FileHeader.MappingTableSize != 0))
  1788. ret = WriteFile(hFile, Mappings, FileHeader.MappingTableSize, &BytesWritten, NULL);
  1789. if (ret && (MappingStrings != NULL) && (FileHeader.MappingStringSize != 0))
  1790. ret = WriteFile(hFile, MappingStrings, FileHeader.MappingStringSize, &BytesWritten, NULL);
  1791. if (!ret)
  1792. Status = GetLastError();
  1793. MappingListSaveExit:
  1794. RtlReleaseResource(&MappingListLock);
  1795. if (hFile != NULL)
  1796. CloseHandle(hFile);
  1797. RtlLeaveCriticalSection(&MappingFileLock);
  1798. //
  1799. // Run through our tables and clean them up
  1800. //
  1801. if (MappingUsers != NULL)
  1802. MIDL_user_free(MappingUsers);
  1803. if (MappingUserStrings != NULL)
  1804. MIDL_user_free(MappingUserStrings);
  1805. if (Mappings != NULL)
  1806. MIDL_user_free(Mappings);
  1807. if (MappingStrings != NULL)
  1808. MIDL_user_free(MappingStrings);
  1809. //
  1810. // If there was an error log it.
  1811. //
  1812. if (Status != STATUS_SUCCESS)
  1813. LogEvent(LLS_EVENT_SAVE_MAPPING, 0, NULL, Status);
  1814. return Status;
  1815. } // MappingListSave
  1816. /////////////////////////////////////////////////////////////////////////
  1817. // User List
  1818. //
  1819. /////////////////////////////////////////////////////////////////////////
  1820. NTSTATUS
  1821. UserListPack (
  1822. DWORD LastReplicated,
  1823. ULONG UserLevel,
  1824. ULONG *pUserTableSize,
  1825. LPVOID *pUsers
  1826. )
  1827. /*++
  1828. Routine Description:
  1829. Arguments:
  1830. Return Value:
  1831. --*/
  1832. {
  1833. NTSTATUS Status = STATUS_SUCCESS;
  1834. LPVOID Users = NULL;
  1835. ULONG i, j, k;
  1836. ULONG TotalRecords = 0;
  1837. PUSER_RECORD pUser;
  1838. #if DBG
  1839. if (TraceFlags & TRACE_FUNCTION_TRACE)
  1840. dprintf(TEXT("LLS TRACE: UserListPack\n"));
  1841. #endif
  1842. ASSERT(pUsers != NULL);
  1843. ASSERT(pUserTableSize != NULL);
  1844. *pUsers = NULL;
  1845. *pUserTableSize = 0;
  1846. //
  1847. // Now walk our tree and figure out how many records we must send.
  1848. //
  1849. i = 0;
  1850. TotalRecords = 0;
  1851. while (i < UserListNumEntries) {
  1852. pUser = LLSGetElementGenericTable(&UserList, i);
  1853. if (pUser != NULL) {
  1854. //
  1855. // Walk each service under each user
  1856. //
  1857. RtlEnterCriticalSection(&pUser->ServiceTableLock);
  1858. for (j = 0; j < pUser->ServiceTableSize; j++)
  1859. if ( (pUser->Services[j].AccessCount > 0) || (pUser->Services[j].LastAccess > LastReplicated) )
  1860. TotalRecords++;
  1861. RtlLeaveCriticalSection(&pUser->ServiceTableLock);
  1862. }
  1863. i++;
  1864. }
  1865. #if DBG
  1866. if (TraceFlags & TRACE_REPLICATION)
  1867. dprintf(TEXT(" LLS Packing %lu User Records\n"), TotalRecords);
  1868. #endif
  1869. //
  1870. // Make sure there is anything to replicate
  1871. //
  1872. if (TotalRecords > 0) {
  1873. //
  1874. // Create our buffer to hold all of the garbage
  1875. //
  1876. Users = MIDL_user_allocate(TotalRecords * ( UserLevel ? sizeof(REPL_USER_RECORD_1)
  1877. : sizeof(REPL_USER_RECORD_0) ) );
  1878. if (Users == NULL) {
  1879. ASSERT(FALSE);
  1880. return STATUS_NO_MEMORY;
  1881. }
  1882. //
  1883. // Fill in the buffer - walk the user tree
  1884. //
  1885. i = 0;
  1886. j = 0;
  1887. while ((i < UserListNumEntries) && (j < TotalRecords)) {
  1888. pUser = LLSGetElementGenericTable(&UserList, i);
  1889. if (pUser != NULL) {
  1890. //
  1891. // Walk each service under each user
  1892. //
  1893. k = 0;
  1894. RtlEnterCriticalSection(&pUser->ServiceTableLock);
  1895. while (k < pUser->ServiceTableSize) {
  1896. if ( (pUser->Services[k].AccessCount > 0) || (pUser->Services[k].LastAccess > LastReplicated) ) {
  1897. if ( 0 == UserLevel )
  1898. {
  1899. ((PREPL_USER_RECORD_0)Users)[j].Name = pUser->UserID;
  1900. ((PREPL_USER_RECORD_0)Users)[j].Service = pUser->Services[k].Service->Index;
  1901. ((PREPL_USER_RECORD_0)Users)[j].AccessCount = pUser->Services[k].AccessCount;
  1902. ((PREPL_USER_RECORD_0)Users)[j].LastAccess = pUser->Services[k].LastAccess;
  1903. }
  1904. else
  1905. {
  1906. ((PREPL_USER_RECORD_1)Users)[j].Name = pUser->UserID;
  1907. ((PREPL_USER_RECORD_1)Users)[j].Service = pUser->Services[k].Service->Index;
  1908. ((PREPL_USER_RECORD_1)Users)[j].AccessCount = pUser->Services[k].AccessCount;
  1909. ((PREPL_USER_RECORD_1)Users)[j].LastAccess = pUser->Services[k].LastAccess;
  1910. ((PREPL_USER_RECORD_1)Users)[j].Flags = pUser->Flags;
  1911. }
  1912. //
  1913. // Reset access count so we don't increment forever
  1914. //
  1915. if (LastReplicated != 0)
  1916. pUser->Services[k].AccessCount = 0;
  1917. j++;
  1918. }
  1919. k++;
  1920. }
  1921. RtlLeaveCriticalSection(&pUser->ServiceTableLock);
  1922. }
  1923. i++;
  1924. }
  1925. } // User Records
  1926. #if DBG
  1927. if (TraceFlags & TRACE_REPLICATION)
  1928. dprintf(TEXT("UserListPack: [%lu]\n"), TotalRecords);
  1929. #endif
  1930. *pUsers = Users;
  1931. *pUserTableSize = TotalRecords;
  1932. return Status;
  1933. } // UserListPack
  1934. /////////////////////////////////////////////////////////////////////////
  1935. VOID
  1936. UserListUnpack (
  1937. ULONG ServiceTableSize,
  1938. PREPL_SERVICE_RECORD Services,
  1939. ULONG ServerTableSize,
  1940. PREPL_SERVER_RECORD Servers,
  1941. ULONG ServerServiceTableSize,
  1942. PREPL_SERVER_SERVICE_RECORD ServerServices,
  1943. ULONG UserLevel,
  1944. ULONG UserTableSize,
  1945. LPVOID Users
  1946. )
  1947. /*++
  1948. Routine Description:
  1949. Arguments:
  1950. Return Value:
  1951. --*/
  1952. {
  1953. NTSTATUS Status = STATUS_SUCCESS;
  1954. ULONG i;
  1955. PREPL_USER_RECORD_0 pReplUser0 = NULL;
  1956. PREPL_USER_RECORD_1 pReplUser1 = NULL;
  1957. PADD_CACHE pAdd = NULL;
  1958. PADD_CACHE tAdd = NULL;
  1959. PADD_CACHE lAdd = NULL;
  1960. ULONG CacheSize = 0;
  1961. ULONG DataLength;
  1962. LPTSTR NewName;
  1963. HRESULT hr;
  1964. UNREFERENCED_PARAMETER(ServiceTableSize);
  1965. UNREFERENCED_PARAMETER(ServerTableSize);
  1966. UNREFERENCED_PARAMETER(Servers);
  1967. UNREFERENCED_PARAMETER(ServerServiceTableSize);
  1968. UNREFERENCED_PARAMETER(ServerServices);
  1969. #if DBG
  1970. if (TraceFlags & (TRACE_REPLICATION | TRACE_FUNCTION_TRACE))
  1971. dprintf(TEXT("UserListUnpack: [%lu]\n"), UserTableSize);
  1972. #endif
  1973. //
  1974. // Walk User table. First fixup service pointers to our local service
  1975. // table. Next create a big add cache list to dump onto our add-cache
  1976. // queue.
  1977. //
  1978. for (i = 0; i < UserTableSize; i++) {
  1979. //
  1980. // Update Index
  1981. //
  1982. if ( 0 == UserLevel )
  1983. {
  1984. pReplUser0 = &( (PREPL_USER_RECORD_0) Users)[i];
  1985. pReplUser0->Service = Services[pReplUser0->Service].Index;
  1986. //
  1987. // Validate the user name.
  1988. //
  1989. // NB : Strange this code is necessary, but occasionally the names
  1990. // received via replication are invalid. Maintain this code
  1991. // for safety until the original problem is completely fixed.
  1992. //
  1993. if (!ValidateDN(pReplUser0->Name))
  1994. {
  1995. //
  1996. // TBD : Log event noting rejected name.
  1997. //
  1998. #if DBG
  1999. dprintf(TEXT("LS: Rejecting invalid user name = \"%s\"\n"),
  2000. pReplUser0->Name);
  2001. #endif
  2002. continue;
  2003. }
  2004. }
  2005. else
  2006. {
  2007. pReplUser1 = &( (PREPL_USER_RECORD_1) Users)[i];
  2008. pReplUser1->Service = Services[pReplUser1->Service].Index;
  2009. //
  2010. // Validate the user name.
  2011. //
  2012. // NB : Strange this code is necessary, but occasionally the names
  2013. // received via replication are invalid. Maintain this code
  2014. // for safety until the original problem is completely fixed.
  2015. //
  2016. if (!ValidateDN(pReplUser1->Name))
  2017. {
  2018. //
  2019. // TBD : Log event noting rejected name.
  2020. //
  2021. #if DBG
  2022. dprintf(TEXT("LS: Rejecting invalid user name = \"%s\"\n"),
  2023. pReplUser1->Name);
  2024. #endif
  2025. continue;
  2026. }
  2027. }
  2028. //
  2029. // Now create Add Cache object
  2030. //
  2031. tAdd = LocalAlloc(LPTR, sizeof(ADD_CACHE));
  2032. if (tAdd != NULL) {
  2033. if ( 0 == UserLevel )
  2034. {
  2035. DataLength = (lstrlen(pReplUser0->Name) + 1) * sizeof(TCHAR);
  2036. }
  2037. else
  2038. {
  2039. DataLength = (lstrlen(pReplUser1->Name) + 1) * sizeof(TCHAR);
  2040. }
  2041. NewName = LocalAlloc( LPTR, DataLength);
  2042. if (NewName == NULL) {
  2043. LocalFree(tAdd);
  2044. ASSERT(FALSE);
  2045. } else {
  2046. tAdd->Data = NewName;
  2047. tAdd->DataType = DATA_TYPE_USERNAME;
  2048. tAdd->DataLength = DataLength;
  2049. if ( 0 == UserLevel )
  2050. {
  2051. hr = StringCbCopy( NewName, DataLength, pReplUser0->Name );
  2052. ASSERT(SUCCEEDED(hr));
  2053. tAdd->AccessCount = pReplUser0->AccessCount;
  2054. tAdd->LastAccess = pReplUser0->LastAccess;
  2055. tAdd->Flags = LLS_FLAG_SUITE_AUTO;
  2056. RtlAcquireResourceShared(&MasterServiceListLock, TRUE);
  2057. tAdd->Service = MasterServiceTable[pReplUser0->Service];
  2058. RtlReleaseResource(&MasterServiceListLock);
  2059. }
  2060. else
  2061. {
  2062. hr = StringCbCopy( NewName, DataLength, pReplUser1->Name );
  2063. ASSERT(SUCCEEDED(hr));
  2064. tAdd->AccessCount = pReplUser1->AccessCount;
  2065. tAdd->LastAccess = pReplUser1->LastAccess;
  2066. tAdd->Flags = pReplUser1->Flags & ( LLS_FLAG_SUITE_USE | LLS_FLAG_SUITE_AUTO );
  2067. RtlAcquireResourceShared(&MasterServiceListLock, TRUE);
  2068. tAdd->Service = MasterServiceTable[pReplUser1->Service];
  2069. RtlReleaseResource(&MasterServiceListLock);
  2070. }
  2071. //
  2072. // Now add it to our cache
  2073. //
  2074. tAdd->prev = pAdd;
  2075. pAdd = tAdd;
  2076. //
  2077. // Keep track of first on (bottom on stack) so we can append
  2078. // it onto the real add cache.
  2079. //
  2080. if (lAdd == NULL)
  2081. lAdd = pAdd;
  2082. CacheSize++;
  2083. }
  2084. } else {
  2085. ASSERT(FALSE);
  2086. }
  2087. if (i % 100 == 0) ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, NSERVICEWAITHINT);
  2088. }
  2089. //
  2090. // Now that we've walked through all the users - update the actual
  2091. // Add Cache.
  2092. //
  2093. if (pAdd != NULL) {
  2094. RtlEnterCriticalSection(&AddCacheLock);
  2095. lAdd->prev = AddCache;
  2096. AddCache = pAdd;
  2097. AddCacheSize += CacheSize;
  2098. RtlLeaveCriticalSection(&AddCacheLock);
  2099. //
  2100. // Now must signal the event so we can pull off the new record.
  2101. //
  2102. Status = NtSetEvent( LLSAddCacheEvent, NULL );
  2103. ASSERT(NT_SUCCESS(Status));
  2104. }
  2105. } // UserListUnpack
  2106. //
  2107. // Illegal user/domain characters.
  2108. //
  2109. #define CTRL_CHARS_0 TEXT( "\001\002\003\004\005\006\007")
  2110. #define CTRL_CHARS_1 TEXT("\010\011\012\013\014\015\016\017")
  2111. #define CTRL_CHARS_2 TEXT("\020\021\022\023\024\025\026\027")
  2112. #define CTRL_CHARS_3 TEXT("\030\031\032\033\034\035\036\037")
  2113. #define CTRL_CHARS_STR CTRL_CHARS_0 CTRL_CHARS_1 CTRL_CHARS_2 CTRL_CHARS_3
  2114. #define ILLEGAL_NAME_CHARS_STR TEXT("\"/\\[]:|<>+=;,?") CTRL_CHARS_STR
  2115. static const TCHAR szUserIllegalChars[] = ILLEGAL_NAME_CHARS_STR TEXT("*");
  2116. static const TCHAR szDomainIllegalChars[] = ILLEGAL_NAME_CHARS_STR TEXT("*") TEXT(" ");
  2117. /////////////////////////////////////////////////////////////////////////
  2118. BOOL
  2119. ValidateDN (
  2120. LPTSTR pszDN
  2121. )
  2122. /*++
  2123. Routine Description:
  2124. Arguments:
  2125. Return Value:
  2126. --*/
  2127. {
  2128. //
  2129. // NB : This code understands only NT4 usernames at present.
  2130. //
  2131. TCHAR szDN[MAX_USERNAME_LENGTH + MAX_DOMAINNAME_LENGTH + 2];
  2132. LPTSTR pszUserName;
  2133. LPTSTR pszDomainName;
  2134. LPTSTR pszBSlash;
  2135. SIZE_T ccUserNameLength;
  2136. SIZE_T ccDomainNameLength;
  2137. if (pszDN == NULL || !*pszDN) {
  2138. return FALSE;
  2139. }
  2140. //
  2141. // Use a local buffer for character replacement during check.
  2142. //
  2143. if (lstrlen(pszDN) < (MAX_USERNAME_LENGTH + MAX_DOMAINNAME_LENGTH + 2)) {
  2144. lstrcpyn(szDN, pszDN, MAX_USERNAME_LENGTH + MAX_DOMAINNAME_LENGTH + 2);
  2145. }
  2146. else {
  2147. return FALSE;
  2148. }
  2149. pszBSlash = STRRCHR(szDN, TEXT('\\'));
  2150. if (pszBSlash == NULL) {
  2151. return FALSE;
  2152. }
  2153. //
  2154. // Isolate user/domain names.
  2155. //
  2156. *pszBSlash = TEXT('\0');
  2157. pszUserName = pszBSlash + 1;
  2158. pszDomainName = szDN;
  2159. ccUserNameLength = lstrlen(pszUserName);
  2160. ccDomainNameLength = pszBSlash - pszDomainName;
  2161. //
  2162. // Check user/domain name length and the existence of invalid chars.
  2163. //
  2164. if (ccUserNameLength && ccUserNameLength <= MAX_USERNAME_LENGTH) {
  2165. if (STRCSPN(pszUserName, szUserIllegalChars) == ccUserNameLength) {
  2166. if (ccDomainNameLength <= MAX_DOMAINNAME_LENGTH) {
  2167. if (STRCSPN(pszDomainName,
  2168. szDomainIllegalChars) == ccDomainNameLength) {
  2169. return TRUE;
  2170. }
  2171. }
  2172. }
  2173. }
  2174. return FALSE;
  2175. }
  2176. /////////////////////////////////////////////////////////////////////////
  2177. NTSTATUS
  2178. UserListStringsPack (
  2179. ULONG UserLevel,
  2180. ULONG UserTableSize,
  2181. LPVOID Users,
  2182. ULONG *pUserStringSize,
  2183. LPTSTR *pUserStrings
  2184. )
  2185. /*++
  2186. Routine Description:
  2187. Arguments:
  2188. Return Value:
  2189. --*/
  2190. {
  2191. NTSTATUS Status = STATUS_SUCCESS;
  2192. ULONG i;
  2193. ULONG StringSize;
  2194. LPTSTR UserStrings = NULL;
  2195. TCHAR *pStr;
  2196. HRESULT hr;
  2197. #if DBG
  2198. if (TraceFlags & TRACE_FUNCTION_TRACE)
  2199. dprintf(TEXT("UserListStringsPack\n"));
  2200. #endif
  2201. ASSERT(pUserStrings != NULL);
  2202. ASSERT(pUserStringSize != NULL);
  2203. *pUserStrings = NULL;
  2204. *pUserStringSize = 0;
  2205. //
  2206. // First walk the list adding up string sizes - to calculate our buff size
  2207. //
  2208. StringSize = 0;
  2209. for (i = 0; i < UserTableSize; i++) {
  2210. if ( 0 == UserLevel )
  2211. {
  2212. StringSize += 1 + lstrlen( ((PREPL_USER_RECORD_0) Users)[i].Name );
  2213. }
  2214. else
  2215. {
  2216. StringSize += 1 + lstrlen( ((PREPL_USER_RECORD_1) Users)[i].Name );
  2217. }
  2218. }
  2219. //
  2220. // Make sure there is anything to replicate
  2221. //
  2222. if (StringSize > 0) {
  2223. //
  2224. // Create our buffer to hold all of the garbage
  2225. //
  2226. UserStrings = MIDL_user_allocate(StringSize * sizeof(TCHAR));
  2227. if (UserStrings == NULL) {
  2228. ASSERT(FALSE);
  2229. return STATUS_NO_MEMORY;
  2230. }
  2231. //
  2232. // Fill in the buffer
  2233. //
  2234. pStr = UserStrings;
  2235. for (i = 0; i < UserTableSize; i++) {
  2236. if ( 0 == UserLevel )
  2237. {
  2238. hr = StringCchCopy( pStr, StringSize, ((PREPL_USER_RECORD_0) Users)[i].Name );
  2239. ASSERT(SUCCEEDED(hr));
  2240. }
  2241. else
  2242. {
  2243. hr = StringCchCopy( pStr, StringSize, ((PREPL_USER_RECORD_1) Users)[i].Name );
  2244. ASSERT(SUCCEEDED(hr));
  2245. }
  2246. pStr += 1 + lstrlen( pStr );
  2247. }
  2248. }
  2249. *pUserStrings = UserStrings;
  2250. *pUserStringSize = StringSize;
  2251. return Status;
  2252. } // UserListStringsPack
  2253. /////////////////////////////////////////////////////////////////////////
  2254. VOID
  2255. UserListStringsUnpack (
  2256. ULONG UserLevel,
  2257. ULONG UserTableSize,
  2258. LPVOID Users,
  2259. ULONG UserStringSize,
  2260. LPTSTR UserStrings
  2261. )
  2262. /*++
  2263. Routine Description:
  2264. Arguments:
  2265. Return Value:
  2266. --*/
  2267. {
  2268. ULONG i;
  2269. TCHAR *pStr;
  2270. UNREFERENCED_PARAMETER(UserStringSize);
  2271. #if DBG
  2272. if (TraceFlags & TRACE_FUNCTION_TRACE)
  2273. dprintf(TEXT("UserListStringsUnpack\n"));
  2274. #endif
  2275. pStr = UserStrings;
  2276. for (i = 0; i < UserTableSize; i++) {
  2277. if ( 0 == UserLevel )
  2278. {
  2279. ((PREPL_USER_RECORD_0) Users)[i].Name = pStr;
  2280. }
  2281. else
  2282. {
  2283. ((PREPL_USER_RECORD_1) Users)[i].Name = pStr;
  2284. }
  2285. //
  2286. // Move to end of current string
  2287. //
  2288. while (*pStr != TEXT('\0'))
  2289. pStr++;
  2290. // now go past ending NULL
  2291. pStr++;
  2292. }
  2293. } // UserListStringsUnpack
  2294. /////////////////////////////////////////////////////////////////////////
  2295. // Service List
  2296. //
  2297. /////////////////////////////////////////////////////////////////////////
  2298. NTSTATUS
  2299. ServiceListPack (
  2300. ULONG *pServiceTableSize,
  2301. PREPL_SERVICE_RECORD *pServices
  2302. )
  2303. /*++
  2304. Routine Description:
  2305. Arguments:
  2306. Return Value:
  2307. --*/
  2308. {
  2309. NTSTATUS Status = STATUS_SUCCESS;
  2310. PREPL_SERVICE_RECORD Services = NULL;
  2311. ULONG i;
  2312. ULONG TotalRecords = 0;
  2313. PMASTER_SERVICE_RECORD pService;
  2314. #if DBG
  2315. if (TraceFlags & TRACE_FUNCTION_TRACE)
  2316. dprintf(TEXT("LLS TRACE: ServiceListPack\n"));
  2317. #endif
  2318. ASSERT(pServices != NULL);
  2319. ASSERT(pServiceTableSize != NULL);
  2320. *pServices = NULL;
  2321. *pServiceTableSize = 0;
  2322. TotalRecords = MasterServiceListSize;
  2323. //
  2324. // Make sure there is anything to replicate
  2325. //
  2326. if (TotalRecords > 0) {
  2327. //
  2328. // Create our buffer to hold all of the garbage
  2329. //
  2330. Services = MIDL_user_allocate(TotalRecords * sizeof(REPL_SERVICE_RECORD));
  2331. if (Services == NULL) {
  2332. ASSERT(FALSE);
  2333. return STATUS_NO_MEMORY;
  2334. }
  2335. //
  2336. // Fill in the buffer - walk the user tree
  2337. //
  2338. for (i = 0; i < MasterServiceListSize; i++) {
  2339. pService = MasterServiceTable[i];
  2340. Services[i].Name = pService->Name;
  2341. Services[i].FamilyName = pService->Family->Name;
  2342. Services[i].Version = pService->Version;
  2343. Services[i].Index = pService->Index;
  2344. }
  2345. }
  2346. #if DBG
  2347. if (TraceFlags & TRACE_REPLICATION)
  2348. dprintf(TEXT("ServiceListPack: [%lu]\n"), TotalRecords);
  2349. #endif
  2350. *pServices = Services;
  2351. *pServiceTableSize = TotalRecords;
  2352. return Status;
  2353. } // ServiceListPack
  2354. /////////////////////////////////////////////////////////////////////////
  2355. VOID
  2356. ServiceListUnpack (
  2357. ULONG ServiceTableSize,
  2358. PREPL_SERVICE_RECORD Services,
  2359. ULONG ServerTableSize,
  2360. PREPL_SERVER_RECORD Servers,
  2361. ULONG ServerServiceTableSize,
  2362. PREPL_SERVER_SERVICE_RECORD ServerServices
  2363. )
  2364. /*++
  2365. Routine Description:
  2366. Arguments:
  2367. Return Value:
  2368. --*/
  2369. {
  2370. ULONG i, j;
  2371. PMASTER_SERVICE_RECORD pService;
  2372. PREPL_SERVICE_RECORD pSvc;
  2373. UNREFERENCED_PARAMETER(ServerTableSize);
  2374. UNREFERENCED_PARAMETER(Servers);
  2375. UNREFERENCED_PARAMETER(ServerServiceTableSize);
  2376. UNREFERENCED_PARAMETER(ServerServices);
  2377. #if DBG
  2378. if (TraceFlags & (TRACE_REPLICATION | TRACE_FUNCTION_TRACE))
  2379. dprintf(TEXT("ServiceListUnpack: [%lu]\n"), ServiceTableSize);
  2380. #endif
  2381. //
  2382. // Walk services table, adding any new services to our local table.
  2383. // Fix up the index pointers to match our local services.
  2384. //
  2385. RtlAcquireResourceExclusive(&MasterServiceListLock, TRUE);
  2386. for (i = 0; i < ServiceTableSize; i++) {
  2387. pSvc = &Services[i];
  2388. pService = MasterServiceListAdd(pSvc->FamilyName, pSvc->Name, pSvc->Version );
  2389. if (pService != NULL) {
  2390. pSvc->Index = pService->Index;
  2391. //
  2392. // In case this got added from the local service list table and we
  2393. // didn't have a version # yet.
  2394. //
  2395. if ( (pService->Version == 0) && (pSvc->Version != 0) ) {
  2396. PMASTER_SERVICE_ROOT ServiceRoot = NULL;
  2397. //
  2398. // Fixup next pointer chain
  2399. //
  2400. ServiceRoot = pService->Family;
  2401. j = 0;
  2402. while ((j < ServiceRoot->ServiceTableSize) && (MasterServiceTable[ServiceRoot->Services[j]]->Version < pSvc->Version))
  2403. j++;
  2404. pService->next = 0;
  2405. pService->Version = pSvc->Version;
  2406. if (j > 0) {
  2407. if (MasterServiceTable[ServiceRoot->Services[j - 1]]->next == pService->Index + 1)
  2408. pService->next = 0;
  2409. else
  2410. pService->next = MasterServiceTable[ServiceRoot->Services[j - 1]]->next;
  2411. if (MasterServiceTable[ServiceRoot->Services[j - 1]] != pService)
  2412. MasterServiceTable[ServiceRoot->Services[j - 1]]->next = pService->Index + 1;
  2413. }
  2414. // Resort it in order of the versions
  2415. qsort((void *) ServiceRoot->Services, (size_t) ServiceRoot->ServiceTableSize, sizeof(ULONG), MServiceRecordCompare);
  2416. }
  2417. } else {
  2418. ASSERT(FALSE);
  2419. pSvc->Index = 0;
  2420. }
  2421. if (i % 100 == 0) ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, NSERVICEWAITHINT);
  2422. }
  2423. RtlReleaseResource(&MasterServiceListLock);
  2424. } // ServiceListUnpack
  2425. /////////////////////////////////////////////////////////////////////////
  2426. NTSTATUS
  2427. ServiceListStringsPack (
  2428. ULONG ServiceTableSize,
  2429. PREPL_SERVICE_RECORD Services,
  2430. ULONG *pServiceStringSize,
  2431. LPTSTR *pServiceStrings
  2432. )
  2433. /*++
  2434. Routine Description:
  2435. Arguments:
  2436. Return Value:
  2437. --*/
  2438. {
  2439. NTSTATUS Status = STATUS_SUCCESS;
  2440. ULONG i;
  2441. ULONG StringSize;
  2442. PREPL_SERVICE_RECORD pService;
  2443. LPTSTR ServiceStrings = NULL;
  2444. TCHAR *pStr;
  2445. HRESULT hr;
  2446. #if DBG
  2447. if (TraceFlags & TRACE_FUNCTION_TRACE)
  2448. dprintf(TEXT("ServiceListStringsPack\n"));
  2449. #endif
  2450. ASSERT(pServiceStrings != NULL);
  2451. ASSERT(pServiceStringSize != NULL);
  2452. *pServiceStrings = NULL;
  2453. *pServiceStringSize = 0;
  2454. //
  2455. // First walk the list adding up string sizes - to calculate our buff size
  2456. //
  2457. StringSize = 0;
  2458. for (i = 0; i < ServiceTableSize; i++) {
  2459. pService = &Services[i];
  2460. StringSize = StringSize + lstrlen(pService->Name) + 1;
  2461. StringSize = StringSize + lstrlen(pService->FamilyName) + 1;
  2462. }
  2463. //
  2464. // Make sure there is anything to replicate
  2465. //
  2466. if (StringSize > 0) {
  2467. //
  2468. // Create our buffer to hold all of the garbage
  2469. //
  2470. ServiceStrings = MIDL_user_allocate(StringSize * sizeof(TCHAR));
  2471. if (ServiceStrings == NULL) {
  2472. ASSERT(FALSE);
  2473. return STATUS_NO_MEMORY;
  2474. }
  2475. //
  2476. // Fill in the buffer
  2477. //
  2478. pStr = ServiceStrings;
  2479. for (i = 0; i < ServiceTableSize; i++) {
  2480. pService = &Services[i];
  2481. hr = StringCchCopy(pStr, StringSize, pService->Name);
  2482. ASSERT(SUCCEEDED(hr));
  2483. pStr = &pStr[lstrlen(pService->Name) + 1];
  2484. hr = StringCchCopy(pStr, StringSize, pService->FamilyName);
  2485. ASSERT(SUCCEEDED(hr));
  2486. pStr = &pStr[lstrlen(pService->FamilyName) + 1];
  2487. }
  2488. }
  2489. *pServiceStrings = ServiceStrings;
  2490. *pServiceStringSize = StringSize;
  2491. return Status;
  2492. } // ServiceListStringsPack
  2493. /////////////////////////////////////////////////////////////////////////
  2494. VOID
  2495. ServiceListStringsUnpack (
  2496. ULONG ServiceTableSize,
  2497. PREPL_SERVICE_RECORD Services,
  2498. ULONG ServiceStringSize,
  2499. LPTSTR ServiceStrings
  2500. )
  2501. /*++
  2502. Routine Description:
  2503. Arguments:
  2504. Return Value:
  2505. --*/
  2506. {
  2507. ULONG i;
  2508. PREPL_SERVICE_RECORD pService;
  2509. TCHAR *pStr;
  2510. UNREFERENCED_PARAMETER(ServiceStringSize);
  2511. #if DBG
  2512. if (TraceFlags & TRACE_FUNCTION_TRACE)
  2513. dprintf(TEXT("ServiceListStringsUnpack\n"));
  2514. #endif
  2515. pStr = ServiceStrings;
  2516. for (i = 0; i < ServiceTableSize; i++) {
  2517. pService = &Services[i];
  2518. pService->Name = pStr;
  2519. //
  2520. // Move to end of current string
  2521. //
  2522. while (*pStr != TEXT('\0'))
  2523. pStr++;
  2524. // now go past ending NULL
  2525. pStr++;
  2526. pService->FamilyName = pStr;
  2527. //
  2528. // Move to end of current string
  2529. //
  2530. while (*pStr != TEXT('\0'))
  2531. pStr++;
  2532. // now go past ending NULL
  2533. pStr++;
  2534. }
  2535. } // ServiceListStringsUnpack
  2536. /////////////////////////////////////////////////////////////////////////
  2537. // Server List
  2538. //
  2539. /////////////////////////////////////////////////////////////////////////
  2540. NTSTATUS
  2541. ServerListPack (
  2542. ULONG *pServerTableSize,
  2543. PREPL_SERVER_RECORD *pServers
  2544. )
  2545. /*++
  2546. Routine Description:
  2547. Arguments:
  2548. Return Value:
  2549. --*/
  2550. {
  2551. NTSTATUS Status = STATUS_SUCCESS;
  2552. PREPL_SERVER_RECORD Servers = NULL;
  2553. ULONG i;
  2554. ULONG TotalRecords = 0;
  2555. PSERVER_RECORD pServer;
  2556. #if DBG
  2557. if (TraceFlags & TRACE_FUNCTION_TRACE)
  2558. dprintf(TEXT("LLS TRACE: ServerListPack\n"));
  2559. #endif
  2560. ASSERT(pServers != NULL);
  2561. ASSERT(pServerTableSize != NULL);
  2562. *pServers = NULL;
  2563. *pServerTableSize = 0;
  2564. TotalRecords = ServerListSize;
  2565. //
  2566. // Make sure there is anything to replicate
  2567. //
  2568. if (TotalRecords > 0) {
  2569. //
  2570. // Create our buffer to hold all of the garbage
  2571. //
  2572. Servers = MIDL_user_allocate(TotalRecords * sizeof(REPL_SERVER_RECORD));
  2573. if (Servers == NULL) {
  2574. ASSERT(FALSE);
  2575. return STATUS_NO_MEMORY;
  2576. }
  2577. //
  2578. // Fill in the buffer - walk the user tree
  2579. //
  2580. for (i = 0; i < ServerListSize; i++) {
  2581. pServer = ServerTable[i];
  2582. Servers[i].Name = pServer->Name;
  2583. Servers[i].MasterServer = pServer->MasterServer;
  2584. Servers[i].Index = pServer->Index;
  2585. }
  2586. }
  2587. #if DBG
  2588. if (TraceFlags & TRACE_REPLICATION)
  2589. dprintf(TEXT("ServerListPack: [%lu]\n"), TotalRecords);
  2590. #endif
  2591. *pServers = Servers;;
  2592. *pServerTableSize = TotalRecords;
  2593. return Status;
  2594. } // ServerListPack
  2595. /////////////////////////////////////////////////////////////////////////
  2596. VOID
  2597. ServerListUnpack (
  2598. ULONG ServiceTableSize,
  2599. PREPL_SERVICE_RECORD Services,
  2600. ULONG ServerTableSize,
  2601. PREPL_SERVER_RECORD Servers,
  2602. ULONG ServerServiceTableSize,
  2603. PREPL_SERVER_SERVICE_RECORD ServerServices
  2604. )
  2605. /*++
  2606. Routine Description:
  2607. Arguments:
  2608. Return Value:
  2609. --*/
  2610. {
  2611. ULONG i;
  2612. PSERVER_RECORD pServer;
  2613. PREPL_SERVER_RECORD pSrv;
  2614. TCHAR ComputerName[MAX_COMPUTERNAME_LENGTH + 1];
  2615. HRESULT hr;
  2616. UNREFERENCED_PARAMETER(ServiceTableSize);
  2617. UNREFERENCED_PARAMETER(Services);
  2618. UNREFERENCED_PARAMETER(ServerServiceTableSize);
  2619. UNREFERENCED_PARAMETER(ServerServices);
  2620. #if DBG
  2621. if (TraceFlags & (TRACE_REPLICATION | TRACE_FUNCTION_TRACE))
  2622. dprintf(TEXT("ServerListUnpack: [%lu]\n"), ServerTableSize);
  2623. #endif
  2624. ComputerName[0] = 0;
  2625. //
  2626. // Walk server table, adding any new servers to our local table.
  2627. // Fix up the index pointers to match our local table and re-fix
  2628. // Service table pointers.
  2629. //
  2630. RtlEnterCriticalSection(&ConfigInfoLock);
  2631. if (ConfigInfo.ComputerName != NULL)
  2632. {
  2633. hr = StringCbCopy(ComputerName, sizeof(ComputerName), ConfigInfo.ComputerName);
  2634. ASSERT(SUCCEEDED(hr));
  2635. }
  2636. RtlLeaveCriticalSection(&ConfigInfoLock);
  2637. RtlAcquireResourceExclusive(&ServerListLock, TRUE);
  2638. for (i = 0; i < ServerTableSize; i++) {
  2639. pSrv = &Servers[i];
  2640. if (pSrv->MasterServer != 0)
  2641. pServer = ServerListAdd(pSrv->Name, Servers[pSrv->MasterServer - 1].Name);
  2642. else
  2643. pServer = ServerListAdd(pSrv->Name, ComputerName);
  2644. if (pServer != NULL)
  2645. pSrv->Index = pServer->Index;
  2646. else {
  2647. ASSERT(FALSE);
  2648. pSrv->Index = 0;
  2649. }
  2650. if (i % 100 == 0) ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, NSERVICEWAITHINT);
  2651. }
  2652. RtlReleaseResource(&ServerListLock);
  2653. } // ServerListUnpack
  2654. /////////////////////////////////////////////////////////////////////////
  2655. NTSTATUS
  2656. ServerServiceListPack (
  2657. ULONG *pServerServiceTableSize,
  2658. PREPL_SERVER_SERVICE_RECORD *pServerServices
  2659. )
  2660. /*++
  2661. Routine Description:
  2662. Arguments:
  2663. Return Value:
  2664. --*/
  2665. {
  2666. NTSTATUS Status = STATUS_SUCCESS;
  2667. PREPL_SERVER_SERVICE_RECORD ServerServices = NULL;
  2668. ULONG i, j, k;
  2669. ULONG TotalRecords = 0;
  2670. PSERVER_RECORD pServer;
  2671. #if DBG
  2672. if (TraceFlags & TRACE_FUNCTION_TRACE)
  2673. dprintf(TEXT("LLS TRACE: ServerServiceListPack\n"));
  2674. #endif
  2675. ASSERT(pServerServices != NULL);
  2676. ASSERT(pServerServiceTableSize != NULL);
  2677. *pServerServices = NULL;
  2678. *pServerServiceTableSize = 0;
  2679. //
  2680. // Walk the ServerList and find all ServiceRecords
  2681. for (i = 0; i < ServerListSize; i++)
  2682. TotalRecords += ServerTable[i]->ServiceTableSize;
  2683. //
  2684. // Make sure there is anything to replicate
  2685. //
  2686. if (TotalRecords > 0) {
  2687. //
  2688. // Create our buffer to hold all of the garbage
  2689. //
  2690. ServerServices = MIDL_user_allocate(TotalRecords * sizeof(REPL_SERVER_SERVICE_RECORD));
  2691. if (ServerServices == NULL) {
  2692. ASSERT(FALSE);
  2693. return STATUS_NO_MEMORY;
  2694. }
  2695. //
  2696. // Fill in the buffer - walk the user tree
  2697. //
  2698. k = 0;
  2699. for (i = 0; i < ServerListSize; i++) {
  2700. pServer = ServerTable[i];
  2701. for (j = 0; j < pServer->ServiceTableSize; j++) {
  2702. ServerServices[k].Server = pServer->Index;
  2703. ServerServices[k].Service = pServer->Services[j]->Service;
  2704. ServerServices[k].MaxSessionCount = pServer->Services[j]->MaxSessionCount;
  2705. ServerServices[k].MaxSetSessionCount = pServer->Services[j]->MaxSetSessionCount;
  2706. ServerServices[k].HighMark = pServer->Services[j]->HighMark;
  2707. k++;
  2708. }
  2709. }
  2710. }
  2711. #if DBG
  2712. if (TraceFlags & TRACE_REPLICATION)
  2713. dprintf(TEXT("ServerServiceListPack: [%lu]\n"), TotalRecords);
  2714. #endif
  2715. *pServerServices = ServerServices;
  2716. *pServerServiceTableSize = TotalRecords;
  2717. return Status;
  2718. } // ServerServiceListPack
  2719. /////////////////////////////////////////////////////////////////////////
  2720. VOID
  2721. ServerServiceListUnpack (
  2722. ULONG ServiceTableSize,
  2723. PREPL_SERVICE_RECORD Services,
  2724. ULONG ServerTableSize,
  2725. PREPL_SERVER_RECORD Servers,
  2726. ULONG ServerServiceTableSize,
  2727. PREPL_SERVER_SERVICE_RECORD ServerServices
  2728. )
  2729. /*++
  2730. Routine Description:
  2731. Arguments:
  2732. Return Value:
  2733. --*/
  2734. {
  2735. ULONG i;
  2736. PSERVER_RECORD pServer;
  2737. PREPL_SERVER_SERVICE_RECORD pSrv;
  2738. PSERVER_SERVICE_RECORD pService;
  2739. PMASTER_SERVICE_RECORD pMasterService;
  2740. UNREFERENCED_PARAMETER(ServiceTableSize);
  2741. UNREFERENCED_PARAMETER(ServerTableSize);
  2742. #if DBG
  2743. if (TraceFlags & (TRACE_REPLICATION | TRACE_FUNCTION_TRACE))
  2744. dprintf(TEXT("ServerServiceListUnpack: [%lu]\n"), ServerServiceTableSize);
  2745. #endif
  2746. //
  2747. // Walk server table, adding any new servers to our local table.
  2748. // Fix up the index pointers to match our local table and re-fix
  2749. // Service table pointers.
  2750. //
  2751. RtlAcquireResourceExclusive(&ServerListLock, TRUE);
  2752. RtlAcquireResourceShared(&MasterServiceListLock, TRUE);
  2753. for (i = 0; i < ServerServiceTableSize; i++) {
  2754. pSrv = &ServerServices[i];
  2755. pServer = ServerListFind(Servers[pSrv->Server - 1].Name);
  2756. ASSERT(pServer != NULL);
  2757. if (pServer != NULL) {
  2758. BOOL bReplaceValues;
  2759. pService = ServerServiceListFind(Services[pSrv->Service].Name, pServer->ServiceTableSize, pServer->Services);
  2760. bReplaceValues = ( NULL != pService );
  2761. pService = ServerServiceListAdd(Services[pSrv->Service].Name,
  2762. Services[pSrv->Service].Index,
  2763. &pServer->ServiceTableSize,
  2764. &pServer->Services);
  2765. ASSERT(pService != NULL);
  2766. if (pService != NULL)
  2767. {
  2768. //
  2769. // Remove any old info
  2770. //
  2771. pMasterService = MasterServiceTable[Services[pSrv->Service].Index];
  2772. if ( bReplaceValues )
  2773. {
  2774. pMasterService->MaxSessionCount -= pService->MaxSessionCount;
  2775. pMasterService->HighMark -= pService->HighMark;
  2776. }
  2777. //
  2778. // Now update new info
  2779. //
  2780. pService->MaxSessionCount = pSrv->MaxSessionCount;
  2781. pService->HighMark = pSrv->HighMark;
  2782. pMasterService->MaxSessionCount += pService->MaxSessionCount;
  2783. pMasterService->HighMark += pService->HighMark;
  2784. }
  2785. }
  2786. if (i % 100 == 0) ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, NSERVICEWAITHINT);
  2787. }
  2788. RtlReleaseResource(&MasterServiceListLock);
  2789. RtlReleaseResource(&ServerListLock);
  2790. } // ServerServiceListUnpack
  2791. /////////////////////////////////////////////////////////////////////////
  2792. NTSTATUS
  2793. ServerListStringsPack (
  2794. ULONG ServerTableSize,
  2795. PREPL_SERVER_RECORD Servers,
  2796. ULONG *pServerStringSize,
  2797. LPTSTR *pServerStrings
  2798. )
  2799. /*++
  2800. Routine Description:
  2801. Arguments:
  2802. Return Value:
  2803. --*/
  2804. {
  2805. NTSTATUS Status = STATUS_SUCCESS;
  2806. ULONG i;
  2807. ULONG StringSize;
  2808. PREPL_SERVER_RECORD pServer;
  2809. LPTSTR ServerStrings = NULL;
  2810. TCHAR *pStr;
  2811. HRESULT hr;
  2812. #if DBG
  2813. if (TraceFlags & TRACE_FUNCTION_TRACE)
  2814. dprintf(TEXT("ServerListStringsPack\n"));
  2815. #endif
  2816. ASSERT(pServerStrings != NULL);
  2817. ASSERT(pServerStringSize != NULL);
  2818. *pServerStrings = NULL;
  2819. *pServerStringSize = 0;
  2820. //
  2821. // First walk the list adding up string sizes - to calculate our buff size
  2822. //
  2823. StringSize = 0;
  2824. for (i = 0; i < ServerTableSize; i++) {
  2825. pServer = &Servers[i];
  2826. StringSize = StringSize + lstrlen(pServer->Name) + 1;
  2827. }
  2828. //
  2829. // Make sure there is anything to replicate
  2830. //
  2831. if (StringSize > 0) {
  2832. //
  2833. // Create our buffer to hold all of the garbage
  2834. //
  2835. ServerStrings = MIDL_user_allocate(StringSize * sizeof(TCHAR));
  2836. if (ServerStrings == NULL) {
  2837. ASSERT(FALSE);
  2838. return STATUS_NO_MEMORY;
  2839. }
  2840. //
  2841. // Fill in the buffer
  2842. //
  2843. pStr = ServerStrings;
  2844. for (i = 0; i < ServerTableSize; i++) {
  2845. pServer = &Servers[i];
  2846. hr = StringCchCopy(pStr, StringSize, pServer->Name);
  2847. ASSERT(SUCCEEDED(hr));
  2848. pStr = &pStr[lstrlen(pServer->Name) + 1];
  2849. }
  2850. }
  2851. *pServerStrings = ServerStrings;
  2852. *pServerStringSize = StringSize;
  2853. return Status;
  2854. } // ServerListStringsPack
  2855. /////////////////////////////////////////////////////////////////////////
  2856. VOID
  2857. ServerListStringsUnpack (
  2858. ULONG ServerTableSize,
  2859. PREPL_SERVER_RECORD Servers,
  2860. ULONG ServerStringSize,
  2861. LPTSTR ServerStrings
  2862. )
  2863. /*++
  2864. Routine Description:
  2865. Arguments:
  2866. Return Value:
  2867. --*/
  2868. {
  2869. ULONG i;
  2870. PREPL_SERVER_RECORD pServer;
  2871. TCHAR *pStr;
  2872. UNREFERENCED_PARAMETER(ServerStringSize);
  2873. #if DBG
  2874. if (TraceFlags & TRACE_FUNCTION_TRACE)
  2875. dprintf(TEXT("ServerListStringsUnpack\n"));
  2876. #endif
  2877. //
  2878. // First do license service strings
  2879. //
  2880. pStr = ServerStrings;
  2881. for (i = 0; i < ServerTableSize; i++) {
  2882. pServer = &Servers[i];
  2883. pServer->Name = pStr;
  2884. //
  2885. // Move to end of current string
  2886. //
  2887. while (*pStr != TEXT('\0'))
  2888. pStr++;
  2889. // now go past ending NULL
  2890. pStr++;
  2891. }
  2892. } // ServerListStringsUnpack
  2893. /////////////////////////////////////////////////////////////////////////
  2894. /////////////////////////////////////////////////////////////////////////
  2895. /////////////////////////////////////////////////////////////////////////
  2896. NTSTATUS
  2897. PackAll (
  2898. DWORD LastReplicated,
  2899. ULONG *pServiceTableSize,
  2900. PREPL_SERVICE_RECORD *pServices,
  2901. ULONG *pServerTableSize,
  2902. PREPL_SERVER_RECORD *pServers,
  2903. ULONG *pServerServiceTableSize,
  2904. PREPL_SERVER_SERVICE_RECORD *pServerServices,
  2905. ULONG UserLevel,
  2906. ULONG *pUserTableSize,
  2907. LPVOID *pUsers
  2908. )
  2909. /*++
  2910. Routine Description:
  2911. Arguments:
  2912. Return Value:
  2913. --*/
  2914. {
  2915. NTSTATUS Status = STATUS_SUCCESS;
  2916. #if DBG
  2917. if (TraceFlags & TRACE_FUNCTION_TRACE)
  2918. dprintf(TEXT("LLS TRACE: PackAll\n"));
  2919. #endif
  2920. //
  2921. // We need to grab all the locks here so that a service isn't snuck in
  2922. // behind our backs - since these tables interact with each other.
  2923. //
  2924. RtlAcquireResourceExclusive(&UserListLock, TRUE);
  2925. RtlAcquireResourceShared(&MasterServiceListLock, TRUE);
  2926. RtlAcquireResourceShared(&ServerListLock, TRUE);
  2927. Status = ServiceListPack(pServiceTableSize, pServices);
  2928. if (Status != STATUS_SUCCESS)
  2929. goto PackAllExit;
  2930. Status = ServerListPack(pServerTableSize, pServers);
  2931. if (Status != STATUS_SUCCESS)
  2932. goto PackAllExit;
  2933. Status = ServerServiceListPack(pServerServiceTableSize, pServerServices);
  2934. if (Status != STATUS_SUCCESS)
  2935. goto PackAllExit;
  2936. Status = UserListPack(LastReplicated, UserLevel, pUserTableSize, pUsers);
  2937. if (Status != STATUS_SUCCESS)
  2938. goto PackAllExit;
  2939. //
  2940. // Now update our last used time
  2941. //
  2942. LastUsedTime = DateSystemGet() + 1;
  2943. PackAllExit:
  2944. RtlReleaseResource(&ServerListLock);
  2945. RtlReleaseResource(&MasterServiceListLock);
  2946. RtlReleaseResource(&UserListLock);
  2947. return Status;
  2948. } // PackAll
  2949. /////////////////////////////////////////////////////////////////////////
  2950. VOID
  2951. UnpackAll (
  2952. ULONG ServiceTableSize,
  2953. PREPL_SERVICE_RECORD Services,
  2954. ULONG ServerTableSize,
  2955. PREPL_SERVER_RECORD Servers,
  2956. ULONG ServerServiceTableSize,
  2957. PREPL_SERVER_SERVICE_RECORD ServerServices,
  2958. ULONG UserLevel,
  2959. ULONG UserTableSize,
  2960. LPVOID Users
  2961. )
  2962. /*++
  2963. Routine Description:
  2964. Arguments:
  2965. Return Value:
  2966. --*/
  2967. {
  2968. #if DBG
  2969. if (TraceFlags & TRACE_FUNCTION_TRACE)
  2970. dprintf(TEXT("LLS TRACE: UnpackAll\n"));
  2971. #endif
  2972. ServiceListUnpack(ServiceTableSize, Services, ServerTableSize, Servers, ServerServiceTableSize, ServerServices);
  2973. ServerListUnpack(ServiceTableSize, Services, ServerTableSize, Servers, ServerServiceTableSize, ServerServices);
  2974. ServerServiceListUnpack(ServiceTableSize, Services, ServerTableSize, Servers, ServerServiceTableSize, ServerServices);
  2975. UserListUnpack(ServiceTableSize, Services, ServerTableSize, Servers, ServerServiceTableSize, ServerServices, UserLevel, UserTableSize, Users);
  2976. } // UnpackAll
  2977. /////////////////////////////////////////////////////////////////////////
  2978. VOID
  2979. LLSDataLoad()
  2980. /*++
  2981. Routine Description:
  2982. Arguments:
  2983. None.
  2984. Return Value:
  2985. None.
  2986. --*/
  2987. {
  2988. BOOL ret;
  2989. DWORD Version, DataSize;
  2990. NTSTATUS Status = STATUS_SUCCESS;
  2991. HANDLE hFile = NULL;
  2992. ULONG ServiceTableSize = 0;
  2993. PREPL_SERVICE_RECORD Services = NULL;
  2994. ULONG ServiceStringSize;
  2995. LPTSTR ServiceStrings = NULL;
  2996. ULONG ServerServiceTableSize = 0;
  2997. PREPL_SERVER_SERVICE_RECORD ServerServices = NULL;
  2998. ULONG ServerTableSize = 0;
  2999. PREPL_SERVER_RECORD Servers = NULL;
  3000. ULONG ServerStringSize;
  3001. LPTSTR ServerStrings = NULL;
  3002. ULONG UserTableSize = 0;
  3003. LPVOID Users = NULL;
  3004. ULONG UserStringSize;
  3005. LPTSTR UserStrings = NULL;
  3006. LLS_DATA_FILE_HEADER FileHeader;
  3007. DWORD BytesRead;
  3008. #if DBG
  3009. if (TraceFlags & (TRACE_FUNCTION_TRACE | TRACE_DATABASE))
  3010. dprintf(TEXT("LLS TRACE: LLSDataLoad\n"));
  3011. #endif
  3012. RtlEnterCriticalSection(&UserFileLock);
  3013. //init
  3014. ZeroMemory(&FileHeader, sizeof(FileHeader));
  3015. //
  3016. // If nothing to load then get-out
  3017. //
  3018. if (!FileExists(UserFileName))
  3019. goto LLSDataLoadExit;
  3020. //
  3021. // Check the init header
  3022. //
  3023. Version = DataSize = 0;
  3024. hFile = LlsFileCheck(UserFileName, &Version, &DataSize );
  3025. if (hFile == NULL) {
  3026. Status = GetLastError();
  3027. goto LLSDataLoadExit;
  3028. }
  3029. if ( ( ( Version != USER_FILE_VERSION_0 )
  3030. || ( DataSize != sizeof(LLS_DATA_FILE_HEADER_0) ) )
  3031. && ( ( Version != USER_FILE_VERSION )
  3032. || ( DataSize != sizeof(LLS_DATA_FILE_HEADER) ) ) )
  3033. {
  3034. Status = STATUS_FILE_INVALID;
  3035. goto LLSDataLoadExit;
  3036. }
  3037. //
  3038. // The init header checks out, so load the license header and data blocks
  3039. //
  3040. if ( USER_FILE_VERSION_0 == Version )
  3041. {
  3042. // 3.51 data file
  3043. LLS_DATA_FILE_HEADER_0 FileHeader0;
  3044. ret = ReadFile(hFile, &FileHeader0, sizeof(LLS_DATA_FILE_HEADER_0), &BytesRead, NULL);
  3045. if ( ret )
  3046. {
  3047. FileHeader.ServiceLevel = 0;
  3048. FileHeader.ServiceTableSize = FileHeader0.ServiceTableSize;
  3049. FileHeader.ServiceStringSize = FileHeader0.ServiceStringSize;
  3050. FileHeader.ServerLevel = 0;
  3051. FileHeader.ServerTableSize = FileHeader0.ServerTableSize;
  3052. FileHeader.ServerStringSize = FileHeader0.ServerStringSize;
  3053. FileHeader.ServerServiceLevel = 0;
  3054. FileHeader.ServerServiceTableSize = FileHeader0.ServerServiceTableSize;
  3055. FileHeader.UserLevel = 0;
  3056. FileHeader.UserTableSize = FileHeader0.UserTableSize;
  3057. FileHeader.UserStringSize = FileHeader0.UserStringSize;
  3058. }
  3059. }
  3060. else
  3061. {
  3062. ret = ReadFile(hFile, &FileHeader, sizeof(LLS_DATA_FILE_HEADER), &BytesRead, NULL);
  3063. }
  3064. if ( ret )
  3065. {
  3066. // header read okay; ensure data type levels are okay
  3067. if ( ( 0 != FileHeader.ServiceLevel )
  3068. || ( 0 != FileHeader.ServerLevel )
  3069. || ( 0 != FileHeader.ServerServiceLevel )
  3070. || ( ( 0 != FileHeader.UserLevel )
  3071. && ( 1 != FileHeader.UserLevel ) ) )
  3072. {
  3073. Status = STATUS_FILE_INVALID;
  3074. goto LLSDataLoadExit;
  3075. }
  3076. }
  3077. ServiceTableSize = 0;
  3078. ServiceStringSize = 0;
  3079. ServerServiceTableSize = 0;
  3080. ServerTableSize = 0;
  3081. ServerStringSize = 0;
  3082. UserTableSize = 0;
  3083. UserStringSize = 0;
  3084. if (ret) {
  3085. //
  3086. // Run through and allocate space to read data blocks into
  3087. //
  3088. if (FileHeader.ServiceTableSize != 0) {
  3089. ServiceTableSize = FileHeader.ServiceTableSize / sizeof(REPL_SERVICE_RECORD);
  3090. Services = MIDL_user_allocate(FileHeader.ServiceTableSize);
  3091. if ( Services == NULL ) {
  3092. Status = STATUS_NO_MEMORY;
  3093. goto LLSDataLoadExit;
  3094. }
  3095. }
  3096. if (FileHeader.ServiceStringSize != 0) {
  3097. ServiceStringSize = FileHeader.ServiceStringSize / sizeof(TCHAR);
  3098. ServiceStrings = MIDL_user_allocate(FileHeader.ServiceStringSize);
  3099. if ( ServiceStrings == NULL ) {
  3100. Status = STATUS_NO_MEMORY;
  3101. goto LLSDataLoadExit;
  3102. }
  3103. }
  3104. if (FileHeader.ServerTableSize != 0) {
  3105. ServerTableSize = FileHeader.ServerTableSize / sizeof(REPL_SERVER_RECORD);
  3106. Servers = MIDL_user_allocate(FileHeader.ServerTableSize);
  3107. if ( Servers == NULL ) {
  3108. Status = STATUS_NO_MEMORY;
  3109. goto LLSDataLoadExit;
  3110. }
  3111. }
  3112. if (FileHeader.ServerStringSize != 0) {
  3113. ServerStringSize = FileHeader.ServerStringSize / sizeof(TCHAR);
  3114. ServerStrings = MIDL_user_allocate(FileHeader.ServerStringSize);
  3115. if ( ServerStrings == NULL ) {
  3116. Status = STATUS_NO_MEMORY;
  3117. goto LLSDataLoadExit;
  3118. }
  3119. }
  3120. if (FileHeader.ServerServiceTableSize != 0) {
  3121. ServerServiceTableSize = FileHeader.ServerServiceTableSize / sizeof(REPL_SERVER_SERVICE_RECORD);
  3122. ServerServices = MIDL_user_allocate(FileHeader.ServerServiceTableSize);
  3123. if ( ServerServices == NULL ) {
  3124. Status = STATUS_NO_MEMORY;
  3125. goto LLSDataLoadExit;
  3126. }
  3127. }
  3128. if (FileHeader.UserTableSize != 0) {
  3129. UserTableSize = FileHeader.UserTableSize / ( FileHeader.UserLevel ? sizeof(REPL_USER_RECORD_1)
  3130. : sizeof(REPL_USER_RECORD_0) );
  3131. Users = MIDL_user_allocate(FileHeader.UserTableSize);
  3132. if ( Users == NULL ) {
  3133. Status = STATUS_NO_MEMORY;
  3134. goto LLSDataLoadExit;
  3135. }
  3136. }
  3137. if (FileHeader.UserStringSize != 0) {
  3138. UserStringSize = FileHeader.UserStringSize / sizeof(TCHAR);
  3139. UserStrings = MIDL_user_allocate(FileHeader.UserStringSize);
  3140. if ( UserStrings == NULL ) {
  3141. Status = STATUS_NO_MEMORY;
  3142. goto LLSDataLoadExit;
  3143. }
  3144. }
  3145. }
  3146. if (ret && (FileHeader.ServiceTableSize != 0) )
  3147. ret = ReadFile(hFile, Services, FileHeader.ServiceTableSize, &BytesRead, NULL);
  3148. if (ret && (FileHeader.ServiceStringSize != 0) )
  3149. ret = ReadFile(hFile, ServiceStrings, FileHeader.ServiceStringSize, &BytesRead, NULL);
  3150. if (ret && (FileHeader.ServerTableSize != 0) )
  3151. ret = ReadFile(hFile, Servers, FileHeader.ServerTableSize, &BytesRead, NULL);
  3152. if (ret && (FileHeader.ServerStringSize != 0) )
  3153. ret = ReadFile(hFile, ServerStrings, FileHeader.ServerStringSize, &BytesRead, NULL);
  3154. if (ret && (FileHeader.ServerServiceTableSize != 0) )
  3155. ret = ReadFile(hFile, ServerServices, FileHeader.ServerServiceTableSize, &BytesRead, NULL);
  3156. if (ret && (FileHeader.UserTableSize != 0) )
  3157. ret = ReadFile(hFile, Users, FileHeader.UserTableSize, &BytesRead, NULL);
  3158. if (ret && (FileHeader.UserStringSize != 0) )
  3159. ret = ReadFile(hFile, UserStrings, FileHeader.UserStringSize, &BytesRead, NULL);
  3160. if (!ret) {
  3161. Status = GetLastError();
  3162. goto LLSDataLoadExit;
  3163. }
  3164. //
  3165. // Decrypt the data
  3166. //
  3167. Status = DeBlock(Services, FileHeader.ServiceTableSize);
  3168. if (Status == STATUS_SUCCESS)
  3169. Status = DeBlock(ServiceStrings, FileHeader.ServiceStringSize);
  3170. if (Status == STATUS_SUCCESS)
  3171. Status = DeBlock(Servers, FileHeader.ServerTableSize);
  3172. if (Status == STATUS_SUCCESS)
  3173. Status = DeBlock(ServerStrings, FileHeader.ServerStringSize);
  3174. if (Status == STATUS_SUCCESS)
  3175. Status = DeBlock(ServerServices, FileHeader.ServerServiceTableSize);
  3176. if (Status == STATUS_SUCCESS)
  3177. Status = DeBlock(Users, FileHeader.UserTableSize);
  3178. if (Status == STATUS_SUCCESS)
  3179. Status = DeBlock(UserStrings, FileHeader.UserStringSize);
  3180. if (Status != STATUS_SUCCESS)
  3181. goto LLSDataLoadExit;
  3182. //
  3183. // Unpack the string data
  3184. //
  3185. ServiceListStringsUnpack( ServiceTableSize, Services, ServiceStringSize, ServiceStrings );
  3186. ServerListStringsUnpack( ServerTableSize, Servers, ServerStringSize, ServerStrings );
  3187. UserListStringsUnpack( FileHeader.UserLevel, UserTableSize, Users, UserStringSize, UserStrings );
  3188. //
  3189. // Unpack the data
  3190. //
  3191. UnpackAll ( ServiceTableSize, Services, ServerTableSize, Servers,
  3192. ServerServiceTableSize, ServerServices,
  3193. FileHeader.UserLevel, UserTableSize, Users );
  3194. LLSDataLoadExit:
  3195. if (hFile != NULL)
  3196. CloseHandle(hFile);
  3197. RtlLeaveCriticalSection(&UserFileLock);
  3198. //
  3199. // Run through our tables and clean them up
  3200. //
  3201. if (Services != NULL)
  3202. MIDL_user_free(Services);
  3203. if (ServiceStrings != NULL)
  3204. MIDL_user_free(ServiceStrings);
  3205. if (Servers != NULL)
  3206. MIDL_user_free(Servers);
  3207. if (ServerStrings != NULL)
  3208. MIDL_user_free(ServerStrings);
  3209. if (ServerServices != NULL)
  3210. MIDL_user_free(ServerServices);
  3211. if (Users != NULL)
  3212. MIDL_user_free(Users);
  3213. if (UserStrings != NULL)
  3214. MIDL_user_free(UserStrings);
  3215. //
  3216. // If there was an error log it.
  3217. //
  3218. if (Status != STATUS_SUCCESS)
  3219. LogEvent(LLS_EVENT_LOAD_USER, 0, NULL, Status);
  3220. } // LLSDataLoad
  3221. /////////////////////////////////////////////////////////////////////////
  3222. NTSTATUS
  3223. LLSDataSave()
  3224. /*++
  3225. Routine Description:
  3226. Arguments:
  3227. None.
  3228. Return Value:
  3229. None.
  3230. --*/
  3231. {
  3232. BOOL ret = TRUE;
  3233. NTSTATUS Status = STATUS_SUCCESS;
  3234. HANDLE hFile = NULL;
  3235. ULONG ServiceTableSize = 0;
  3236. PREPL_SERVICE_RECORD Services = NULL;
  3237. ULONG ServiceStringSize;
  3238. LPTSTR ServiceStrings = NULL;
  3239. ULONG ServerServiceTableSize = 0;
  3240. PREPL_SERVER_SERVICE_RECORD ServerServices = NULL;
  3241. ULONG ServerTableSize = 0;
  3242. PREPL_SERVER_RECORD Servers = NULL;
  3243. ULONG ServerStringSize;
  3244. LPTSTR ServerStrings = NULL;
  3245. ULONG UserTableSize = 0;
  3246. PREPL_USER_RECORD_1 Users = NULL;
  3247. ULONG UserStringSize;
  3248. LPTSTR UserStrings = NULL;
  3249. LLS_DATA_FILE_HEADER FileHeader;
  3250. DWORD BytesWritten;
  3251. #if DBG
  3252. if (TraceFlags & (TRACE_FUNCTION_TRACE | TRACE_DATABASE))
  3253. dprintf(TEXT("LLS TRACE: LLSDataSave\n"));
  3254. #endif
  3255. RtlEnterCriticalSection(&UserFileLock);
  3256. //
  3257. // Pack the data
  3258. //
  3259. Status = PackAll ( 0,
  3260. &ServiceTableSize, &Services,
  3261. &ServerTableSize, &Servers,
  3262. &ServerServiceTableSize, &ServerServices,
  3263. 1, &UserTableSize, &Users );
  3264. if (Status != STATUS_SUCCESS)
  3265. goto LLSDataSaveExit;
  3266. //
  3267. // Now pack the String data
  3268. //
  3269. Status = ServiceListStringsPack( ServiceTableSize, Services, &ServiceStringSize, &ServiceStrings );
  3270. if (Status != STATUS_SUCCESS)
  3271. goto LLSDataSaveExit;
  3272. Status = ServerListStringsPack( ServerTableSize, Servers, &ServerStringSize, &ServerStrings );
  3273. if (Status != STATUS_SUCCESS)
  3274. goto LLSDataSaveExit;
  3275. Status = UserListStringsPack( 1, UserTableSize, Users, &UserStringSize, &UserStrings );
  3276. if (Status != STATUS_SUCCESS)
  3277. goto LLSDataSaveExit;
  3278. //
  3279. // Fill out the file header - sizes are byte sizes
  3280. //
  3281. FileHeader.ServiceTableSize = ServiceTableSize * sizeof(REPL_SERVICE_RECORD);
  3282. FileHeader.ServiceStringSize = ServiceStringSize * sizeof(TCHAR);
  3283. FileHeader.ServerTableSize = ServerTableSize * sizeof(REPL_SERVER_RECORD);
  3284. FileHeader.ServerStringSize = ServerStringSize * sizeof(TCHAR);
  3285. FileHeader.ServerServiceTableSize = ServerServiceTableSize * sizeof(REPL_SERVER_SERVICE_RECORD);
  3286. FileHeader.UserTableSize = UserTableSize * sizeof(REPL_USER_RECORD_1);
  3287. FileHeader.UserStringSize = UserStringSize * sizeof(TCHAR);
  3288. FileHeader.ServiceLevel = 0;
  3289. FileHeader.ServerLevel = 0;
  3290. FileHeader.ServerServiceLevel = 0;
  3291. FileHeader.UserLevel = 1;
  3292. //
  3293. // Encrypt the data before saving it out.
  3294. //
  3295. Status = EBlock(Services, FileHeader.ServiceTableSize);
  3296. if (Status == STATUS_SUCCESS)
  3297. Status = EBlock(ServiceStrings, FileHeader.ServiceStringSize);
  3298. if (Status == STATUS_SUCCESS)
  3299. Status = EBlock(Servers, FileHeader.ServerTableSize);
  3300. if (Status == STATUS_SUCCESS)
  3301. Status = EBlock(ServerStrings, FileHeader.ServerStringSize);
  3302. if (Status == STATUS_SUCCESS)
  3303. Status = EBlock(ServerServices, FileHeader.ServerServiceTableSize);
  3304. if (Status == STATUS_SUCCESS)
  3305. Status = EBlock(Users, FileHeader.UserTableSize);
  3306. if (Status == STATUS_SUCCESS)
  3307. Status = EBlock(UserStrings, FileHeader.UserStringSize);
  3308. if (Status != STATUS_SUCCESS)
  3309. goto LLSDataSaveExit;
  3310. //
  3311. // Save out the header record
  3312. //
  3313. hFile = LlsFileInit(UserFileName, USER_FILE_VERSION, sizeof(LLS_DATA_FILE_HEADER) );
  3314. if (hFile == NULL) {
  3315. Status = GetLastError();
  3316. goto LLSDataSaveExit;
  3317. }
  3318. //
  3319. // Now write out all the data blocks
  3320. //
  3321. ret = WriteFile(hFile, &FileHeader, sizeof(LLS_DATA_FILE_HEADER), &BytesWritten, NULL);
  3322. if (ret && (Services != NULL) && (FileHeader.ServiceTableSize != 0) )
  3323. ret = WriteFile(hFile, Services, FileHeader.ServiceTableSize, &BytesWritten, NULL);
  3324. if (ret && (ServiceStrings != NULL) && (FileHeader.ServiceStringSize != 0) )
  3325. ret = WriteFile(hFile, ServiceStrings, FileHeader.ServiceStringSize, &BytesWritten, NULL);
  3326. if (ret && (Servers != NULL) && (FileHeader.ServerTableSize != 0) )
  3327. ret = WriteFile(hFile, Servers, FileHeader.ServerTableSize, &BytesWritten, NULL);
  3328. if (ret && (ServerStrings != NULL) && (FileHeader.ServerStringSize != 0) )
  3329. ret = WriteFile(hFile, ServerStrings, FileHeader.ServerStringSize, &BytesWritten, NULL);
  3330. if (ret && (ServerServices != NULL) && (FileHeader.ServerServiceTableSize != 0) )
  3331. ret = WriteFile(hFile, ServerServices, FileHeader.ServerServiceTableSize, &BytesWritten, NULL);
  3332. if (ret && (Users != NULL) && (FileHeader.UserTableSize != 0) )
  3333. ret = WriteFile(hFile, Users, FileHeader.UserTableSize, &BytesWritten, NULL);
  3334. if (ret && (UserStrings != NULL) && (FileHeader.UserStringSize != 0) )
  3335. ret = WriteFile(hFile, UserStrings, FileHeader.UserStringSize, &BytesWritten, NULL);
  3336. if (!ret)
  3337. Status = GetLastError();
  3338. LLSDataSaveExit:
  3339. if (hFile != NULL)
  3340. CloseHandle(hFile);
  3341. RtlLeaveCriticalSection(&UserFileLock);
  3342. //
  3343. // Run through our tables and clean them up
  3344. //
  3345. if (Services != NULL)
  3346. MIDL_user_free(Services);
  3347. if (ServiceStrings != NULL)
  3348. MIDL_user_free(ServiceStrings);
  3349. if (Servers != NULL)
  3350. MIDL_user_free(Servers);
  3351. if (ServerStrings != NULL)
  3352. MIDL_user_free(ServerStrings);
  3353. if (ServerServices != NULL)
  3354. MIDL_user_free(ServerServices);
  3355. if (Users != NULL)
  3356. MIDL_user_free(Users);
  3357. if (UserStrings != NULL)
  3358. MIDL_user_free(UserStrings);
  3359. //
  3360. // If there was an error log it.
  3361. //
  3362. if (Status != STATUS_SUCCESS)
  3363. LogEvent(LLS_EVENT_SAVE_USER, 0, NULL, Status);
  3364. return Status;
  3365. } // LLSDataSave
  3366. /////////////////////////////////////////////////////////////////////////
  3367. VOID
  3368. LoadAll ( )
  3369. /*++
  3370. Routine Description:
  3371. Arguments:
  3372. Return Value:
  3373. --*/
  3374. {
  3375. #if DBG
  3376. if (TraceFlags & (TRACE_FUNCTION_TRACE | TRACE_DATABASE))
  3377. dprintf(TEXT("LLS TRACE: LoadAll\n"));
  3378. #endif
  3379. PurchaseFile = NULL;
  3380. try {
  3381. LicenseListLoad();
  3382. } except (TRUE) {
  3383. LogEvent(LLS_EVENT_LOAD_LICENSE, 0, NULL, GetExceptionCode());
  3384. }
  3385. try {
  3386. MappingListLoad();
  3387. } except (TRUE) {
  3388. LogEvent(LLS_EVENT_LOAD_MAPPING, 0, NULL, GetExceptionCode());
  3389. }
  3390. try {
  3391. LLSDataLoad();
  3392. } except (TRUE) {
  3393. LogEvent(LLS_EVENT_LOAD_USER, 0, NULL, GetExceptionCode());
  3394. }
  3395. try {
  3396. CertDbLoad();
  3397. } except (TRUE) {
  3398. LogEvent(LLS_EVENT_LOAD_CERT_DB, 0, NULL, GetExceptionCode());
  3399. }
  3400. } // LoadAll
  3401. /////////////////////////////////////////////////////////////////////////
  3402. VOID
  3403. SaveAll ( )
  3404. /*++
  3405. Routine Description:
  3406. Arguments:
  3407. Return Value:
  3408. --*/
  3409. {
  3410. #if DBG
  3411. if (TraceFlags & (TRACE_FUNCTION_TRACE | TRACE_DATABASE))
  3412. dprintf(TEXT("LLS TRACE: SaveAll\n"));
  3413. #endif
  3414. LicenseListSave();
  3415. MappingListSave();
  3416. LLSDataSave();
  3417. CertDbSave();
  3418. } // SaveAll