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.

670 lines
17 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. mofgen.cpp
  5. Abstract:
  6. This file contains the implementation of the CMofGen class
  7. Author:
  8. Mohit Srivastava 28-Nov-00
  9. Revision History:
  10. --*/
  11. #include "iisprov.h"
  12. #include "mofgen.h"
  13. #include "MultiSzData.h"
  14. #include <initguid.h>
  15. // {041FFF3F-EB8F-4d51-9736-A26E91E3A3CA}
  16. DEFINE_GUID(IisWmiMofgenGuid,
  17. 0x41fff3f, 0xeb8f, 0x4d51, 0x97, 0x36, 0xa2, 0x6e, 0x91, 0xe3, 0xa3, 0xca);
  18. //
  19. // Debugging Stuff
  20. //
  21. #include "pudebug.h"
  22. DECLARE_DEBUG_PRINTS_OBJECT()
  23. extern CDynSchema* g_pDynSch; // Initialized to NULL in schemadynamic.cpp
  24. void ConstructFlatContainerList(METABASE_KEYTYPE*, bool*);
  25. bool CMofGen::ParseCmdLine (int argc, wchar_t **argv)
  26. {
  27. for (int i=1; i<argc; ++i)
  28. {
  29. static wchar_t * wszOUT = L"/out:";
  30. static wchar_t * wszHEADER = L"/header:";
  31. static wchar_t * wszFOOTER = L"/footer:";
  32. if (wcsncmp (argv[i], wszOUT, wcslen(wszOUT)) == 0)
  33. {
  34. if (m_wszOutFileName != 0)
  35. {
  36. // duplicate parameter
  37. return false;
  38. }
  39. m_wszOutFileName = new WCHAR [wcslen (argv[i]) - wcslen (wszOUT) + 1];
  40. if (m_wszOutFileName == 0)
  41. {
  42. return false;
  43. }
  44. wcscpy (m_wszOutFileName, argv[i] + wcslen(wszOUT));
  45. }
  46. else if (wcsncmp (argv[i], wszHEADER, wcslen (wszHEADER)) == 0)
  47. {
  48. if (m_wszHeaderFileName != 0)
  49. {
  50. // duplicate parameter
  51. return false;
  52. }
  53. m_wszHeaderFileName = new WCHAR [wcslen (argv[i]) - wcslen (wszHEADER) + 1];
  54. if (m_wszHeaderFileName == 0)
  55. {
  56. return false;
  57. }
  58. wcscpy (m_wszHeaderFileName, argv[i] + wcslen(wszHEADER));
  59. }
  60. else if (wcsncmp (argv[i], wszFOOTER, wcslen (wszFOOTER)) == 0)
  61. {
  62. if (m_wszFooterFileName != 0)
  63. {
  64. // duplicate parameter
  65. return false;
  66. }
  67. m_wszFooterFileName = new WCHAR [wcslen (argv[i]) - wcslen (wszFOOTER) + 1];
  68. if (m_wszFooterFileName == 0)
  69. {
  70. return false;
  71. }
  72. wcscpy (m_wszFooterFileName, argv[i] + wcslen(wszFOOTER));
  73. }
  74. else
  75. {
  76. wprintf (L"Unknown parameter: %s\n", argv[i]);
  77. return false;
  78. }
  79. }
  80. // verify that we have the required parameters
  81. if (m_wszOutFileName == 0)
  82. {
  83. printf ("You need to specify an output file name\n");
  84. return false;
  85. }
  86. if (m_wszHeaderFileName == 0)
  87. {
  88. printf ("You need to specify a header file name\n");
  89. return false;
  90. }
  91. if (m_wszFooterFileName == 0)
  92. {
  93. printf ("You need to specify a footer file name\n");
  94. return false;
  95. }
  96. return true;
  97. }
  98. void CMofGen::PrintUsage (wchar_t **argv)
  99. {
  100. DBG_ASSERT(argv != NULL);
  101. wprintf (L"Usage:\n%s /out:<filename> /header:<filename> /footer:<filename>\n", argv[0]);
  102. }
  103. HRESULT CMofGen::PushMethods(WMI_CLASS* i_pElement)
  104. {
  105. DBG_ASSERT(i_pElement != NULL);
  106. DBG_ASSERT(m_pFile != NULL);
  107. WMI_METHOD* pMethCurrent;
  108. LPCWSTR wszRetType = NULL;
  109. LPWSTR wszDescription = NULL;
  110. LPWSTR wszParamType = NULL;
  111. LPWSTR wszParamTypeSuffix = NULL;
  112. LPWSTR wszParamInOut = NULL;
  113. int iError = 0;
  114. if(i_pElement->ppMethod == NULL)
  115. {
  116. return S_OK;
  117. }
  118. for(ULONG i = 0; i_pElement->ppMethod[i] != NULL; i++)
  119. {
  120. pMethCurrent = i_pElement->ppMethod[i];
  121. if(pMethCurrent->typeRetVal == NULL)
  122. {
  123. wszRetType = L"void";
  124. }
  125. else
  126. {
  127. CimTypeStringMapping* pCimType =
  128. CMofGenUtils::LookupCimType(pMethCurrent->typeRetVal);
  129. DBG_ASSERT(pCimType != NULL);
  130. if (!pCimType) {
  131. return E_FAIL;
  132. }
  133. wszRetType = pCimType->wszString;
  134. }
  135. wszDescription = pMethCurrent->pszDescription;
  136. iError = fwprintf(m_pFile, L"\t[Implemented,bypass_getobject");
  137. if(iError < 0)
  138. {
  139. return E_FAIL;
  140. }
  141. if(wszDescription)
  142. {
  143. iError = fwprintf(m_pFile, L",Description(\"%s\")", wszDescription);
  144. }
  145. iError = fwprintf(m_pFile, L"] %s %s(", wszRetType, pMethCurrent->pszMethodName);
  146. if(iError < 0)
  147. {
  148. return E_FAIL;
  149. }
  150. ULONG j = 0;
  151. if(pMethCurrent->ppParams != NULL)
  152. {
  153. for(j = 0; pMethCurrent->ppParams[j] != NULL; j++)
  154. {
  155. wszParamType = L"";
  156. wszParamTypeSuffix = L"";
  157. wszParamInOut = L"";
  158. if(j != 0)
  159. {
  160. iError = fwprintf(m_pFile, L", ");
  161. if(iError < 0)
  162. {
  163. return E_FAIL;
  164. }
  165. }
  166. switch(pMethCurrent->ppParams[j]->type)
  167. {
  168. case CIM_STRING:
  169. wszParamType = L"string";
  170. break;
  171. case CIM_SINT32:
  172. wszParamType = L"sint32";
  173. break;
  174. case VT_ARRAY | CIM_STRING:
  175. wszParamType = L"string";
  176. wszParamTypeSuffix = L"[]";
  177. break;
  178. case VT_ARRAY | VT_UNKNOWN:
  179. wszParamType = L"ServerBinding";
  180. wszParamTypeSuffix = L"[]";
  181. break;
  182. case CIM_BOOLEAN:
  183. wszParamType = L"boolean";
  184. break;
  185. case CIM_DATETIME:
  186. wszParamType = L"datetime";
  187. break;
  188. default:
  189. wprintf(L"Warning: Type of Param: %s in Method: %s unknown. Not outputting type.\n",
  190. pMethCurrent->ppParams[j]->pszParamName,
  191. pMethCurrent->pszMethodName);
  192. break;
  193. }
  194. switch(pMethCurrent->ppParams[j]->iInOut)
  195. {
  196. case PARAM_IN:
  197. wszParamInOut = L"[IN]";
  198. break;
  199. case PARAM_OUT:
  200. wszParamInOut = L"[OUT]";
  201. break;
  202. case PARAM_INOUT:
  203. wszParamInOut = L"[IN,OUT]";
  204. break;
  205. default:
  206. wprintf(L"Warning: Unsure if Param: %s in Method: %s is IN or OUT param. Not outputting IN/OUT qualifier\n",
  207. pMethCurrent->ppParams[j]->pszParamName,
  208. pMethCurrent->pszMethodName);
  209. break;
  210. }
  211. // CreateNewSite has an optional param
  212. if (!wcscmp(pMethCurrent->pszMethodName, L"CreateNewSite") &&
  213. !wcscmp(pMethCurrent->ppParams[j]->pszParamName, L"ServerId")) {
  214. wszParamInOut = L"[IN,OPTIONAL]";
  215. }
  216. iError = fwprintf(m_pFile, L"%s %s %s%s",
  217. wszParamInOut, wszParamType, pMethCurrent->ppParams[j]->pszParamName, wszParamTypeSuffix);
  218. if(iError < 0)
  219. {
  220. return E_FAIL;
  221. }
  222. }
  223. }
  224. iError = fwprintf(m_pFile, L");\n");
  225. if(iError < 0)
  226. {
  227. return E_FAIL;
  228. }
  229. }
  230. return S_OK;
  231. }
  232. HRESULT CMofGen::GenerateEscapedString(LPCWSTR i_wsz)
  233. {
  234. DBG_ASSERT(i_wsz != NULL);
  235. ULONG cchOld = 0;
  236. ULONG cchNew = 0;
  237. LPWSTR wsz;
  238. for(ULONG i = 0; i_wsz[i] != L'\0'; i++)
  239. {
  240. if(i_wsz[i] == L'\\' || i_wsz[i] == L'\"')
  241. {
  242. cchNew += 2;
  243. }
  244. else
  245. {
  246. cchNew++;
  247. }
  248. cchOld++;
  249. }
  250. if(cchNew > m_cchTemp || m_wszTemp == NULL)
  251. {
  252. delete [] m_wszTemp;
  253. m_wszTemp = new WCHAR[1+cchNew*2];
  254. if(m_wszTemp == NULL)
  255. {
  256. m_cchTemp = 0;
  257. return E_OUTOFMEMORY;
  258. }
  259. m_cchTemp = cchNew*2;
  260. }
  261. ULONG j = 0;
  262. for(ULONG i = 0; i < cchOld; i++)
  263. {
  264. if(i_wsz[i] == L'\\' || i_wsz[i] == L'\"')
  265. {
  266. m_wszTemp[j] = L'\\';
  267. m_wszTemp[j+1] = i_wsz[i];
  268. j+=2;
  269. }
  270. else
  271. {
  272. m_wszTemp[j] = i_wsz[i];
  273. j++;
  274. }
  275. }
  276. DBG_ASSERT(m_wszTemp != NULL);
  277. m_wszTemp[j] = L'\0';
  278. return S_OK;
  279. }
  280. HRESULT CMofGen::PushProperties(WMI_CLASS* i_pElement)
  281. {
  282. DBG_ASSERT(i_pElement != NULL);
  283. DBG_ASSERT(m_pFile != NULL);
  284. HRESULT hr = S_OK;
  285. METABASE_PROPERTY* pPropCurrent;
  286. LPWSTR wszType = NULL;
  287. LPWSTR wszTypeSuffix = NULL;
  288. LPWSTR wszQual = NULL;
  289. LPWSTR wszDefault = NULL;
  290. LPWSTR wszQuote = L"";
  291. int iError = 0;
  292. if(i_pElement->ppmbp == NULL)
  293. {
  294. return hr;
  295. }
  296. for(ULONG i = 0; i_pElement->ppmbp[i] != NULL; i++)
  297. {
  298. wszQual = wszTypeSuffix = wszType = wszQuote = L"";
  299. wszDefault = NULL;
  300. WCHAR wszBuf[20];
  301. pPropCurrent= i_pElement->ppmbp[i];
  302. switch(pPropCurrent->dwMDDataType)
  303. {
  304. case DWORD_METADATA:
  305. if(pPropCurrent->dwMDMask != 0)
  306. {
  307. wszType = L"boolean";
  308. if(pPropCurrent->pDefaultValue)
  309. {
  310. if(*((int *)(pPropCurrent->pDefaultValue)) == 0)
  311. {
  312. //wcscpy(wszBuf, L"false");
  313. //wszDefault = wszBuf;
  314. }
  315. else
  316. {
  317. //wcscpy(wszBuf, L"true");
  318. //wszDefault = wszBuf;
  319. }
  320. }
  321. }
  322. else
  323. {
  324. wszType = L"sint32";
  325. if(pPropCurrent->pDefaultValue)
  326. {
  327. //swprintf(wszBuf, L"%d", *((int *)(pPropCurrent->pDefaultValue)));
  328. //wszDefault = wszBuf;
  329. }
  330. }
  331. break;
  332. case STRING_METADATA:
  333. case EXPANDSZ_METADATA:
  334. wszType = L"string";
  335. wszQuote = L"\"";
  336. /*if(pPropCurrent->pDefaultValue != NULL)
  337. {
  338. //
  339. // Sets m_wszTemp
  340. //
  341. hr = GenerateEscapedString((LPWSTR)pPropCurrent->pDefaultValue);
  342. if(FAILED(hr))
  343. {
  344. goto exit;
  345. }
  346. wszDefault = m_wszTemp;;
  347. }*/
  348. break;
  349. case MULTISZ_METADATA:
  350. {
  351. wszType = L"string";
  352. TFormattedMultiSz* pFormattedMultiSz =
  353. TFormattedMultiSzData::Find(pPropCurrent->dwMDIdentifier);
  354. if(pFormattedMultiSz)
  355. {
  356. wszType = pFormattedMultiSz->wszWmiClassName;
  357. }
  358. wszTypeSuffix = L"[]";
  359. break;
  360. }
  361. case BINARY_METADATA:
  362. wszType = L"uint8";
  363. wszTypeSuffix = L"[]";
  364. break;
  365. default:
  366. wprintf(L"Warning: Cannot determine type of Prop: %s in Class: %s. Ignoring property.\n", pPropCurrent->pszPropName, i_pElement->pszClassName);
  367. continue;
  368. }
  369. //
  370. // qualifier for read-only
  371. //
  372. if(pPropCurrent->fReadOnly)
  373. {
  374. wszQual = L"[read, write(FALSE)]";
  375. }
  376. else
  377. {
  378. wszQual = L"[read, write]";
  379. }
  380. if(wszDefault)
  381. {
  382. iError = fwprintf(m_pFile, L"\t%s %s %s%s = %s%s%s;\n",
  383. wszQual, wszType, pPropCurrent->pszPropName, wszTypeSuffix,
  384. wszQuote, wszDefault, wszQuote);
  385. }
  386. else
  387. {
  388. iError = fwprintf(m_pFile, L"\t%s %s %s%s;\n",
  389. wszQual, wszType, pPropCurrent->pszPropName, wszTypeSuffix);
  390. }
  391. if(iError < 0)
  392. {
  393. hr = E_FAIL;
  394. goto exit;
  395. }
  396. }
  397. exit:
  398. return hr;
  399. }
  400. HRESULT CMofGen::PushAssociationComponent(LPWSTR i_wszComp,
  401. LPWSTR i_wszClass)
  402. {
  403. DBG_ASSERT(i_wszComp != NULL);
  404. DBG_ASSERT(i_wszClass != NULL);
  405. DBG_ASSERT(m_pFile != NULL);
  406. HRESULT hr = S_OK;
  407. int iError = fwprintf(m_pFile, L"\t[key] %s ref %s = NULL;\n", i_wszClass, i_wszComp);
  408. if(iError < 0)
  409. {
  410. return E_FAIL;
  411. }
  412. return hr;
  413. }
  414. HRESULT CMofGen::PushFormattedMultiSz()
  415. {
  416. DBG_ASSERT(m_pFile != NULL);
  417. HRESULT hr = S_OK;
  418. int iError = 0;
  419. TFormattedMultiSz** apFormattedMultiSz = TFormattedMultiSzData::apFormattedMultiSz;
  420. if(apFormattedMultiSz == NULL)
  421. {
  422. goto exit;
  423. }
  424. for(ULONG i = 0; apFormattedMultiSz[i] != NULL; i++)
  425. {
  426. iError = fwprintf(m_pFile, L"[provider(\"%s\"),Locale(1033)", g_wszIIsProvider);
  427. if(iError < 0)
  428. {
  429. hr = E_FAIL;
  430. goto exit;
  431. }
  432. iError = fwprintf(m_pFile, L"]\n");
  433. if(iError < 0)
  434. {
  435. hr = E_FAIL;
  436. goto exit;
  437. }
  438. iError = fwprintf(m_pFile, L"class %s : IIsStructuredDataClass\n", apFormattedMultiSz[i]->wszWmiClassName);
  439. if(iError < 0)
  440. {
  441. hr = E_FAIL;
  442. goto exit;
  443. }
  444. iError = fwprintf(m_pFile, L"{\n");
  445. if(iError < 0)
  446. {
  447. hr = E_FAIL;
  448. goto exit;
  449. }
  450. LPCWSTR* awszFields = apFormattedMultiSz[i]->awszFields;
  451. if(awszFields != NULL)
  452. {
  453. for(ULONG j = 0; awszFields[j] != NULL; j++)
  454. {
  455. iError = fwprintf(m_pFile, L"\t[key, read, write] string %s;\n", awszFields[j]);
  456. if(iError < 0)
  457. {
  458. hr = E_FAIL;
  459. goto exit;
  460. }
  461. }
  462. }
  463. iError = fwprintf(m_pFile, L"};\n\n");
  464. if(iError < 0)
  465. {
  466. hr = E_FAIL;
  467. goto exit;
  468. }
  469. }
  470. exit:
  471. return hr;
  472. }
  473. HRESULT CMofGen::PushFile (LPWSTR i_wszFile)
  474. {
  475. DBG_ASSERT(i_wszFile != NULL);
  476. DBG_ASSERT(m_pFile != NULL);
  477. FILE *pFile = _wfopen (i_wszFile, L"r");
  478. if (pFile == NULL)
  479. {
  480. wprintf(L"Could not open %s for reading\n", i_wszFile);
  481. return RETURNCODETOHRESULT(ERROR_OPEN_FAILED);
  482. }
  483. WCHAR wszBuffer[512];
  484. while (fgetws (wszBuffer, 512, pFile) != 0)
  485. {
  486. fputws (wszBuffer, m_pFile);
  487. }
  488. fclose (pFile);
  489. return S_OK;
  490. }
  491. HRESULT CMofGen::Push()
  492. {
  493. HRESULT hr = S_OK;
  494. if(m_pFile == NULL)
  495. {
  496. m_pFile = _wfopen(m_wszOutFileName, L"w+");
  497. if(m_pFile == NULL)
  498. {
  499. wprintf(L"Could not open %s for writing\n", m_wszOutFileName);
  500. hr = RETURNCODETOHRESULT(ERROR_OPEN_FAILED);
  501. goto exit;
  502. }
  503. }
  504. hr = PushFile(m_wszHeaderFileName);
  505. if(FAILED(hr))
  506. {
  507. goto exit;
  508. }
  509. if(fwprintf(m_pFile, L"\n\n") < 0)
  510. {
  511. hr = E_FAIL;
  512. goto exit;
  513. }
  514. hr = PushFormattedMultiSz();
  515. if(FAILED(hr))
  516. {
  517. goto exit;
  518. }
  519. hr = PushClasses(g_pDynSch->GetHashClasses(), false);
  520. if(FAILED(hr))
  521. {
  522. goto exit;
  523. }
  524. hr = PushClasses(g_pDynSch->GetHashAssociations(), true);
  525. if(FAILED(hr))
  526. {
  527. goto exit;
  528. }
  529. hr = PushFile(m_wszFooterFileName);
  530. if(FAILED(hr))
  531. {
  532. goto exit;
  533. }
  534. exit:
  535. return hr;
  536. }
  537. int __cdecl wmain(int argc, wchar_t* argv[])
  538. {
  539. #ifndef _NO_TRACING_
  540. // CREATE_DEBUG_PRINT_OBJECT("Mofgen.exe", IisWmiMofgenGuid);
  541. CREATE_DEBUG_PRINT_OBJECT("Mofgen.exe");
  542. #else
  543. CREATE_DEBUG_PRINT_OBJECT("Mofgen.exe");
  544. #endif
  545. HRESULT hr = S_OK;
  546. CMofGen mofgen;
  547. CSchemaExtensions catalog;
  548. g_pDynSch = new CDynSchema();
  549. if(g_pDynSch == NULL)
  550. {
  551. hr = E_OUTOFMEMORY;
  552. goto exit;
  553. }
  554. hr = g_pDynSch->Initialize();
  555. if(FAILED(hr))
  556. {
  557. goto exit;
  558. }
  559. hr = g_pDynSch->RunRules(&catalog, false);
  560. if(FAILED(hr))
  561. {
  562. goto exit;
  563. }
  564. if(!mofgen.ParseCmdLine(argc, argv))
  565. {
  566. mofgen.PrintUsage(argv);
  567. hr = E_INVALIDARG;
  568. goto exit;
  569. }
  570. hr = mofgen.Push();
  571. if(FAILED(hr))
  572. {
  573. goto exit;
  574. }
  575. exit:
  576. delete g_pDynSch;
  577. g_pDynSch = NULL;
  578. DELETE_DEBUG_PRINT_OBJECT();
  579. if(FAILED(hr))
  580. {
  581. printf("MofGen failed, code: 0x%x\n", hr);
  582. return 1;
  583. }
  584. else
  585. {
  586. wprintf(L"MofGen successful! %s created.\n", mofgen.GetOutFileName());
  587. return 0;
  588. }
  589. }