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.

1001 lines
32 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. iis.cpp
  5. Abstract:
  6. Search IIS metabase and replace the matching value data.
  7. Author:
  8. Geoffrey Guo (geoffguo) 15-Jan-2002 Created
  9. Revision History:
  10. <alias> <date> <comments>
  11. --*/
  12. #define INITGUID
  13. #define MD_DEFAULT_TIMEOUT 10000 //10 second
  14. #define NOT_USE_SAFE_STRING
  15. #include "clmt.h"
  16. #include <OLE2.H>
  17. #include <coguid.h>
  18. #include "iiscnfg.h"
  19. #define STRSAFE_LIB
  20. #include <strsafe.h>
  21. #define TEXT_METABASE_SECTION TEXT("MetabaseSettings")
  22. DWORD RegType2MetaType(DWORD);
  23. DWORD MetaType2RegType(DWORD);
  24. /*
  25. */
  26. HRESULT MigrateMetabaseSettings(HINF hInf)
  27. {
  28. HRESULT hr = E_FAIL;
  29. BOOL bRet;
  30. LONG lComponentCount;
  31. LONG lLineIndex;
  32. INFCONTEXT context;
  33. LPCTSTR lpSectionName;
  34. TCHAR szKeyName[MAX_PATH];
  35. TCHAR szDataType[16], szUpdateType[16];
  36. TCHAR szValueName[MAX_PATH];
  37. LPTSTR lpValueData = NULL;
  38. DWORD cchReqSize, dwUpdateType;
  39. const TCHAR szPerSystemSection[] = TEXT_METABASE_SECTION;
  40. if (hInf == INVALID_HANDLE_VALUE)
  41. {
  42. hr = E_INVALIDARG;
  43. goto exit;
  44. }
  45. DPF(REGmsg, TEXT("Enter MigrateMetabaseSettings:"));
  46. lpSectionName = szPerSystemSection;
  47. // Get all components from appropriate section
  48. lComponentCount = SetupGetLineCount(hInf, lpSectionName);
  49. if (!lComponentCount)
  50. {
  51. hr = S_FALSE;
  52. goto exit;
  53. }
  54. for (lLineIndex = 0 ; lLineIndex < lComponentCount ; lLineIndex++)
  55. {
  56. bRet = SetupGetLineByIndex(hInf, lpSectionName, lLineIndex, &context);
  57. if (!bRet)
  58. {
  59. DPF(REGwar, TEXT("Failed to get line %d, in section %s"),lLineIndex,lpSectionName);
  60. continue;
  61. }
  62. bRet = SetupGetStringField(&context,
  63. 1,
  64. szUpdateType,
  65. ARRAYSIZE(szUpdateType),
  66. &cchReqSize);
  67. if (!bRet)
  68. {
  69. DPF(REGwar, TEXT("Failed to get field 1 in line %d in section %s"),lLineIndex,lpSectionName);
  70. continue;
  71. }
  72. dwUpdateType = _tstoi(szUpdateType);
  73. switch (dwUpdateType)
  74. {
  75. case 0:
  76. bRet = SetupGetStringField(&context,
  77. 2,
  78. szKeyName,
  79. ARRAYSIZE(szKeyName),
  80. &cchReqSize),
  81. SetupGetStringField(&context,
  82. 3,
  83. szDataType,
  84. ARRAYSIZE(szDataType),
  85. &cchReqSize),
  86. SetupGetStringField(&context,
  87. 4,
  88. szValueName,
  89. ARRAYSIZE(szValueName),
  90. &cchReqSize);
  91. if (!bRet)
  92. {
  93. DPF(REGwar, TEXT("Failed to get field 2/3/4 in line %d in section %s"),lLineIndex,lpSectionName);
  94. continue;
  95. }
  96. bRet = SetupGetStringField(&context, 6, NULL, 0, &cchReqSize);
  97. if (!bRet)
  98. {
  99. DPF(REGwar, TEXT("Failed to get field 6 size in line %d in section %s"),lLineIndex,lpSectionName);
  100. continue;
  101. }
  102. lpValueData = (LPTSTR)calloc(cchReqSize, sizeof(TCHAR));
  103. if (!lpValueData)
  104. {
  105. hr = E_OUTOFMEMORY;
  106. goto exit;
  107. }
  108. bRet = SetupGetStringField(&context, 6, lpValueData, cchReqSize, &cchReqSize);
  109. if (bRet)
  110. {
  111. //Add metabase value change information to INF file
  112. hr = AddRegValueRename(szKeyName, szValueName, NULL, NULL,
  113. lpValueData, Str2REG(szDataType), 0,
  114. APPLICATION_DATA_METABASE);
  115. if (FAILED(hr))
  116. {
  117. DPF(REGerr, TEXT("Failed to do meatbase migration"));
  118. }
  119. }
  120. free(lpValueData);
  121. break;
  122. case 1:
  123. LPTSTR lpField[16];
  124. REG_STRING_REPLACE myTable;
  125. HRESULT hr1, hr2, hr3;
  126. for (int i = 0; i <= ARRAYSIZE(lpField); i++)
  127. {
  128. lpField[i] = NULL;
  129. }
  130. hr = ReadFieldFromContext(&context, lpField, 2, 4);
  131. if (hr != S_OK)
  132. {
  133. DPF(REGwar, TEXT("Failed to get field in line %d, in section %s, ReadFieldFromContext returns hr = %d"),lLineIndex,lpSectionName,hr);
  134. continue;
  135. }
  136. hr1 = Sz2MultiSZ(lpField[3],TEXT(';'));
  137. hr2 = Sz2MultiSZ(lpField[4],TEXT(';'));
  138. hr3 = ConstructUIReplaceStringTable(lpField[3], lpField[4],&myTable);
  139. if ( SUCCEEDED(hr1) && SUCCEEDED(hr2) && SUCCEEDED(hr3))
  140. {
  141. hr = MetabaseAnalyze (lpField[2],&myTable,FALSE);
  142. if (FAILED(hr))
  143. {
  144. DPF(REGwar, TEXT("MetabaseAnalyze failed in line %d, in section %s, hr = %d"),lLineIndex,lpSectionName,hr);
  145. }
  146. }
  147. else
  148. {
  149. DPF(REGwar, TEXT("Failed to do conversion in line %d, in section %s, hr1 = %d,hr2 = %d,hr3 = %d"),lLineIndex,lpSectionName,hr1, hr2, hr3);
  150. }
  151. for (int i = 0; i <= ARRAYSIZE(lpField); i++)
  152. {
  153. if (lpField[i])
  154. {
  155. MEMFREE(lpField[i]);
  156. }
  157. }
  158. break;
  159. }
  160. }
  161. hr = S_OK;
  162. exit:
  163. DPF(REGmsg, TEXT("Exit MigrateMetabaseSettings:"));
  164. return hr;
  165. }
  166. //-----------------------------------------------------------------------//
  167. //
  168. // QueryData()
  169. //
  170. // DESCRIPTION:
  171. // Query and analyze one record metabase data.
  172. //
  173. // pMD_Rec: Point to a MetaData record
  174. // lpFullKey: Full key path
  175. // lpValList: Updated value list
  176. // lpRegStr: Input parameter structure
  177. //-----------------------------------------------------------------------//
  178. HRESULT QueryData (
  179. PMETADATA_RECORD pMD_Rec,
  180. LPTSTR lpFullKey,
  181. PVALLIST *lpValList,
  182. PREG_STRING_REPLACE lpRegStr,
  183. BOOL bStrChk)
  184. {
  185. HRESULT hresError = S_OK;
  186. DWORD dwType;
  187. LPTSTR lpBuff;
  188. lpBuff = (LPTSTR)pMD_Rec->pbMDData;
  189. switch (pMD_Rec->dwMDDataType)
  190. {
  191. case EXPANDSZ_METADATA:
  192. dwType = REG_EXPAND_SZ;
  193. break;
  194. case MULTISZ_METADATA:
  195. dwType = REG_MULTI_SZ;
  196. break;
  197. case STRING_METADATA:
  198. dwType = REG_SZ;
  199. break;
  200. default:
  201. goto Exit;
  202. }
  203. hresError = ReplaceValueSettings (
  204. NULL,
  205. lpBuff,
  206. pMD_Rec->dwMDDataLen,
  207. NULL,
  208. dwType,
  209. lpRegStr,
  210. lpValList,
  211. lpFullKey,
  212. bStrChk);
  213. Exit:
  214. return hresError;
  215. }
  216. //-----------------------------------------------------------------------//
  217. //
  218. // SetDataValueChange()
  219. //
  220. // DESCRIPTION:
  221. // Set metabase value based on the value list
  222. //
  223. // lpValList: Updated value list
  224. // lpFullKey: Full sub-key path
  225. //-----------------------------------------------------------------------//
  226. HRESULT SetDataValueChange (
  227. IMSAdminBase *pcAdmCom,
  228. METADATA_HANDLE hmdHandle,
  229. PVALLIST *lpValList,
  230. LPTSTR lpFullKey)
  231. {
  232. HRESULT hResult = S_OK;
  233. PVALLIST lpVal;
  234. TCHAR szValueID[16];
  235. if (*lpValList)
  236. {
  237. lpVal = *lpValList;
  238. while (lpVal)
  239. {
  240. hResult = StringCchPrintf(szValueID, 15, TEXT("%d"), lpVal->md.dwMDIdentifier);
  241. if (FAILED(hResult))
  242. {
  243. DPF(APPerr,L"IIS:SetDataValueChange:Failed Valud ID %d is too long", lpVal->md.dwMDIdentifier);
  244. break;
  245. }
  246. //Add metabase value change information to INF file
  247. hResult = AddRegValueRename(
  248. lpFullKey,
  249. szValueID,
  250. NULL,
  251. NULL,
  252. (LPTSTR)lpVal->md.pbMDData,
  253. MetaType2RegType(lpVal->md.dwMDDataType),
  254. lpVal->val_attrib,
  255. APPLICATION_DATA_METABASE);
  256. if (FAILED(hResult))
  257. {
  258. DPF(APPerr,L"IIS:AddRegValueRename:Failed with HR = %d (%#x)", hResult, hResult);
  259. break;
  260. }
  261. lpVal = lpVal->pvl_next;
  262. }
  263. RemoveValueList (lpValList);
  264. }
  265. if (SUCCEEDED(hResult))
  266. {
  267. hResult = S_OK;
  268. }
  269. return hResult;
  270. }
  271. //-----------------------------------------------------------------------//
  272. //
  273. // RecursiveEnumKey()
  274. //
  275. // DESCRIPTION:
  276. // Recursive enumerate metabase key
  277. //
  278. // pcAdmCom: Point to IMSAdminBase
  279. // lpFullKey: Full key path
  280. // lpRegStr: Input parameter structure
  281. //-----------------------------------------------------------------------//
  282. HRESULT RecursiveEnumKey (
  283. IMSAdminBase *pcAdmCom,
  284. LPTSTR lpFullKey,
  285. PREG_STRING_REPLACE lpRegStr,
  286. BOOL bStrChk)
  287. {
  288. HRESULT hresError;
  289. DWORD dwDataIndex, dwKeyIndex;
  290. DWORD dwRequiredSize;
  291. BOOL bAllocBuf;
  292. METADATA_RECORD md_Rec;
  293. METADATA_HANDLE hmdHandle;
  294. PVALLIST lpValList = NULL, lpTemp;
  295. LPBYTE lpDataBuf;
  296. TCHAR szDataBuf[MAX_PATH];
  297. TCHAR szNewKeyPath[METADATA_MAX_NAME_LEN+1];
  298. TCHAR szChildPathName[METADATA_MAX_NAME_LEN+1];
  299. hresError = pcAdmCom->OpenKey (METADATA_MASTER_ROOT_HANDLE,
  300. lpFullKey,
  301. METADATA_PERMISSION_READ, // | METADATA_PERMISSION_WRITE,
  302. MD_DEFAULT_TIMEOUT,
  303. &hmdHandle);
  304. if (FAILED(hresError))
  305. {
  306. DPF(APPerr,
  307. L"RecursiveEnumKey: OpenKey1 failed at the key %s", lpFullKey);
  308. goto Exit;
  309. }
  310. dwDataIndex = 0;
  311. do
  312. {
  313. bAllocBuf = FALSE;
  314. md_Rec.dwMDIdentifier = 0;
  315. md_Rec.dwMDAttributes = METADATA_NO_ATTRIBUTES;
  316. md_Rec.dwMDUserType = 0;
  317. md_Rec.dwMDDataType = 0;
  318. md_Rec.dwMDDataLen = sizeof(szDataBuf);
  319. md_Rec.pbMDData = (unsigned char*)szDataBuf;
  320. hresError = pcAdmCom->EnumData (
  321. hmdHandle,
  322. L"/",
  323. &md_Rec,
  324. dwDataIndex,
  325. &dwRequiredSize);
  326. if (SUCCEEDED(hresError))
  327. {
  328. lpDataBuf = (LPBYTE)szDataBuf;
  329. goto DataAnalysis;
  330. } else if (HRESULT_CODE(hresError) == ERROR_INSUFFICIENT_BUFFER)
  331. {
  332. lpDataBuf = (LPBYTE)calloc(dwRequiredSize, 1);
  333. if (!lpDataBuf)
  334. {
  335. DPF(APPerr,
  336. L"RecursiveEnumKey: No enough memory at the key %s", lpFullKey);
  337. pcAdmCom->CloseKey (hmdHandle);
  338. goto Exit;
  339. }
  340. bAllocBuf = TRUE;
  341. md_Rec.dwMDIdentifier = 0;
  342. md_Rec.dwMDAttributes = METADATA_NO_ATTRIBUTES;
  343. md_Rec.dwMDUserType = 0;
  344. md_Rec.dwMDDataType = 0;
  345. md_Rec.dwMDDataLen = dwRequiredSize;
  346. md_Rec.pbMDData = (unsigned char*)lpDataBuf;
  347. hresError = pcAdmCom->EnumData (
  348. hmdHandle,
  349. L"/",
  350. &md_Rec,
  351. dwDataIndex,
  352. &dwRequiredSize);
  353. }
  354. else if (HRESULT_CODE(hresError) == ERROR_NO_MORE_ITEMS)
  355. {
  356. hresError = S_OK;
  357. break;
  358. } else if(HRESULT_CODE(hresError) == ERROR_ACCESS_DENIED)
  359. {
  360. DPF(APPerr,
  361. L"RecursiveEnumKey: Access is denied under the key %s",
  362. lpFullKey);
  363. hresError = S_OK;
  364. goto NextKey;
  365. } else
  366. {
  367. DPF(APPerr,
  368. L"RecursiveEnumKey: EnumData failed at the key %s hresError=%d", lpFullKey, hresError);
  369. hresError = S_OK;
  370. goto NextKey;
  371. }
  372. DataAnalysis:
  373. if (SUCCEEDED(hresError) &&
  374. (md_Rec.dwMDDataType == EXPANDSZ_METADATA ||
  375. md_Rec.dwMDDataType == MULTISZ_METADATA ||
  376. md_Rec.dwMDDataType == STRING_METADATA))
  377. {
  378. hresError = QueryData (
  379. &md_Rec,
  380. lpFullKey,
  381. &lpValList,
  382. lpRegStr,
  383. bStrChk);
  384. if (SUCCEEDED(hresError))
  385. {
  386. lpTemp = lpValList;
  387. if (lpTemp)
  388. {
  389. while (lpTemp->pvl_next)
  390. {
  391. lpTemp = lpTemp->pvl_next;
  392. }
  393. if (lpTemp->md.dwMDIdentifier == 0x00FFFFFF)
  394. {
  395. lpTemp->md.dwMDIdentifier = md_Rec.dwMDIdentifier;
  396. lpTemp->md.dwMDAttributes = md_Rec.dwMDAttributes;
  397. lpTemp->md.dwMDUserType = md_Rec.dwMDUserType;
  398. lpTemp->md.dwMDDataType = md_Rec.dwMDDataType;
  399. lpTemp->md.dwMDDataLen = lpTemp->ve.ve_valuelen;
  400. lpTemp->md.pbMDData = (unsigned char *)lpTemp->ve.ve_valueptr ;
  401. lpTemp->md.dwMDDataTag = md_Rec.dwMDDataTag;
  402. }
  403. }
  404. } else
  405. DPF(APPerr, L"RecursiveEnumKey: QueryData fails at key %s hresError = %d",
  406. lpFullKey, hresError);
  407. }
  408. NextKey:
  409. if (bAllocBuf)
  410. free(lpDataBuf);
  411. dwDataIndex++;
  412. } while (SUCCEEDED(hresError));
  413. SetDataValueChange (pcAdmCom, hmdHandle, &lpValList, lpFullKey);
  414. pcAdmCom->CloseKey (hmdHandle);
  415. //
  416. // Now Enumerate all of the keys
  417. //
  418. dwKeyIndex = 0;
  419. do
  420. {
  421. hresError = pcAdmCom->OpenKey (METADATA_MASTER_ROOT_HANDLE,
  422. lpFullKey,
  423. METADATA_PERMISSION_READ, // | METADATA_PERMISSION_WRITE,
  424. MD_DEFAULT_TIMEOUT,
  425. &hmdHandle);
  426. if (FAILED(hresError))
  427. {
  428. DPF(APPerr,
  429. L"RecursiveEnumKey: OpenKey2 failed at the key %s", lpFullKey);
  430. break;
  431. }
  432. hresError = pcAdmCom->EnumKeys (
  433. hmdHandle,
  434. L"/",
  435. // METADATA_MASTER_ROOT_HANDLE,
  436. // lpFullKey,
  437. szChildPathName,
  438. dwKeyIndex);
  439. pcAdmCom->CloseKey (hmdHandle);
  440. if (FAILED(hresError))
  441. {
  442. if (HRESULT_CODE(hresError) != ERROR_NO_MORE_ITEMS)
  443. {
  444. DPF(APPerr, L"RecursiveEnumKey: EnumKeys failed at the key %s", lpFullKey);
  445. }
  446. break;
  447. }
  448. // copy the full path to the child and call RecursiveEnumKey
  449. if (FAILED(hresError = StringCchCopy (szNewKeyPath, METADATA_MAX_NAME_LEN, lpFullKey)))
  450. {
  451. DPF(APPerr, L"RecursiveEnumKey: Buffer szNewKeyPath is too small, EnumKeys failed at the key %s", lpFullKey);
  452. break;
  453. }
  454. if (FAILED(hresError = StringCchCat (szNewKeyPath, METADATA_MAX_NAME_LEN, szChildPathName)))
  455. {
  456. DPF(APPerr, L"RecursiveEnumKey: Buffer szNewKeyPath is too small, EnumKeys failed at the key %s", lpFullKey);
  457. break;
  458. }
  459. if (FAILED(hresError = StringCchCat (szNewKeyPath, METADATA_MAX_NAME_LEN, L"/")))
  460. {
  461. DPF(APPerr, L"RecursiveEnumKey: Buffer szNewKeyPath is too small, EnumKeys failed at the key %s", lpFullKey);
  462. break;
  463. }
  464. hresError = RecursiveEnumKey (pcAdmCom, szNewKeyPath, lpRegStr, bStrChk);
  465. if (FAILED(hresError))
  466. {
  467. if(HRESULT_CODE(hresError) == ERROR_ACCESS_DENIED) // continue to query next key
  468. {
  469. DPF(APPerr, L"RecursiveEnumKey: Access is denied in the key %s", szNewKeyPath);
  470. hresError = ERROR_SUCCESS;
  471. }
  472. else
  473. DPF(APPerr,L"RecursiveEnumKey fail in the key %s", szNewKeyPath);
  474. }
  475. dwKeyIndex++;
  476. } while (SUCCEEDED(hresError));
  477. if (HRESULT_CODE(hresError) == ERROR_NO_MORE_ITEMS)
  478. hresError = ERROR_SUCCESS;
  479. Exit:
  480. return hresError;
  481. }
  482. HRESULT InitInstance(
  483. IMSAdminBase **pcAdmCom,
  484. IClassFactory **pcsfFactory)
  485. {
  486. size_t cchSize;
  487. HRESULT hresError;
  488. METADATA_HANDLE hMDHandle;
  489. COSERVERINFO csiMachineName;
  490. COSERVERINFO *pcsiParam = NULL;
  491. LPTSTR lpMachineName;
  492. //fill the structure for CoGetClassObject
  493. csiMachineName.pAuthInfo = NULL;
  494. csiMachineName.dwReserved1 = 0;
  495. csiMachineName.dwReserved2 = 0;
  496. pcsiParam = &csiMachineName;
  497. // Get Machine Name for COM
  498. cchSize = ExpandEnvironmentStrings (L"%COMPUTERNAME%", NULL, 0);
  499. if (cchSize == 0)
  500. {
  501. hresError = E_INVALIDARG;
  502. goto Exit;
  503. }
  504. lpMachineName = (LPTSTR) calloc (cchSize+1, sizeof(TCHAR));
  505. if (!lpMachineName)
  506. {
  507. hresError = E_OUTOFMEMORY;
  508. goto Exit;
  509. }
  510. ExpandEnvironmentStrings(L"%COMPUTERNAME%", lpMachineName, cchSize);
  511. csiMachineName.pwszName = lpMachineName;
  512. hresError = CoGetClassObject(GETAdminBaseCLSID(TRUE), CLSCTX_SERVER, pcsiParam,
  513. IID_IClassFactory, (void**) pcsfFactory);
  514. if (FAILED(hresError))
  515. goto Exit1;
  516. else
  517. {
  518. hresError = (*pcsfFactory)->CreateInstance(NULL, IID_IMSAdminBase, (void **) pcAdmCom);
  519. if (FAILED(hresError))
  520. {
  521. DPF (APPerr, L"SetMetabaseValue: CreateInstance Failed! Error: %d (%#x)\n", hresError, hresError);
  522. (*pcsfFactory)->Release();
  523. }
  524. }
  525. Exit1:
  526. free (lpMachineName);
  527. Exit:
  528. return hresError;
  529. }
  530. //-----------------------------------------------------------------------//
  531. //
  532. // MetabaseAnalyze()
  533. //
  534. // DESCRIPTION:
  535. // Enumerate metabase and replace localized string to English.
  536. //
  537. // lpRegStr: Input parameter structure
  538. //
  539. //-----------------------------------------------------------------------//
  540. HRESULT MetabaseAnalyze (
  541. LPTSTR lpRoot,
  542. PREG_STRING_REPLACE lpRegStr,
  543. BOOL bStrChk)
  544. {
  545. HRESULT hresError;
  546. IMSAdminBase *pcAdmCom = NULL;
  547. IClassFactory *pcsfFactory = NULL;
  548. DPF(APPmsg, L"Enter MetabaseAnalyze: ");
  549. if (!lpRegStr || lpRegStr->lpSearchString == NULL || lpRegStr->lpReplaceString == NULL)
  550. {
  551. hresError = E_INVALIDARG;
  552. goto Exit;
  553. }
  554. lpRegStr->cchMaxStrLen = GetMaxStrLen (lpRegStr);
  555. hresError = InitInstance(&pcAdmCom, &pcsfFactory);
  556. if (FAILED(hresError))
  557. {
  558. if (IsServiceRunning(L"iisadmin"))
  559. {
  560. DoMessageBox(GetConsoleWindow(), IDS_IIS_ERROR, IDS_MAIN_TITLE, MB_OK);
  561. DPF (APPerr, L"MetabaseAnalyze: CoGetClassObject Failed! Error: %d (%#x)\n", hresError, hresError);
  562. } else
  563. hresError = S_OK;
  564. goto Exit;
  565. }
  566. if (!lpRoot)
  567. {
  568. hresError = RecursiveEnumKey (pcAdmCom, L"/", lpRegStr, bStrChk);
  569. }
  570. else
  571. {
  572. hresError = RecursiveEnumKey (pcAdmCom, lpRoot, lpRegStr, bStrChk);
  573. }
  574. if (FAILED(hresError))
  575. {
  576. DPF (APPerr, L"MetabaseAnalyze: Recursive data dump FAILED! Error: %d (%#x)\n", hresError, hresError);
  577. }
  578. // Release the object
  579. pcAdmCom->Release();
  580. pcsfFactory->Release();
  581. Exit:
  582. DPF(APPmsg, L"Exit MetabaseAnalyze: ");
  583. return hresError;
  584. }
  585. DWORD RegType2MetaType(DWORD dwType)
  586. {
  587. switch (dwType)
  588. {
  589. case REG_SZ:
  590. return STRING_METADATA;
  591. break;
  592. case REG_EXPAND_SZ:
  593. return EXPANDSZ_METADATA;
  594. break;
  595. case REG_MULTI_SZ:
  596. return MULTISZ_METADATA;
  597. break;
  598. }
  599. return (-1);
  600. }
  601. DWORD MetaType2RegType(DWORD dwType)
  602. {
  603. switch (dwType)
  604. {
  605. case STRING_METADATA:
  606. return REG_SZ;
  607. break;
  608. case EXPANDSZ_METADATA:
  609. return REG_EXPAND_SZ;
  610. break;
  611. case MULTISZ_METADATA:
  612. return REG_MULTI_SZ;
  613. break;
  614. }
  615. return (-1);
  616. }
  617. //-----------------------------------------------------------------------//
  618. //
  619. // SetMetabaseValue()
  620. //
  621. // DESCRIPTION:
  622. // Set metabase value
  623. //
  624. // lpValList: Updated value list
  625. // lpFullKey: Full sub-key path
  626. //-----------------------------------------------------------------------//
  627. HRESULT SetMetabaseValue (
  628. LPCTSTR lpFullKey,
  629. LPCTSTR lpValueID,
  630. DWORD dwType,
  631. LPCTSTR lpValueData)
  632. {
  633. HRESULT hresError;
  634. IMSAdminBase *pcAdmCom = NULL;
  635. IClassFactory *pcsfFactory = NULL;
  636. LPBYTE lpDataBuf = NULL;
  637. METADATA_RECORD md_Rec;
  638. METADATA_HANDLE hmdHandle;
  639. DWORD dwRequiredSize;
  640. DWORD dwSize;
  641. TCHAR szDataBuf[MAX_PATH];
  642. DPF(APPmsg, L"Enter SetMetabaseValue: ");
  643. hresError = InitInstance(&pcAdmCom, &pcsfFactory);
  644. if (FAILED(hresError))
  645. {
  646. if (IsServiceRunning(L"iisadmin"))
  647. {
  648. DoMessageBox(GetConsoleWindow(), IDS_IIS_ERROR, IDS_MAIN_TITLE, MB_OK);
  649. DPF (APPerr, L"SetMetabaseValue: CoGetClassObject Failed! Error: %d (%#x)\n", hresError, hresError);
  650. } else
  651. hresError = S_OK;
  652. goto Exit;
  653. }
  654. hresError = pcAdmCom->OpenKey (METADATA_MASTER_ROOT_HANDLE,
  655. lpFullKey,
  656. METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE,
  657. MD_DEFAULT_TIMEOUT,
  658. &hmdHandle);
  659. if (FAILED(hresError))
  660. {
  661. if ( (HRESULT_CODE(hresError) == ERROR_FILE_NOT_FOUND)
  662. || (HRESULT_CODE(hresError) == ERROR_PATH_NOT_FOUND) )
  663. {
  664. DPF(APPwar, L"SetMetabaseValue: OpenKey failed at the key %s ,hr = %d , error = %d", lpFullKey,hresError,HRESULT_CODE(hresError));
  665. hresError = S_FALSE;
  666. }
  667. else
  668. {
  669. DPF(APPerr, L"SetMetabaseValue: OpenKey failed at the key %s ,hr = %d , error = %d", lpFullKey,hresError,HRESULT_CODE(hresError));
  670. }
  671. goto Exit1;
  672. }
  673. md_Rec.dwMDIdentifier = (DWORD)_tstoi(lpValueID);
  674. md_Rec.dwMDAttributes = METADATA_NO_ATTRIBUTES;
  675. md_Rec.dwMDUserType = 0;
  676. md_Rec.dwMDDataType = 0;
  677. md_Rec.dwMDDataLen = sizeof(szDataBuf);
  678. md_Rec.pbMDData = (unsigned char*)szDataBuf;
  679. hresError = pcAdmCom->GetData (hmdHandle,
  680. L"/",
  681. &md_Rec,
  682. &dwRequiredSize);
  683. if (FAILED(hresError))
  684. {
  685. if (HRESULT_CODE(hresError) == ERROR_INSUFFICIENT_BUFFER)
  686. {
  687. lpDataBuf = (LPBYTE)calloc(dwRequiredSize, 1);
  688. if (!lpDataBuf)
  689. {
  690. DPF(APPerr,
  691. L"SetMetabaseValue: No enough memory at the key %s", lpFullKey);
  692. goto Exit2;
  693. }
  694. md_Rec.dwMDDataLen = dwRequiredSize;
  695. md_Rec.pbMDData = (unsigned char*)lpDataBuf;
  696. hresError = pcAdmCom->GetData (hmdHandle,
  697. L"/",
  698. &md_Rec,
  699. &dwRequiredSize);
  700. if (FAILED(hresError))
  701. {
  702. DPF(APPerr, L"SetMetabaseValue: GetData failed at the key %s", lpFullKey);
  703. goto Exit3;
  704. }
  705. } else
  706. {
  707. DPF(APPerr, L"SetMetabaseValue: GetData failed at the key %s", lpFullKey);
  708. goto Exit2;
  709. }
  710. }
  711. if (md_Rec.dwMDDataType != dwType)
  712. {
  713. DPF(APPerr, L"SetMetabaseValue: Wrong data type at the key %s", lpFullKey);
  714. goto Exit3;
  715. }
  716. switch (dwType)
  717. {
  718. case EXPANDSZ_METADATA:
  719. case STRING_METADATA:
  720. dwSize = (lstrlen(lpValueData)+1)*sizeof(TCHAR);
  721. break;
  722. case MULTISZ_METADATA:
  723. dwSize = MultiSzLen(lpValueData)*sizeof(TCHAR);
  724. break;
  725. default:
  726. goto Exit3;
  727. }
  728. md_Rec.dwMDDataLen = dwSize;
  729. md_Rec.pbMDData = (unsigned char*)lpValueData;
  730. hresError = pcAdmCom->SetData (hmdHandle,
  731. L"/",
  732. &md_Rec);
  733. if (SUCCEEDED(hresError))
  734. DPF (APPinf, L"SetMetabaseValue: replace the data of valueID %d under the key %s",
  735. md_Rec.dwMDIdentifier , lpFullKey);
  736. else
  737. DPF (APPerr, L"SetMetabaseValue: Failed hResult=%x the data of valueID %d under the key %s",
  738. hresError, md_Rec.dwMDIdentifier , lpFullKey);
  739. Exit3:
  740. if (lpDataBuf)
  741. free(lpDataBuf);
  742. Exit2:
  743. pcAdmCom->CloseKey (hmdHandle);
  744. Exit1:
  745. // Release the object
  746. pcAdmCom->Release();
  747. pcsfFactory->Release();
  748. Exit:
  749. DPF(APPmsg, L"Exit SetMetabaseValue: ");
  750. return hresError;
  751. }
  752. HRESULT BatchUpateIISMetabase(
  753. HINF hInf,
  754. LPTSTR lpszSection)
  755. {
  756. HRESULT hr;
  757. UINT LineCount,LineNo,nFieldIndex;
  758. INFCONTEXT InfContext;
  759. #define REG_UPDATE_FIELD_COUNT 5
  760. int i;
  761. TCHAR szUpdateType[MAX_PATH],szStrType[MAX_PATH];
  762. DWORD dwUpdateType, dwStrType;
  763. DWORD pdwSizeRequired[REG_UPDATE_FIELD_COUNT+1] = {0,ARRAYSIZE(szUpdateType),0,0,0,0};
  764. LPTSTR lpszField[REG_UPDATE_FIELD_COUNT+1] = {NULL, szUpdateType, NULL, NULL, NULL, NULL};
  765. //check the INF file handle
  766. if(hInf == INVALID_HANDLE_VALUE)
  767. {
  768. hr = E_INVALIDARG;
  769. goto Cleanup;
  770. }
  771. if (!lpszSection || !lpszSection[0])
  772. {
  773. hr = E_INVALIDARG;
  774. goto Cleanup;
  775. }
  776. //here we got the section name and then try to get how many lines there
  777. LineCount = (UINT)SetupGetLineCount(hInf,lpszSection);
  778. if ((LONG)LineCount <= 0)
  779. {
  780. hr = S_FALSE;
  781. goto Cleanup;
  782. }
  783. //Scan the INF file section to get the max buf required for each field
  784. for (LineNo = 0; LineNo < LineCount; LineNo++)
  785. {
  786. DWORD dwNumField;
  787. DWORD dwDataStart;
  788. if (!SetupGetLineByIndex(hInf,lpszSection,LineNo,&InfContext))
  789. {
  790. DPF(INFwar ,TEXT("can not get line %d of section %s !"),LineNo, lpszSection);
  791. continue;
  792. }
  793. dwNumField = SetupGetFieldCount(&InfContext);
  794. if ( dwNumField < 4 )
  795. {
  796. DPF(INFwar ,TEXT("can not get line %d of section %s !"),LineNo, lpszSection);
  797. continue;
  798. }
  799. if (!SetupGetStringField(&InfContext,1,lpszField[1],pdwSizeRequired[1],NULL))
  800. {
  801. DPF(INFwar ,TEXT("can not get line %d of section %s !"),LineNo, lpszSection);
  802. continue;
  803. }
  804. dwUpdateType = _tstoi(lpszField[1]);
  805. switch (dwUpdateType)
  806. {
  807. case CONSTANT_REG_VALUE_DATA_RENAME:
  808. if (!SetupGetStringField(&InfContext,2,szStrType,ARRAYSIZE(szStrType),NULL))
  809. {
  810. DPF(INFwar ,TEXT("can not get line %d of section %s !"),LineNo, lpszSection);
  811. continue;
  812. }
  813. dwStrType = _tstoi(szStrType);
  814. dwDataStart = 3;
  815. break;
  816. case CONSTANT_REG_VALUE_NAME_RENAME:
  817. case CONSTANT_REG_KEY_RENAME:
  818. dwDataStart = 2;
  819. break;
  820. }
  821. for (nFieldIndex = dwDataStart ; nFieldIndex <= min(dwNumField,REG_UPDATE_FIELD_COUNT) ; nFieldIndex++)
  822. {
  823. BOOL bRet;
  824. DWORD cchReqSize;
  825. if ((nFieldIndex == REG_UPDATE_FIELD_COUNT) && (dwStrType == REG_MULTI_SZ))
  826. {
  827. bRet = SetupGetMultiSzField(&InfContext,nFieldIndex,NULL,0,&cchReqSize);
  828. }
  829. else
  830. {
  831. bRet = SetupGetMultiSzField(&InfContext,nFieldIndex,NULL,0,&cchReqSize);
  832. }
  833. if (!bRet)
  834. {
  835. DPF(INFwar ,TEXT("can not get line %d of section %s !"),LineNo, lpszSection);
  836. continue;
  837. }
  838. pdwSizeRequired[nFieldIndex] = max(pdwSizeRequired[nFieldIndex],cchReqSize);
  839. }
  840. }
  841. for (i = 2; i<= REG_UPDATE_FIELD_COUNT; i++)
  842. {
  843. if (pdwSizeRequired[i])
  844. {
  845. if ( NULL == (lpszField[i] = (LPTSTR)malloc(++pdwSizeRequired[i] * sizeof(TCHAR))))
  846. {
  847. hr = E_OUTOFMEMORY;
  848. goto Cleanup;
  849. }
  850. }
  851. }
  852. for(LineNo=0; LineNo<LineCount; LineNo++)
  853. {
  854. SetupGetLineByIndex(hInf,lpszSection,LineNo,&InfContext);
  855. SetupGetStringField(&InfContext,1,lpszField[1],pdwSizeRequired[1],NULL);
  856. dwUpdateType = _tstoi(lpszField[1]);
  857. switch (dwUpdateType)
  858. {
  859. case CONSTANT_REG_VALUE_DATA_RENAME:
  860. SetupGetStringField(&InfContext,2,szStrType,ARRAYSIZE(szStrType),NULL);
  861. dwStrType = _tstoi(szStrType);
  862. SetupGetStringField(&InfContext,3,lpszField[3],pdwSizeRequired[3],NULL);
  863. SetupGetStringField(&InfContext,4,lpszField[4],pdwSizeRequired[4],NULL);
  864. if ( (dwStrType == REG_EXPAND_SZ) || (dwStrType == REG_SZ))
  865. {
  866. SetupGetStringField(&InfContext,5,lpszField[5],pdwSizeRequired[5],NULL);
  867. }
  868. else
  869. {
  870. SetupGetMultiSzField(&InfContext,5,lpszField[5],pdwSizeRequired[5],NULL);
  871. }
  872. dwStrType = RegType2MetaType(dwStrType);
  873. SetMetabaseValue (lpszField[3],lpszField[4],dwStrType,lpszField[5]);
  874. break;
  875. case CONSTANT_REG_VALUE_NAME_RENAME:
  876. case CONSTANT_REG_KEY_RENAME:
  877. for (i = 2; i <= 4 ;i++)
  878. {
  879. SetupGetStringField(&InfContext,i,lpszField[i],pdwSizeRequired[i],NULL);
  880. }
  881. break;
  882. }
  883. }
  884. hr = S_OK;
  885. Cleanup:
  886. for (i = 2; i< ARRAYSIZE(lpszField); i++)
  887. {
  888. FreePointer(lpszField[i]);
  889. }
  890. return hr;
  891. }