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.

1333 lines
32 KiB

  1. /*++
  2. Copyright(c) 2001 Microsoft Corporation
  3. Module Name:
  4. NLB Manager
  5. File Name:
  6. Fake.cpp
  7. Abstract:
  8. Fake Implementation of NlbHostXXX Apis (FakeNlbHostXXX apis)
  9. NLBHost is responsible for connecting to an NLB host and getting/setting
  10. its NLB-related configuration.
  11. History:
  12. 09/02/01 JosephJ Created
  13. --*/
  14. #include "private.h"
  15. #define SZ_REG_HOSTS L"Hosts" // Where host information is saved.
  16. #define SZ_REG_FQDN L"FQDN" // Fully qualified domain name
  17. #define SZ_REG_INTERFACES L"Interfaces" // Fully qualified domain name
  18. #define BASE_SLEEP 125
  19. BOOL
  20. is_ip_address(LPCWSTR szMachine);
  21. HKEY
  22. open_demo_key(LPCWSTR szSubKey, BOOL fCreate);
  23. DWORD WINAPI FakeThreadProc(
  24. LPVOID lpParameter // thread data
  25. );
  26. typedef struct
  27. {
  28. LPCWSTR szDomainName;
  29. LPCWSTR szClusterNetworkAddress;
  30. LPCWSTR *pszPortRules;
  31. } CLUSTER_INFO;
  32. LPCWSTR rgPortRules1[] = {
  33. L"ip=255.255.255.255 protocol=UDP start=80 end=288 mode=MULTIPLE"
  34. L" affinity=NONE load=80",
  35. NULL
  36. };
  37. CLUSTER_INFO
  38. Cluster1Info = {L"good1.com", L"10.0.0.100/255.0.0.0", rgPortRules1};
  39. //
  40. // Keeps track of a pending operation...
  41. //
  42. class CFakePendingInfo
  43. {
  44. public:
  45. CFakePendingInfo(const NLB_EXTENDED_CLUSTER_CONFIGURATION *pCfg)
  46. {
  47. wStatus = Config.Update(pCfg);
  48. if (!FAILED(wStatus))
  49. {
  50. wStatus = WBEM_S_PENDING;
  51. }
  52. // bstrLog;
  53. }
  54. NLB_EXTENDED_CLUSTER_CONFIGURATION Config;
  55. WBEMSTATUS wStatus;
  56. _bstr_t bstrLog;
  57. };
  58. typedef struct
  59. {
  60. //
  61. // These fields are set on initialization
  62. //
  63. LPCWSTR szInterfaceGuid;
  64. LPCWSTR szFriendlyName;
  65. LPCWSTR szNetworkAddress;
  66. BOOL fNlb;
  67. BOOL fHidden;
  68. CLUSTER_INFO *pCluster1Info;
  69. UINT InitialHostPriority;
  70. //
  71. // These are set/updated
  72. //
  73. //
  74. // Current configuration
  75. //
  76. PNLB_EXTENDED_CLUSTER_CONFIGURATION pConfig;
  77. //
  78. // If there is a pending update, info about the pending update.
  79. //
  80. CFakePendingInfo *pPendingInfo;
  81. WBEMSTATUS CompletedUpdateStatus;
  82. } FAKE_IF_INFO;
  83. typedef struct
  84. {
  85. LPCWSTR szHostName;
  86. LPCWSTR szFQDN;
  87. FAKE_IF_INFO *IfInfoList;
  88. LPCWSTR szUserName;
  89. LPCWSTR szPassword;
  90. //
  91. // Run-time state:
  92. //
  93. DWORD dwOperationalState; // WLBS_STOPPED, etc...
  94. BOOL fDead; // If set, we'll pretend this host is dead.
  95. } FAKE_HOST_INFO;
  96. WBEMSTATUS initialize_interface(FAKE_IF_INFO *pIF);
  97. WBEMSTATUS lookup_fake_if(
  98. FAKE_HOST_INFO *pHost,
  99. LPCWSTR szNicGuid,
  100. FAKE_IF_INFO **ppIF
  101. );
  102. WBEMSTATUS lookup_fake_host(
  103. LPCWSTR szConnectionString,
  104. FAKE_IF_INFO **ppIF,
  105. FAKE_HOST_INFO **ppHost
  106. );
  107. FAKE_IF_INFO rgH1IfList[] = {
  108. { L"{H1I10000-0000-0000-0000-000000000000}",
  109. L"NLB-Front1", L"172.31.56.101/255.0.0.0", FALSE },
  110. { L"{H1I20000-0000-0000-0000-000000000000}",
  111. L"back1", L"10.0.0.1/255.0.0.0", FALSE },
  112. { L"{H1I30000-0000-0000-0000-000000000000}",
  113. L"back2", L"11.0.0.1/255.0.0.0", FALSE }, { NULL }
  114. };
  115. FAKE_IF_INFO rgH2IfList[] = {
  116. { L"{H2I10000-0000-0000-0000-000000000000}",
  117. L"NLB-Front2", L"172.31.56.102/255.0.0.0", FALSE },
  118. { L"{H2I20000-0000-0000-0000-000000000000}",
  119. L"back1", L"10.0.0.2/255.0.0.0", FALSE },
  120. { L"{H2I30000-0000-0000-0000-000000000000}",
  121. L"back2", L"11.0.0.2/255.0.0.0", FALSE },
  122. { NULL }
  123. };
  124. FAKE_IF_INFO rgH3IfList[] = {
  125. { L"{H3I10000-0000-0000-0000-000000000000}",
  126. L"NLB-Front3", L"172.31.56.103/255.0.0.0", FALSE },
  127. { L"{H3I20000-0000-0000-0000-000000000000}",
  128. L"back1", L"10.0.0.3/255.0.0.0", FALSE },
  129. { L"{H3I30000-0000-0000-0000-000000000000}",
  130. L"back2", L"11.0.0.3/255.0.0.0", FALSE },
  131. { NULL }
  132. };
  133. FAKE_IF_INFO rgH4IfList[] = {
  134. { L"{H4I10000-0000-0000-0000-000000000000}",
  135. L"nic1", L"10.1.0.1/255.0.0.0", TRUE, FALSE, &Cluster1Info},
  136. { L"{H4I20000-0000-0000-0000-000000000000}",
  137. L"nic2", L"11.1.0.1/255.0.0.0", FALSE },
  138. { L"{H4I30000-0000-0000-0000-000000000000}",
  139. L"nic3", L"12.1.0.1/255.0.0.0", FALSE },
  140. { NULL }
  141. };
  142. FAKE_IF_INFO rgH5IfList[] = {
  143. { L"{H5I10000-0000-0000-0000-000000000000}",
  144. L"nic1", L"10.1.0.2/255.0.0.0", TRUE },
  145. { L"{H5I20000-0000-0000-0000-000000000000}",
  146. L"nic2", L"11.1.0.2/255.0.0.0", FALSE },
  147. { L"{H5I30000-0000-0000-0000-000000000000}",
  148. L"nic3", L"12.1.0.2/255.0.0.0", FALSE },
  149. { NULL }
  150. };
  151. FAKE_IF_INFO rgH6IfList[] = {
  152. { L"{H6I10000-0000-0000-0000-000000000000}",
  153. L"nic1", L"10.1.0.3/255.0.0.0", TRUE },
  154. { L"{H6I20000-0000-0000-0000-000000000000}",
  155. L"nic2", L"11.1.0.3/255.0.0.0", FALSE },
  156. { L"{H6I30000-0000-0000-0000-000000000000}",
  157. L"nic3", L"12.1.0.3/255.0.0.0", FALSE },
  158. { NULL }
  159. };
  160. FAKE_HOST_INFO rgFakeHostInfo[] =
  161. {
  162. { L"NLB-A", L"nlb-a.cheesegalaxy.com", rgH1IfList },
  163. { L"NLB-B", L"nlb-b.cheesegalaxy.com", rgH2IfList },
  164. { L"NLB-C", L"nlb-c.cheesegalaxy.com", rgH3IfList },
  165. { L"NLB-X", L"nlb-x.cheesegalaxy.com", rgH4IfList },
  166. { L"NLB-Y", L"nlb-y.cheesegalaxy.com", rgH5IfList },
  167. { L"NLB-Z", L"nlb-z.cheesegalaxy.com", rgH6IfList, L"un", L"pwd" },
  168. { NULL }
  169. };
  170. class CFake
  171. {
  172. public:
  173. CFake(void)
  174. {
  175. InitializeCriticalSection(&m_crit);
  176. }
  177. ~CFake()
  178. {
  179. DeleteCriticalSection(&m_crit);
  180. }
  181. CRITICAL_SECTION m_Lock;
  182. PNLB_EXTENDED_CLUSTER_CONFIGURATION pConfig;
  183. // map<_bstr_t, PNLB_EXTENDED_CLUSTER_CONFIGURATION> mapGuidToExtCfg;
  184. // map<_bstr_t, UINT> mapGuidToExtCfg;
  185. CRITICAL_SECTION m_crit;
  186. void mfn_Lock(void) {EnterCriticalSection(&m_crit);}
  187. void mfn_Unlock(void) {LeaveCriticalSection(&m_crit);}
  188. };
  189. CFake gFake;
  190. VOID
  191. FakeInitialize(VOID)
  192. {
  193. //
  194. //
  195. //
  196. }
  197. LPWSTR
  198. reg_read_string(
  199. HKEY hk,
  200. LPCWSTR szName,
  201. BOOL fMultiSz
  202. );
  203. WBEMSTATUS
  204. FakeNlbHostConnect(
  205. PWMI_CONNECTION_INFO pConnInfo, // NULL implies local
  206. OUT FAKE_HOST_INFO **pHost
  207. );
  208. WBEMSTATUS
  209. FakeNlbHostGetCompatibleNics(
  210. PWMI_CONNECTION_INFO pConnInfo, // NULL implies local
  211. OUT LPWSTR **ppszNics, // free using delete
  212. OUT UINT *pNumNics, // free using delete
  213. OUT UINT *pNumBoundToNlb
  214. )
  215. {
  216. FAKE_HOST_INFO *pHost = NULL;
  217. WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
  218. UINT NumNics=0;
  219. UINT NumBoundToNlb=0;
  220. LPWSTR *pszNics = NULL;
  221. *ppszNics = NULL;
  222. *pNumNics = NULL;
  223. *pNumBoundToNlb = NULL;
  224. Status = FakeNlbHostConnect(pConnInfo, &pHost);
  225. gFake.mfn_Lock();
  226. if (FAILED(Status))
  227. {
  228. goto end;
  229. }
  230. FAKE_IF_INFO *pIF = NULL;
  231. for (pIF=pHost->IfInfoList; pIF->szInterfaceGuid!=NULL; pIF++)
  232. {
  233. if (!pIF->fHidden)
  234. {
  235. NumNics++;
  236. }
  237. }
  238. if (NumNics==0)
  239. {
  240. Status = WBEM_NO_ERROR;
  241. goto end;
  242. }
  243. //
  244. // Now let's allocate space for all the nic strings and
  245. // copy them over..
  246. //
  247. #define MY_GUID_LENGTH 38
  248. pszNics = CfgUtilsAllocateStringArray(NumNics, MY_GUID_LENGTH);
  249. if (pszNics == NULL)
  250. {
  251. Status = WBEM_E_OUT_OF_MEMORY;
  252. goto end;
  253. }
  254. for (pIF=pHost->IfInfoList; pIF->szInterfaceGuid!=NULL; pIF++)
  255. {
  256. UINT u = (UINT)(pIF-pHost->IfInfoList);
  257. UINT Len = wcslen(pIF->szInterfaceGuid);
  258. if (pIF->fHidden)
  259. {
  260. continue;
  261. }
  262. if (Len > MY_GUID_LENGTH)
  263. {
  264. ASSERT(FALSE);
  265. Status = WBEM_E_CRITICAL_ERROR;
  266. goto end;
  267. }
  268. CopyMemory(
  269. pszNics[u],
  270. pIF->szInterfaceGuid,
  271. (Len+1)*sizeof(WCHAR));
  272. ASSERT(pszNics[u][Len]==0);
  273. if (pIF->fNlb)
  274. {
  275. NumBoundToNlb++;
  276. }
  277. }
  278. Status = WBEM_NO_ERROR;
  279. end:
  280. gFake.mfn_Unlock();
  281. if (FAILED(Status))
  282. {
  283. delete pszNics;
  284. pszNics = NULL;
  285. NumNics = 0;
  286. NumBoundToNlb = 0;
  287. }
  288. *ppszNics = pszNics;
  289. *pNumNics = NumNics;
  290. if (pNumBoundToNlb !=NULL)
  291. {
  292. *pNumBoundToNlb = NumBoundToNlb;
  293. }
  294. return Status;
  295. }
  296. WBEMSTATUS
  297. FakeNlbHostGetMachineIdentification(
  298. IN PWMI_CONNECTION_INFO pConnInfo, // NULL implies local
  299. OUT LPWSTR *pszMachineName, // free using delete
  300. OUT LPWSTR *pszMachineGuid, // free using delete -- may be null
  301. OUT BOOL *pfNlbMgrProviderInstalled // If nlb manager provider is installed.
  302. )
  303. {
  304. FAKE_HOST_INFO *pHost = NULL;
  305. WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
  306. *pszMachineName = NULL;
  307. *pszMachineGuid = NULL;
  308. *pfNlbMgrProviderInstalled = TRUE;
  309. Status = FakeNlbHostConnect(pConnInfo, &pHost);
  310. if (FAILED(Status))
  311. {
  312. goto end;
  313. }
  314. //
  315. // Set WMI machine name
  316. //
  317. {
  318. UINT u = wcslen(pHost->szHostName);
  319. LPWSTR szMachineName = NULL;
  320. szMachineName = new WCHAR[u+1];
  321. if (szMachineName == NULL)
  322. {
  323. Status = WBEM_E_CRITICAL_ERROR;
  324. goto end;
  325. }
  326. StringCchCopy(szMachineName, u+1, pHost->szHostName);
  327. *pszMachineName = szMachineName;
  328. }
  329. Status = WBEM_NO_ERROR;
  330. end:
  331. return Status;
  332. }
  333. WBEMSTATUS
  334. FakeNlbHostGetConfiguration(
  335. IN PWMI_CONNECTION_INFO pConnInfo, // NULL implies local
  336. IN LPCWSTR szNicGuid,
  337. OUT PNLB_EXTENDED_CLUSTER_CONFIGURATION pCurrentCfg
  338. )
  339. {
  340. WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
  341. FAKE_HOST_INFO *pHost = NULL;
  342. Status = FakeNlbHostConnect(pConnInfo, &pHost);
  343. if (FAILED(Status))
  344. {
  345. goto end;
  346. }
  347. //
  348. // Look for the specified interface
  349. //
  350. FAKE_IF_INFO *pIF = NULL;
  351. Status = lookup_fake_if(pHost, szNicGuid, &pIF);
  352. if (!FAILED(Status))
  353. {
  354. gFake.mfn_Lock();
  355. Status = pCurrentCfg->Update(pIF->pConfig);
  356. gFake.mfn_Unlock();
  357. }
  358. end:
  359. return Status;
  360. }
  361. WBEMSTATUS
  362. FakeNlbHostDoUpdate(
  363. IN PWMI_CONNECTION_INFO pConnInfo, // NULL implies local
  364. IN LPCWSTR szNicGuid,
  365. IN LPCWSTR szClientDescription,
  366. IN PNLB_EXTENDED_CLUSTER_CONFIGURATION pNewState,
  367. OUT UINT *pGeneration,
  368. OUT WCHAR **ppLog // free using delete operator.
  369. )
  370. {
  371. WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
  372. FAKE_HOST_INFO *pHost = NULL;
  373. *ppLog = NULL;
  374. Status = FakeNlbHostConnect(pConnInfo, &pHost);
  375. if (FAILED(Status))
  376. {
  377. goto end;
  378. }
  379. //
  380. // Look for the specified interface
  381. //
  382. FAKE_IF_INFO *pIF = NULL;
  383. Status = lookup_fake_if(pHost, szNicGuid, &pIF);
  384. if (!FAILED(Status))
  385. {
  386. BOOL fSetPwd = FALSE;
  387. DWORD dwHashPwd = 0;
  388. //
  389. // Report if there's a password specified...
  390. //
  391. {
  392. LPCWSTR szNewPwd = pNewState->GetNewRemoteControlPasswordRaw();
  393. WCHAR rgTmp[256];
  394. if (szNewPwd == NULL)
  395. {
  396. BOOL fRet = FALSE;
  397. fRet = pNewState->GetNewHashedRemoteControlPassword(
  398. dwHashPwd
  399. );
  400. if (fRet)
  401. {
  402. StringCbPrintf(rgTmp, sizeof(rgTmp), L"NewHashPwd=0x%08lx", dwHashPwd);
  403. szNewPwd = rgTmp;
  404. fSetPwd = TRUE;
  405. }
  406. }
  407. else
  408. {
  409. //
  410. // Create our own ad-hoc hash here...
  411. //
  412. for (LPCWSTR sz = szNewPwd; *sz; sz++)
  413. {
  414. dwHashPwd ^= *sz;
  415. if (dwHashPwd & 0x80000000)
  416. {
  417. dwHashPwd <<= 1;
  418. dwHashPwd |= 1;
  419. }
  420. else
  421. {
  422. dwHashPwd <<=1;
  423. }
  424. }
  425. fSetPwd = TRUE;
  426. }
  427. if (szNewPwd != NULL)
  428. {
  429. #if 0
  430. ::MessageBox(
  431. NULL,
  432. szNewPwd, // msg
  433. L"Update: new password specified!", // caption
  434. MB_ICONINFORMATION | MB_OK
  435. );
  436. #endif // 0
  437. }
  438. }
  439. Sleep(2*BASE_SLEEP);
  440. gFake.mfn_Lock();
  441. NLB_EXTENDED_CLUSTER_CONFIGURATION NewCopy;
  442. Status = NewCopy.Update(pNewState);
  443. if (!FAILED(Status))
  444. {
  445. NLBERROR nerr;
  446. BOOL fConnChange = FALSE;
  447. DWORD dwOldHashPwd = CfgUtilGetHashedRemoteControlPassword(
  448. &pIF->pConfig->NlbParams
  449. );
  450. //
  451. // Set the hashed pwd field if necessary, otherwise preserve
  452. // the old one.
  453. //
  454. if (!fSetPwd)
  455. {
  456. dwHashPwd = dwOldHashPwd;
  457. }
  458. #if 0
  459. if (dwHashPwd != dwOldHashPwd)
  460. {
  461. WCHAR buf[64];
  462. (void)StringCbPrintf(
  463. buf,
  464. sizeof(buf),
  465. L"Old=0x%lx New=0x%lx",
  466. dwOldHashPwd, dwHashPwd
  467. );
  468. ::MessageBox(
  469. NULL,
  470. buf, // msg
  471. L"Fake Update: Change in dwHashPwd!", // caption
  472. MB_ICONINFORMATION | MB_OK
  473. );
  474. }
  475. #endif // 0
  476. CfgUtilSetHashedRemoteControlPassword(
  477. &NewCopy.NlbParams,
  478. dwHashPwd
  479. );
  480. nerr = pIF->pConfig->AnalyzeUpdate(&NewCopy, &fConnChange);
  481. // TODO: if fConnChange, do stuff in background.
  482. if (NLBOK(nerr))
  483. {
  484. if (pIF->pPendingInfo != NULL)
  485. {
  486. Status = WBEM_E_SERVER_TOO_BUSY;
  487. }
  488. else
  489. {
  490. if (fConnChange)
  491. {
  492. //
  493. // We'll do the update in the background.
  494. //
  495. CFakePendingInfo *pPendingInfo;
  496. pPendingInfo = new CFakePendingInfo(&NewCopy);
  497. if (pPendingInfo == NULL)
  498. {
  499. Status = WBEM_E_OUT_OF_MEMORY;
  500. }
  501. else
  502. {
  503. BOOL fRet;
  504. pIF->pPendingInfo = pPendingInfo;
  505. fRet = QueueUserWorkItem(
  506. FakeThreadProc,
  507. pIF,
  508. // WT_EXECUTEDEFAULT
  509. WT_EXECUTELONGFUNCTION
  510. );
  511. if (fRet)
  512. {
  513. Status = WBEM_S_PENDING;
  514. }
  515. else
  516. {
  517. Status = WBEM_E_OUT_OF_MEMORY;
  518. pIF->pPendingInfo = NULL;
  519. delete pPendingInfo;
  520. }
  521. }
  522. }
  523. else
  524. {
  525. Status = pIF->pConfig->Update(&NewCopy);
  526. pIF->pConfig->Generation++;
  527. }
  528. }
  529. }
  530. else
  531. {
  532. if (nerr == NLBERR_NO_CHANGE)
  533. {
  534. Status = WBEM_S_FALSE;
  535. }
  536. else if (nerr == NLBERR_INVALID_CLUSTER_SPECIFICATION)
  537. {
  538. Status = WBEM_E_INVALID_PARAMETER;
  539. }
  540. }
  541. }
  542. gFake.mfn_Unlock();
  543. }
  544. end:
  545. return Status;
  546. }
  547. WBEMSTATUS
  548. FakeNlbHostGetUpdateStatus(
  549. IN PWMI_CONNECTION_INFO pConnInfo, // NULL implies local
  550. IN LPCWSTR szNicGuid,
  551. IN UINT Generation,
  552. OUT WBEMSTATUS *pCompletionStatus,
  553. OUT WCHAR **ppLog // free using delete operator.
  554. )
  555. {
  556. WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
  557. FAKE_HOST_INFO *pHost = NULL;
  558. Status = FakeNlbHostConnect(pConnInfo, &pHost);
  559. if (FAILED(Status))
  560. {
  561. goto end;
  562. }
  563. //
  564. // Look for the specified interface
  565. //
  566. FAKE_IF_INFO *pIF = NULL;
  567. Status = lookup_fake_if(pHost, szNicGuid, &pIF);
  568. if (!FAILED(Status))
  569. {
  570. gFake.mfn_Lock();
  571. if (pIF->pPendingInfo != NULL)
  572. {
  573. *pCompletionStatus = WBEM_S_PENDING;
  574. }
  575. else
  576. {
  577. *pCompletionStatus = pIF->CompletedUpdateStatus;
  578. }
  579. Status = WBEM_NO_ERROR;
  580. gFake.mfn_Unlock();
  581. }
  582. end:
  583. return Status;
  584. }
  585. WBEMSTATUS
  586. FakeNlbHostPing(
  587. IN LPCWSTR szBindString,
  588. IN UINT Timeout, // In milliseconds.
  589. OUT ULONG *pResolvedIpAddress // in network byte order.
  590. )
  591. {
  592. WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
  593. FAKE_HOST_INFO *pHost = NULL;
  594. //Status = FakeNlbHostConnect(pConnInfo, &pHost);
  595. *pResolvedIpAddress = 0x0100000a;
  596. Status = WBEM_NO_ERROR;
  597. if (FAILED(Status))
  598. {
  599. goto end;
  600. }
  601. end:
  602. return Status;
  603. }
  604. BOOL
  605. is_ip_address(LPCWSTR szMachine)
  606. /*
  607. Returns TRUE IFF szMachine is an IP address.
  608. It doesn't check if it's a valid IP address.
  609. In fact, all it checks is if it's only consisting
  610. of numbers and dots.
  611. */
  612. {
  613. BOOL fRet = FALSE;
  614. #define BUFSZ 20
  615. WCHAR rgBuf[BUFSZ];
  616. if (wcslen(szMachine) >= BUFSZ) goto end;
  617. if (swscanf(szMachine, L"%[0-9.]", rgBuf)!=1) goto end;
  618. if (wcscmp(szMachine, rgBuf)) goto end;
  619. fRet = TRUE;
  620. end:
  621. return fRet;
  622. }
  623. HKEY
  624. open_demo_key(LPCWSTR szSubKey, BOOL fCreate)
  625. /*
  626. Open nlbmanager demo registry key with read/write access.
  627. */
  628. {
  629. WCHAR szKey[1024];
  630. HKEY hKey = NULL;
  631. LONG lRet;
  632. StringCbCopy(szKey, sizeof(szKey),
  633. L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NLB\\NlbManager\\Demo"
  634. );
  635. if (szSubKey != NULL)
  636. {
  637. StringCbCat(szKey, sizeof(szKey), L"\\");
  638. StringCbCat(szKey, sizeof(szKey), szSubKey);
  639. }
  640. if (fCreate)
  641. {
  642. DWORD dwDisposition;
  643. lRet = RegCreateKeyEx(
  644. HKEY_LOCAL_MACHINE, // handle to an open key
  645. szKey, // address of subkey name
  646. 0, // reserved
  647. L"class", // address of class string
  648. 0, // special options flag
  649. KEY_ALL_ACCESS, // desired security access
  650. NULL, // address of key security structure
  651. &hKey, // address of buffer for opened handle
  652. &dwDisposition // address of disposition value buffer
  653. );
  654. }
  655. else
  656. {
  657. lRet = RegOpenKeyEx(
  658. HKEY_LOCAL_MACHINE, // handle to an open key
  659. szKey, // address of subkey name
  660. 0, // reserved
  661. KEY_ALL_ACCESS, // desired security access
  662. &hKey // address of buffer for opened handle
  663. );
  664. }
  665. if (lRet != ERROR_SUCCESS)
  666. {
  667. hKey = NULL;
  668. }
  669. return hKey;
  670. }
  671. LPWSTR
  672. reg_read_string(
  673. HKEY hk,
  674. LPCWSTR szName,
  675. BOOL fMultiSz
  676. )
  677. /*
  678. Read a string from the registry, allocating memory using "new WCHAR"
  679. */
  680. {
  681. LONG lRet;
  682. DWORD dwType;
  683. DWORD dwData = 0;
  684. DWORD dwDesiredType = REG_SZ;
  685. if (fMultiSz)
  686. {
  687. dwDesiredType = REG_MULTI_SZ;
  688. }
  689. lRet = RegQueryValueEx(
  690. hk, // handle to key to query
  691. szName,
  692. NULL, // reserved
  693. &dwType, // address of buffer for value type
  694. (LPBYTE) NULL, // address of data buffer
  695. &dwData // address of data buffer size
  696. );
  697. if ( lRet != ERROR_SUCCESS
  698. || dwType != dwDesiredType
  699. || dwData <= sizeof(WCHAR))
  700. {
  701. goto end;
  702. }
  703. LPWSTR szValue = new WCHAR[dwData/sizeof(WCHAR)+1]; // bytes to wchars
  704. if (szValue == NULL) goto end;
  705. lRet = RegQueryValueEx(
  706. hk, // handle to key to query
  707. szName,
  708. NULL, // reserved
  709. &dwType, // address of buffer for value type
  710. (LPBYTE) szValue, // address of data buffer
  711. &dwData // address of data buffer size
  712. );
  713. if ( lRet != ERROR_SUCCESS
  714. || dwType != dwDesiredType
  715. || dwData <= sizeof(WCHAR))
  716. {
  717. delete[] szValue;
  718. szValue = NULL;
  719. goto end;
  720. }
  721. end:
  722. return szValue;
  723. }
  724. WBEMSTATUS
  725. FakeNlbHostConnect(
  726. PWMI_CONNECTION_INFO pConnInfo, // NULL implies local
  727. OUT FAKE_HOST_INFO **ppHost
  728. )
  729. {
  730. WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
  731. /*
  732. For now, just look for machine name of fqdn
  733. */
  734. FAKE_HOST_INFO *pfhi = rgFakeHostInfo;
  735. LPCWSTR szHostName;
  736. LPCWSTR szFQDN;
  737. FAKE_IF_INFO *IfInfoList;
  738. LPCWSTR szMachine = NULL;
  739. LPCWSTR szUserName = pConnInfo->szUserName;
  740. LPCWSTR szPassword = pConnInfo->szPassword;
  741. *ppHost = NULL;
  742. if (pConnInfo == NULL)
  743. {
  744. // We don't support local connections.
  745. Status = WBEM_E_NOT_FOUND;
  746. goto end;
  747. }
  748. if (szUserName == NULL)
  749. {
  750. szUserName = L"null-name";
  751. }
  752. szMachine = pConnInfo->szMachine; // should not be NULL.
  753. for (; pfhi->szHostName != NULL; pfhi++)
  754. {
  755. if ( !_wcsicmp(szMachine, pfhi->szHostName)
  756. || !_wcsicmp(szMachine, pfhi->szFQDN))
  757. {
  758. break;
  759. }
  760. }
  761. if (pfhi->szHostName == NULL || pfhi->fDead)
  762. {
  763. Sleep(3*BASE_SLEEP);
  764. Status = WBEM_E_NOT_FOUND;
  765. }
  766. else
  767. {
  768. Sleep(BASE_SLEEP);
  769. if (pfhi->szUserName != NULL)
  770. {
  771. WCHAR rgClearPassword[128];
  772. if (szPassword == NULL)
  773. {
  774. ARRAYSTRCPY(rgClearPassword, L"null-password");
  775. }
  776. else
  777. {
  778. BOOL fRet = CfgUtilDecryptPassword(
  779. szPassword,
  780. ASIZE(rgClearPassword),
  781. rgClearPassword
  782. );
  783. if (!fRet)
  784. {
  785. ARRAYSTRCPY(rgClearPassword, L"bogus-password");
  786. }
  787. }
  788. if ( !_wcsicmp(szUserName, pfhi->szUserName)
  789. && !_wcsicmp(rgClearPassword, pfhi->szPassword))
  790. {
  791. Status = WBEM_NO_ERROR;
  792. *ppHost = pfhi;
  793. }
  794. else
  795. {
  796. Status = (WBEMSTATUS) E_ACCESSDENIED;
  797. }
  798. // We don't need to put this here, because
  799. // this is fake (demo-mode) code:
  800. // RtlSecureZeroMemory(rgClearPassword);
  801. }
  802. else
  803. {
  804. Status = WBEM_NO_ERROR;
  805. *ppHost = pfhi;
  806. }
  807. }
  808. end:
  809. return Status;
  810. }
  811. WBEMSTATUS initialize_interface(FAKE_IF_INFO *pIF)
  812. {
  813. WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
  814. PNLB_EXTENDED_CLUSTER_CONFIGURATION pConfig = NULL;
  815. if (pIF->pConfig != NULL)
  816. {
  817. ASSERT(FALSE);
  818. goto end;
  819. }
  820. pConfig = new NLB_EXTENDED_CLUSTER_CONFIGURATION;
  821. if (pConfig == NULL) goto end;
  822. Status = pConfig->SetFriendlyName(pIF->szFriendlyName);
  823. if (FAILED(Status)) goto end;
  824. Status = pConfig->SetNetworkAddresses(&pIF->szNetworkAddress, 1);
  825. if (FAILED(Status)) goto end;
  826. if (pIF->fNlb)
  827. {
  828. pConfig->SetDefaultNlbCluster();
  829. pConfig->SetClusterName(L"BadCluster.COM");
  830. }
  831. pIF->pConfig = pConfig;
  832. pIF->pConfig->Generation = 1;
  833. pIF->pPendingInfo = NULL;
  834. pIF->CompletedUpdateStatus = WBEM_E_CRITICAL_ERROR;
  835. end:
  836. return Status;
  837. }
  838. WBEMSTATUS lookup_fake_if(
  839. FAKE_HOST_INFO *pHost,
  840. LPCWSTR szNicGuid,
  841. FAKE_IF_INFO **ppIF
  842. )
  843. {
  844. WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
  845. FAKE_IF_INFO *pIF;
  846. *ppIF = NULL;
  847. for (pIF=pHost->IfInfoList; pIF->szInterfaceGuid!=NULL; pIF++)
  848. {
  849. if (!wcscmp(szNicGuid, pIF->szInterfaceGuid))
  850. {
  851. if (!pIF->fHidden)
  852. {
  853. break;
  854. }
  855. }
  856. }
  857. if (pIF->szInterfaceGuid==NULL)
  858. {
  859. Status = WBEM_E_NOT_FOUND;
  860. goto end;
  861. }
  862. //
  863. // Perform on-demand initialization
  864. //
  865. {
  866. Status = WBEM_NO_ERROR;
  867. gFake.mfn_Lock();
  868. if (pIF->pConfig == NULL)
  869. {
  870. Status = initialize_interface(pIF);
  871. ASSERT(pIF->pConfig!=NULL);
  872. }
  873. gFake.mfn_Unlock();
  874. *ppIF = pIF;
  875. }
  876. end:
  877. return Status;
  878. }
  879. WBEMSTATUS lookup_fake_host(
  880. LPCWSTR szConnectionString,
  881. FAKE_IF_INFO **ppIF,
  882. FAKE_HOST_INFO **ppHost
  883. );
  884. WBEMSTATUS
  885. FakeNlbHostControlCluster(
  886. IN PWMI_CONNECTION_INFO pConnInfo, // NULL implies local
  887. IN LPCWSTR szNicGuid,
  888. IN LPCWSTR szVip,
  889. IN DWORD *pdwPortNum,
  890. IN WLBS_OPERATION_CODES Operation,
  891. OUT DWORD *pdwOperationStatus,
  892. OUT DWORD *pdwClusterOrPortStatus,
  893. OUT DWORD *pdwHostMap
  894. )
  895. {
  896. FAKE_HOST_INFO *pHost = NULL;
  897. WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
  898. DWORD dwPort = 0;
  899. LPCWSTR szPort = L"(null)";
  900. LPCWSTR szOp = L"";
  901. if (pdwPortNum != NULL)
  902. {
  903. dwPort = *pdwPortNum;
  904. szPort = L"";
  905. }
  906. if (szVip == NULL)
  907. {
  908. szVip = L"null";
  909. }
  910. Status = FakeNlbHostConnect(pConnInfo, &pHost);
  911. if (FAILED(Status))
  912. {
  913. goto end;
  914. }
  915. DWORD dwOperationalState = WLBS_CONVERGED;
  916. if (pHost->dwOperationalState != 0)
  917. {
  918. dwOperationalState = pHost->dwOperationalState;
  919. }
  920. switch(Operation)
  921. {
  922. case WLBS_START:
  923. szOp = L"start";
  924. if (dwOperationalState == WLBS_STOPPED)
  925. {
  926. dwOperationalState = WLBS_CONVERGING;
  927. }
  928. else
  929. {
  930. dwOperationalState = WLBS_CONVERGED;
  931. }
  932. break;
  933. case WLBS_STOP:
  934. szOp = L"stop";
  935. dwOperationalState = WLBS_STOPPED;
  936. break;
  937. case WLBS_DRAIN:
  938. szOp = L"drain";
  939. dwOperationalState = WLBS_DRAINING;
  940. break;
  941. case WLBS_SUSPEND:
  942. szOp = L"suspend";
  943. dwOperationalState = WLBS_SUSPENDED;
  944. break;
  945. case WLBS_RESUME:
  946. szOp = L"resume";
  947. // dwOperationalState = WLBS_CONVERGED;
  948. dwOperationalState = WLBS_DISCONNECTED;
  949. break;
  950. case WLBS_PORT_ENABLE:
  951. szOp = L"port-enable";
  952. break;
  953. case WLBS_PORT_DISABLE:
  954. szOp = L"port-disable";
  955. break;
  956. case WLBS_PORT_DRAIN:
  957. szOp = L"port-drain";
  958. break;
  959. case WLBS_QUERY:
  960. szOp = L"query";
  961. break;
  962. case WLBS_QUERY_PORT_STATE:
  963. szOp = L"port-query";
  964. break;
  965. default:
  966. szOp = L"unknown";
  967. break;
  968. }
  969. wprintf(
  970. L"FakeNlbHostControlCluster: op=%ws "
  971. L"ip=%ws "
  972. L"Port=%lu%ws\n",
  973. szOp,
  974. szVip,
  975. dwPort, szPort
  976. );
  977. pHost->dwOperationalState = dwOperationalState;
  978. *pdwOperationStatus = WLBS_ALREADY; // dummy values ...
  979. *pdwClusterOrPortStatus = dwOperationalState;
  980. *pdwHostMap = 0x3;
  981. end:
  982. return Status;
  983. }
  984. WBEMSTATUS
  985. FakeNlbHostGetClusterMembers(
  986. IN PWMI_CONNECTION_INFO pConnInfo, // NULL implies local
  987. IN LPCWSTR szNicGuid,
  988. OUT DWORD *pNumMembers,
  989. OUT NLB_CLUSTER_MEMBER_INFO **ppMembers // free using delete[]
  990. )
  991. {
  992. WBEMSTATUS Status = WBEM_E_CRITICAL_ERROR;
  993. FAKE_HOST_INFO *pHost = NULL;
  994. *pNumMembers = 0;
  995. *ppMembers = NULL;
  996. Status = FakeNlbHostConnect(pConnInfo, &pHost);
  997. if (FAILED(Status))
  998. {
  999. goto end;
  1000. }
  1001. //
  1002. // Look for the specified interface
  1003. //
  1004. FAKE_IF_INFO *pIF = NULL;
  1005. Status = lookup_fake_if(pHost, szNicGuid, &pIF);
  1006. if (!FAILED(Status))
  1007. {
  1008. gFake.mfn_Lock();
  1009. if (pIF->pConfig->IsValidNlbConfig())
  1010. {
  1011. NLB_CLUSTER_MEMBER_INFO *pMembers;
  1012. pMembers = new NLB_CLUSTER_MEMBER_INFO[1];
  1013. if (pMembers == NULL)
  1014. {
  1015. Status = WBEM_E_OUT_OF_MEMORY;
  1016. }
  1017. else
  1018. {
  1019. ZeroMemory(pMembers, sizeof(*pMembers));
  1020. pMembers->HostId = pIF->pConfig->NlbParams.host_priority;
  1021. StringCbCopy(
  1022. pMembers->DedicatedIpAddress,
  1023. sizeof(pMembers->DedicatedIpAddress),
  1024. pIF->pConfig->NlbParams.ded_ip_addr
  1025. );
  1026. StringCbCopy(
  1027. pMembers->HostName,
  1028. sizeof(pMembers->HostName),
  1029. pHost->szFQDN
  1030. );
  1031. *pNumMembers = 1;
  1032. *ppMembers = pMembers;
  1033. }
  1034. }
  1035. gFake.mfn_Unlock();
  1036. }
  1037. end:
  1038. return Status;
  1039. }
  1040. DWORD WINAPI FakeThreadProc(
  1041. LPVOID lpParameter // thread data
  1042. )
  1043. {
  1044. FAKE_IF_INFO *pIF = (FAKE_IF_INFO *) lpParameter;
  1045. //
  1046. // Display the msg box to block input.
  1047. //
  1048. {
  1049. WCHAR rgBuf[256];
  1050. gFake.mfn_Lock();
  1051. StringCbPrintf(
  1052. rgBuf,
  1053. sizeof(rgBuf),
  1054. L"Update of NIC %ws (GUID %ws)",
  1055. pIF->szFriendlyName,
  1056. pIF->szInterfaceGuid
  1057. );
  1058. gFake.mfn_Unlock();
  1059. //
  1060. // Call this AFTER unlocking!
  1061. //
  1062. #if 0
  1063. MessageBox(NULL, rgBuf, L"FakeThreadProc", MB_OK);
  1064. #endif // 0
  1065. }
  1066. //
  1067. // Now actually lock and perform the update...
  1068. //
  1069. gFake.mfn_Lock();
  1070. if (pIF->pPendingInfo == NULL)
  1071. {
  1072. ASSERT(FALSE);
  1073. goto end_unlock;
  1074. }
  1075. pIF->CompletedUpdateStatus =
  1076. pIF->pConfig->Update(&pIF->pPendingInfo->Config);
  1077. pIF->pConfig->Generation++;
  1078. delete pIF->pPendingInfo;
  1079. pIF->pPendingInfo = NULL;
  1080. end_unlock:
  1081. gFake.mfn_Unlock();
  1082. return 0;
  1083. }