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.

1507 lines
38 KiB

  1. //---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 1997
  5. //
  6. // File: schemini.cxx
  7. //
  8. // Contents: Loading Schema/Property from metabase code
  9. //
  10. // History: 28-Apr-97 Markand Created.
  11. // History: 18-Aug-98 sophiac Extensible schema
  12. //
  13. //----------------------------------------------------------------------------
  14. #include "iis.hxx"
  15. #define INITGUID
  16. #pragma hdrstop
  17. #include "mddef.h"
  18. #include <tchar.h>
  19. #define DEFAULT_TIMEOUT_VALUE 30000
  20. StrMap::StrMap() {
  21. count = 0;
  22. mapSize = 64;
  23. map = (StrMapEntry *)malloc(sizeof(StrMapEntry) * mapSize);
  24. }
  25. StrMap::~StrMap() {
  26. free(map);
  27. }
  28. DWORD StrMap::GetEntries() {
  29. return count;
  30. }
  31. LPWSTR StrMap::GetEntryName(DWORD dwIndex) {
  32. return map[dwIndex].m_str;
  33. }
  34. BOOL StrMap::CheckSpace() {
  35. if (count < mapSize)
  36. return TRUE;
  37. mapSize += 32;
  38. StrMapEntry* map_old = map;
  39. if ((map = (StrMapEntry *)realloc(map, sizeof(StrMapEntry)*mapSize)) == NULL)
  40. {
  41. if (map_old)
  42. {
  43. free(map_old);
  44. }
  45. return FALSE;
  46. }
  47. return TRUE;
  48. }
  49. BOOL StrMap::Add(LPWSTR str, void *data) {
  50. if (!CheckSpace())
  51. return FALSE;
  52. map[count].m_str = str;
  53. map[count].m_data = data;
  54. count++;
  55. return TRUE;
  56. }
  57. BOOL StrMap::ClearEntry(DWORD dwIndex) {
  58. count--;
  59. void* prop = map[dwIndex].m_data;
  60. // replace object to be deleted by last object in list and decrement count
  61. map[dwIndex].m_str = map[count].m_str;
  62. map[dwIndex].m_data = map[count].m_data;
  63. map[count].m_str = NULL;
  64. map[count].m_data = NULL;
  65. if (prop)
  66. delete prop;
  67. return TRUE;
  68. }
  69. void *StrMap::Find(LPWSTR str) {
  70. for (int i=0; i < count; i++) {
  71. if (!_wcsicmp(str, map[i].m_str))
  72. return map[i].m_data;
  73. }
  74. return NULL;
  75. }
  76. void *StrMap::operator[] (LPWSTR str) {
  77. return Find(str);
  78. }
  79. DWORDMap::DWORDMap() {
  80. count = 0;
  81. mapSize = 64;
  82. map = (DWORDMapEntry *)malloc(sizeof(DWORDMapEntry) * mapSize);
  83. }
  84. DWORDMap::~DWORDMap() {
  85. free(map);
  86. }
  87. BOOL DWORDMap::CheckSpace() {
  88. if (count < mapSize)
  89. return TRUE;
  90. mapSize += 32;
  91. DWORDMapEntry* map_old = map;
  92. if ((map = (DWORDMapEntry *)realloc(map, sizeof(DWORDMapEntry)*mapSize)) == NULL)
  93. {
  94. if (map_old)
  95. {
  96. free(map_old);
  97. }
  98. return FALSE;
  99. }
  100. return TRUE;
  101. }
  102. BOOL DWORDMap::Add(DWORD val, void *data) {
  103. if (!CheckSpace())
  104. return FALSE;
  105. map[count].m_val = val;
  106. map[count].m_data = data;
  107. count++;
  108. return TRUE;
  109. }
  110. BOOL DWORDMap::ClearEntry(DWORD id) {
  111. // !! don't delete the m_data here
  112. // !! it will be or already has been deleted
  113. // !! by StrMap::ClearEntry
  114. int ri = 0;
  115. for (int i=0; i < count; i++) {
  116. if (id == map[i].m_val)
  117. ri = i;
  118. }
  119. count--;
  120. map[ri].m_val = map[count].m_val;
  121. map[ri].m_data = map[count].m_data;
  122. map[count].m_val = NULL;
  123. map[count].m_data = NULL;
  124. return TRUE;
  125. }
  126. void *DWORDMap::Find(DWORD val) {
  127. for (int i=0; i < count; i++) {
  128. if (val == map[i].m_val)
  129. return map[i].m_data;
  130. }
  131. return NULL;
  132. }
  133. void *DWORDMap::operator[] (DWORD val) {
  134. return Find(val);
  135. }
  136. IIsSchemaClass::IIsSchemaClass(LPWSTR _name) {
  137. memset(&classInfo, 0, sizeof(CLASSINFO));
  138. name = new WCHAR[wcslen(_name)+1];
  139. wcscpy(name, _name);
  140. }
  141. IIsSchemaClass::~IIsSchemaClass() {
  142. delete[] name;
  143. if (classInfo.bstrContainment)
  144. FreeADsMem(classInfo.bstrContainment);
  145. if (classInfo.bstrOptionalProperties)
  146. FreeADsMem(classInfo.bstrOptionalProperties);
  147. if (classInfo.bstrMandatoryProperties)
  148. FreeADsMem(classInfo.bstrMandatoryProperties);
  149. }
  150. HRESULT
  151. IISSchemaProperty::SetpropInfo(PROPERTYINFO *ppropInfo) {
  152. HRESULT hr = S_OK;
  153. LPWSTR pszStr;
  154. if (propInfo.bstrOID) {
  155. ADsFreeString( propInfo.bstrOID );
  156. }
  157. if (propInfo.bstrSyntax) {
  158. ADsFreeString( propInfo.bstrSyntax );
  159. }
  160. if (propInfo.szDefault) {
  161. if (propInfo.dwSyntaxId == IIS_SYNTAX_ID_STRING ||
  162. propInfo.dwSyntaxId == IIS_SYNTAX_ID_EXPANDSZ) {
  163. FreeADsStr( propInfo.szDefault );
  164. }
  165. else if (propInfo.dwSyntaxId == IIS_SYNTAX_ID_MULTISZ) {
  166. FreeADsMem( propInfo.szDefault );
  167. }
  168. }
  169. memset(&propInfo, 0, sizeof(PROPERTYINFO));
  170. memcpy(&propInfo, ppropInfo, sizeof(PROPERTYINFO));
  171. hr = ADsAllocString(ppropInfo->bstrSyntax, &propInfo.bstrSyntax);
  172. BAIL_ON_FAILURE(hr);
  173. hr = ADsAllocString(ppropInfo->bstrOID, &propInfo.bstrOID);
  174. BAIL_ON_FAILURE(hr);
  175. switch(ppropInfo->dwSyntaxId) {
  176. case IIS_SYNTAX_ID_DWORD:
  177. case IIS_SYNTAX_ID_BOOL:
  178. case IIS_SYNTAX_ID_BOOL_BITMASK:
  179. propInfo.dwDefault = ppropInfo->dwDefault;
  180. break;
  181. case IIS_SYNTAX_ID_STRING:
  182. case IIS_SYNTAX_ID_EXPANDSZ:
  183. if (ppropInfo->szDefault) {
  184. propInfo.szDefault = AllocADsStr((LPWSTR)(ppropInfo->szDefault));
  185. if (!propInfo.szDefault) {
  186. hr = E_OUTOFMEMORY;
  187. BAIL_ON_FAILURE(hr);
  188. }
  189. }
  190. break;
  191. case IIS_SYNTAX_ID_MIMEMAP:
  192. case IIS_SYNTAX_ID_MULTISZ:
  193. pszStr = ppropInfo->szDefault;
  194. //
  195. // calculate length
  196. //
  197. if (pszStr) {
  198. DWORD dwLen = 0;
  199. //
  200. // if first char is a null char
  201. //
  202. if (*pszStr == L'\0') {
  203. dwLen = 1;
  204. pszStr++;
  205. }
  206. while (*pszStr != L'\0') {
  207. while (*pszStr != L'\0') {
  208. pszStr++;
  209. dwLen++;
  210. }
  211. pszStr++;
  212. dwLen++;
  213. }
  214. propInfo.szDefault = (LPWSTR)AllocADsMem((dwLen +1) * sizeof(WCHAR));
  215. if (!propInfo.szDefault) {
  216. hr = E_OUTOFMEMORY;
  217. BAIL_ON_FAILURE(hr);
  218. }
  219. memcpy(propInfo.szDefault, (LPWSTR)ppropInfo->szDefault,
  220. (dwLen+1)*sizeof(WCHAR));
  221. }
  222. break;
  223. default:
  224. break;
  225. }
  226. error:
  227. RRETURN(hr);
  228. }
  229. IISSchemaProperty::IISSchemaProperty(DWORD id, LPWSTR _name, int nameLen) {
  230. memset(&propInfo, 0, sizeof(PROPERTYINFO));
  231. name = new WCHAR[nameLen];
  232. wcscpy(name, _name);
  233. propID = id;
  234. }
  235. IISSchemaProperty::~IISSchemaProperty() {
  236. delete[] name;
  237. if (propInfo.szDefault) {
  238. if (propInfo.dwSyntaxId == IIS_SYNTAX_ID_MULTISZ) {
  239. FreeADsMem(propInfo.szDefault);
  240. }
  241. else {
  242. FreeADsStr(propInfo.szDefault);
  243. }
  244. }
  245. }
  246. HRESULT IIsSchemaClass::findContainedClassName(LPWSTR pszContainName) {
  247. WCHAR szName[MAX_PATH];
  248. LPWSTR ObjectList = (LPWSTR)classInfo.bstrContainment;
  249. while ((ObjectList = grabProp(szName, ObjectList)) != NULL) {
  250. if (*szName != L'\0') {
  251. if (!_wcsicmp(szName, pszContainName)) {
  252. return S_OK;
  253. }
  254. }
  255. }
  256. return E_ADS_SCHEMA_VIOLATION;
  257. }
  258. HRESULT IIsSchemaClass::SetclassInfo(PCLASSINFO pClassInfo) {
  259. HRESULT hr = S_OK;
  260. LPBYTE pBuffer = NULL;
  261. DWORD dwSize;
  262. if (classInfo.bstrContainment)
  263. FreeADsMem(classInfo.bstrContainment);
  264. if (classInfo.bstrOptionalProperties)
  265. FreeADsMem(classInfo.bstrOptionalProperties);
  266. if (classInfo.bstrMandatoryProperties)
  267. FreeADsMem(classInfo.bstrMandatoryProperties);
  268. memset(&classInfo, 0, sizeof(CLASSINFO));
  269. if (pClassInfo) {
  270. if (pClassInfo->bstrContainment) {
  271. dwSize = ((DWORD)wcslen(pClassInfo->bstrContainment)+1)*sizeof(WCHAR);
  272. pBuffer = (LPBYTE)AllocADsMem(dwSize);
  273. if (!pBuffer) {
  274. hr = E_OUTOFMEMORY;
  275. BAIL_ON_FAILURE(hr);
  276. }
  277. memcpy(pBuffer, pClassInfo->bstrContainment, dwSize);
  278. classInfo.bstrContainment = (BSTR)pBuffer;
  279. }
  280. if (pClassInfo->bstrMandatoryProperties) {
  281. dwSize = ((DWORD)wcslen(pClassInfo->bstrMandatoryProperties)+1)*sizeof(WCHAR);
  282. pBuffer = (LPBYTE)AllocADsMem(dwSize);
  283. if (!pBuffer) {
  284. hr = E_OUTOFMEMORY;
  285. BAIL_ON_FAILURE(hr);
  286. }
  287. memcpy(pBuffer, pClassInfo->bstrMandatoryProperties, dwSize);
  288. classInfo.bstrMandatoryProperties = (BSTR)pBuffer;
  289. }
  290. if (pClassInfo->bstrOptionalProperties) {
  291. dwSize = ((DWORD)wcslen(pClassInfo->bstrOptionalProperties)+1)*sizeof(WCHAR);
  292. pBuffer = (LPBYTE)AllocADsMem(dwSize);
  293. if (!pBuffer) {
  294. hr = E_OUTOFMEMORY;
  295. BAIL_ON_FAILURE(hr);
  296. }
  297. memcpy(pBuffer, pClassInfo->bstrOptionalProperties, dwSize);
  298. classInfo.bstrOptionalProperties = (BSTR)pBuffer;
  299. }
  300. classInfo.fContainer = pClassInfo->fContainer;
  301. }
  302. error:
  303. RRETURN(hr);
  304. }
  305. HRESULT IIsSchemaClass::findProp(LPWSTR pszPropName) {
  306. WCHAR szName[MAX_PATH];
  307. LPWSTR ObjectList = (LPWSTR)classInfo.bstrOptionalProperties;
  308. while ((ObjectList = grabProp(szName, ObjectList)) != NULL) {
  309. if (*szName != L'\0') {
  310. if (!_wcsicmp(szName, pszPropName)) {
  311. return S_OK;
  312. }
  313. }
  314. }
  315. ObjectList = (LPWSTR)classInfo.bstrMandatoryProperties;
  316. while ((ObjectList = grabProp(szName, ObjectList)) != NULL) {
  317. if (*szName != L'\0') {
  318. if (!_wcsicmp(szName, pszPropName)) {
  319. return S_OK;
  320. }
  321. }
  322. }
  323. return E_ADS_PROPERTY_NOT_SUPPORTED;
  324. }
  325. BOOL IISSchemaProperty::InitFromMetaData(METADATA_GETALL_RECORD *mdga, BYTE *data) {
  326. PropValue pv;
  327. WCHAR* pszSyntax = NULL;
  328. if (mdga->dwMDDataType == BINARY_METADATA &&
  329. mdga->dwMDDataLen >= sizeof(PropValue) - sizeof(LPWSTR))
  330. {
  331. memcpy(&pv, (data+mdga->dwMDDataOffset), sizeof(PropValue));
  332. propInfo.dwMetaID = pv.dwMetaID;
  333. propInfo.dwPropID = pv.dwPropID;
  334. propInfo.dwSyntaxId = pv.dwSynID;
  335. propInfo.lMaxRange = (long)pv.dwMaxRange;
  336. propInfo.lMinRange = (long)pv.dwMinRange;
  337. propInfo.dwFlags = pv.dwFlags;
  338. propInfo.dwMask = pv.dwMask;
  339. propInfo.dwMetaFlags = pv.dwMetaFlags;
  340. propInfo.dwUserGroup = pv.dwUserGroup;
  341. propInfo.fMultiValued = pv.fMultiValued;
  342. pszSyntax = SyntaxIdToString(pv.dwSynID);
  343. HRESULT hr = ADsAllocString(pszSyntax, &(propInfo.bstrSyntax));
  344. if FAILED(hr)
  345. {
  346. return FALSE;
  347. }
  348. return TRUE;
  349. }
  350. return FALSE;
  351. }
  352. BOOL IISSchemaProperty::InitPropertyDefaults(METADATA_GETALL_RECORD *mdga, BYTE *data) {
  353. WCHAR *ptr;
  354. BYTE *bptr;
  355. propInfo.dwDefault = 0;
  356. propInfo.szDefault = NULL;
  357. if (!(mdga && data)){
  358. return TRUE;
  359. }
  360. switch(mdga->dwMDDataType) {
  361. case DWORD_METADATA:
  362. propInfo.dwDefault = *(DWORD *)(data+mdga->dwMDDataOffset);
  363. break;
  364. case STRING_METADATA:
  365. case EXPANDSZ_METADATA:
  366. propInfo.szDefault = AllocADsStr((LPWSTR)(data+mdga->dwMDDataOffset));
  367. break;
  368. case MULTISZ_METADATA:
  369. ptr = (LPWSTR)(data+mdga->dwMDDataOffset);
  370. propInfo.szDefault = (LPWSTR) AllocADsMem(mdga->dwMDDataLen);
  371. memcpy(propInfo.szDefault, (LPWSTR)ptr, mdga->dwMDDataLen);
  372. break;
  373. case BINARY_METADATA:
  374. if (mdga->dwMDDataLen > 0)
  375. {
  376. bptr = (BYTE*)(data+mdga->dwMDDataOffset);
  377. propInfo.szDefault = (LPWSTR) AllocADsMem(mdga->dwMDDataLen);
  378. memcpy(propInfo.szDefault, bptr, mdga->dwMDDataLen);
  379. propInfo.dwBinDataLen = mdga->dwMDDataLen;
  380. }
  381. else
  382. {
  383. propInfo.dwBinDataLen = 0;
  384. }
  385. break;
  386. }
  387. return TRUE;
  388. }
  389. WCHAR *grabProp(WCHAR *out, WCHAR *in) {
  390. if (!in || *in == L'\0') {
  391. *out = L'\0';
  392. return NULL;
  393. }
  394. while (*in != L',' && *in != L'\0') {
  395. *out++ = *in++;
  396. }
  397. *out = L'\0';
  398. if (*in == L',')
  399. return ++in;
  400. return in;
  401. }
  402. WCHAR *SyntaxIdToString(DWORD syntaxID) {
  403. switch(syntaxID) {
  404. case IIS_SYNTAX_ID_BOOL:
  405. case IIS_SYNTAX_ID_BOOL_BITMASK:
  406. return L"Boolean";
  407. case IIS_SYNTAX_ID_DWORD:
  408. return L"Integer";
  409. case IIS_SYNTAX_ID_STRING:
  410. return L"String";
  411. case IIS_SYNTAX_ID_EXPANDSZ:
  412. return L"ExpandSz";
  413. case IIS_SYNTAX_ID_MIMEMAP:
  414. return L"MimeMapList";
  415. case IIS_SYNTAX_ID_MULTISZ:
  416. return L"List";
  417. case IIS_SYNTAX_ID_IPSECLIST:
  418. return L"IPSec";
  419. case IIS_SYNTAX_ID_NTACL:
  420. return L"NTAcl";
  421. case IIS_SYNTAX_ID_BINARY:
  422. return L"Binary";
  423. default:
  424. return L"(ERROR -- UNDEFINED SYNTAX ID)";
  425. }
  426. }
  427. BOOL DataForSyntaxID(PROPERTYINFO *pp, METADATA_RECORD *mdr) {
  428. static DWORD value=0;
  429. WCHAR *ptr;
  430. switch(pp->dwSyntaxId) {
  431. case IIS_SYNTAX_ID_BOOL:
  432. case IIS_SYNTAX_ID_BOOL_BITMASK:
  433. case IIS_SYNTAX_ID_DWORD:
  434. mdr->dwMDDataType = DWORD_METADATA;
  435. mdr->dwMDDataLen = sizeof(DWORD);
  436. mdr->pbMDData = (unsigned char *)&(pp->dwDefault);
  437. break;
  438. case IIS_SYNTAX_ID_STRING:
  439. mdr->dwMDDataType = STRING_METADATA;
  440. if (pp->szDefault) {
  441. mdr->dwMDDataLen = ((DWORD)wcslen(pp->szDefault)+1)*2;
  442. }
  443. else {
  444. mdr->dwMDDataLen = 0;
  445. }
  446. mdr->pbMDData = (unsigned char *)pp->szDefault;
  447. break;
  448. case IIS_SYNTAX_ID_EXPANDSZ:
  449. mdr->dwMDDataType = EXPANDSZ_METADATA;
  450. if (pp->szDefault) {
  451. mdr->dwMDDataLen = ((DWORD)wcslen(pp->szDefault)+1)*2;
  452. }
  453. else {
  454. mdr->dwMDDataLen = 0;
  455. }
  456. mdr->pbMDData = (unsigned char *)pp->szDefault;
  457. break;
  458. case IIS_SYNTAX_ID_MIMEMAP:
  459. case IIS_SYNTAX_ID_MULTISZ:
  460. //
  461. // Note, ALL multisz types must have an extra \0 in the table.
  462. //
  463. mdr->dwMDDataType = MULTISZ_METADATA;
  464. if (pp->szDefault) {
  465. ptr = pp->szDefault;
  466. if (*ptr == L'\0') {
  467. ptr++;
  468. }
  469. while (*ptr!=0) {
  470. ptr += wcslen(ptr)+1;
  471. }
  472. mdr->dwMDDataLen = (DWORD)DIFF((char *)ptr - (char *)pp->szDefault)+2;
  473. }
  474. else {
  475. mdr->dwMDDataLen = 0;
  476. }
  477. mdr->pbMDData = (unsigned char *)pp->szDefault;
  478. break;
  479. case IIS_SYNTAX_ID_IPSECLIST:
  480. case IIS_SYNTAX_ID_NTACL:
  481. case IIS_SYNTAX_ID_BINARY:
  482. mdr->dwMDDataType = BINARY_METADATA;
  483. mdr->dwMDDataLen = 0;
  484. mdr->pbMDData = NULL;
  485. break;
  486. default:
  487. mdr->dwMDDataType = DWORD_METADATA;
  488. mdr->dwMDDataLen = sizeof(DWORD);
  489. mdr->pbMDData = (unsigned char *)&value;
  490. return FALSE;
  491. }
  492. return TRUE;
  493. }
  494. DWORD SyntaxToMetaID(DWORD syntaxID) {
  495. switch(syntaxID) {
  496. case IIS_SYNTAX_ID_BOOL:
  497. case IIS_SYNTAX_ID_BOOL_BITMASK:
  498. case IIS_SYNTAX_ID_DWORD:
  499. return DWORD_METADATA;
  500. case IIS_SYNTAX_ID_STRING:
  501. return STRING_METADATA;
  502. case IIS_SYNTAX_ID_EXPANDSZ:
  503. return EXPANDSZ_METADATA;
  504. case IIS_SYNTAX_ID_MIMEMAP:
  505. case IIS_SYNTAX_ID_MULTISZ:
  506. case IIS_SYNTAX_ID_HTTPERRORS:
  507. case IIS_SYNTAX_ID_HTTPHEADERS:
  508. return MULTISZ_METADATA;
  509. case IIS_SYNTAX_ID_IPSECLIST:
  510. case IIS_SYNTAX_ID_NTACL:
  511. case IIS_SYNTAX_ID_BINARY:
  512. return BINARY_METADATA;
  513. default:
  514. // printf("ERROR, Unknown Syntax Type %x", syntaxID);
  515. return 0;
  516. }
  517. return 0;
  518. }
  519. MetaHandle::MetaHandle(IMSAdminBasePtr _pmb) : pmb(_pmb) {
  520. if (pmb)
  521. pmb->AddRef();
  522. h = 0;
  523. }
  524. MetaHandle::~MetaHandle() {
  525. if (pmb) {
  526. if (h)
  527. pmb->CloseKey(h);
  528. pmb->Release();
  529. }
  530. }
  531. HRESULT IIsSchema::IdToPropNameW(DWORD id, LPWSTR buf) {
  532. IISSchemaProperty *prop = (IISSchemaProperty *)idToProp[id];
  533. if (!prop)
  534. return E_ADS_PROPERTY_NOT_SUPPORTED;
  535. wcscpy(buf, prop->getName());
  536. return S_OK;
  537. }
  538. HRESULT IIsSchema::PropNameWToId(LPWSTR propNameW, DWORD *id) {
  539. IISSchemaProperty *prop = (IISSchemaProperty *)nameToProp[propNameW];
  540. if (!prop)
  541. return E_ADS_PROPERTY_NOT_SUPPORTED;
  542. *id = prop->getPropID();
  543. return S_OK;
  544. }
  545. HRESULT IIsSchema::LookupFlagPropName(LPWSTR propNameW, LPWSTR FlagPropName) {
  546. DWORD id;
  547. IISSchemaProperty *prop = (IISSchemaProperty *)nameToProp[propNameW];
  548. if (!prop)
  549. return E_ADS_PROPERTY_NOT_SUPPORTED;
  550. id = prop->getMetaID();
  551. return (ConvertID_To_PropName(id, FlagPropName));
  552. }
  553. HRESULT IIsSchema::LookupMetaID(LPWSTR propNameW, PDWORD pdwMetaId) {
  554. IISSchemaProperty *prop = (IISSchemaProperty *)nameToProp[propNameW];
  555. if (!prop)
  556. return E_ADS_PROPERTY_NOT_SUPPORTED;
  557. *pdwMetaId = prop->getMetaID();
  558. return S_OK;
  559. }
  560. HRESULT IIsSchema::LookupPropID(LPWSTR propNameW, PDWORD pdwPropId) {
  561. IISSchemaProperty *prop = (IISSchemaProperty *)nameToProp[propNameW];
  562. if (!prop)
  563. return E_ADS_PROPERTY_NOT_SUPPORTED;
  564. *pdwPropId = prop->getPropID();
  565. return S_OK;
  566. }
  567. HRESULT IIsSchema::PropNameWToIISSchemaProp(LPWSTR propNameW, IISSchemaProperty **prop) {
  568. *prop = NULL;
  569. *prop = (IISSchemaProperty *)nameToProp[propNameW];
  570. if (!*prop)
  571. return E_ADS_PROPERTY_NOT_SUPPORTED;
  572. return S_OK;
  573. }
  574. HRESULT IIsSchema::ValidatePropertyName( LPWSTR szPropName) {
  575. DWORD propID;
  576. HRESULT hr;
  577. hr = PropNameWToId(szPropName, &propID);
  578. RRETURN(hr);
  579. }
  580. HRESULT IIsSchema::ValidateProperty(LPWSTR szClassName, LPWSTR szPropName) {
  581. HRESULT hr;
  582. IIsSchemaClass *sc;
  583. sc = (IIsSchemaClass*)nameToClass[szClassName];
  584. if (!sc)
  585. return E_ADS_PROPERTY_NOT_SUPPORTED;
  586. hr = sc->findProp(szPropName);
  587. RRETURN(hr);
  588. }
  589. HRESULT IIsSchema::ValidateContainedClassName(LPWSTR szClassName, LPWSTR szContainName) {
  590. HRESULT hr;
  591. IIsSchemaClass *sc;
  592. sc = (IIsSchemaClass *)nameToClass[szClassName];
  593. if (!sc)
  594. RRETURN(E_ADS_UNKNOWN_OBJECT);
  595. hr = sc->findContainedClassName(szContainName);
  596. RRETURN(hr);
  597. }
  598. HRESULT
  599. IIsSchema::GetDefaultProperty(
  600. LPWSTR szPropName,
  601. PDWORD pdwNumValues,
  602. PDWORD pdwSyntax,
  603. LPBYTE *pBuffer
  604. )
  605. /*++
  606. Routine Description:
  607. Arguments:
  608. LPBYTE *pBuffer - pBuffer is not allocated, it just holds the
  609. address of the default value in the PROPINFO
  610. structure
  611. Return Value:
  612. Notes:
  613. Called by CPropertyCache::getproperty
  614. Currently binary values are not supported correctly, we
  615. may not ever support them.
  616. --*/
  617. {
  618. HRESULT hr = S_OK;
  619. IISSchemaProperty *prop = (IISSchemaProperty *)nameToProp[szPropName];
  620. if (!prop)
  621. return E_ADS_PROPERTY_NOT_SUPPORTED;
  622. *pdwSyntax = prop->getSyntaxID();
  623. switch(*pdwSyntax) {
  624. case IIS_SYNTAX_ID_BOOL:
  625. case IIS_SYNTAX_ID_BOOL_BITMASK:
  626. case IIS_SYNTAX_ID_DWORD:
  627. *pBuffer = (LPBYTE)prop->getdwDefaultAddr();
  628. *pdwNumValues = 1;
  629. break;
  630. case IIS_SYNTAX_ID_BINARY:
  631. case IIS_SYNTAX_ID_IPSECLIST:
  632. case IIS_SYNTAX_ID_NTACL:
  633. //
  634. // We don't currently support setting or getting default values,
  635. // so pBuffer should always be NULL. To support default values
  636. // on binaries, we need to transmit the length in the PROPINFO
  637. // structure.
  638. //
  639. *pBuffer = (LPBYTE)prop->getszDefault();
  640. *pdwNumValues = (DWORD)prop->getdwBinDataLen();
  641. break;
  642. case IIS_SYNTAX_ID_MULTISZ:
  643. {
  644. *pBuffer = (LPBYTE)prop->getszDefault();
  645. LPWSTR pszStr = (LPWSTR)*pBuffer;
  646. if (*pszStr == 0) {
  647. *pdwNumValues = 1;
  648. }
  649. else {
  650. *pdwNumValues = 0;
  651. }
  652. while (*pszStr != L'\0') {
  653. while (*pszStr != L'\0') {
  654. pszStr++;
  655. }
  656. (*pdwNumValues)++;
  657. pszStr++;
  658. }
  659. break;
  660. }
  661. default:
  662. *pBuffer = (LPBYTE)prop->getszDefault();
  663. *pdwNumValues = 1;
  664. break;
  665. }
  666. RRETURN(hr);
  667. }
  668. HRESULT IIsSchema::PropNameWToSyntaxId(LPWSTR propNameW, DWORD *syntaxID) {
  669. IISSchemaProperty *prop;
  670. HRESULT hr;
  671. hr = PropNameWToIISSchemaProp(propNameW, &prop);
  672. BAIL_ON_FAILURE(hr);
  673. *syntaxID = prop->getSyntaxID();
  674. return S_OK;
  675. error:
  676. return E_ADS_PROPERTY_NOT_SUPPORTED;
  677. }
  678. HRESULT IIsSchema::ValidateClassName(LPWSTR classNameW) {
  679. if (nameToClass[classNameW])
  680. RRETURN(ERROR_SUCCESS);
  681. else
  682. RRETURN(E_ADS_SCHEMA_VIOLATION);
  683. }
  684. HRESULT IIsSchema::ConvertID_To_PropName(
  685. DWORD dwIdentifier,
  686. LPWSTR pszPropertyName
  687. )
  688. {
  689. HRESULT hr = S_OK;
  690. hr = IdToPropNameW(dwIdentifier, pszPropertyName);
  691. RRETURN(hr);
  692. }
  693. HRESULT IIsSchema::ConvertPropName_To_ID(
  694. LPWSTR pszPropertyName,
  695. PDWORD pdwIdentifier
  696. )
  697. {
  698. HRESULT hr = S_OK;
  699. if (!pszPropertyName) {
  700. hr = E_ADS_PROPERTY_NOT_SUPPORTED;
  701. BAIL_ON_FAILURE(hr);
  702. }
  703. hr = PropNameWToId(pszPropertyName, pdwIdentifier);
  704. error:
  705. RRETURN(hr);
  706. }
  707. HRESULT IIsSchema::LookupSyntaxID(
  708. LPWSTR pszPropertyName,
  709. PDWORD pdwSyntaxId
  710. )
  711. {
  712. HRESULT hr = S_OK;
  713. if (!pszPropertyName) {
  714. hr = E_ADS_PROPERTY_NOT_SUPPORTED;
  715. BAIL_ON_FAILURE(hr);
  716. }
  717. hr = PropNameWToSyntaxId(pszPropertyName, pdwSyntaxId);
  718. error:
  719. RRETURN(hr);
  720. }
  721. HRESULT IIsSchema::LookupMDFlags(
  722. DWORD dwPropID,
  723. PDWORD pdwAttribute,
  724. PDWORD pdwUserType
  725. )
  726. {
  727. HRESULT hr = S_OK;
  728. IISSchemaProperty *prop=(IISSchemaProperty *)idToProp[dwPropID];
  729. if (prop) {
  730. *pdwAttribute = prop->getMetaFlags();
  731. *pdwUserType = prop->getUserGroup();
  732. } else {
  733. hr = E_ADS_PROPERTY_NOT_SUPPORTED;
  734. BAIL_ON_FAILURE(hr);
  735. }
  736. return S_OK;
  737. error:
  738. RRETURN(hr);
  739. }
  740. HRESULT
  741. IIsSchema::LookupBitMask(
  742. LPWSTR pszPropertyName,
  743. PDWORD pdwMaskBits
  744. )
  745. {
  746. HRESULT hr = S_OK;
  747. IISSchemaProperty *prop=NULL;
  748. hr = PropNameWToIISSchemaProp(pszPropertyName, &prop);
  749. BAIL_ON_FAILURE(hr);
  750. if (prop) {
  751. *pdwMaskBits = prop->getMask();
  752. } else {
  753. hr = E_ADS_PROPERTY_NOT_SUPPORTED;
  754. BAIL_ON_FAILURE(hr);
  755. }
  756. return S_OK;
  757. error:
  758. RRETURN(hr);
  759. }
  760. HRESULT IIsSchema::LoadAllData(IMSAdminBasePtr &pmb,
  761. MetaHandle &root,
  762. WCHAR *subdir,
  763. BYTE **buf,
  764. DWORD *size,
  765. DWORD *count) {
  766. DWORD dataSet;
  767. DWORD neededSize;
  768. HRESULT hr;
  769. //
  770. // Try to get the property names.
  771. //
  772. hr = pmb->GetAllData(root,
  773. subdir,
  774. METADATA_NO_ATTRIBUTES,
  775. ALL_METADATA,
  776. ALL_METADATA,
  777. count,
  778. &dataSet,
  779. *size,
  780. *buf,
  781. &neededSize);
  782. if (!SUCCEEDED(hr)) {
  783. DWORD code = ERROR_INSUFFICIENT_BUFFER;
  784. if (hr == RETURNCODETOHRESULT(ERROR_INSUFFICIENT_BUFFER)) {
  785. // printf("Names buf of %d not big enough. Need %d bytes\n",
  786. // getAllBufSize,
  787. // neededSize);
  788. delete *buf;
  789. *buf = 0;
  790. *size = neededSize;
  791. *buf = new BYTE[neededSize];
  792. hr = pmb->GetAllData(root,
  793. subdir,
  794. METADATA_NO_ATTRIBUTES,
  795. ALL_METADATA,
  796. ALL_METADATA,
  797. count,
  798. &dataSet,
  799. *size,
  800. *buf,
  801. &neededSize);
  802. }
  803. }
  804. return hr;
  805. }
  806. // BUGBUG: Get rid of this constant ASAP!
  807. // Sergeia: fix for bug 189797, buffer was too small
  808. const DWORD getAllBufSize = 4096*2;
  809. HRESULT IIsSchema::InitSchema(WCHAR *baseName, CCredentials& Credentials)
  810. {
  811. DWORD bufSize = getAllBufSize;
  812. BYTE *buf = new BYTE[bufSize];
  813. HRESULT hr;
  814. COSERVERINFO csiName;
  815. COSERVERINFO *pcsiParam = &csiName;
  816. IClassFactory * pcsfFactory = NULL;
  817. IMSAdminBase * pAdminBase = NULL;
  818. IMSAdminBase * pAdminBaseT = NULL;
  819. DWORD count=0, dataSet=0, neededSize=0;
  820. METADATA_GETALL_RECORD *pmd;
  821. DWORD propBufSize = 128;
  822. DWORD i;
  823. MetaHandle root(NULL);
  824. LPWSTR pContainment = NULL;
  825. LPWSTR pOptProp = NULL;
  826. LPWSTR pMandProp = NULL;
  827. DWORD dwData = 0;
  828. CLASSINFO classInfo;
  829. BOOL bMayBeIIS4 = FALSE;
  830. LPWSTR pszUserName = NULL;
  831. LPWSTR pszPassword = NULL;
  832. hr = Credentials.GetUserName(&pszUserName);
  833. if (FAILED(hr))
  834. {
  835. if (buf)
  836. {
  837. delete [] buf;
  838. }
  839. return hr;
  840. }
  841. hr = Credentials.GetPassword(&pszPassword);
  842. if (FAILED(hr))
  843. {
  844. if (buf)
  845. {
  846. delete [] buf;
  847. }
  848. return hr;
  849. }
  850. CComAuthInfo localAuthInfo(baseName,
  851. pszUserName,
  852. pszPassword);
  853. memset(pcsiParam, 0, sizeof(COSERVERINFO));
  854. pcsiParam = localAuthInfo.CreateServerInfoStruct();
  855. hr = CoGetClassObject(
  856. CLSID_MSAdminBase,
  857. CLSCTX_SERVER,
  858. pcsiParam,
  859. IID_IClassFactory,
  860. (void**) &pcsfFactory
  861. );
  862. BAIL_ON_FAILURE(hr);
  863. hr = localAuthInfo.ApplyProxyBlanket(pcsfFactory);
  864. BAIL_ON_FAILURE(hr);
  865. hr = pcsfFactory->CreateInstance(
  866. NULL,
  867. IID_IMSAdminBase,
  868. (void **) &pAdminBase
  869. );
  870. BAIL_ON_FAILURE(hr);
  871. hr = localAuthInfo.ApplyProxyBlanket(pAdminBase);
  872. BAIL_ON_FAILURE(hr);
  873. METADATA_HANDLE MDataHandle;
  874. hr = pAdminBase->OpenKey(METADATA_MASTER_ROOT_HANDLE,
  875. L"/Schema/Properties/Defaults", // Present Only in IIS5
  876. METADATA_PERMISSION_READ,
  877. 20,
  878. &MDataHandle);
  879. if (HRESULTTOWIN32(hr) == ERROR_PATH_NOT_FOUND)
  880. {
  881. bMayBeIIS4 = TRUE;
  882. }
  883. if (HRESULTTOWIN32(hr) == ERROR_SUCCESS)
  884. {
  885. pAdminBase->CloseKey(MDataHandle);
  886. }
  887. root.setpointer(pAdminBase);
  888. hr = pAdminBase->OpenKey(METADATA_MASTER_ROOT_HANDLE,
  889. L"/Schema/Properties",
  890. METADATA_PERMISSION_READ,
  891. DEFAULT_TIMEOUT_VALUE,
  892. root);
  893. BAIL_ON_FAILURE(hr);
  894. hr = LoadAllData(pAdminBase, root, L"Names", &buf, &bufSize, &count);
  895. BAIL_ON_FAILURE(hr);
  896. // Now, here we've gotten the list of properties/names.
  897. // Create IIsSchemaProperty objects for each. We then
  898. // Add the object to the two maps. Later, we will load
  899. // all of the "Properties/Values" properties, look up (by
  900. // id) the object, and initialize the property value.
  901. pmd = (METADATA_GETALL_RECORD *)buf;
  902. for ( i=0;i < count; i++, pmd++)
  903. {
  904. if (pmd->dwMDDataType != STRING_METADATA)
  905. {
  906. continue;
  907. }
  908. LPWSTR name = (WCHAR *)(buf + pmd->dwMDDataOffset);
  909. IISSchemaProperty *pProp = new IISSchemaProperty(
  910. pmd->dwMDIdentifier,
  911. name,
  912. pmd->dwMDDataLen);
  913. idToProp.Add(pmd->dwMDIdentifier, pProp);
  914. nameToProp.Add(pProp->getName(), pProp);
  915. }
  916. if (!bMayBeIIS4)
  917. {
  918. hr = LoadAllData(pAdminBase, root, L"Types", &buf, &bufSize, &count);
  919. BAIL_ON_FAILURE(hr);
  920. // Now, here we've gotten the list of properties/values.
  921. // We then need to look up the properties by id (since that's
  922. // what we have) and initialize the property type information.
  923. for (i=0;i < count; i++)
  924. {
  925. pmd = ((METADATA_GETALL_RECORD*)buf) + i;
  926. IISSchemaProperty *pProp = (IISSchemaProperty *)(idToProp[pmd->dwMDIdentifier]);
  927. if (pProp == NULL)
  928. {
  929. continue;
  930. }
  931. pProp->InitFromMetaData(pmd, buf);
  932. }
  933. }
  934. else
  935. { // IIS4 Code
  936. // since the binary data stored in metabase changed, read from the resources
  937. for (i=0;i < g_cIISProperties; i++)
  938. {
  939. PROPERTYINFO * pPrpInfo = &g_aIISProperties[i];
  940. IISSchemaProperty *pProp = (IISSchemaProperty *)(idToProp[pPrpInfo->dwPropID]);
  941. if (pProp == NULL) {
  942. continue;
  943. }
  944. memcpy(pProp->GetpropInfo(),pPrpInfo,sizeof(PROPERTYINFO));
  945. }
  946. }
  947. if (!bMayBeIIS4)
  948. { // in IIS4 the defaults has been already loaded
  949. hr = LoadAllData(pAdminBase, root, L"Defaults", &buf, &bufSize, &count);
  950. BAIL_ON_FAILURE(hr);
  951. // Now, here we've gotten the list of properties/defaults.
  952. // We then need to look up the properties by id (since that's
  953. // what we have) and initialize the property type information.
  954. for (i=0;i < count; i++)
  955. {
  956. pmd = ((METADATA_GETALL_RECORD*)buf) + i;
  957. IISSchemaProperty *pProp = (IISSchemaProperty *)(idToProp[pmd->dwMDIdentifier]);
  958. if (pProp == NULL)
  959. {
  960. continue;
  961. }
  962. pProp->InitPropertyDefaults(pmd, buf);
  963. }
  964. }
  965. root.close();
  966. // Next, we need to initialize the class map.
  967. WCHAR className[METADATA_MAX_NAME_LEN];
  968. hr = pAdminBase->OpenKey(METADATA_MASTER_ROOT_HANDLE,
  969. L"/Schema/Classes",
  970. METADATA_PERMISSION_READ,
  971. DEFAULT_TIMEOUT_VALUE,
  972. root);
  973. BAIL_ON_FAILURE(hr);
  974. for (i=0; TRUE ; i++)
  975. {
  976. hr = pAdminBase->EnumKeys(root, L"", (LPWSTR)className, i);
  977. if (!SUCCEEDED(hr))
  978. {
  979. hr = ERROR_SUCCESS;
  980. break;
  981. }
  982. IIsSchemaClass *psc = new IIsSchemaClass(className);
  983. if (bMayBeIIS4)
  984. {
  985. DWORD i; // the scope saves us and this variable name
  986. for (i=0;i<g_cIISClasses;i++)
  987. {
  988. if (!_wcsicmp(className, g_aIISClasses[i].bstrName))
  989. {
  990. if (g_aIISClasses[i].bstrContainment)
  991. {
  992. pContainment = (LPWSTR)AllocADsMem((lstrlenW(g_aIISClasses[i].bstrContainment)+1)*sizeof(WCHAR));
  993. lstrcpyW(pContainment,g_aIISClasses[i].bstrContainment);
  994. }
  995. else
  996. {
  997. pContainment=NULL;
  998. }
  999. if (g_aIISClasses[i].bstrOptionalProperties)
  1000. {
  1001. pOptProp = (LPWSTR)AllocADsMem((lstrlenW(g_aIISClasses[i].bstrOptionalProperties)+1)*sizeof(WCHAR));
  1002. lstrcpyW(pOptProp,g_aIISClasses[i].bstrOptionalProperties);
  1003. }
  1004. else
  1005. {
  1006. pOptProp = NULL;
  1007. }
  1008. if (g_aIISClasses[i].bstrMandatoryProperties)
  1009. {
  1010. pMandProp = (LPWSTR)AllocADsMem((lstrlenW(g_aIISClasses[i].bstrMandatoryProperties)+1)*sizeof(WCHAR));
  1011. lstrcpyW(pMandProp,g_aIISClasses[i].bstrMandatoryProperties);
  1012. }
  1013. else
  1014. {
  1015. pMandProp = NULL;
  1016. }
  1017. dwData = g_aIISClasses[i].fContainer?TRUE:FALSE;
  1018. break;
  1019. }
  1020. }
  1021. }
  1022. else
  1023. {
  1024. //
  1025. // Load the Containment, Mandatory, Optional, and Container properties.
  1026. //
  1027. hr = MetaBaseGetStringData(pAdminBase,
  1028. root,
  1029. className,
  1030. MD_SCHEMA_CLASS_CONTAINMENT,
  1031. (LPBYTE*)&pContainment
  1032. );
  1033. BAIL_ON_FAILURE(hr);
  1034. hr = MetaBaseGetStringData(pAdminBase,
  1035. root,
  1036. className,
  1037. MD_SCHEMA_CLASS_OPT_PROPERTIES,
  1038. (LPBYTE*)&pOptProp
  1039. );
  1040. BAIL_ON_FAILURE(hr);
  1041. hr = MetaBaseGetStringData(pAdminBase,
  1042. root,
  1043. className,
  1044. MD_SCHEMA_CLASS_MAND_PROPERTIES,
  1045. (LPBYTE*)&pMandProp
  1046. );
  1047. BAIL_ON_FAILURE(hr);
  1048. hr = MetaBaseGetDwordData(pAdminBase,
  1049. root,
  1050. className,
  1051. MD_SCHEMA_CLASS_CONTAINER,
  1052. &dwData
  1053. );
  1054. BAIL_ON_FAILURE(hr);
  1055. }
  1056. classInfo.bstrContainment = pContainment;
  1057. classInfo.bstrOptionalProperties = pOptProp;
  1058. classInfo.bstrMandatoryProperties = pMandProp;
  1059. classInfo.fContainer = dwData ? TRUE : FALSE;
  1060. psc->SetclassInfo(&classInfo);
  1061. nameToClass.Add(psc->getName(), psc);
  1062. if (pContainment)
  1063. {
  1064. FreeADsMem(pContainment);
  1065. }
  1066. if (pOptProp)
  1067. {
  1068. FreeADsMem(pOptProp);
  1069. }
  1070. if (pMandProp)
  1071. {
  1072. FreeADsMem(pMandProp);
  1073. }
  1074. }
  1075. localAuthInfo.FreeServerInfoStruct(pcsiParam);
  1076. error:
  1077. if (pAdminBase)
  1078. {
  1079. pAdminBase->Release();
  1080. }
  1081. if (buf)
  1082. {
  1083. delete [] buf;
  1084. }
  1085. if (pcsfFactory)
  1086. {
  1087. pcsfFactory->Release();
  1088. }
  1089. RRETURN(hr);
  1090. }
  1091. HRESULT IIsSchema::GetTotalEntries(PDWORD pdwEntries) {
  1092. *pdwEntries = nameToClass.GetEntries() + nameToProp.GetEntries();
  1093. RRETURN(S_OK);
  1094. }
  1095. DWORD IIsSchema::GetClassEntries() {
  1096. return nameToClass.GetEntries();
  1097. }
  1098. DWORD IIsSchema::GetPropEntries() {
  1099. return nameToProp.GetEntries();
  1100. }
  1101. LPWSTR IIsSchema::GetClassName(DWORD dwIndex) {
  1102. return nameToClass.GetEntryName(dwIndex);
  1103. }
  1104. LPWSTR IIsSchema::GetPropName(DWORD dwIndex) {
  1105. return nameToProp.GetEntryName(dwIndex);
  1106. }
  1107. HRESULT IIsSchema::RemoveEntry(BOOL bClass, LPWSTR pszName) {
  1108. DWORD i;
  1109. DWORD id = 0;
  1110. LPWSTR pszPropName;
  1111. LPWSTR pszClassName;
  1112. IISSchemaProperty *prop;
  1113. if (bClass)
  1114. {
  1115. // clear nameToClass entry using pszName
  1116. for ( i = 0; i < nameToClass.GetEntries(); i++ )
  1117. {
  1118. pszClassName = nameToClass.GetEntryName(i);
  1119. if (pszClassName != NULL && _wcsicmp( pszClassName, pszName) == 0 ) {
  1120. nameToClass.ClearEntry(i);
  1121. }
  1122. }
  1123. }
  1124. else
  1125. {
  1126. // clear nameToProp entry using pszName
  1127. for ( i = 0; i < nameToProp.GetEntries(); i++ )
  1128. {
  1129. pszPropName = nameToProp.GetEntryName(i);
  1130. if (pszPropName != NULL && _wcsicmp( pszPropName, pszName) == 0 ) {
  1131. prop = (IISSchemaProperty *)nameToProp[pszPropName];
  1132. if (!prop)
  1133. RRETURN(E_ADS_PROPERTY_NOT_SUPPORTED);
  1134. id = prop->getPropID();
  1135. nameToProp.ClearEntry(i);
  1136. }
  1137. }
  1138. // clear idToProp entry using id
  1139. if (id != 0)
  1140. {
  1141. idToProp.ClearEntry(id);
  1142. }
  1143. }
  1144. RRETURN(S_OK);
  1145. }
  1146. PCLASSINFO IIsSchema::GetClassInfo(LPWSTR pszName) {
  1147. DWORD i;
  1148. LPWSTR pszClassName;
  1149. IIsSchemaClass *sc;
  1150. for ( i = 0; i < nameToClass.GetEntries(); i++ )
  1151. {
  1152. pszClassName = nameToClass.GetEntryName(i);
  1153. if (pszClassName != NULL && _wcsicmp( pszClassName, pszName) == 0 ) {
  1154. sc = (IIsSchemaClass *)nameToClass[pszClassName];
  1155. return sc != NULL ? sc->GetclassInfo() : NULL;
  1156. }
  1157. }
  1158. return NULL;
  1159. }
  1160. PPROPERTYINFO IIsSchema::GetPropertyInfo(LPWSTR pszName) {
  1161. DWORD i;
  1162. LPWSTR pszPropName;
  1163. IISSchemaProperty *prop;
  1164. for ( i = 0; i < nameToProp.GetEntries(); i++ )
  1165. {
  1166. pszPropName = nameToProp.GetEntryName(i);
  1167. if (pszPropName != NULL && _wcsicmp( pszPropName, pszName) == 0 ) {
  1168. prop = (IISSchemaProperty *)nameToProp[pszPropName];
  1169. return prop->GetpropInfo();
  1170. }
  1171. }
  1172. return NULL;
  1173. }
  1174. HRESULT IIsSchema::SetClassInfo(LPWSTR pszName, PCLASSINFO pClassInfo) {
  1175. DWORD i;
  1176. LPWSTR pszClassName;
  1177. IIsSchemaClass *sc;
  1178. for ( i = 0; i < nameToClass.GetEntries(); i++ )
  1179. {
  1180. pszClassName = nameToClass.GetEntryName(i);
  1181. if (pszClassName != NULL && _wcsicmp( pszClassName, pszName) == 0 ) {
  1182. sc = (IIsSchemaClass *)nameToClass[pszClassName];
  1183. return sc != NULL ? sc->SetclassInfo(pClassInfo) : E_FAIL;
  1184. }
  1185. }
  1186. //
  1187. // add to schema cache if doesn't exist
  1188. //
  1189. sc = new IIsSchemaClass(pszName);
  1190. sc->SetclassInfo(pClassInfo);
  1191. nameToClass.Add(sc->getName(), sc);
  1192. RRETURN(S_OK);
  1193. }
  1194. HRESULT IIsSchema::SetPropertyInfo(LPWSTR pszName, PPROPERTYINFO pPropInfo) {
  1195. DWORD i;
  1196. LPWSTR pszPropName;
  1197. IISSchemaProperty *prop;
  1198. for ( i = 0; i < nameToProp.GetEntries(); i++ )
  1199. {
  1200. pszPropName = nameToProp.GetEntryName(i);
  1201. if ( _wcsicmp( pszPropName, pszName) == 0 ) {
  1202. prop = (IISSchemaProperty *)nameToProp[pszPropName];
  1203. return prop != NULL ? prop->SetpropInfo(pPropInfo) : E_FAIL;
  1204. }
  1205. }
  1206. //
  1207. // add to schema cache if doesn't exist
  1208. //
  1209. prop = new IISSchemaProperty(pPropInfo->dwPropID,
  1210. pszName,
  1211. (DWORD)wcslen(pszName)+1);
  1212. if (prop != NULL)
  1213. prop->SetpropInfo(pPropInfo);
  1214. else
  1215. return E_FAIL;
  1216. idToProp.Add(pPropInfo->dwPropID, prop);
  1217. nameToProp.Add(prop->getName(), prop);
  1218. RRETURN(S_OK);
  1219. }
  1220. IIsSchema::IIsSchema() {}
  1221. void InitPropValue(PropValue *pv, PROPERTYINFO *pi) {
  1222. pv->dwSynID = pi->dwSyntaxId;
  1223. pv->dwMetaID = pi->dwMetaID;
  1224. pv->dwPropID = pi->dwPropID;
  1225. pv->dwMaxRange = (DWORD)pi->lMaxRange;
  1226. pv->dwMinRange = (DWORD)pi->lMinRange;
  1227. switch(pi->dwSyntaxId) {
  1228. case IIS_SYNTAX_ID_DWORD:
  1229. case IIS_SYNTAX_ID_BOOL:
  1230. case IIS_SYNTAX_ID_BOOL_BITMASK:
  1231. pv->dwMetaType = DWORD_METADATA;
  1232. break;
  1233. case IIS_SYNTAX_ID_STRING:
  1234. pv->dwMetaType = STRING_METADATA;
  1235. break;
  1236. case IIS_SYNTAX_ID_EXPANDSZ:
  1237. pv->dwMetaType = EXPANDSZ_METADATA;
  1238. break;
  1239. case IIS_SYNTAX_ID_MIMEMAP:
  1240. case IIS_SYNTAX_ID_MULTISZ:
  1241. pv->dwMetaType = MULTISZ_METADATA;
  1242. break;
  1243. case IIS_SYNTAX_ID_NTACL:
  1244. case IIS_SYNTAX_ID_BINARY:
  1245. case IIS_SYNTAX_ID_IPSECLIST:
  1246. pv->dwMetaType = BINARY_METADATA;
  1247. break;
  1248. }
  1249. pv->dwFlags = pi->dwFlags;
  1250. pv->fMultiValued = pi->fMultiValued;
  1251. pv->dwMask = pi->dwMask;
  1252. pv->dwMetaFlags = pi->dwMetaFlags;
  1253. pv->dwUserGroup = pi->dwUserGroup;
  1254. }