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.

345 lines
12 KiB

  1. #include "stdafx.h"
  2. #include <wchar.h>
  3. #include <activeds.h>
  4. #include "DSAdminExt.h"
  5. #define MMC_REG_NODETYPES L"software\\microsoft\\mmc\\nodetypes"
  6. #define MMC_REG_SNAPINS L"software\\microsoft\\mmc\\snapins"
  7. #define MMC_REG_SNAPINS L"software\\microsoft\\mmc\\snapins"
  8. //MMC Extension subkeys
  9. #define MMC_REG_EXTENSIONS L"Extensions"
  10. #define MMC_REG_NAMESPACE L"NameSpace"
  11. #define MMC_REG_CONTEXTMENU L"ContextMenu"
  12. #define MMC_REG_TOOLBAR L"ToolBar"
  13. #define MMC_REG_PROPERTYSHEET L"PropertySheet"
  14. #define MMC_REG_TASKPAD L"Task"
  15. //DSADMIN key
  16. #define MMC_DSADMIN_CLSID L"{E355E538-1C2E-11D0-8C37-00C04FD8FE93}"
  17. HRESULT GetCOMGUIDStr(LPOLESTR *ppAttributeName,IDirectoryObject *pDO, LPOLESTR *ppGUIDString);
  18. HRESULT RegisterNodeType( LPOLESTR pszSchemaIDGUID );
  19. HRESULT AddExtensionToNodeType(LPOLESTR pszSchemaIDGUID,
  20. LPOLESTR pszExtensionType,
  21. LPOLESTR pszExtensionSnapinCLSID,
  22. LPOLESTR pszRegValue
  23. );
  24. //WCHAR * GetDirectoryObjectAttrib(IDirectoryObject *pDirObject,LPWSTR pAttrName);
  25. HRESULT RegisterSnapinAsExtension(_TCHAR* szNameString) // NameString
  26. {
  27. LPOLESTR szPath = new OLECHAR[MAX_PATH];
  28. HRESULT hr = S_OK;
  29. IADs *pObject = NULL;
  30. VARIANT var;
  31. IDirectoryObject *pDO = NULL;
  32. LPOLESTR pAttributeName = L"schemaIDGUID";
  33. LPOLESTR pGUIDString = NULL;
  34. //Convert CLSIDs of our "extension objects" to strings
  35. LPOLESTR wszCMenuExtCLSID = NULL;
  36. LPOLESTR wszPropPageExtCLSID = NULL;
  37. hr = StringFromCLSID(CLSID_CMenuExt, &wszCMenuExtCLSID);
  38. hr = StringFromCLSID(CLSID_PropPageExt, &wszPropPageExtCLSID);
  39. wcscpy(szPath, L"LDAP://");
  40. CoInitialize(NULL);
  41. //Get rootDSE and the schema container's DN.
  42. //Bind to current user's domain using current user's security context.
  43. hr = ADsOpenObject(L"LDAP://rootDSE",
  44. NULL,
  45. NULL,
  46. ADS_SECURE_AUTHENTICATION, //Use Secure Authentication
  47. IID_IADs,
  48. (void**)&pObject);
  49. if (SUCCEEDED(hr))
  50. {
  51. hr = pObject->Get(L"schemaNamingContext",&var);
  52. if (SUCCEEDED(hr))
  53. {
  54. wcscat(szPath, L"cn=user,");
  55. wcscat(szPath,var.bstrVal);
  56. hr = ADsOpenObject(szPath,
  57. NULL,
  58. NULL,
  59. ADS_SECURE_AUTHENTICATION, //Use Secure Authentication
  60. IID_IDirectoryObject,
  61. (void**)&pDO);
  62. if (SUCCEEDED(hr))
  63. {
  64. hr = GetCOMGUIDStr(&pAttributeName,
  65. pDO,
  66. &pGUIDString);
  67. if (SUCCEEDED(hr))
  68. {
  69. wprintf(L"schemaIDGUID: %s\n", pGUIDString);
  70. hr = RegisterNodeType( pGUIDString);
  71. wprintf(L"hr %x\n", hr);
  72. //do twice, once for each extension CLSID
  73. hr = AddExtensionToNodeType(pGUIDString,
  74. MMC_REG_CONTEXTMENU,
  75. wszCMenuExtCLSID, //our context menu extension object's CLSID
  76. szNameString
  77. );
  78. hr = AddExtensionToNodeType(pGUIDString,
  79. MMC_REG_PROPERTYSHEET,
  80. wszPropPageExtCLSID, //our prop page extension object's CLSID
  81. szNameString
  82. );
  83. }
  84. }
  85. }
  86. }
  87. if (pDO)
  88. pDO->Release();
  89. VariantClear(&var);
  90. // Free memory.
  91. CoTaskMemFree(wszCMenuExtCLSID);
  92. CoTaskMemFree(wszPropPageExtCLSID);
  93. // Uninitialize COM
  94. CoUninitialize();
  95. return 0;
  96. }
  97. HRESULT GetCOMGUIDStr(LPOLESTR *ppAttributeName,IDirectoryObject *pDO, LPOLESTR *ppGUIDString)
  98. {
  99. HRESULT hr = S_OK;
  100. PADS_ATTR_INFO pAttributeEntries;
  101. VARIANT varX;
  102. DWORD dwAttributesReturned = 0;
  103. hr = pDO->GetObjectAttributes( ppAttributeName, //objectGUID
  104. 1, //Only objectGUID
  105. &pAttributeEntries, // Returned attributes
  106. &dwAttributesReturned //Number of attributes returned
  107. );
  108. if (SUCCEEDED(hr) && dwAttributesReturned>0)
  109. {
  110. //Make sure that we got the right type--GUID is ADSTYPE_OCTET_STRING
  111. if (pAttributeEntries->dwADsType == ADSTYPE_OCTET_STRING)
  112. {
  113. LPGUID pObjectGUID = (GUID*)(pAttributeEntries->pADsValues[0].OctetString.lpValue);
  114. //OLE str to fit a GUID
  115. LPOLESTR szDSGUID = new WCHAR [39];
  116. //Convert GUID to string.
  117. ::StringFromGUID2(*pObjectGUID, szDSGUID, 39);
  118. *ppGUIDString = (OLECHAR *)CoTaskMemAlloc (sizeof(OLECHAR)*(wcslen(szDSGUID)+1));
  119. if (*ppGUIDString)
  120. wcscpy(*ppGUIDString, szDSGUID);
  121. else
  122. hr=E_FAIL;
  123. }
  124. else
  125. hr = E_FAIL;
  126. //Free the memory for the attributes.
  127. FreeADsMem(pAttributeEntries);
  128. VariantClear(&varX);
  129. }
  130. return hr;
  131. }
  132. HRESULT RegisterNodeType(LPOLESTR pszSchemaIDGUID)
  133. {
  134. LONG lResult;
  135. HKEY hKey;
  136. HKEY hSubKey, hNewKey;
  137. DWORD dwDisposition;
  138. LPOLESTR szRegSubKey = new OLECHAR[MAX_PATH];
  139. // first, open the HKEY_LOCAL_MACHINE
  140. lResult = RegConnectRegistry( NULL, HKEY_LOCAL_MACHINE, &hKey );
  141. if ( ERROR_SUCCESS == lResult )
  142. {
  143. //go to the MMC_REG_NODETYPES subkey
  144. lResult = RegOpenKey( hKey, MMC_REG_NODETYPES, &hSubKey );
  145. if ( ERROR_SUCCESS == lResult )
  146. {
  147. // Create a key for the node type of the class represented by pszSchemaIDGUID
  148. lResult = RegCreateKeyEx( hSubKey, // handle of an open key
  149. pszSchemaIDGUID, // address of subkey name
  150. 0L , // reserved
  151. NULL,
  152. REG_OPTION_NON_VOLATILE,// special options flag
  153. KEY_ALL_ACCESS,
  154. NULL,
  155. &hNewKey,
  156. &dwDisposition );
  157. RegCloseKey( hSubKey );
  158. if ( ERROR_SUCCESS == lResult )
  159. {
  160. hSubKey = hNewKey;
  161. // Create an extensions key
  162. lResult = RegCreateKeyEx( hSubKey,
  163. MMC_REG_EXTENSIONS,
  164. 0L ,
  165. NULL,
  166. REG_OPTION_NON_VOLATILE,
  167. KEY_ALL_ACCESS,
  168. NULL,
  169. &hNewKey,
  170. &dwDisposition );
  171. //go to the MMC_REG_SNAPINS subkey
  172. RegCloseKey( hSubKey );
  173. //Build the subkey path to the NodeTypes key of dsadmin
  174. wcscpy(szRegSubKey, MMC_REG_SNAPINS); //Snapins key
  175. wcscat(szRegSubKey, L"\\");
  176. wcscat(szRegSubKey, MMC_DSADMIN_CLSID); //CLSID for DSADMIN
  177. wcscat(szRegSubKey, L"\\NodeTypes");
  178. lResult = RegOpenKey( hKey, szRegSubKey, &hSubKey );
  179. if ( ERROR_SUCCESS == lResult )
  180. {
  181. // Create a key for the node type of the class represented by pszSchemaIDGUID
  182. lResult = RegCreateKeyEx( hSubKey, // handle of an open key
  183. pszSchemaIDGUID, // address of subkey name
  184. 0L , // reserved
  185. NULL,
  186. REG_OPTION_NON_VOLATILE,// special options flag
  187. KEY_ALL_ACCESS,
  188. NULL,
  189. &hNewKey,
  190. &dwDisposition );
  191. RegCloseKey( hSubKey );
  192. }
  193. }
  194. }
  195. }
  196. RegCloseKey( hSubKey );
  197. RegCloseKey( hNewKey );
  198. RegCloseKey( hKey );
  199. return lResult;
  200. }
  201. HRESULT AddExtensionToNodeType(LPOLESTR pszSchemaIDGUID,
  202. LPOLESTR pszExtensionType,
  203. LPOLESTR pszExtensionSnapinCLSID,
  204. LPOLESTR pszRegValue
  205. )
  206. {
  207. LONG lResult;
  208. HKEY hKey;
  209. HKEY hSubKey, hNewKey;
  210. DWORD dwDisposition;
  211. LPOLESTR szRegSubKey = new OLECHAR[MAX_PATH];
  212. HRESULT hr = S_OK;
  213. // first, open the HKEY_LOCAL_MACHINE
  214. lResult = RegConnectRegistry( NULL, HKEY_LOCAL_MACHINE, &hKey );
  215. if ( ERROR_SUCCESS == lResult )
  216. {
  217. //Build the subkey path to the NodeType specified by pszSchemaIDGUID
  218. wcscpy(szRegSubKey, MMC_REG_NODETYPES);
  219. wcscat(szRegSubKey, L"\\");
  220. wcscat(szRegSubKey, pszSchemaIDGUID);
  221. //go to the subkey
  222. lResult = RegOpenKey( hKey, szRegSubKey, &hSubKey );
  223. if ( ERROR_SUCCESS != lResult )
  224. {
  225. // Create the key for the nodetype if it doesn't already exist.
  226. hr = RegisterNodeType(pszSchemaIDGUID);
  227. if ( ERROR_SUCCESS != lResult )
  228. return E_FAIL;
  229. lResult = RegOpenKey( hKey, szRegSubKey, &hSubKey );
  230. }
  231. // Create an extensions key if one doesn't already exist
  232. lResult = RegCreateKeyEx( hSubKey,
  233. MMC_REG_EXTENSIONS,
  234. 0L ,
  235. NULL,
  236. REG_OPTION_NON_VOLATILE,
  237. KEY_ALL_ACCESS,
  238. NULL,
  239. &hNewKey,
  240. &dwDisposition );
  241. RegCloseKey( hSubKey );
  242. if ( ERROR_SUCCESS == lResult )
  243. {
  244. hSubKey = hNewKey;
  245. // Create an extension type subkey if one doesn't already exist
  246. lResult = RegCreateKeyEx( hSubKey,
  247. pszExtensionType,
  248. 0L ,
  249. NULL,
  250. REG_OPTION_NON_VOLATILE,
  251. KEY_ALL_ACCESS,
  252. NULL,
  253. &hNewKey,
  254. &dwDisposition );
  255. RegCloseKey( hSubKey );
  256. if ( ERROR_SUCCESS == lResult )
  257. {
  258. hSubKey = hNewKey;
  259. // Add your snap-in to the
  260. //extension type key if it hasn't been already.
  261. lResult = RegSetValueEx( hSubKey,
  262. pszExtensionSnapinCLSID,
  263. 0L ,
  264. REG_SZ,
  265. (const BYTE*)pszRegValue,
  266. (wcslen(pszRegValue)+1)*sizeof(OLECHAR)
  267. );
  268. }
  269. }
  270. }
  271. RegCloseKey( hSubKey );
  272. RegCloseKey( hNewKey );
  273. RegCloseKey( hKey );
  274. return lResult;
  275. }
  276. //GetDirectoryObjectAttrib() isn't used in this sample
  277. ////////////////////////////////////////////////////////////////////////////////////////////////////
  278. /*
  279. GetDirectoryObjectAttrib() - Returns the value of the attribute named in pAttrName
  280. from the IDirectoryObject passed
  281. Parameters
  282. IDirectoryObject *pDirObject - Object from which to retrieve an attribute value
  283. LPWSTR pAttrName - Name of attribute to retrieve
  284. ////////////////////////////////////////////////////////////////////////////////////////////////////
  285. WCHAR * GetDirectoryObjectAttrib(IDirectoryObject *pDirObject,LPWSTR pAttrName)
  286. {
  287. HRESULT hr;
  288. ADS_ATTR_INFO *pAttrInfo=NULL;
  289. DWORD dwReturn;
  290. static WCHAR pwReturn[1024];
  291. pwReturn[0] = 0l;
  292. hr = pDirObject->GetObjectAttributes( &pAttrName,
  293. 1,
  294. &pAttrInfo,
  295. &dwReturn );
  296. if ( SUCCEEDED(hr) )
  297. {
  298. for(DWORD idx=0; idx < dwReturn;idx++, pAttrInfo++ )
  299. {
  300. if ( _wcsicmp(pAttrInfo->pszAttrName,pAttrName) == 0 )
  301. {
  302. wcscpy(pwReturn,pAttrInfo->pADsValues->CaseIgnoreString);
  303. break;
  304. }
  305. }
  306. FreeADsMem( pAttrInfo );
  307. }
  308. return pwReturn;
  309. }
  310. */