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.

384 lines
13 KiB

  1. /**********************************************************************************
  2. *
  3. *
  4. * ui_ext.C - contains functions for handling/creating the extension property
  5. * sheets to the wab property sheets
  6. *
  7. * Created - 9/97 - vikramm
  8. *
  9. **********************************************************************************/
  10. #include "_apipch.h"
  11. static const TCHAR szExtDisplayMailUser[] = TEXT("Software\\Microsoft\\WAB\\WAB4\\ExtDisplay\\MailUser");
  12. static const TCHAR szExtDisplayDistList[] = TEXT("Software\\Microsoft\\WAB\\WAB4\\ExtDisplay\\DistList");
  13. DEFINE_GUID(CLSID_DsPropertyPages,
  14. 0xd45d530, 0x764b, 0x11d0, 0xa1, 0xca, 0x0, 0xaa, 0x0, 0xc1, 0x6e, 0x65);
  15. //$$/////////////////////////////////////////////////////////////////////////////
  16. //
  17. // AddPropSheetPageProc
  18. //
  19. // CallBack from the Extension Sheets Prop Sheet creation function
  20. //
  21. /////////////////////////////////////////////////////////////////////////////////
  22. BOOL CALLBACK AddPropSheetPageProc( HPROPSHEETPAGE hpage, LPARAM lParam )
  23. {
  24. LPPROP_ARRAY_INFO lpPropArrayInfo = (LPPROP_ARRAY_INFO) lParam;
  25. HPROPSHEETPAGE * lphTemp = NULL;
  26. int i = 0;
  27. BOOL bNTDSExt = IsEqualGUID(&lpPropArrayInfo->guidExt, &CLSID_DsPropertyPages); //special casing for NTDS extensions
  28. int nPages = bNTDSExt ? lpPropArrayInfo->nNTDSPropSheetPages : lpPropArrayInfo->nPropSheetPages;
  29. HPROPSHEETPAGE * lph = bNTDSExt ? lpPropArrayInfo->lphNTDSpages : lpPropArrayInfo->lphpages;
  30. if(!hpage)
  31. return FALSE;
  32. // Grow the lpPropArrayInfo->lphpages array
  33. lphTemp = LocalAlloc(LMEM_ZEROINIT, sizeof(HPROPSHEETPAGE) * (nPages+1));
  34. if(!lphTemp)
  35. return FALSE;
  36. // really inefficient
  37. if(lph)
  38. {
  39. for(i=0;i<nPages;i++)
  40. {
  41. lphTemp[i] = lph[i];
  42. }
  43. LocalFree(lph);
  44. }
  45. if(bNTDSExt)
  46. {
  47. lpPropArrayInfo->lphNTDSpages = lphTemp;
  48. lpPropArrayInfo->lphNTDSpages[lpPropArrayInfo->nNTDSPropSheetPages] = hpage;
  49. lpPropArrayInfo->nNTDSPropSheetPages++;
  50. }
  51. else
  52. {
  53. lpPropArrayInfo->lphpages = lphTemp;
  54. lpPropArrayInfo->lphpages[lpPropArrayInfo->nPropSheetPages] = hpage;
  55. lpPropArrayInfo->nPropSheetPages++;
  56. }
  57. return TRUE;
  58. }
  59. //$$////////////////////////////////////////////////////////////////////
  60. //
  61. // HrGetExtDLLInfo
  62. //
  63. // Enumerate all the registered DLL names and Function procs from the
  64. // registry
  65. //
  66. // bMailUser - if true, look for mailuser extensions
  67. // - if false, look for distlist extensions
  68. ////////////////////////////////////////////////////////////////////////
  69. HRESULT HrGetExtDLLInfo(LPEXTDLLINFO * lppList, ULONG * lpulCount, BOOL bMailUser, LPGUID lpguidPSExt)
  70. {
  71. HRESULT hr = E_FAIL;
  72. HKEY hKey = NULL;
  73. DWORD dwIndex = 0, dwSize = 0;
  74. LPTSTR lpReg = NULL;
  75. LPEXTDLLINFO lpList = NULL;
  76. ULONG ulCount = 0;
  77. if(!lppList || !lpulCount)
  78. goto out;
  79. *lppList = NULL;
  80. *lpulCount = 0;
  81. lpReg = (LPTSTR) (bMailUser ? szExtDisplayMailUser : szExtDisplayDistList);
  82. if(ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  83. lpReg,
  84. 0, KEY_READ,
  85. &hKey))
  86. {
  87. goto out;
  88. }
  89. {
  90. TCHAR szGUIDName[MAX_PATH];
  91. DWORD dwGUIDIndex = 0, dwGUIDSize = CharSizeOf(szGUIDName), dwType = 0;
  92. *szGUIDName = '\0';
  93. while(ERROR_SUCCESS == RegEnumValue(hKey, dwGUIDIndex,
  94. szGUIDName, &dwGUIDSize,
  95. 0, &dwType,
  96. NULL, NULL))
  97. {
  98. // The values under this entry are all GUIDs
  99. // Read the GUID string and translate it into a GUID
  100. //
  101. GUID guidTmp = {0};
  102. WCHAR szW[MAX_PATH];
  103. StrCpyN(szW, szGUIDName, ARRAYSIZE(szW));
  104. if( lstrlen(szW) && !(HR_FAILED(hr = CLSIDFromString(szW, &guidTmp))) )
  105. {
  106. // Some applications may not want to see their property sheet extensions displayed
  107. // unless they have invoked the WAB. These applications can provide a GUID identifying
  108. // them which will be compared to the extension GUIDs. If the GUID has a Data Value of
  109. // "1" this means it should only be loaded on-demand ..
  110. // First check the data Value
  111. TCHAR sz[32];
  112. DWORD dw = CharSizeOf(sz), dwT = 0;
  113. if(ERROR_SUCCESS == RegQueryValueEx(hKey, szGUIDName, NULL, &dwT, (LPBYTE) sz, &dw))
  114. {
  115. if( !lstrcmpi(sz, TEXT("1")) // this one wants to be loaded on demand only
  116. && memcmp(&guidTmp, lpguidPSExt, sizeof(GUID)) ) //but guid doesnt match
  117. {
  118. goto endwhile;
  119. }
  120. }
  121. {
  122. LPEXTDLLINFO lpTemp = LocalAlloc(LMEM_ZEROINIT, sizeof(EXTDLLINFO));
  123. if(!lpTemp)
  124. {
  125. hr = MAPI_E_NOT_ENOUGH_MEMORY;
  126. goto out;
  127. }
  128. CopyMemory(&(lpTemp->guidPropExt), &guidTmp, sizeof(GUID));
  129. lpTemp->bMailUser = bMailUser;
  130. lpTemp->lpNext = lpList;
  131. lpList = lpTemp;
  132. ulCount++;
  133. }
  134. }
  135. endwhile:
  136. dwGUIDIndex++;
  137. *szGUIDName = '\0';
  138. dwGUIDSize = CharSizeOf(szGUIDName);
  139. }
  140. }
  141. *lppList = lpList;
  142. *lpulCount = ulCount;
  143. hr = S_OK;
  144. out:
  145. if(hKey)
  146. RegCloseKey(hKey);
  147. return hr;
  148. }
  149. BOOL fPropExtCoinit = FALSE;
  150. //$$//////////////////////////////////////////////////////////////////////
  151. //
  152. // UninitExtInfo
  153. //
  154. //
  155. //////////////////////////////////////////////////////////////////////////
  156. void UninitExtInfo()
  157. {
  158. if(fPropExtCoinit)
  159. {
  160. CoUninitialize();
  161. fPropExtCoinit = FALSE;
  162. }
  163. }
  164. //$$///////////////////////////////////////////////////////////////////
  165. //
  166. // FreePropExtList
  167. //
  168. ///////////////////////////////////////////////////////////////////////
  169. void FreePropExtList(LPEXTDLLINFO lpList)
  170. {
  171. LPEXTDLLINFO lpTemp = lpList;
  172. while(lpList)
  173. {
  174. lpList = lpTemp->lpNext;
  175. SafeRelease(lpTemp->lpWABExtInit);
  176. SafeRelease(lpTemp->lpPropSheetExt);
  177. LocalFree(lpTemp);
  178. lpTemp = lpList;
  179. }
  180. }
  181. //$$///////////////////////////////////////////////////////////////////
  182. //
  183. // GetExtDisplayInfo
  184. //
  185. // Gets all the requisite info for the extended property pages
  186. //
  187. // fReadOnly - specifies if all prop sheet controls should be readonly
  188. // fMailUser - true for contact, false for group
  189. //
  190. ///////////////////////////////////////////////////////////////////////
  191. HRESULT GetExtDisplayInfo(LPIAB lpIAB,
  192. LPPROP_ARRAY_INFO lpPropArrayInfo,
  193. BOOL fReadOnly,
  194. BOOL bMailUser)
  195. {
  196. ULONG i=0, nDLLs = 0;
  197. HRESULT hr = E_FAIL;
  198. LPEXTDLLINFO lpList = NULL, lpDLL = NULL;
  199. if(!lpIAB->lpPropExtDllList)
  200. {
  201. // There can be seperate registered entries for MailUsers and for DistLists
  202. // We will read everything and collate it into 1 large list
  203. LPEXTDLLINFO lpListMU = NULL, lpListDL = NULL;
  204. ULONG nDllsMU = 0, nDllsDL = 0;
  205. HRESULT hrMU = S_OK, hrDL = S_OK;
  206. // Get the list of registered DLL names for MailUsers
  207. //
  208. hrMU = HrGetExtDLLInfo(&lpListMU, &nDllsMU, TRUE, &lpIAB->guidPSExt);
  209. hrDL = HrGetExtDLLInfo(&lpListDL, &nDllsDL, FALSE, &lpIAB->guidPSExt);
  210. if( (!lpListMU && !lpListDL) ||
  211. !(nDllsDL + nDllsMU) ||
  212. (HR_FAILED(hrMU) && HR_FAILED(hrDL)) )
  213. {
  214. hr = E_FAIL;
  215. goto out;
  216. }
  217. if(lpListMU)
  218. {
  219. lpIAB->lpPropExtDllList = lpListMU;
  220. while(lpListMU->lpNext)
  221. lpListMU = lpListMU->lpNext;
  222. lpListMU->lpNext = lpListDL;
  223. }
  224. else
  225. lpIAB->lpPropExtDllList = lpListDL;
  226. lpIAB->nPropExtDLLs = nDllsDL + nDllsMU;
  227. }
  228. lpList = lpIAB->lpPropExtDllList;
  229. nDLLs = lpIAB->nPropExtDLLs;
  230. lpPropArrayInfo->lpWED = LocalAlloc(LMEM_ZEROINIT, sizeof(WABEXTDISPLAY));
  231. if(!lpPropArrayInfo->lpWED)
  232. {
  233. hr = MAPI_E_NOT_ENOUGH_MEMORY;
  234. goto out;
  235. }
  236. lpPropArrayInfo->lpWED->lpWABObject = (LPWABOBJECT) ((LPIAB)lpPropArrayInfo->lpIAB)->lpWABObject;
  237. lpPropArrayInfo->lpWED->lpAdrBook = lpPropArrayInfo->lpIAB;
  238. lpPropArrayInfo->lpWED->lpPropObj = lpPropArrayInfo->lpPropObj;
  239. lpPropArrayInfo->lpWED->fReadOnly = fReadOnly;
  240. lpPropArrayInfo->lpWED->fDataChanged = FALSE;
  241. if(lpPropArrayInfo->lpLDAPURL && lstrlen(lpPropArrayInfo->lpLDAPURL))
  242. {
  243. lpPropArrayInfo->lpWED->ulFlags |= WAB_DISPLAY_LDAPURL;
  244. lpPropArrayInfo->lpWED->lpsz = lpPropArrayInfo->lpLDAPURL;
  245. lpPropArrayInfo->lpWED->ulFlags |= MAPI_UNICODE;
  246. if(lpPropArrayInfo->bIsNTDSURL)
  247. lpPropArrayInfo->lpWED->ulFlags |= WAB_DISPLAY_ISNTDS;
  248. }
  249. if (CoInitialize(NULL) == S_FALSE)
  250. {
  251. CoUninitialize(); // Already initialized, undo the extra.
  252. }
  253. else
  254. fPropExtCoinit = TRUE;
  255. lpDLL = lpList;
  256. for(i=0;i<nDLLs;i++)
  257. {
  258. if(lpDLL)
  259. {
  260. if(lpDLL->bMailUser==bMailUser)
  261. {
  262. if(!lpDLL->lpPropSheetExt || !lpDLL->lpWABExtInit)
  263. {
  264. LPSHELLPROPSHEETEXT lpShellPropSheetExt = NULL;
  265. hr = CoCreateInstance( &(lpDLL->guidPropExt),
  266. NULL,
  267. CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
  268. &IID_IShellPropSheetExt,
  269. (LPVOID *)&(lpDLL->lpPropSheetExt));
  270. if(lpDLL->lpPropSheetExt && !HR_FAILED(hr))
  271. {
  272. hr = lpDLL->lpPropSheetExt->lpVtbl->QueryInterface(lpDLL->lpPropSheetExt,
  273. &IID_IWABExtInit,
  274. (LPVOID *)&(lpDLL->lpWABExtInit));
  275. if(HR_FAILED(hr) || !lpDLL->lpWABExtInit)
  276. {
  277. SafeRelease(lpDLL->lpPropSheetExt);
  278. }
  279. }
  280. }
  281. if(lpDLL->lpPropSheetExt && lpDLL->lpWABExtInit)
  282. {
  283. lpPropArrayInfo->guidExt = lpDLL->guidPropExt;
  284. hr = lpDLL->lpWABExtInit->lpVtbl->Initialize( lpDLL->lpWABExtInit,
  285. lpPropArrayInfo->lpWED);
  286. if(!HR_FAILED(hr))
  287. {
  288. hr = lpDLL->lpPropSheetExt->lpVtbl->AddPages(lpDLL->lpPropSheetExt,
  289. &AddPropSheetPageProc,
  290. (LPARAM) lpPropArrayInfo);
  291. }
  292. }
  293. }
  294. lpDLL = lpDLL->lpNext;
  295. }
  296. }
  297. //lpPropArrayInfo->lpExtList = lpList;
  298. lpList = NULL;
  299. hr = S_OK;
  300. out:
  301. if(lpList)
  302. FreePropExtList(lpList);
  303. return hr;
  304. }
  305. //$$//////////////////////////////////////////////////////////////////////
  306. //
  307. // FreeExtDisplayInfo
  308. //
  309. //
  310. //////////////////////////////////////////////////////////////////////////
  311. void FreeExtDisplayInfo(LPPROP_ARRAY_INFO lpPropArrayInfo)
  312. {
  313. if(lpPropArrayInfo->lpExtList)
  314. FreePropExtList(lpPropArrayInfo->lpExtList);
  315. if(lpPropArrayInfo->lpWED)
  316. LocalFree(lpPropArrayInfo->lpWED);
  317. if(lpPropArrayInfo->lphpages)
  318. LocalFree(lpPropArrayInfo->lphpages);
  319. //UninitExtInfo();
  320. return;
  321. }
  322. //$$/////////////////////////////////////////////////////////////////////
  323. //
  324. // ChangedExtDisplayInfo
  325. //
  326. // Returns true if the info changed on any of the prop sheets
  327. //
  328. /////////////////////////////////////////////////////////////////////////
  329. BOOL ChangedExtDisplayInfo(LPPROP_ARRAY_INFO lpPropArrayInfo, BOOL bChanged)
  330. {
  331. if(lpPropArrayInfo->lpWED && lpPropArrayInfo->lpWED->fDataChanged)
  332. return TRUE;
  333. return bChanged;
  334. }