Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1718 lines
52 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1999-2000 Microsoft Corporation
  4. //
  5. // Module Name:
  6. //
  7. // iasmdbtool.cpp
  8. //
  9. // Abstract:
  10. //
  11. // dump the "Properties" table from ias.mdb to a text format
  12. // and also restore ias.mdb from such dump
  13. //
  14. //
  15. // Revision History:
  16. //
  17. // tperraut 04/07/1999
  18. // tperraut 04/03/2000 Version table exported and imported.
  19. // Set to 0 for old scripts (no version table)
  20. // tperraut 06/13/2000 Make use of the new upgrade code for IAS. i.e.
  21. // remove all the code to write into a database.
  22. //
  23. //////////////////////////////////////////////////////////////////////////////
  24. #include "stdafx.h"
  25. #include <string>
  26. #include <shlwapi.h>
  27. using namespace std;
  28. //////////////////////////////////////////////////////////////////////////////
  29. HRESULT
  30. IASExpandString(const WCHAR* pInputString, /*in/out*/ WCHAR** ppOutputString);
  31. //////////////////////////////////////////////////////////////////////////////
  32. #ifdef DEBUG
  33. #define CHECK_CALL_HRES(expr) \
  34. hres = expr; \
  35. if (FAILED(hres)) \
  36. { \
  37. wprintf(L"### %S returned 0x%X ###\n", ## #expr, hres); \
  38. return hres; \
  39. }
  40. #define CHECK_CALL_HRES_NO_RETURN(expr) \
  41. hres = expr; \
  42. if (FAILED(hres)) \
  43. { \
  44. wprintf(L"### %S returned 0x%X ###\n", ## #expr, hres); \
  45. }
  46. #define CHECK_CALL_HRES_BREAK(expr) \
  47. hres = expr; \
  48. if (FAILED(hres)) \
  49. { \
  50. wprintf(L"### %S returned 0x%X ###\n", ## #expr, hres); \
  51. break; \
  52. }
  53. #else //no printf, only the error code return if needed
  54. #define CHECK_CALL_HRES(expr) \
  55. hres = expr; \
  56. if (FAILED(hres)) \
  57. { \
  58. return hres; \
  59. }
  60. #define CHECK_CALL_HRES_NO_RETURN(expr) \
  61. hres = expr;
  62. #define CHECK_CALL_HRES_BREAK(expr) \
  63. hres = expr; \
  64. if (FAILED(hres)) break;
  65. #endif //DEBUG
  66. #define celems(_x) (sizeof(_x) / sizeof(_x[0]))
  67. namespace
  68. {
  69. const int SIZELINEMAX = 512;
  70. const int SIZE_LONG_MAX = 33;
  71. // Number of files generated
  72. // here one: backup.mdb
  73. const int MAX_FILES = 1;
  74. const int EXTRA_CHAR_SPACE = 32;
  75. // file order
  76. const int BACKUP_NB = 0;
  77. const int BINARY_NB = 100;
  78. // that's a lot
  79. const int DECOMPRESS_FACTOR = 100;
  80. const int FILE_BUFFER_SIZE = 1024;
  81. struct IASKEY
  82. {
  83. const WCHAR* c_wcKey;
  84. const WCHAR* c_wcValue;
  85. DWORD c_dwType;
  86. } IAS_Key_Struct;
  87. IASKEY c_wcKEYS[] =
  88. {
  89. {
  90. L"SYSTEM\\CurrentControlSet\\Services\\IAS\\Parameters",
  91. L"Allow SNMP Set",
  92. REG_DWORD
  93. },
  94. {
  95. L"SYSTEM\\CurrentControlSet\\Services\\RasMan\\PPP\\ControlProtocols\\BuiltIn",
  96. L"DefaultDomain",
  97. REG_SZ
  98. },
  99. {
  100. L"SYSTEM\\CurrentControlSet\\Services\\RemoteAccess\\Parameters\\AccountLockout",
  101. L"MaxDenials",
  102. REG_DWORD
  103. },
  104. {
  105. L"SYSTEM\\CurrentControlSet\\Services\\IAS\\Parameters",
  106. L"ResetTime (mins)",
  107. REG_DWORD
  108. },
  109. {
  110. L"SYSTEM\\CurrentControlSet\\Services\\RemoteAccess\\Policy",
  111. L"Allow LM Authentication",
  112. REG_DWORD
  113. },
  114. {
  115. L"SYSTEM\\CurrentControlSet\\Services\\IAS\\Parameters",
  116. L"Default User Identity",
  117. REG_SZ
  118. },
  119. {
  120. L"SYSTEM\\CurrentControlSet\\Services\\IAS\\Parameters",
  121. L"User Identity Attribute",
  122. REG_DWORD
  123. },
  124. {
  125. L"SYSTEM\\CurrentControlSet\\Services\\IAS\\Parameters",
  126. L"Override User-Name",
  127. REG_DWORD
  128. },
  129. };
  130. const WCHAR c_wcKEYS_FILE[] = L"%TEMP%\\";
  131. #ifdef _WIN64
  132. const WCHAR c_wcIAS_MDB_FILE_NAME[] =
  133. L"%SystemRoot%\\SysWow64\\ias\\ias.mdb";
  134. const WCHAR c_wcIAS_OLD[] = L"%SystemRoot%\\SysWow64\\ias\\iasold.mdb";
  135. #else
  136. const WCHAR c_wcIAS_MDB_FILE_NAME[] =
  137. L"%SystemRoot%\\System32\\ias\\ias.mdb";
  138. const WCHAR c_wcIAS_OLD[] = L"%SystemRoot%\\System32\\ias\\iasold.mdb";
  139. #endif
  140. const WCHAR c_wcFILE_BACKUP[] = L"%TEMP%\\Backup.mdb";
  141. const WCHAR c_wcSELECT_PROPERTIES_INTO[] =
  142. L"SELECT * "
  143. L"INTO Properties IN "
  144. L"\"%TEMP%\\Backup.mdb\" "
  145. L"FROM Properties;";
  146. const WCHAR c_wcSELECT_OBJECTS_INTO[] =
  147. L"SELECT * "
  148. L"INTO Objects IN "
  149. L"\"%TEMP%\\Backup.mdb\" "
  150. L"FROM Objects;";
  151. const WCHAR c_wcSELECT_VERSION_INTO[] =
  152. L"SELECT * "
  153. L"INTO Version IN "
  154. L"\"%TEMP%\\Backup.mdb\" "
  155. L"FROM Version;";
  156. }
  157. //////////////////////////////////////////////////////////////////////////////
  158. //
  159. // WideToAnsi
  160. //
  161. // CALLED BY:everywhere
  162. //
  163. // PARAMETERS: lpStr - destination string
  164. // lpWStr - string to convert
  165. // cchStr - size of dest buffer
  166. //
  167. // DESCRIPTION:
  168. // converts unicode lpWStr to ansi lpStr.
  169. // fills in unconvertable chars w/ DPLAY_DEFAULT_CHAR "-"
  170. //
  171. //
  172. // RETURNS: if cchStr is 0, returns the size required to hold the string
  173. // otherwise, returns the number of chars converted
  174. //
  175. //////////////////////////////////////////////////////////////////////////////
  176. int WideToAnsi(char* lpStr,unsigned short* lpWStr, int cchStr)
  177. {
  178. BOOL bDefault;
  179. // use the default code page (CP_ACP)
  180. // -1 indicates WStr must be null terminated
  181. return WideCharToMultiByte(GetConsoleOutputCP(),0,lpWStr,-1,lpStr,cchStr,"-",&bDefault);
  182. }
  183. /////////////////////////////////////////////////////////////////////////////
  184. //
  185. // IASEnableBackupPrivilege
  186. //
  187. /////////////////////////////////////////////////////////////////////////////
  188. HRESULT IASEnableBackupPrivilege()
  189. {
  190. LONG lResult = ERROR_SUCCESS;
  191. HANDLE hToken = NULL;
  192. do
  193. {
  194. if ( ! OpenProcessToken(
  195. GetCurrentProcess(),
  196. TOKEN_ADJUST_PRIVILEGES,
  197. &hToken
  198. ))
  199. {
  200. lResult = ERROR_CAN_NOT_COMPLETE;
  201. break;
  202. }
  203. LUID luidB;
  204. if ( ! LookupPrivilegeValue(NULL, SE_BACKUP_NAME, &luidB))
  205. {
  206. lResult = ERROR_CAN_NOT_COMPLETE;
  207. break;
  208. }
  209. LUID luidR;
  210. if ( ! LookupPrivilegeValue(NULL, SE_RESTORE_NAME, &luidR))
  211. {
  212. lResult = ERROR_CAN_NOT_COMPLETE;
  213. break;
  214. }
  215. TOKEN_PRIVILEGES tp;
  216. tp.PrivilegeCount = 1;
  217. tp.Privileges[0].Luid = luidB;
  218. tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  219. if ( ! AdjustTokenPrivileges(
  220. hToken,
  221. FALSE,
  222. &tp,
  223. sizeof(TOKEN_PRIVILEGES),
  224. NULL,
  225. NULL
  226. ) )
  227. {
  228. lResult = ERROR_CAN_NOT_COMPLETE;
  229. break;
  230. }
  231. tp.PrivilegeCount = 1;
  232. tp.Privileges[0].Luid = luidR;
  233. tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  234. if ( ! AdjustTokenPrivileges(
  235. hToken,
  236. FALSE,
  237. &tp,
  238. sizeof(TOKEN_PRIVILEGES),
  239. NULL,
  240. NULL
  241. ) )
  242. {
  243. lResult = ERROR_CAN_NOT_COMPLETE;
  244. break;
  245. }
  246. } while (false);
  247. if ( hToken )
  248. {
  249. CloseHandle(hToken);
  250. }
  251. if ( lResult == ERROR_SUCCESS )
  252. {
  253. return S_OK;
  254. }
  255. else
  256. {
  257. return E_FAIL;
  258. }
  259. }
  260. /////////////////////////////////////////////////////////////////////////////
  261. //
  262. // IASSaveRegKeys
  263. //
  264. /////////////////////////////////////////////////////////////////////////////
  265. HRESULT IASSaveRegKeys()
  266. {
  267. HRESULT hres;
  268. int c_NbKeys = celems(c_wcKEYS);
  269. if ( c_NbKeys == 0 )
  270. {
  271. hres = S_OK;
  272. }
  273. else
  274. {
  275. ////////////////////////////
  276. // Enable backup privilege.
  277. ////////////////////////////
  278. CHECK_CALL_HRES (IASEnableBackupPrivilege());
  279. WCHAR* CompleteFile;
  280. CHECK_CALL_HRES (IASExpandString(c_wcKEYS_FILE, &CompleteFile));
  281. for ( int i = 0; i < c_NbKeys; ++i )
  282. {
  283. DWORD dwType = 0;
  284. DWORD cbData = SIZELINEMAX / 2;
  285. LPVOID pvData = CoTaskMemAlloc(sizeof(WCHAR) * SIZELINEMAX);
  286. if (!pvData)
  287. {
  288. hres = E_OUTOFMEMORY;
  289. break;
  290. }
  291. DWORD lResult = SHGetValueW(
  292. HKEY_LOCAL_MACHINE,
  293. c_wcKEYS[i].c_wcKey,
  294. c_wcKEYS[i].c_wcValue,
  295. &dwType,
  296. pvData,
  297. &cbData
  298. );
  299. //
  300. // Try to allocate more memory if cbData returned the size needed
  301. //
  302. if ((lResult != ERROR_SUCCESS) && (cbData > SIZELINEMAX))
  303. {
  304. CoTaskMemFree(pvData);
  305. pvData = CoTaskMemAlloc(sizeof(WCHAR) * cbData);
  306. if ( !pvData )
  307. {
  308. return E_OUTOFMEMORY;
  309. }
  310. lResult = SHGetValue(
  311. HKEY_LOCAL_MACHINE,
  312. c_wcKEYS[i].c_wcKey,
  313. c_wcKEYS[i].c_wcValue,
  314. &dwType,
  315. pvData,
  316. &cbData
  317. );
  318. if ( lResult != ERROR_SUCCESS )
  319. {
  320. hres = E_OUTOFMEMORY;
  321. break;
  322. }
  323. }
  324. //
  325. // Create the file (in all situations)
  326. //
  327. wstring sFileName(CompleteFile);
  328. WCHAR buffer[SIZE_LONG_MAX];
  329. _itow(i, buffer, 10); // 10 means base 10
  330. sFileName += buffer;
  331. sFileName += L".txt";
  332. HANDLE hFile = CreateFileW(
  333. sFileName.c_str(),
  334. GENERIC_WRITE,
  335. 0,
  336. NULL,
  337. CREATE_ALWAYS,
  338. FILE_ATTRIBUTE_NORMAL,
  339. NULL
  340. );
  341. if ( hFile == INVALID_HANDLE_VALUE )
  342. {
  343. hres = E_FAIL;
  344. CoTaskMemFree(pvData);
  345. break;
  346. }
  347. //
  348. // lResult = result of SHGetValue
  349. // and might be an error but not
  350. // a memory problem
  351. //
  352. if ( lResult == ERROR_SUCCESS )
  353. {
  354. //
  355. // Wrong data type
  356. //
  357. if ( dwType != c_wcKEYS[i].c_dwType )
  358. {
  359. // There's an error, fail
  360. #ifdef DEBUG // DEBUG
  361. wprintf(L"#SHGetValue ok but wrong type returned . code %X"
  362. L" param %s%s\n",
  363. dwType,
  364. c_wcKEYS[i].c_wcKey,
  365. c_wcKEYS[i].c_wcValue
  366. );
  367. #endif //DEBUG
  368. hres = E_FAIL;
  369. CoTaskMemFree(pvData);
  370. CloseHandle(hFile);
  371. break;
  372. }
  373. else
  374. {
  375. //
  376. // Save the value to the file
  377. //
  378. BYTE* bBuffer = static_cast<BYTE*>(VirtualAlloc
  379. (
  380. NULL,
  381. (cbData > FILE_BUFFER_SIZE)?
  382. cbData:FILE_BUFFER_SIZE,
  383. MEM_COMMIT,
  384. PAGE_READWRITE
  385. ));
  386. #ifdef DEBUG //DEBUG
  387. wprintf(L"#cbdata = %d \n",cbData);
  388. #endif //DEBUG
  389. if ( !bBuffer )
  390. {
  391. #ifdef DEBUG // DEBUG
  392. wprintf(L"#VirtualAlloc failed");
  393. #endif //DEBUG
  394. CoTaskMemFree(pvData);
  395. CloseHandle(hFile);
  396. hres = E_FAIL;
  397. break;
  398. }
  399. memset(bBuffer, '\0', (cbData > FILE_BUFFER_SIZE)?
  400. cbData:FILE_BUFFER_SIZE);
  401. if ( REG_SZ == c_wcKEYS[i].c_dwType )
  402. {
  403. wcscpy((WCHAR*)bBuffer, (WCHAR*)pvData);
  404. }
  405. else
  406. {
  407. memcpy(bBuffer, pvData, cbData);
  408. }
  409. CoTaskMemFree(pvData);
  410. DWORD NumberOfBytesWritten;
  411. BOOL bResult = WriteFile(
  412. hFile,
  413. bBuffer,
  414. (cbData > FILE_BUFFER_SIZE)?
  415. cbData:FILE_BUFFER_SIZE,
  416. &NumberOfBytesWritten,
  417. NULL
  418. );
  419. VirtualFree(
  420. bBuffer,
  421. (cbData > FILE_BUFFER_SIZE)?
  422. cbData:FILE_BUFFER_SIZE,
  423. MEM_RELEASE
  424. ); // ignore result
  425. CloseHandle(hFile);
  426. if ( bResult )
  427. {
  428. #ifdef DEBUG // DEBUG
  429. wprintf(L"#nb of bytes written %d\n"
  430. ,NumberOfBytesWritten);
  431. #endif //DEBUG
  432. hres = S_OK;
  433. }
  434. else
  435. {
  436. #ifdef DEBUG // DEBUG
  437. wprintf(L"#WriteFile failed %X\n",GetLastError());
  438. #endif //DEBUG
  439. hres = E_FAIL;
  440. break;
  441. }
  442. }
  443. }
  444. else
  445. {
  446. //
  447. // create an empty file
  448. #ifdef DEBUG // DEBUG
  449. wprintf(L"#REG_SZ = %d, REG_DWORD = %d\n",REG_SZ, REG_DWORD);
  450. wprintf(L"#SHGetValue failed code %X"
  451. L" param %s\\%s\n"
  452. L"# type = %d cbdata = %d\n",
  453. lResult,
  454. c_wcKEYS[i].c_wcKey,
  455. c_wcKEYS[i].c_wcValue,
  456. dwType,
  457. cbData
  458. );
  459. wprintf(L"#create an empty file\n\n");
  460. #endif //DEBUG
  461. BYTE bBuffer[FILE_BUFFER_SIZE];
  462. memset(bBuffer, '#', (cbData > FILE_BUFFER_SIZE)?
  463. cbData:FILE_BUFFER_SIZE);
  464. DWORD NumberOfBytesWritten;
  465. BOOL bResult = WriteFile(
  466. hFile,
  467. &bBuffer,
  468. FILE_BUFFER_SIZE,
  469. &NumberOfBytesWritten,
  470. NULL
  471. );
  472. CoTaskMemFree(pvData);
  473. CloseHandle(hFile);
  474. if ( bResult )
  475. {
  476. #ifdef DEBUG // DEBUG
  477. wprintf(L"#nb of bytes written %d\n"
  478. ,NumberOfBytesWritten);
  479. #endif //DEBUG
  480. hres = S_OK;
  481. }
  482. else
  483. {
  484. #ifdef DEBUG // DEBUG
  485. wprintf(L"#WriteFile failed\n");
  486. #endif //DEBUG
  487. hres = E_FAIL;
  488. break;
  489. }
  490. }
  491. }
  492. ////////////
  493. // Clean
  494. ////////////
  495. CoTaskMemFree(CompleteFile);
  496. }
  497. return hres;
  498. }
  499. //////////////////////////////////////////////////////////////////////////////
  500. //
  501. // IASRestoreRegKeys
  502. //
  503. // if something cannot be restored because of an empty
  504. // backup file (no key saved), that's not an error
  505. //
  506. //////////////////////////////////////////////////////////////////////////////
  507. HRESULT IASRestoreRegKeys()
  508. {
  509. HRESULT hres;
  510. int c_NbKeys = celems(c_wcKEYS);
  511. if ( c_NbKeys == 0 )
  512. {
  513. hres = S_OK;
  514. }
  515. else
  516. {
  517. ////////////////////////////
  518. // Enable backup privilege.
  519. // and sets hres
  520. ////////////////////////////
  521. CHECK_CALL_HRES (IASEnableBackupPrivilege());
  522. WCHAR* CompleteFile;
  523. CHECK_CALL_HRES (IASExpandString(c_wcKEYS_FILE, &CompleteFile));
  524. for ( int i = 0; i < c_NbKeys; ++i )
  525. {
  526. wstring sFileName(CompleteFile);
  527. WCHAR buffer[SIZE_LONG_MAX];
  528. DWORD dwDisposition;
  529. _itow(i, buffer, 10); // 10 means base 10
  530. sFileName += buffer;
  531. sFileName += L".txt";
  532. // open the file
  533. HANDLE hFile = CreateFileW(
  534. sFileName.c_str(),
  535. GENERIC_READ,
  536. 0,
  537. NULL,
  538. OPEN_EXISTING,
  539. FILE_ATTRIBUTE_NORMAL,
  540. NULL
  541. );
  542. if (INVALID_HANDLE_VALUE == hFile)
  543. {
  544. hres = E_FAIL;
  545. break;
  546. }
  547. // check the type of data expected
  548. LPVOID lpBuffer = NULL;
  549. DWORD SizeToRead;
  550. if (REG_SZ == c_wcKEYS[i].c_dwType)
  551. {
  552. lpBuffer = CoTaskMemAlloc(sizeof(WCHAR) * FILE_BUFFER_SIZE);
  553. SizeToRead = FILE_BUFFER_SIZE;
  554. }
  555. else if (REG_DWORD == c_wcKEYS[i].c_dwType)
  556. {
  557. lpBuffer = CoTaskMemAlloc(sizeof(DWORD));
  558. SizeToRead = sizeof(DWORD);
  559. }
  560. else
  561. {
  562. // unknown
  563. ASSERT(FALSE);
  564. }
  565. if (!lpBuffer)
  566. {
  567. CloseHandle(hFile);
  568. hres = E_OUTOFMEMORY;
  569. break;
  570. }
  571. memset(lpBuffer,'\0',SizeToRead);
  572. // read the file
  573. DWORD NumberOfBytesRead;
  574. ReadFile(
  575. hFile,
  576. lpBuffer,
  577. SizeToRead,
  578. &NumberOfBytesRead,
  579. NULL
  580. ); // ignore return value. uses NumberOfBytesRead
  581. // to determine success condition
  582. CloseHandle(hFile);
  583. // check if the file contains ####
  584. if ( NumberOfBytesRead == 0 )
  585. {
  586. // problem
  587. #ifdef DEBUG // DEBUG
  588. wprintf(L"#ReadFile failed %d %d\n",
  589. SizeToRead,
  590. NumberOfBytesRead
  591. );
  592. #endif //DEBUG
  593. CoTaskMemFree(lpBuffer);
  594. hres = E_FAIL;
  595. break;
  596. }
  597. else
  598. {
  599. BYTE TempBuffer[sizeof(DWORD)];
  600. memset(TempBuffer, '#', sizeof(DWORD));
  601. if (0 == memcmp(lpBuffer, TempBuffer, sizeof(DWORD)))
  602. {
  603. // no key saved, delete existing key if any
  604. #ifdef DEBUG // DEBUG
  605. wprintf(L"#no key saved, delete existing key if any\n");
  606. #endif //DEBUG
  607. HKEY hKeyToDelete = NULL;
  608. if (ERROR_SUCCESS == RegOpenKeyW(
  609. HKEY_LOCAL_MACHINE,
  610. c_wcKEYS[i].c_wcKey,
  611. &hKeyToDelete
  612. ))
  613. {
  614. if (ERROR_SUCCESS != RegDeleteValueW
  615. (
  616. hKeyToDelete,
  617. c_wcKEYS[i].c_wcValue
  618. ))
  619. {
  620. #ifdef DEBUG // DEBUG
  621. wprintf(L"#delete existing key failed\n");
  622. #endif //DEBUG
  623. }
  624. RegCloseKey(hKeyToDelete);
  625. }
  626. //
  627. // else do nothing: key doesn't exist
  628. //
  629. }
  630. else
  631. {
  632. // key saved: restore value
  633. // what if the value is bigger than
  634. // the buffer size?
  635. #ifdef DEBUG // DEBUG
  636. wprintf(L"#key saved: restore value\n");
  637. #endif //DEBUG
  638. HKEY hKeyToUpdate;
  639. LONG lResult = RegCreateKeyExW(
  640. HKEY_LOCAL_MACHINE,
  641. c_wcKEYS[i].c_wcKey,
  642. 0,
  643. NULL,
  644. REG_OPTION_NON_VOLATILE |
  645. REG_OPTION_BACKUP_RESTORE ,
  646. KEY_ALL_ACCESS,
  647. NULL,
  648. &hKeyToUpdate,
  649. &dwDisposition
  650. );
  651. if (ERROR_SUCCESS != lResult)
  652. {
  653. lResult = RegCreateKeyW(
  654. HKEY_LOCAL_MACHINE,
  655. c_wcKEYS[i].c_wcKey,
  656. &hKeyToUpdate
  657. );
  658. if (ERROR_SUCCESS != lResult)
  659. {
  660. #ifdef DEBUG
  661. // DEBUG
  662. wprintf(L"#RegCreateKeyW failed. code %x param %s\n",
  663. lResult,
  664. sFileName.c_str()
  665. );
  666. #endif //DEBUG
  667. RegCloseKey(hKeyToUpdate);
  668. hres = E_FAIL;
  669. break;
  670. }
  671. }
  672. if (REG_SZ == c_wcKEYS[i].c_dwType)
  673. {
  674. // nb of
  675. NumberOfBytesRead = (
  676. ( wcslen((WCHAR*)lpBuffer)
  677. + 1 // for /0
  678. ) * sizeof(WCHAR)
  679. );
  680. };
  681. //
  682. // Key created or key existing
  683. // both can be here (error = break)
  684. //
  685. if (ERROR_SUCCESS != RegSetValueExW(
  686. hKeyToUpdate,
  687. c_wcKEYS[i].c_wcValue,
  688. 0,
  689. c_wcKEYS[i].c_dwType,
  690. (BYTE*)lpBuffer,
  691. NumberOfBytesRead
  692. ))
  693. {
  694. RegCloseKey(hKeyToUpdate);
  695. hres = E_FAIL;
  696. break;
  697. }
  698. RegCloseKey(hKeyToUpdate);
  699. hres = S_OK;
  700. }
  701. CoTaskMemFree(lpBuffer);
  702. }
  703. }
  704. /////////
  705. // Clean
  706. /////////
  707. CoTaskMemFree(CompleteFile);
  708. }
  709. return hres;
  710. }
  711. /////////////////////////////////////////////////////////////////////////////
  712. //
  713. // IASExpandString
  714. //
  715. // Expands strings containing %ENV_VARIABLE%
  716. //
  717. // The output string is allocated only when the function succeed
  718. /////////////////////////////////////////////////////////////////////////////
  719. HRESULT
  720. IASExpandString(const WCHAR* pInputString, /*in/out*/ WCHAR** ppOutputString)
  721. {
  722. _ASSERTE(pInputString);
  723. _ASSERTE(pppOutputString);
  724. HRESULT hres;
  725. *ppOutputString = static_cast<WCHAR*>(CoTaskMemAlloc(
  726. SIZELINEMAX
  727. * sizeof(WCHAR)
  728. ));
  729. if ( ! *ppOutputString )
  730. {
  731. hres = E_OUTOFMEMORY;
  732. }
  733. else
  734. {
  735. if ( ExpandEnvironmentStringsForUserW(
  736. NULL,
  737. pInputString,
  738. *ppOutputString,
  739. SIZELINEMAX
  740. )
  741. )
  742. {
  743. hres = S_OK;
  744. }
  745. else
  746. {
  747. CoTaskMemFree(*ppOutputString);
  748. hres = E_FAIL;
  749. }
  750. }
  751. #ifdef DEBUG // DEBUG
  752. wprintf(L"#ExpandString: %s\n", *ppOutputString);
  753. #endif //DEBUG
  754. return hres;
  755. };
  756. /////////////////////////////////////////////////////////////////////////////
  757. //
  758. // DeleteTemporaryFiles()
  759. //
  760. // delete the temporary files if any
  761. //
  762. /////////////////////////////////////////////////////////////////////////////
  763. HRESULT DeleteTemporaryFiles()
  764. {
  765. HRESULT hres;
  766. WCHAR* sz_FileBackup;
  767. CHECK_CALL_HRES (IASExpandString(c_wcFILE_BACKUP,
  768. &sz_FileBackup
  769. )
  770. );
  771. DeleteFile(sz_FileBackup); //return value not checked
  772. CoTaskMemFree(sz_FileBackup);
  773. WCHAR* TempPath;
  774. CHECK_CALL_HRES (IASExpandString(c_wcKEYS_FILE, &TempPath));
  775. int c_NbKeys = celems(c_wcKEYS);
  776. for ( int i = 0; i < c_NbKeys; ++i )
  777. {
  778. wstring sFileName(TempPath);
  779. WCHAR buffer[SIZE_LONG_MAX];
  780. _itow(i, buffer, 10); // 10 means base 10
  781. sFileName += buffer;
  782. sFileName += L".txt";
  783. DeleteFile(sFileName.c_str()); //return value not checked
  784. }
  785. CoTaskMemFree(TempPath);
  786. return hres;
  787. }
  788. /////////////////////////////////////////////////////////////////////////////
  789. //
  790. // IASCompress
  791. //
  792. // Wrapper for RtlCompressBuffer
  793. //
  794. /////////////////////////////////////////////////////////////////////////////
  795. HRESULT IASCompress(
  796. PUCHAR pInputBuffer,
  797. ULONG* pulFileSize,
  798. PUCHAR* ppCompressedBuffer
  799. )
  800. {
  801. ULONG size, ignore;
  802. NTSTATUS status = RtlGetCompressionWorkSpaceSize(
  803. COMPRESSION_FORMAT_LZNT1 | COMPRESSION_ENGINE_MAXIMUM,
  804. &size,
  805. &ignore
  806. );
  807. if (!NT_SUCCESS(status))
  808. {
  809. #ifdef DEBUG
  810. printf("RtlGetCompressionWorkSpaceSize returned 0x%08X.\n", status);
  811. #endif //DEBUG
  812. return E_FAIL;
  813. }
  814. PVOID workSpace;
  815. workSpace = RtlAllocateHeap(
  816. RtlProcessHeap(),
  817. 0,
  818. size
  819. );
  820. if ( !workSpace )
  821. {
  822. return E_OUTOFMEMORY;
  823. }
  824. size = *pulFileSize;
  825. // That's a minimum buffer size that can be used
  826. if ( size < FILE_BUFFER_SIZE )
  827. {
  828. size = FILE_BUFFER_SIZE;
  829. }
  830. *ppCompressedBuffer = static_cast<PUCHAR>(RtlAllocateHeap(
  831. RtlProcessHeap(),
  832. 0,
  833. size
  834. ));
  835. if ( !*ppCompressedBuffer )
  836. {
  837. return E_OUTOFMEMORY;
  838. }
  839. status = RtlCompressBuffer(
  840. COMPRESSION_FORMAT_LZNT1 | COMPRESSION_ENGINE_MAXIMUM,
  841. pInputBuffer,
  842. size,
  843. *ppCompressedBuffer,
  844. size,
  845. 0,
  846. &size,
  847. workSpace
  848. );
  849. if (!NT_SUCCESS(status))
  850. {
  851. if (STATUS_BUFFER_TOO_SMALL == status)
  852. {
  853. #ifdef DEBUG
  854. printf("STATUS_BUFFER_TOO_SMALL\n");
  855. printf("RtlCompressBuffer returned 0x%08X.\n", status);
  856. #endif //DEBUG
  857. }
  858. else
  859. {
  860. #ifdef DEBUG
  861. printf("RtlCompressBuffer returned 0x%08X.\n", status);
  862. #endif //DEBUG
  863. }
  864. return E_FAIL;
  865. }
  866. *pulFileSize = size;
  867. RtlFreeHeap(
  868. RtlProcessHeap(),
  869. 0,
  870. workSpace
  871. );
  872. return S_OK;
  873. }
  874. /////////////////////////////////////////////////////////////////////////////
  875. //
  876. // IASUnCompress
  877. //
  878. //
  879. /////////////////////////////////////////////////////////////////////////////
  880. HRESULT IASUnCompress(
  881. PUCHAR pInputBuffer,
  882. ULONG* pulFileSize,
  883. PUCHAR* ppDeCompressedBuffer
  884. )
  885. {
  886. ULONG size, ignore;
  887. NTSTATUS status = RtlGetCompressionWorkSpaceSize(
  888. COMPRESSION_FORMAT_LZNT1 | COMPRESSION_ENGINE_MAXIMUM,
  889. &size,
  890. &ignore
  891. );
  892. if ( !NT_SUCCESS(status) )
  893. {
  894. #ifdef DEBUG
  895. printf("RtlGetCompressionWorkSpaceSize returned 0x%08X.\n", status);
  896. #endif //DEBUG
  897. return E_FAIL;
  898. }
  899. size = *pulFileSize;
  900. if( FILE_BUFFER_SIZE >= size)
  901. {
  902. size = FILE_BUFFER_SIZE;
  903. }
  904. *ppDeCompressedBuffer = static_cast<PUCHAR>(RtlAllocateHeap(
  905. RtlProcessHeap(),
  906. 0,
  907. size * DECOMPRESS_FACTOR
  908. ));
  909. if ( !*ppDeCompressedBuffer )
  910. {
  911. return E_OUTOFMEMORY;
  912. }
  913. ULONG UncompressedSize;
  914. status = RtlDecompressBuffer(
  915. COMPRESSION_FORMAT_LZNT1 | COMPRESSION_ENGINE_MAXIMUM,
  916. *ppDeCompressedBuffer,
  917. size * DECOMPRESS_FACTOR,
  918. pInputBuffer,
  919. *pulFileSize ,
  920. &UncompressedSize
  921. );
  922. if ( !NT_SUCCESS(status) )
  923. {
  924. #ifdef DEBUG
  925. printf("RtlUnCompressBuffer returned 0x%08X.\n", status);
  926. #endif //DEBUG
  927. switch (status)
  928. {
  929. case STATUS_INVALID_PARAMETER:
  930. #ifdef DEBUG
  931. printf("STATUS_INVALID_PARAMETER");
  932. #endif //DEBUG
  933. break;
  934. case STATUS_BAD_COMPRESSION_BUFFER:
  935. #ifdef DEBUG
  936. printf("STATUS_BAD_COMPRESSION_BUFFER ");
  937. printf("size = %d %d",pulFileSize,UncompressedSize);
  938. #endif //DEBUG
  939. break;
  940. case STATUS_UNSUPPORTED_COMPRESSION:
  941. #ifdef DEBUG
  942. printf("STATUS_UNSUPPORTED_COMPRESSION ");
  943. #endif //DEBUG
  944. break;
  945. }
  946. return E_FAIL;
  947. }
  948. *pulFileSize = UncompressedSize;
  949. return S_OK;
  950. }
  951. /////////////////////////////////////////////////////////////////////////////
  952. //
  953. // IASFileToBase64
  954. //
  955. // Compress then encode to Base64
  956. //
  957. // BSTR by Allocated IASFileToBase64, should be freed by the caller
  958. //
  959. /////////////////////////////////////////////////////////////////////////////
  960. HRESULT
  961. IASFileToBase64(const WCHAR* pFileName, /*out*/ BSTR* pOutputBSTR)
  962. {
  963. _ASSERTE(pFileName);
  964. _ASSERTE(pppOutputString);
  965. HRESULT hres;
  966. HANDLE hFileHandle = CreateFileW(
  967. pFileName,
  968. GENERIC_READ,
  969. FILE_SHARE_READ,
  970. NULL,
  971. OPEN_EXISTING,
  972. FILE_ATTRIBUTE_NORMAL,
  973. NULL
  974. );
  975. if ( hFileHandle == INVALID_HANDLE_VALUE )
  976. {
  977. #ifdef DEBUG
  978. wprintf(L"#filename = %s",pFileName);
  979. wprintf(L"### INVALID_HANDLE_VALUE ###\n");
  980. #endif //DEBUG
  981. hres = E_FAIL;
  982. return hres;
  983. }
  984. // safe cast from DWORD to ULONG
  985. ULONG ulFileSize = (ULONG) GetFileSize(
  986. hFileHandle, // file for which to get size
  987. NULL// high-order word of file size
  988. );
  989. if (0xFFFFFFFF == ulFileSize)
  990. {
  991. #ifdef DEBUG
  992. wprintf(L"### GetFileSize Failed ###\n");
  993. #endif //DEBUG
  994. hres = E_FAIL;
  995. return hres;
  996. }
  997. HANDLE hFileMapping = CreateFileMapping(
  998. hFileHandle, // handle to file to map
  999. NULL, // optional security attributes
  1000. PAGE_READONLY, // protection for mapping object
  1001. 0, // high-order 32 bits of object size
  1002. 0, // low-order 32 bits of object size
  1003. NULL // name of file-mapping object
  1004. );
  1005. if (NULL == hFileMapping)
  1006. {
  1007. #ifdef DEBUG
  1008. wprintf(L"### CreateFileMapping Failed ###\n");
  1009. #endif //DEBUG
  1010. hres = E_FAIL;
  1011. return hres;
  1012. }
  1013. LPVOID pMemoryFile = MapViewOfFile(
  1014. hFileMapping, // file-mapping object to map into
  1015. // address space
  1016. FILE_MAP_READ, // access mode
  1017. 0, // high-order 32 bits of file offset
  1018. 0, // low-order 32 bits of file offset
  1019. 0 // number of bytes to map
  1020. );
  1021. if (NULL == pMemoryFile)
  1022. {
  1023. #ifdef DEBUG
  1024. wprintf(L"### MapViewOfFile Failed ###\n");
  1025. #endif //DEBUG
  1026. hres = E_FAIL;
  1027. return hres;
  1028. }
  1029. /////////////////////////////
  1030. // NOW compress
  1031. /////////////////////////////
  1032. WCHAR* pCompressedBuffer;
  1033. CHECK_CALL_HRES (IASCompress((PUCHAR) pMemoryFile,
  1034. /*IN OUT*/(ULONG *) &ulFileSize,
  1035. /*IN OUT*/(PUCHAR*) &pCompressedBuffer));
  1036. /////////////////////
  1037. // Encode to Base64
  1038. /////////////////////
  1039. CHECK_CALL_HRES (ToBase64(
  1040. pCompressedBuffer,
  1041. (ULONG) ulFileSize,
  1042. pOutputBSTR
  1043. )
  1044. );
  1045. /////////////////////////////
  1046. // Clean
  1047. /////////////////////////////
  1048. RtlFreeHeap(
  1049. RtlProcessHeap(),
  1050. 0,
  1051. pCompressedBuffer
  1052. );
  1053. BOOL bResult = UnmapViewOfFile(
  1054. pMemoryFile// address where mapped view begins
  1055. );
  1056. if (FALSE == bResult)
  1057. {
  1058. #ifdef DEBUG
  1059. wprintf(L"### UnmapViewOfFile Failed ###\n");
  1060. #endif //DEBUG
  1061. hres = E_FAIL;
  1062. }
  1063. CloseHandle(hFileMapping);
  1064. CloseHandle(hFileHandle);
  1065. return hres;
  1066. }
  1067. /////////////////////////////////////////////////////////////////////////////
  1068. //
  1069. // IASDumpConfig
  1070. //
  1071. // Dump the configuration to some temporary files, then indidually
  1072. // compress then encode them.
  1073. // one big string is created from those multiple Base64 strings.
  1074. //
  1075. // Remarks: IASDumpConfig does a malloc and allocates memory for
  1076. // *ppDumpString. The calling function will have to free that memory
  1077. //
  1078. /////////////////////////////////////////////////////////////////////////////
  1079. HRESULT
  1080. IASDumpConfig(/*inout*/ WCHAR **ppDumpString, /*inout*/ ULONG *ulSize)
  1081. {
  1082. _ASSERTE(ppDumpString);
  1083. _ASSERTE(ulSize);
  1084. HRESULT hres;
  1085. ///////////////////////////////////////
  1086. // delete the temporary files if any
  1087. ///////////////////////////////////////
  1088. CHECK_CALL_HRES (DeleteTemporaryFiles());
  1089. ////////////////////////////////////////////////////
  1090. // Save the Registry keys. that creates many files
  1091. ////////////////////////////////////////////////////
  1092. CHECK_CALL_HRES (IASSaveRegKeys());
  1093. //////////////////////
  1094. // connect to the DB
  1095. //////////////////////
  1096. WCHAR* sz_DBPath;
  1097. CHECK_CALL_HRES (IASExpandString(c_wcIAS_MDB_FILE_NAME, &sz_DBPath));
  1098. CComPtr<IIASNetshJetHelper> JetHelper;
  1099. CHECK_CALL_HRES (CoCreateInstance(
  1100. __uuidof(CIASNetshJetHelper),
  1101. NULL,
  1102. CLSCTX_SERVER,
  1103. __uuidof(IIASNetshJetHelper),
  1104. (PVOID*) &JetHelper
  1105. ));
  1106. CComBSTR DBPath(sz_DBPath);
  1107. if ( !DBPath ) { return E_OUTOFMEMORY; }
  1108. CHECK_CALL_HRES (JetHelper->OpenJetDatabase(DBPath, TRUE));
  1109. //////////////////////////////////////
  1110. // Create a new DB named "Backup.mdb"
  1111. //////////////////////////////////////
  1112. WCHAR* sz_FileBackup;
  1113. CHECK_CALL_HRES (IASExpandString(c_wcFILE_BACKUP,
  1114. &sz_FileBackup
  1115. )
  1116. );
  1117. CComBSTR BackupDb(sz_FileBackup);
  1118. if ( !BackupDb ) { return E_OUTOFMEMORY; }
  1119. CHECK_CALL_HRES (JetHelper->CreateJetDatabase(BackupDb));
  1120. //////////////////////////////////////////////////////////
  1121. // exec the sql statements (to export)
  1122. // the content into the temp database
  1123. //////////////////////////////////////////////////////////
  1124. WCHAR* sz_SelectProperties;
  1125. CHECK_CALL_HRES (IASExpandString(c_wcSELECT_PROPERTIES_INTO,
  1126. &sz_SelectProperties
  1127. )
  1128. );
  1129. CComBSTR SelectProperties(sz_SelectProperties);
  1130. if ( !SelectProperties ) { return E_OUTOFMEMORY; }
  1131. CHECK_CALL_HRES (JetHelper->ExecuteSQLCommand(SelectProperties));
  1132. WCHAR* sz_SelectObjects;
  1133. CHECK_CALL_HRES (IASExpandString(c_wcSELECT_OBJECTS_INTO,
  1134. &sz_SelectObjects
  1135. )
  1136. );
  1137. CComBSTR SelectObjects(sz_SelectObjects);
  1138. if ( !SelectObjects ) { return E_OUTOFMEMORY; }
  1139. CHECK_CALL_HRES (JetHelper->ExecuteSQLCommand(SelectObjects));
  1140. WCHAR* sz_SelectVersion;
  1141. CHECK_CALL_HRES (IASExpandString(c_wcSELECT_VERSION_INTO,
  1142. &sz_SelectVersion
  1143. )
  1144. );
  1145. CComBSTR SelectVersion(sz_SelectVersion);
  1146. if ( !SelectVersion ) { return E_OUTOFMEMORY; }
  1147. CHECK_CALL_HRES (JetHelper->ExecuteSQLCommand(SelectVersion));
  1148. /////////////////////////////////////////////
  1149. // transform the file into Base64 BSTR
  1150. /////////////////////////////////////////////
  1151. BSTR FileBackupBSTR;
  1152. CHECK_CALL_HRES (IASFileToBase64(
  1153. sz_FileBackup,
  1154. &FileBackupBSTR
  1155. )
  1156. );
  1157. int NumberOfKeyFiles = celems(c_wcKEYS);
  1158. BSTR pFileKeys[celems(c_wcKEYS)];
  1159. WCHAR* sz_FileRegistry;
  1160. CHECK_CALL_HRES (IASExpandString(c_wcKEYS_FILE,
  1161. &sz_FileRegistry
  1162. )
  1163. );
  1164. for ( int i = 0; i < NumberOfKeyFiles; ++i )
  1165. {
  1166. wstring sFileName(sz_FileRegistry);
  1167. WCHAR buffer[SIZE_LONG_MAX];
  1168. _itow(i, buffer, 10); // 10 means base 10
  1169. sFileName += buffer;
  1170. sFileName += L".txt";
  1171. CHECK_CALL_HRES (IASFileToBase64(
  1172. sFileName.c_str(),
  1173. &pFileKeys[i]
  1174. )
  1175. );
  1176. }
  1177. CoTaskMemFree(sz_FileRegistry);
  1178. ///////////////////////////////////////////////
  1179. // alloc the memory for full the Base64 string
  1180. ///////////////////////////////////////////////
  1181. *ulSize = SysStringByteLen(FileBackupBSTR)
  1182. + EXTRA_CHAR_SPACE;
  1183. for ( int j = 0; j < NumberOfKeyFiles; ++j )
  1184. {
  1185. *ulSize += SysStringByteLen(pFileKeys[j]);
  1186. *ulSize += 2; // extra characters
  1187. }
  1188. *ppDumpString = (WCHAR *) calloc(
  1189. *ulSize ,
  1190. sizeof(WCHAR)
  1191. );
  1192. //////////////////////////////////////////////////
  1193. // copy the different strings into one big string
  1194. //////////////////////////////////////////////////
  1195. if (*ppDumpString)
  1196. {
  1197. wcsncpy(
  1198. (WCHAR*) *ppDumpString,
  1199. (WCHAR*) FileBackupBSTR,
  1200. SysStringLen(FileBackupBSTR)
  1201. );
  1202. for ( int k = 0; k < NumberOfKeyFiles; ++k )
  1203. {
  1204. wcscat(
  1205. (WCHAR*) *ppDumpString,
  1206. L"*\\\n"
  1207. );
  1208. wcsncat(
  1209. (WCHAR*) *ppDumpString,
  1210. (WCHAR*) pFileKeys[k],
  1211. SysStringLen(pFileKeys[k])
  1212. );
  1213. }
  1214. wcscat(
  1215. (WCHAR*) *ppDumpString,
  1216. L"QWER * QWER\\\n"
  1217. );
  1218. *ulSize = wcslen(*ppDumpString);
  1219. }
  1220. else
  1221. {
  1222. hres = E_OUTOFMEMORY;
  1223. #ifdef DEBUG
  1224. wprintf(L"### calloc failed ###\n");
  1225. #endif //DEBUG
  1226. }
  1227. ///////////////////////////////////////
  1228. // delete the temporary files if any
  1229. ///////////////////////////////////////
  1230. CHECK_CALL_HRES (DeleteTemporaryFiles());
  1231. /////////////////////////////////////////////
  1232. // Clean
  1233. /////////////////////////////////////////////
  1234. for ( int k = 0; k < NumberOfKeyFiles; ++k )
  1235. {
  1236. SysFreeString(pFileKeys[k]);
  1237. }
  1238. CoTaskMemFree(sz_SelectVersion);
  1239. CoTaskMemFree(sz_SelectProperties);
  1240. CoTaskMemFree(sz_SelectObjects);
  1241. CoTaskMemFree(sz_FileBackup);
  1242. CoTaskMemFree(sz_DBPath);
  1243. SysFreeString(FileBackupBSTR);
  1244. CHECK_CALL_HRES (JetHelper->CloseJetDatabase());
  1245. return hres;
  1246. }
  1247. /////////////////////////////////////////////////////////////////////////////
  1248. //
  1249. // IASSaveToFile
  1250. //
  1251. // Remark: if a new table has to be saved, an "entry" for that should be
  1252. // created in that function to deal with the filemname
  1253. //
  1254. /////////////////////////////////////////////////////////////////////////////
  1255. HRESULT IASSaveToFile(
  1256. /* in */ int Index,
  1257. /* in */ WCHAR* pContent,
  1258. DWORD lSize = 0
  1259. )
  1260. {
  1261. HRESULT hres;
  1262. wstring sFileName;
  1263. switch (Index)
  1264. {
  1265. case BACKUP_NB:
  1266. {
  1267. WCHAR* sz_FileBackup;
  1268. CHECK_CALL_HRES (IASExpandString(c_wcIAS_OLD,
  1269. &sz_FileBackup
  1270. )
  1271. );
  1272. sFileName = sz_FileBackup;
  1273. CoTaskMemFree(sz_FileBackup);
  1274. break;
  1275. }
  1276. ///////////
  1277. // binary
  1278. ///////////
  1279. default:
  1280. {
  1281. ///////////////////////////////////
  1282. // i + BINARY_NB is the parameter
  1283. ///////////////////////////////////
  1284. WCHAR* sz_FileRegistry;
  1285. CHECK_CALL_HRES (IASExpandString(c_wcKEYS_FILE,
  1286. &sz_FileRegistry
  1287. )
  1288. );
  1289. sFileName = sz_FileRegistry;
  1290. WCHAR buffer[SIZE_LONG_MAX];
  1291. _itow(Index - BINARY_NB, buffer, 10); // 10 means base 10
  1292. sFileName += buffer;
  1293. sFileName += L".txt";
  1294. CoTaskMemFree(sz_FileRegistry);
  1295. break;
  1296. }
  1297. }
  1298. HANDLE hFile = CreateFileW(
  1299. sFileName.c_str(),
  1300. GENERIC_WRITE,
  1301. FILE_SHARE_WRITE | FILE_SHARE_READ,
  1302. NULL,
  1303. CREATE_ALWAYS,
  1304. FILE_ATTRIBUTE_NORMAL,
  1305. NULL
  1306. );
  1307. if (INVALID_HANDLE_VALUE == hFile)
  1308. {
  1309. hres = E_FAIL;
  1310. }
  1311. else
  1312. {
  1313. DWORD NumberOfBytesWritten;
  1314. BOOL bResult = WriteFile(
  1315. hFile,
  1316. (LPVOID) pContent,
  1317. lSize,
  1318. &NumberOfBytesWritten,
  1319. NULL
  1320. );
  1321. if (bResult)
  1322. {
  1323. hres = S_OK;
  1324. }
  1325. else
  1326. {
  1327. hres = E_FAIL;
  1328. }
  1329. CloseHandle(hFile);
  1330. }
  1331. return hres;
  1332. }
  1333. /////////////////////////////////////////////////////////////////////////////
  1334. // IASRestoreConfig
  1335. //
  1336. // Clean the DB first, then insert back everything.
  1337. /////////////////////////////////////////////////////////////////////////////
  1338. HRESULT IASRestoreConfig(/*in*/ const WCHAR *pRestoreString)
  1339. {
  1340. _ASSERTE(pRestoreString);
  1341. bool bCoInitialized = false;
  1342. HRESULT hres = CoInitializeEx(NULL, COINIT_MULTITHREADED);
  1343. if (FAILED(hres))
  1344. {
  1345. if (RPC_E_CHANGED_MODE == hres)
  1346. {
  1347. hres = S_OK;
  1348. }
  1349. else
  1350. {
  1351. return hres;
  1352. }
  1353. }
  1354. else
  1355. {
  1356. bCoInitialized = true;
  1357. }
  1358. BSTR bstr = NULL;
  1359. do
  1360. {
  1361. ///////////////////////////////////////
  1362. // delete the temporary files if any
  1363. ///////////////////////////////////////
  1364. CHECK_CALL_HRES_BREAK (DeleteTemporaryFiles());
  1365. CComPtr<IIASNetshJetHelper> JetHelper;
  1366. CHECK_CALL_HRES_BREAK (CoCreateInstance(
  1367. __uuidof(CIASNetshJetHelper),
  1368. NULL,
  1369. CLSCTX_SERVER,
  1370. __uuidof(IIASNetshJetHelper),
  1371. (PVOID*) &JetHelper
  1372. ));
  1373. bstr = SysAllocStringLen(
  1374. pRestoreString,
  1375. wcslen(pRestoreString) + 2
  1376. );
  1377. if (bstr == NULL)
  1378. {
  1379. #ifdef DEBUG
  1380. wprintf(L"### IASRestoreConfig->SysAllocStringLen failed\n");
  1381. #endif //DEBUG
  1382. return E_OUTOFMEMORY;
  1383. }
  1384. int RealNumberOfFiles = MAX_FILES + celems(c_wcKEYS);
  1385. for ( int i = 0; i < RealNumberOfFiles; ++i )
  1386. {
  1387. BLOB lBlob;
  1388. lBlob.cbSize = 0;
  1389. lBlob.pBlobData = NULL;
  1390. // split the files and registry info
  1391. // uncompress (in memory ?)
  1392. CHECK_CALL_HRES_BREAK (FromBase64(bstr, &lBlob, i));
  1393. ULONG ulSize = lBlob.cbSize;
  1394. PUCHAR pDeCompressedBuffer;
  1395. ////////////////////////////////////
  1396. // decode and decompress the base64
  1397. ////////////////////////////////////
  1398. CHECK_CALL_HRES_BREAK (IASUnCompress(
  1399. lBlob.pBlobData,
  1400. &ulSize,
  1401. &pDeCompressedBuffer
  1402. ))
  1403. if ( i >= MAX_FILES )
  1404. {
  1405. /////////////////////////////////////
  1406. // Binary; i + BINARY_NB used here
  1407. /////////////////////////////////////
  1408. IASSaveToFile(
  1409. i - MAX_FILES + BINARY_NB,
  1410. (WCHAR*)pDeCompressedBuffer,
  1411. (DWORD) ulSize
  1412. );
  1413. }
  1414. else
  1415. {
  1416. IASSaveToFile(
  1417. i,
  1418. (WCHAR*)pDeCompressedBuffer,
  1419. (DWORD) ulSize
  1420. );
  1421. }
  1422. ////////////
  1423. // Clean
  1424. ////////////
  1425. RtlFreeHeap(RtlProcessHeap(), 0, pDeCompressedBuffer);
  1426. CoTaskMemFree(lBlob.pBlobData);
  1427. }
  1428. ///////////////////////////////////////////////////
  1429. // Now Upgrade the database (That's transactional)
  1430. ///////////////////////////////////////////////////
  1431. hres = JetHelper->UpgradeDatabase();
  1432. if ( SUCCEEDED(hres) )
  1433. {
  1434. #ifdef DEBUG
  1435. wprintf(L"### IASRestoreConfig->DB stuff successful\n");
  1436. #endif //DEBUG
  1437. ////////////////////////////////////////////////////////
  1438. // Now restore the registry.
  1439. ////////////////////////////////////////////////////////
  1440. hres = IASRestoreRegKeys();
  1441. if ( FAILED(hres) )
  1442. {
  1443. #ifdef DEBUG
  1444. wprintf(L"### IASRestoreConfig->restore reg keys failed\n");
  1445. #endif //DEBUG
  1446. }
  1447. }
  1448. // delete the temporary files
  1449. DeleteTemporaryFiles(); // do not check the result
  1450. } while (false);
  1451. SysFreeString(bstr);
  1452. if (bCoInitialized)
  1453. {
  1454. CoUninitialize();
  1455. }
  1456. return hres;
  1457. }