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

1027 lines
31 KiB

  1. #include <stdio.h>
  2. #define INITGUID // must be before iadmw.h
  3. #include <iadmw.h> // Interface header
  4. #include <iiscnfg.h> // MD_ & IIS_MD_ defines
  5. #define REASONABLE_TIMEOUT 1000
  6. void ShowHelp(void);
  7. LPSTR StripWhitespace(LPSTR pszString);
  8. BOOL OpenMetabaseAndDoStuff(WCHAR * wszVDir, WCHAR * wszDir, int iTrans);
  9. BOOL GetVdirPhysicalPath(IMSAdminBase *pIMSAdminBase,WCHAR * wszVDir,WCHAR *wszStringPathToFill);
  10. BOOL AddVirtualDir(IMSAdminBase *pIMSAdminBase, WCHAR * wszVDir, WCHAR * wszDir);
  11. BOOL RemoveVirtualDir(IMSAdminBase *pIMSAdminBase, WCHAR * wszVDir);
  12. HRESULT LoadAllData(IMSAdminBase * pmb, METADATA_HANDLE hMetabase,WCHAR *subdir, BYTE **buf, DWORD *size,DWORD *count);
  13. HRESULT AddVirtualServer(UINT iServerNum, UINT iServerPort, WCHAR * wszDefaultVDirDir);
  14. HRESULT DelVirtualServer(UINT iServerNum);
  15. #define TRANS_ADD 0
  16. #define TRANS_DEL 1
  17. #define TRANS_PRINT_PATH 2
  18. #define TRANS_ADD_VIRTUAL_SERVER 4
  19. #define TRANS_DEL_VIRTUAL_SERVER 8
  20. int __cdecl
  21. main(
  22. int argc,
  23. char *argv[]
  24. )
  25. {
  26. BOOL fRet = FALSE;
  27. int argno;
  28. char * pArg = NULL;
  29. char * pCmdStart = NULL;
  30. WCHAR wszPrintString[MAX_PATH];
  31. char szTempString[MAX_PATH];
  32. int iGotParamS = FALSE;
  33. int iGotParamP = FALSE;
  34. int iGotParamV = FALSE;
  35. int iDoDelete = FALSE;
  36. int iDoWebPath = FALSE;
  37. int iTrans = 0;
  38. WCHAR wszDirPath[MAX_PATH];
  39. WCHAR wszVDirName[MAX_PATH];
  40. WCHAR wszTempString_S[MAX_PATH];
  41. WCHAR wszTempString_P[MAX_PATH];
  42. wszDirPath[0] = '\0';
  43. wszVDirName[0] = '\0';
  44. wszTempString_S[0] = '\0';
  45. wszTempString_P[0] = '\0';
  46. for(argno=1; argno<argc; argno++) {
  47. if ( argv[argno][0] == '-' || argv[argno][0] == '/' ) {
  48. switch (argv[argno][1]) {
  49. case 'd':
  50. case 'D':
  51. iDoDelete = TRUE;
  52. break;
  53. case 'o':
  54. case 'O':
  55. iDoWebPath = TRUE;
  56. break;
  57. case 's':
  58. case 'S':
  59. // Get the string for this flag
  60. pArg = CharNextA(argv[argno]);
  61. pArg = CharNextA(pArg);
  62. if (*pArg == ':') {
  63. pArg = CharNextA(pArg);
  64. // Check if it's quoted
  65. if (*pArg == '\"') {
  66. pArg = CharNextA(pArg);
  67. pCmdStart = pArg;
  68. while ((*pArg) && (*pArg != '\"')){pArg = CharNextA(pArg);}
  69. } else {
  70. pCmdStart = pArg;
  71. while (*pArg){pArg = CharNextA(pArg);}
  72. }
  73. *pArg = '\0';
  74. lstrcpyA(szTempString, StripWhitespace(pCmdStart));
  75. // Convert to unicode
  76. MultiByteToWideChar(CP_ACP, 0, (LPCSTR)szTempString, -1, (LPWSTR) wszTempString_S, 50);
  77. iGotParamS = TRUE;
  78. }
  79. break;
  80. case 'p':
  81. case 'P':
  82. // Get the string for this flag
  83. pArg = CharNextA(argv[argno]);
  84. pArg = CharNextA(pArg);
  85. if (*pArg == ':') {
  86. pArg = CharNextA(pArg);
  87. // Check if it's quoted
  88. if (*pArg == '\"') {
  89. pArg = CharNextA(pArg);
  90. pCmdStart = pArg;
  91. while ((*pArg) && (*pArg != '\"')){pArg = CharNextA(pArg);}
  92. } else {
  93. pCmdStart = pArg;
  94. while (*pArg){pArg = CharNextA(pArg);}
  95. }
  96. *pArg = '\0';
  97. lstrcpyA(szTempString, StripWhitespace(pCmdStart));
  98. // Convert to unicode
  99. MultiByteToWideChar(CP_ACP, 0, (LPCSTR)szTempString, -1, (LPWSTR) wszTempString_P, 50);
  100. iGotParamP = TRUE;
  101. }
  102. break;
  103. case 'v':
  104. case 'V':
  105. // Get the string for this flag
  106. pArg = CharNextA(argv[argno]);
  107. pArg = CharNextA(pArg);
  108. if (*pArg == ':') {
  109. pArg = CharNextA(pArg);
  110. // Check if it's quoted
  111. if (*pArg == '\"') {
  112. pArg = CharNextA(pArg);
  113. pCmdStart = pArg;
  114. while ((*pArg) && (*pArg != '\"')){pArg = CharNextA(pArg);}
  115. } else {
  116. pCmdStart = pArg;
  117. while (*pArg){pArg = CharNextA(pArg);}
  118. }
  119. *pArg = '\0';
  120. lstrcpyA(szTempString, StripWhitespace(pCmdStart));
  121. // Convert to unicode
  122. MultiByteToWideChar(CP_ACP, 0, (LPCSTR)szTempString, -1, (LPWSTR) wszVDirName, 50);
  123. iGotParamV = TRUE;
  124. }
  125. break;
  126. case '?':
  127. goto main_exit_with_help;
  128. break;
  129. }
  130. } else {
  131. if ( *wszDirPath == '\0' ) {
  132. // if no arguments, then get the filename portion
  133. MultiByteToWideChar(CP_ACP, 0, argv[argno], -1, (LPWSTR) wszDirPath, 50);
  134. }
  135. }
  136. }
  137. iTrans = TRANS_ADD_VIRTUAL_SERVER;
  138. if (TRUE == iGotParamS)
  139. {
  140. HRESULT hr;
  141. UINT iServerNum = 100;
  142. if (iDoDelete)
  143. {
  144. iTrans = TRANS_DEL_VIRTUAL_SERVER;
  145. if (*wszTempString_S == '\0')
  146. {
  147. // sorry, we need something in here
  148. goto main_exit_with_help;
  149. }
  150. iServerNum = _wtoi(wszTempString_S);
  151. hr = DelVirtualServer(iServerNum);
  152. if (FAILED(hr))
  153. {
  154. wsprintf(wszPrintString,L"FAILED to remove virtual server: W3SVC/%d\n", iServerNum);
  155. wprintf(wszPrintString);
  156. fRet = TRUE;
  157. }
  158. else
  159. {
  160. wsprintf(wszPrintString,L"SUCCESS:removed virtual server: W3SVC/%d\n", iServerNum);
  161. wprintf(wszPrintString);
  162. fRet = FALSE;
  163. }
  164. goto main_exit_gracefully;
  165. }
  166. else
  167. {
  168. if (TRUE == iGotParamP)
  169. {
  170. UINT iServerPort = 81;
  171. // we need the filename too
  172. if (*wszDirPath == '\0')
  173. {
  174. // sorry, we need all 3 parameters
  175. goto main_exit_with_help;
  176. }
  177. if (*wszTempString_S == '\0')
  178. {
  179. // sorry, we need all 3 parameters
  180. goto main_exit_with_help;
  181. }
  182. if (*wszTempString_P == '\0')
  183. {
  184. // sorry, we need all 3 parameters
  185. goto main_exit_with_help;
  186. }
  187. iServerNum = _wtoi(wszTempString_S);
  188. iServerPort = _wtoi(wszTempString_P);
  189. hr = AddVirtualServer(iServerNum, iServerPort, wszDirPath);
  190. if (FAILED(hr))
  191. {
  192. wsprintf(wszPrintString,L"FAILED to create virtual server: W3SVC/%d=%s, port=%d. err=0x%x\n", iServerNum, wszDirPath, iServerPort,hr);
  193. wprintf(wszPrintString);
  194. fRet = TRUE;
  195. }
  196. else
  197. {
  198. wsprintf(wszPrintString,L"SUCCESS:created virtual server: W3SVC/%d=%s, port=%d\n", iServerNum, wszDirPath, iServerPort);
  199. wprintf(wszPrintString);
  200. fRet = FALSE;
  201. }
  202. goto main_exit_gracefully;
  203. }
  204. }
  205. }
  206. iTrans = TRANS_ADD;
  207. if (iDoWebPath){
  208. iTrans = TRANS_PRINT_PATH;
  209. }
  210. else {
  211. if (iDoDelete) {
  212. iTrans = TRANS_DEL;
  213. if (FALSE == iGotParamV) {
  214. // sorry, we need at parameter -v
  215. goto main_exit_with_help;
  216. }
  217. } else if (FALSE == iGotParamV || *wszDirPath == '\0') {
  218. // sorry, we need both parameters
  219. goto main_exit_with_help;
  220. }
  221. }
  222. fRet = OpenMetabaseAndDoStuff(wszVDirName, wszDirPath, iTrans);
  223. main_exit_gracefully:
  224. exit(fRet);
  225. main_exit_with_help:
  226. ShowHelp();
  227. exit(fRet);
  228. }
  229. LPSTR StripWhitespace( LPSTR pszString )
  230. {
  231. LPSTR pszTemp = NULL;
  232. if ( pszString == NULL ) {
  233. return NULL;
  234. }
  235. while ( *pszString == ' ' || *pszString == '\t' ) {
  236. pszString += 1;
  237. }
  238. // Catch case where string consists entirely of whitespace or empty string.
  239. if ( *pszString == '\0' ) {
  240. return pszString;
  241. }
  242. pszTemp = pszString;
  243. pszString += lstrlenA(pszString) - 1;
  244. while ( *pszString == ' ' || *pszString == '\t' ) {
  245. *pszString = '\0';
  246. pszString -= 1;
  247. }
  248. return pszTemp;
  249. }
  250. void
  251. ShowHelp()
  252. {
  253. wprintf(L"Creates/Removes an IIS5 virtual directory to default web site\n\n");
  254. wprintf(L"IISVDIR [FullPath] [-v:VDirName] [-d] [-o]\n\n");
  255. wprintf(L"Instructions for add\\delete virtual directory:\n");
  256. wprintf(L" FullPath DOS path where vdir will point to (required for add)\n");
  257. wprintf(L" -v:vdirname The virtual dir name (required for both add\\delete)\n");
  258. wprintf(L" -d If set will delete vdir. if not set will add\n");
  259. wprintf(L" -o If set will printout web root path\n\n");
  260. wprintf(L"Instructions for add\\delete virtual server:\n");
  261. wprintf(L" FullPath DOS path where default vdir will point to in the virtual server (required for add)\n");
  262. wprintf(L" -s:sitenum For adding virtual server: The virtual server site number (required for both add\\delete)\n");
  263. wprintf(L" -p:portnum For adding virtual server: The virtual server port number (required for add)\n");
  264. wprintf(L" -d If set will delete virtual server. if not set will add\n");
  265. wprintf(L"\n");
  266. wprintf(L"Add Example: IISVDIR c:\\MyGroup\\MyStuff -v:Stuff\n");
  267. wprintf(L"Del Example: IISVDIR -v:Stuff -d\n");
  268. wprintf(L"Get Example: IISVDIR -o\n");
  269. wprintf(L"Add Virtual Server Example: IISVDIR c:\\MyGroup\\MyStuff -s:200 -p:81\n");
  270. wprintf(L"Del Virtual Server Example: IISVDIR -s:200 -d\n");
  271. return;
  272. }
  273. BOOL
  274. OpenMetabaseAndDoStuff(
  275. WCHAR * wszVDir,
  276. WCHAR * wszDir,
  277. int iTrans
  278. )
  279. {
  280. BOOL fRet = FALSE;
  281. HRESULT hr;
  282. IMSAdminBase *pIMSAdminBase = NULL; // Metabase interface pointer
  283. WCHAR wszPrintString[MAX_PATH + MAX_PATH];
  284. if( FAILED (CoInitializeEx( NULL, COINIT_MULTITHREADED )) ||
  285. FAILED (::CoCreateInstance(CLSID_MSAdminBase,
  286. NULL,
  287. CLSCTX_ALL,
  288. IID_IMSAdminBase,
  289. (void **)&pIMSAdminBase))) {
  290. return FALSE;
  291. }
  292. switch (iTrans) {
  293. case TRANS_DEL:
  294. if( RemoveVirtualDir( pIMSAdminBase, wszVDir)) {
  295. hr = pIMSAdminBase->SaveData();
  296. if( SUCCEEDED( hr )) {
  297. fRet = TRUE;
  298. }
  299. }
  300. if (TRUE == fRet) {
  301. wsprintf(wszPrintString,L"SUCCESS:removed vdir=%s\n", wszVDir);
  302. wprintf(wszPrintString);
  303. } else {
  304. wsprintf(wszPrintString,L"FAILED to remove vdir=%s, err=0x%x\n", wszVDir, hr);
  305. wprintf(wszPrintString);
  306. }
  307. break;
  308. case TRANS_ADD:
  309. if( AddVirtualDir( pIMSAdminBase, wszVDir, wszDir)) {
  310. hr = pIMSAdminBase->SaveData();
  311. if( SUCCEEDED( hr )) {
  312. fRet = TRUE;
  313. }
  314. }
  315. if (TRUE == fRet) {
  316. wsprintf(wszPrintString,L"SUCCESS: %s=%s", wszVDir, wszDir);
  317. wprintf(wszPrintString);
  318. } else {
  319. wsprintf(wszPrintString,L"FAILED to set: %s=%s, err=0x%x", wszVDir, wszDir, hr);
  320. wprintf(wszPrintString);
  321. }
  322. break;
  323. default:
  324. WCHAR wszRootPath[MAX_PATH];
  325. if (TRUE == GetVdirPhysicalPath(pIMSAdminBase,wszVDir,(WCHAR *) wszRootPath))
  326. {
  327. fRet = TRUE;
  328. if (_wcsicmp(wszVDir, L"") == 0) {
  329. wsprintf(wszPrintString,L"/=%s", wszRootPath);
  330. } else {
  331. wsprintf(wszPrintString,L"%s=%s", wszVDir, wszRootPath);
  332. }
  333. wprintf(wszPrintString);
  334. }
  335. else
  336. {
  337. wprintf(L"FAILED to get root path");
  338. }
  339. break;
  340. }
  341. if (pIMSAdminBase) {
  342. pIMSAdminBase->Release();
  343. pIMSAdminBase = NULL;
  344. }
  345. CoUninitialize();
  346. return fRet;
  347. }
  348. BOOL
  349. GetVdirPhysicalPath(
  350. IMSAdminBase *pIMSAdminBase,
  351. WCHAR * wszVDir,
  352. WCHAR *wszStringPathToFill
  353. )
  354. {
  355. HRESULT hr;
  356. BOOL fRet = FALSE;
  357. METADATA_HANDLE hMetabase = NULL; // handle to metabase
  358. METADATA_RECORD mr;
  359. WCHAR szTmpData[MAX_PATH];
  360. DWORD dwMDRequiredDataLen;
  361. // open key to ROOT on website #1 (default)
  362. hr = pIMSAdminBase->OpenKey(METADATA_MASTER_ROOT_HANDLE,
  363. L"/LM/W3SVC/1",
  364. METADATA_PERMISSION_READ,
  365. REASONABLE_TIMEOUT,
  366. &hMetabase);
  367. if( FAILED( hr )) {
  368. return FALSE;
  369. }
  370. // Get the physical path for the WWWROOT
  371. mr.dwMDIdentifier = MD_VR_PATH;
  372. mr.dwMDAttributes = 0;
  373. mr.dwMDUserType = IIS_MD_UT_FILE;
  374. mr.dwMDDataType = STRING_METADATA;
  375. mr.dwMDDataLen = sizeof( szTmpData );
  376. mr.pbMDData = reinterpret_cast<unsigned char *>(szTmpData);
  377. // if nothing specified get the root.
  378. if (_wcsicmp(wszVDir, L"") == 0) {
  379. WCHAR wszTempDir[MAX_PATH];
  380. wsprintf(wszTempDir,L"/ROOT/%s", wszVDir);
  381. hr = pIMSAdminBase->GetData( hMetabase, wszTempDir, &mr, &dwMDRequiredDataLen );
  382. } else {
  383. hr = pIMSAdminBase->GetData( hMetabase, L"/ROOT", &mr, &dwMDRequiredDataLen );
  384. }
  385. pIMSAdminBase->CloseKey( hMetabase );
  386. if( SUCCEEDED( hr )) {
  387. wcscpy(wszStringPathToFill,szTmpData);
  388. fRet = TRUE;
  389. }
  390. pIMSAdminBase->CloseKey( hMetabase );
  391. return fRet;
  392. }
  393. BOOL
  394. AddVirtualDir(
  395. IMSAdminBase *pIMSAdminBase,
  396. WCHAR * wszVDir,
  397. WCHAR * wszDir
  398. )
  399. {
  400. HRESULT hr;
  401. BOOL fRet = FALSE;
  402. METADATA_HANDLE hMetabase = NULL; // handle to metabase
  403. WCHAR wszTempPath[MAX_PATH];
  404. DWORD dwMDRequiredDataLen = 0;
  405. DWORD dwAccessPerm = 0;
  406. METADATA_RECORD mr;
  407. // Attempt to open the virtual dir set on Web server #1 (default server)
  408. hr = pIMSAdminBase->OpenKey( METADATA_MASTER_ROOT_HANDLE,
  409. L"/LM/W3SVC/1/ROOT",
  410. METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE,
  411. REASONABLE_TIMEOUT,
  412. &hMetabase );
  413. // Create the key if it does not exist.
  414. if( FAILED( hr )) {
  415. return FALSE;
  416. }
  417. fRet = TRUE;
  418. mr.dwMDIdentifier = MD_VR_PATH;
  419. mr.dwMDAttributes = 0;
  420. mr.dwMDUserType = IIS_MD_UT_FILE;
  421. mr.dwMDDataType = STRING_METADATA;
  422. mr.dwMDDataLen = sizeof( wszTempPath );
  423. mr.pbMDData = reinterpret_cast<unsigned char *>(wszTempPath);
  424. // see if MD_VR_PATH exists.
  425. hr = pIMSAdminBase->GetData( hMetabase, wszVDir, &mr, &dwMDRequiredDataLen );
  426. if( FAILED( hr )) {
  427. fRet = FALSE;
  428. if( hr == MD_ERROR_DATA_NOT_FOUND ||
  429. HRESULT_CODE(hr) == ERROR_PATH_NOT_FOUND ) {
  430. // Write both the key and the values if GetData() failed with any of the two errors.
  431. pIMSAdminBase->AddKey( hMetabase, wszVDir );
  432. mr.dwMDIdentifier = MD_VR_PATH;
  433. mr.dwMDAttributes = METADATA_INHERIT;
  434. mr.dwMDUserType = IIS_MD_UT_FILE;
  435. mr.dwMDDataType = STRING_METADATA;
  436. mr.dwMDDataLen = (wcslen(wszDir) + 1) * sizeof(WCHAR);
  437. mr.pbMDData = reinterpret_cast<unsigned char *>(wszDir);
  438. // Write MD_VR_PATH value
  439. hr = pIMSAdminBase->SetData( hMetabase, wszVDir, &mr );
  440. fRet = SUCCEEDED( hr );
  441. // Set the default authentication method
  442. if( fRet ) {
  443. DWORD dwAuthorization = MD_AUTH_NT; // NTLM only.
  444. mr.dwMDIdentifier = MD_AUTHORIZATION;
  445. mr.dwMDAttributes = METADATA_INHERIT; // need to inherit so that all subdirs are also protected.
  446. mr.dwMDUserType = IIS_MD_UT_FILE;
  447. mr.dwMDDataType = DWORD_METADATA;
  448. mr.dwMDDataLen = sizeof(DWORD);
  449. mr.pbMDData = reinterpret_cast<unsigned char *>(&dwAuthorization);
  450. // Write MD_AUTHORIZATION value
  451. hr = pIMSAdminBase->SetData( hMetabase, wszVDir, &mr );
  452. fRet = SUCCEEDED( hr );
  453. }
  454. }
  455. }
  456. // In the following, do the stuff that we always want to do to the virtual dir, regardless of Admin's setting.
  457. if( fRet ) {
  458. dwAccessPerm = MD_ACCESS_READ | MD_ACCESS_SCRIPT;
  459. mr.dwMDIdentifier = MD_ACCESS_PERM;
  460. mr.dwMDAttributes = METADATA_INHERIT; // Make it inheritable so all subdirectories will have the same rights.
  461. mr.dwMDUserType = IIS_MD_UT_FILE;
  462. mr.dwMDDataType = DWORD_METADATA;
  463. mr.dwMDDataLen = sizeof(DWORD);
  464. mr.pbMDData = reinterpret_cast<unsigned char *>(&dwAccessPerm);
  465. // Write MD_ACCESS_PERM value
  466. hr = pIMSAdminBase->SetData( hMetabase, wszVDir, &mr );
  467. fRet = SUCCEEDED( hr );
  468. }
  469. if( fRet ) {
  470. PWCHAR szDefLoadFile = L"Default.htm,Default.asp";
  471. mr.dwMDIdentifier = MD_DEFAULT_LOAD_FILE;
  472. mr.dwMDAttributes = 0; // no need for inheritence
  473. mr.dwMDUserType = IIS_MD_UT_FILE;
  474. mr.dwMDDataType = STRING_METADATA;
  475. mr.dwMDDataLen = (wcslen(szDefLoadFile) + 1) * sizeof(WCHAR);
  476. mr.pbMDData = reinterpret_cast<unsigned char *>(szDefLoadFile);
  477. // Write MD_DEFAULT_LOAD_FILE value
  478. hr = pIMSAdminBase->SetData( hMetabase, wszVDir, &mr );
  479. fRet = SUCCEEDED( hr );
  480. }
  481. if( fRet ) {
  482. PWCHAR wszKeyType = IIS_CLASS_WEB_VDIR_W;
  483. mr.dwMDIdentifier = MD_KEY_TYPE;
  484. mr.dwMDAttributes = 0; // no need for inheritence
  485. mr.dwMDUserType = IIS_MD_UT_SERVER;
  486. mr.dwMDDataType = STRING_METADATA;
  487. mr.dwMDDataLen = (wcslen(wszKeyType) + 1) * sizeof(WCHAR);
  488. mr.pbMDData = reinterpret_cast<unsigned char *>(wszKeyType);
  489. // Write MD_DEFAULT_LOAD_FILE value
  490. hr = pIMSAdminBase->SetData( hMetabase, wszVDir, &mr );
  491. fRet = SUCCEEDED( hr );
  492. }
  493. pIMSAdminBase->CloseKey( hMetabase );
  494. return fRet;
  495. }
  496. BOOL
  497. RemoveVirtualDir(
  498. IMSAdminBase *pIMSAdminBase,
  499. WCHAR * wszVDir
  500. )
  501. {
  502. METADATA_HANDLE hMetabase = NULL; // handle to metabase
  503. HRESULT hr;
  504. // Attempt to open the virtual dir set on Web server #1 (default server)
  505. hr = pIMSAdminBase->OpenKey( METADATA_MASTER_ROOT_HANDLE,
  506. L"/LM/W3SVC/1/ROOT",
  507. METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE,
  508. REASONABLE_TIMEOUT,
  509. &hMetabase );
  510. if( FAILED( hr )) {
  511. return FALSE;
  512. }
  513. // We don't check the return value since the key may already
  514. // not exist and we could get an error for that reason.
  515. pIMSAdminBase->DeleteKey( hMetabase, wszVDir );
  516. pIMSAdminBase->CloseKey( hMetabase );
  517. return TRUE;
  518. }
  519. HRESULT LoadAllData(IMSAdminBase * pmb,
  520. METADATA_HANDLE hMetabase,
  521. WCHAR *subdir,
  522. BYTE **buf,
  523. DWORD *size,
  524. DWORD *count) {
  525. DWORD dataSet;
  526. DWORD neededSize;
  527. HRESULT hr;
  528. //
  529. // Try to get the property names.
  530. //
  531. hr = pmb->GetAllData(hMetabase,
  532. subdir,
  533. METADATA_NO_ATTRIBUTES,
  534. ALL_METADATA,
  535. ALL_METADATA,
  536. count,
  537. &dataSet,
  538. *size,
  539. *buf,
  540. &neededSize);
  541. if (!SUCCEEDED(hr)) {
  542. DWORD code = ERROR_INSUFFICIENT_BUFFER;
  543. if (hr == RETURNCODETOHRESULT(ERROR_INSUFFICIENT_BUFFER)) {
  544. delete *buf;
  545. *buf = 0;
  546. *size = neededSize;
  547. *buf = new BYTE[neededSize];
  548. hr = pmb->GetAllData(hMetabase,
  549. subdir,
  550. METADATA_NO_ATTRIBUTES,
  551. ALL_METADATA,
  552. ALL_METADATA,
  553. count,
  554. &dataSet,
  555. *size,
  556. *buf,
  557. &neededSize);
  558. }
  559. }
  560. return hr;
  561. }
  562. const DWORD getAllBufSize = 4096*2;
  563. HRESULT
  564. OpenMetabaseAndGetAllData(void)
  565. {
  566. HRESULT hr = E_FAIL;
  567. IMSAdminBase *pIMSAdminBase = NULL; // Metabase interface pointer
  568. WCHAR wszPrintString[MAX_PATH + MAX_PATH];
  569. METADATA_HANDLE hMetabase = NULL; // handle to metabase
  570. DWORD bufSize = getAllBufSize;
  571. BYTE *buf = new BYTE[bufSize];
  572. DWORD count=0;
  573. DWORD linesize =0;
  574. BYTE *pBuf1=NULL;
  575. BYTE *pBuf2=NULL;
  576. if( FAILED (CoInitializeEx( NULL, COINIT_MULTITHREADED )) ||
  577. FAILED (::CoCreateInstance(CLSID_MSAdminBase,
  578. NULL,
  579. CLSCTX_ALL,
  580. IID_IMSAdminBase,
  581. (void **)&pIMSAdminBase))) {
  582. wprintf(L"CoCreateInstance. FAILED. code=0x%x\n",hr);
  583. return hr;
  584. }
  585. // Attempt to open the virtual dir set on Web server #1 (default server)
  586. hr = pIMSAdminBase->OpenKey( METADATA_MASTER_ROOT_HANDLE,
  587. L"/Schema/Properties",
  588. METADATA_PERMISSION_READ,
  589. REASONABLE_TIMEOUT,
  590. &hMetabase );
  591. if( FAILED( hr )) {
  592. wprintf(L"pIMSAdminBase->OpenKey. FAILED. code=0x%x\n",hr);
  593. goto OpenMetabaseAndGetAllData_Exit;
  594. }
  595. hr = LoadAllData(pIMSAdminBase, hMetabase, L"Names", &buf, &bufSize, &count);
  596. if( FAILED( hr )) {
  597. wprintf(L"LoadAllData: FAILED. code=0x%x\n",hr);
  598. goto OpenMetabaseAndGetAllData_Exit;
  599. }
  600. wprintf(L"LoadAllData: Succeeded. bufSize=0x%x, count=0x%x, buf=%p, end of buf=%p\n",bufSize,count,buf,buf+bufSize);
  601. wprintf(L"Here is the last 1000 bytes, that the client received.\n");
  602. linesize = 0;
  603. pBuf1 = buf+bufSize - 1000;
  604. for (int i=0;pBuf1<buf+bufSize;pBuf1++,i++) {
  605. if (NULL == *pBuf1) {
  606. wprintf(L".");
  607. }
  608. else {
  609. wprintf(L"%c",*pBuf1);
  610. }
  611. linesize++;
  612. if (linesize >= 16) {
  613. linesize=0;
  614. wprintf(L"\n");
  615. }
  616. }
  617. wprintf(L"\n");
  618. hr = ERROR_SUCCESS;
  619. OpenMetabaseAndGetAllData_Exit:
  620. if (pIMSAdminBase) {
  621. pIMSAdminBase->Release();
  622. pIMSAdminBase = NULL;
  623. }
  624. CoUninitialize();
  625. return hr;
  626. }
  627. // Calculate the size of a Multi-String in WCHAR, including the ending 2 '\0's.
  628. int GetMultiStrSize(LPWSTR p)
  629. {
  630. int c = 0;
  631. while (1) {
  632. if (*p) {
  633. p++;
  634. c++;
  635. } else {
  636. c++;
  637. if (*(p+1)) {
  638. p++;
  639. } else {
  640. c++;
  641. break;
  642. }
  643. }
  644. }
  645. return c;
  646. }
  647. HRESULT DelVirtualServer(UINT iServerNum)
  648. {
  649. HRESULT hr = E_FAIL;
  650. return hr;
  651. }
  652. // iServerNum the virtual server number
  653. // iServerPort the virtual server port (port 80 is the default site's port,so you can't use this and you can't use one that is already in use)
  654. // wszDir the physical directory where the default site is located
  655. HRESULT AddVirtualServer(UINT iServerNum, UINT iServerPort, WCHAR * wszDefaultVDirDir)
  656. {
  657. HRESULT hr = E_FAIL;
  658. IMSAdminBase *pIMSAdminBase = NULL; // Metabase interface pointer
  659. METADATA_HANDLE hMetabase = NULL; // handle to metabase
  660. METADATA_RECORD mr;
  661. WCHAR wszMetabasePath[_MAX_PATH];
  662. WCHAR wszMetabasePathRoot[10];
  663. WCHAR wszData[_MAX_PATH];
  664. DWORD dwData = 0;
  665. METADATA_HANDLE hKeyBase = METADATA_MASTER_ROOT_HANDLE;
  666. if( FAILED (CoInitializeEx( NULL, COINIT_MULTITHREADED )) ||
  667. FAILED (::CoCreateInstance(CLSID_MSAdminBase,
  668. NULL,
  669. CLSCTX_ALL,
  670. IID_IMSAdminBase,
  671. (void **)&pIMSAdminBase))) {
  672. wprintf(L"CoCreateInstance. FAILED. code=0x%x\n",hr);
  673. return hr;
  674. }
  675. // Create the new node
  676. wsprintf(wszMetabasePath,L"LM/W3SVC/%i",iServerNum);
  677. // try to open the specified metabase node, it might already exist
  678. hr = pIMSAdminBase->OpenKey(hKeyBase,
  679. wszMetabasePath,
  680. METADATA_PERMISSION_READ,
  681. REASONABLE_TIMEOUT,
  682. &hMetabase);
  683. if (hr == RETURNCODETOHRESULT(ERROR_PATH_NOT_FOUND)) {
  684. hr = pIMSAdminBase->CloseKey(hMetabase);
  685. // open the metabase root handle
  686. hr = pIMSAdminBase->OpenKey(hKeyBase,
  687. L"",
  688. METADATA_PERMISSION_WRITE | METADATA_PERMISSION_READ,
  689. REASONABLE_TIMEOUT,&hMetabase);
  690. if( FAILED( hr )) {
  691. // if we can't even open the root handle, then we're pretty hosed
  692. wprintf(L"1OpenKey. FAILED. code=0x%x\n",hr);
  693. goto AddVirtualServer_Exit;
  694. }
  695. // and add our node
  696. hr = pIMSAdminBase->AddKey(hMetabase, wszMetabasePath);
  697. if (FAILED(hr)) {
  698. wprintf(L"AddKey. FAILED. code=0x%x\n",hr);
  699. pIMSAdminBase->CloseKey(hMetabase);
  700. goto AddVirtualServer_Exit;
  701. } else {
  702. hr = pIMSAdminBase->CloseKey(hMetabase);
  703. if (FAILED(hr)) {
  704. goto AddVirtualServer_Exit;
  705. } else {
  706. // open it again
  707. hr = pIMSAdminBase->OpenKey(hKeyBase,
  708. wszMetabasePath,
  709. METADATA_PERMISSION_WRITE | METADATA_PERMISSION_READ,
  710. REASONABLE_TIMEOUT,
  711. &hMetabase);
  712. if (FAILED(hr)) {
  713. wprintf(L"2OpenKey. FAILED. code=0x%x\n",hr);
  714. pIMSAdminBase->CloseKey(hMetabase);
  715. goto AddVirtualServer_Exit;
  716. }
  717. }
  718. }
  719. } else {
  720. if (FAILED(hr))
  721. {
  722. wprintf(L"3OpenKey. FAILED. code=0x%x\n",hr);
  723. goto AddVirtualServer_Exit;
  724. }
  725. else
  726. {
  727. // we were able to open the path, so it must already exist!
  728. hr = ERROR_ALREADY_EXISTS;
  729. pIMSAdminBase->CloseKey(hMetabase);
  730. goto AddVirtualServer_Exit;
  731. }
  732. }
  733. // We should have a brand new Key now...
  734. //
  735. // Create stuff in the node of this path!
  736. //
  737. //
  738. // /LM/W3SVC/1/KeyType
  739. //
  740. memset( (PVOID)wszData, 0, sizeof(wszData));
  741. wcscpy(wszData,IIS_CLASS_WEB_SERVER_W);
  742. mr.dwMDIdentifier = MD_KEY_TYPE;
  743. mr.dwMDAttributes = 0; // no need for inheritence
  744. mr.dwMDUserType = IIS_MD_UT_SERVER;
  745. mr.dwMDDataType = STRING_METADATA;
  746. mr.dwMDDataLen = (wcslen(wszData) + 1) * sizeof(WCHAR);
  747. mr.pbMDData = reinterpret_cast<unsigned char *>(wszData);
  748. hr = pIMSAdminBase->SetData( hMetabase, L"", &mr );
  749. if (FAILED(hr)) {
  750. wprintf(L"SetData[MD_KEY_TYPE]. FAILED. code=0x%x\n",hr);
  751. }
  752. //
  753. // /W3SVC/1/ServerBindings
  754. //
  755. memset( (PVOID)wszData, 0, sizeof(wszData));
  756. wsprintf(wszData, L":%d:", iServerPort);
  757. mr.dwMDIdentifier = MD_SERVER_BINDINGS;
  758. mr.dwMDAttributes = METADATA_INHERIT;
  759. mr.dwMDUserType = IIS_MD_UT_SERVER;
  760. mr.dwMDDataType = MULTISZ_METADATA;
  761. mr.dwMDDataLen = GetMultiStrSize(wszData) * sizeof(WCHAR);
  762. mr.pbMDData = reinterpret_cast<unsigned char *>(wszData);
  763. hr = pIMSAdminBase->SetData( hMetabase, L"", &mr );
  764. if (FAILED(hr)) {
  765. wprintf(L"SetData[MD_SERVER_BINDINGS]. FAILED. code=0x%x\n",hr);
  766. }
  767. //
  768. // /W3SVC/1/SecureBindings
  769. //
  770. memset( (PVOID)wszData, 0, sizeof(wszData));
  771. wcscpy(wszData, L" ");
  772. mr.dwMDIdentifier = MD_SECURE_BINDINGS;
  773. mr.dwMDAttributes = METADATA_INHERIT;
  774. mr.dwMDUserType = IIS_MD_UT_SERVER;
  775. mr.dwMDDataType = MULTISZ_METADATA;
  776. mr.dwMDDataLen = GetMultiStrSize(wszData) * sizeof(WCHAR);
  777. mr.pbMDData = reinterpret_cast<unsigned char *>(wszData);
  778. hr = pIMSAdminBase->SetData( hMetabase, L"", &mr );
  779. if (FAILED(hr)) {
  780. wprintf(L"SetData[MD_SECURE_BINDINGS]. FAILED. code=0x%x\n",hr);
  781. }
  782. //
  783. // Create stuff in the /Root node of this path!
  784. //
  785. wcscpy(wszMetabasePathRoot, L"/Root");
  786. wcscpy(wszData,IIS_CLASS_WEB_VDIR_W);
  787. // W3SVC/3/Root/KeyType
  788. mr.dwMDIdentifier = MD_KEY_TYPE;
  789. mr.dwMDAttributes = 0; // no need for inheritence
  790. mr.dwMDUserType = IIS_MD_UT_SERVER;
  791. mr.dwMDDataType = STRING_METADATA;
  792. mr.dwMDDataLen = (wcslen(wszData) + 1) * sizeof(WCHAR);
  793. mr.pbMDData = reinterpret_cast<unsigned char *>(wszData);
  794. hr = pIMSAdminBase->SetData( hMetabase, wszMetabasePathRoot, &mr );
  795. if (FAILED(hr)) {
  796. wprintf(L"SetData[MD_KEY_TYPE]. FAILED. code=0x%x\n",hr);
  797. }
  798. // W3SVC/3/Root/VrPath
  799. mr.dwMDIdentifier = MD_VR_PATH;
  800. mr.dwMDAttributes = METADATA_INHERIT;
  801. mr.dwMDUserType = IIS_MD_UT_FILE;
  802. mr.dwMDDataType = STRING_METADATA;
  803. mr.dwMDDataLen = (wcslen(wszDefaultVDirDir) + 1) * sizeof(WCHAR);
  804. mr.pbMDData = reinterpret_cast<unsigned char *>(wszDefaultVDirDir);
  805. hr = pIMSAdminBase->SetData( hMetabase, wszMetabasePathRoot, &mr );
  806. if (FAILED(hr)) {
  807. wprintf(L"SetData[MD_VR_PATH]. FAILED. code=0x%x\n",hr);
  808. }
  809. // W3SVC/3/Root/Authorizaton
  810. dwData = MD_AUTH_ANONYMOUS | MD_AUTH_NT;
  811. mr.dwMDIdentifier = MD_AUTHORIZATION;
  812. mr.dwMDAttributes = METADATA_INHERIT;
  813. mr.dwMDUserType = IIS_MD_UT_FILE;
  814. mr.dwMDDataType = DWORD_METADATA;
  815. mr.dwMDDataLen = sizeof(DWORD);
  816. mr.pbMDData = reinterpret_cast<unsigned char *>(&dwData);
  817. hr = pIMSAdminBase->SetData( hMetabase, wszMetabasePathRoot, &mr );
  818. if (FAILED(hr)) {
  819. wprintf(L"SetData[MD_AUTHORIZATION]. FAILED. code=0x%x\n",hr);
  820. }
  821. // W3SVC/3/Root/AccessPerm
  822. dwData = MD_ACCESS_SCRIPT | MD_ACCESS_READ;
  823. mr.dwMDIdentifier = MD_ACCESS_PERM;
  824. mr.dwMDAttributes = METADATA_INHERIT;
  825. mr.dwMDUserType = IIS_MD_UT_FILE;
  826. mr.dwMDDataType = DWORD_METADATA;
  827. mr.dwMDDataLen = sizeof(DWORD);
  828. mr.pbMDData = reinterpret_cast<unsigned char *>(&dwData);
  829. hr = pIMSAdminBase->SetData( hMetabase, wszMetabasePathRoot, &mr );
  830. if (FAILED(hr)) {
  831. wprintf(L"SetData[MD_ACCESS_PERM]. FAILED. code=0x%x\n",hr);
  832. }
  833. // W3SVC/3/Root/DirectoryBrowsing
  834. dwData = MD_DIRBROW_SHOW_DATE
  835. | MD_DIRBROW_SHOW_TIME
  836. | MD_DIRBROW_SHOW_SIZE
  837. | MD_DIRBROW_SHOW_EXTENSION
  838. | MD_DIRBROW_LONG_DATE
  839. | MD_DIRBROW_LOADDEFAULT;
  840. // | MD_DIRBROW_ENABLED;
  841. mr.dwMDIdentifier = MD_DIRECTORY_BROWSING;
  842. mr.dwMDAttributes = METADATA_INHERIT;
  843. mr.dwMDUserType = IIS_MD_UT_FILE;
  844. mr.dwMDDataType = DWORD_METADATA;
  845. mr.dwMDDataLen = sizeof(DWORD);
  846. mr.pbMDData = reinterpret_cast<unsigned char *>(&dwData);
  847. hr = pIMSAdminBase->SetData( hMetabase, wszMetabasePathRoot, &mr );
  848. if (FAILED(hr)) {
  849. wprintf(L"SetData[MD_DIRECTORY_BROWSING]. FAILED. code=0x%x\n",hr);
  850. }
  851. /*
  852. dwData = 0;
  853. mr.dwMDIdentifier = MD_SERVER_AUTOSTART;
  854. mr.dwMDAttributes = METADATA_INHERIT;
  855. mr.dwMDUserType = IIS_MD_UT_FILE;
  856. mr.dwMDDataType = DWORD_METADATA;
  857. mr.dwMDDataLen = sizeof(DWORD);
  858. mr.pbMDData = reinterpret_cast<unsigned char *>(&dwData);
  859. hr = pIMSAdminBase->SetData( hMetabase, wszMetabasePathRoot, &mr );
  860. if (FAILED(hr)) {
  861. wprintf(L"SetData[MD_SERVER_AUTOSTART]. FAILED. code=0x%x\n",hr);
  862. }
  863. */
  864. pIMSAdminBase->CloseKey(hMetabase);
  865. AddVirtualServer_Exit:
  866. if (pIMSAdminBase) {
  867. pIMSAdminBase->Release();
  868. pIMSAdminBase = NULL;
  869. }
  870. CoUninitialize();
  871. return hr;
  872. }