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.

578 lines
13 KiB

  1. /***********************************************************************
  2. *
  3. * STATUS.C
  4. *
  5. *
  6. * The Microsoft At Work Fax Address Book Provider.
  7. * This file contains the methods that implement the status object.
  8. *
  9. * The following routines are implemented in this file:
  10. *
  11. * HrNewStatusObject()
  12. * ABS_QueryInterface()
  13. * ABS_Release()
  14. * ABS_ValidateState()
  15. * ABS_SettingsDialog()
  16. * ABS_ChangePassword()
  17. * ABS_FlushQueues()
  18. *
  19. * Copyright 1992, 1993, 1994 Microsoft Corporation. All Rights Reserved.
  20. *
  21. ***********************************************************************/
  22. #include "faxab.h"
  23. /*
  24. * AB Status vtbl filled in here
  25. */
  26. static const ABS_Vtbl vtblABS =
  27. {
  28. ABS_QueryInterface,
  29. (ABS_AddRef_METHOD *) ROOT_AddRef,
  30. ABS_Release,
  31. (ABS_GetLastError_METHOD *) ROOT_GetLastError,
  32. (ABS_SaveChanges_METHOD *) WRAP_SaveChanges,
  33. (ABS_GetProps_METHOD *) WRAP_GetProps,
  34. (ABS_GetPropList_METHOD *) WRAP_GetPropList,
  35. (ABS_OpenProperty_METHOD *) WRAP_OpenProperty,
  36. (ABS_SetProps_METHOD *) WRAP_SetProps,
  37. (ABS_DeleteProps_METHOD *) WRAP_DeleteProps,
  38. (ABS_CopyTo_METHOD *) WRAP_CopyTo,
  39. (ABS_CopyProps_METHOD *) WRAP_CopyProps,
  40. (ABS_GetNamesFromIDs_METHOD *) WRAP_GetNamesFromIDs,
  41. (ABS_GetIDsFromNames_METHOD *) WRAP_GetIDsFromNames,
  42. ABS_ValidateState,
  43. ABS_SettingsDialog,
  44. ABS_ChangePassword,
  45. ABS_FlushQueues
  46. };
  47. /*************************************************************************
  48. *
  49. - HrNewStatusObject
  50. -
  51. * Creates the Status object associated with a particular FAB logon object
  52. *
  53. *
  54. */
  55. HRESULT
  56. HrNewStatusObject( LPMAPISTATUS * lppABS,
  57. ULONG * lpulObjType,
  58. ULONG ulFlags,
  59. LPABLOGON lpABLogon,
  60. LPCIID lpIID,
  61. HINSTANCE hLibrary,
  62. LPALLOCATEBUFFER lpAllocBuff,
  63. LPALLOCATEMORE lpAllocMore,
  64. LPFREEBUFFER lpFreeBuff,
  65. LPMALLOC lpMalloc
  66. )
  67. {
  68. LPABSTATUS lpABS = NULL;
  69. SCODE sc;
  70. HRESULT hr = hrSuccess;
  71. LPPROPDATA lpPropData = NULL;
  72. SPropValue spv[6];
  73. LPTSTR lpszFileName;
  74. #ifdef UNICODE
  75. CHAR szAnsiFileName[ MAX_PATH ];
  76. #endif
  77. /*
  78. *
  79. */
  80. if ( lpIID &&
  81. (memcmp(lpIID, &IID_IMAPIStatus, SIZEOF(IID)) &&
  82. memcmp(lpIID, &IID_IMAPIProp, SIZEOF(IID)) &&
  83. memcmp(lpIID, &IID_IUnknown, SIZEOF(IID))
  84. )
  85. )
  86. {
  87. DebugTraceSc(HrNewStatusObject, E_NOINTERFACE);
  88. return ResultFromScode(E_NOINTERFACE);
  89. }
  90. /*
  91. * Allocate space for the ABSTATUS structure
  92. */
  93. sc = lpAllocBuff( SIZEOF(ABSTATUS), (LPVOID *) &lpABS );
  94. if (FAILED(sc))
  95. {
  96. hr = ResultFromScode(sc);
  97. goto err;
  98. }
  99. lpABS->lpVtbl = &vtblABS;
  100. lpABS->lcInit = 1;
  101. lpABS->hResult = hrSuccess;
  102. lpABS->idsLastError = 0;
  103. lpABS->hLibrary = hLibrary;
  104. lpABS->lpAllocBuff = lpAllocBuff;
  105. lpABS->lpAllocMore = lpAllocMore;
  106. lpABS->lpFreeBuff = lpFreeBuff;
  107. lpABS->lpMalloc = lpMalloc;
  108. lpABS->lpABLogon = lpABLogon;
  109. /*
  110. * Create lpPropData
  111. */
  112. sc = CreateIProp( (LPIID) &IID_IMAPIPropData,
  113. lpAllocBuff,
  114. lpAllocMore,
  115. lpFreeBuff,
  116. lpMalloc,
  117. &lpPropData
  118. );
  119. if (FAILED(sc))
  120. {
  121. hr = ResultFromScode(sc);
  122. goto err;
  123. }
  124. /*
  125. * Set up initial set of properties associated with this
  126. * status object.
  127. */
  128. /*
  129. * Register my status row...
  130. */
  131. hr = HrLpszGetCurrentFileName(lpABLogon, &lpszFileName);
  132. if (HR_FAILED(hr))
  133. {
  134. goto err;
  135. }
  136. spv[0].ulPropTag = PR_DISPLAY_NAME_A;
  137. #ifdef UNICODE
  138. szAnsiFileName[0] = 0;
  139. WideCharToMultiByte( CP_ACP, 0, lpszFileName, -1, szAnsiFileName, ARRAYSIZE(szAnsiFileName), NULL, NULL );
  140. spv[0].Value.lpszA = szAnsiFileName;
  141. #else
  142. spv[0].Value.LPSZ = lpszFileName;
  143. #endif
  144. spv[1].ulPropTag = PR_RESOURCE_METHODS;
  145. spv[1].Value.l = 0;
  146. spv[2].ulPropTag = PR_RESOURCE_FLAGS;
  147. spv[2].Value.l = 0;
  148. spv[3].ulPropTag = PR_STATUS_CODE;
  149. spv[3].Value.l = STATUS_AVAILABLE;
  150. spv[4].ulPropTag = PR_STATUS_STRING_A;
  151. spv[4].Value.lpszA = "Available";
  152. spv[5].ulPropTag = PR_PROVIDER_DISPLAY_A;
  153. spv[5].Value.lpszA = "Microsoft Fax Address Book Provider";
  154. /*
  155. * Set the default properties
  156. */
  157. hr = lpPropData->lpVtbl->SetProps( lpPropData,
  158. ARRAYSIZE(spv),
  159. spv,
  160. NULL
  161. );
  162. /*
  163. * Done with the current file name
  164. */
  165. lpFreeBuff(lpszFileName);
  166. if (HR_FAILED(hr))
  167. {
  168. goto err;
  169. }
  170. (void) lpPropData->lpVtbl->HrSetObjAccess(lpPropData, IPROP_READONLY);
  171. lpABS->lpPropData = (LPMAPIPROP) lpPropData;
  172. InitializeCriticalSection(&lpABS->cs);
  173. *lpulObjType = MAPI_STATUS;
  174. *lppABS = (LPMAPISTATUS) lpABS;
  175. out:
  176. DebugTraceResult(HrNewStatusObject, hr);
  177. return hr;
  178. err:
  179. if (lpPropData)
  180. lpPropData->lpVtbl->Release(lpPropData);
  181. lpFreeBuff( lpABS );
  182. goto out;
  183. }
  184. /*************************************************************************
  185. *
  186. *
  187. - ABS_QueryInterface
  188. -
  189. * This method would allow this object to return a different interface than
  190. * the current one. This object need only support IMAPIStatus and any interface
  191. * it derives from.
  192. *
  193. */
  194. STDMETHODIMP
  195. ABS_QueryInterface( LPABSTATUS lpABS,
  196. REFIID lpiid,
  197. LPVOID FAR * lppNewObj
  198. )
  199. {
  200. HRESULT hr = hrSuccess;
  201. /*
  202. * Check to see if lpABS is what we expect
  203. */
  204. if ( IsBadReadPtr(lpABS, SIZEOF(ABSTATUS)) ||
  205. lpABS->lpVtbl != &vtblABS
  206. )
  207. {
  208. hr = ResultFromScode(E_INVALIDARG);
  209. goto out;
  210. }
  211. /* Validate other parameters */
  212. if ( IsBadReadPtr(lpiid, (UINT) SIZEOF(IID)) ||
  213. IsBadWritePtr(lppNewObj, SIZEOF(LPVOID))
  214. )
  215. {
  216. hr = ResultFromScode(E_INVALIDARG);
  217. goto out;
  218. }
  219. /* See if the requested interface is one of ours */
  220. if ( memcmp(lpiid, &IID_IUnknown, SIZEOF(IID)) &&
  221. memcmp(lpiid, &IID_IMAPIProp, SIZEOF(IID)) &&
  222. memcmp(lpiid, &IID_IMAPIStatus, SIZEOF(IID))
  223. )
  224. {
  225. *lppNewObj = NULL; /* OLE requires zeroing [out] parameter */
  226. hr = ResultFromScode(E_NOINTERFACE);
  227. goto out;
  228. }
  229. /* We'll do this one. Bump the usage count and return a new pointer. */
  230. EnterCriticalSection(&lpABS->cs);
  231. ++lpABS->lcInit;
  232. LeaveCriticalSection(&lpABS->cs);
  233. *lppNewObj = lpABS;
  234. out:
  235. DebugTraceResult(ABS_QueryInterface, hr);
  236. return hr;
  237. }
  238. /**************************************************
  239. *
  240. - ABS_Release
  241. -
  242. * Decrement lpInit.
  243. * When lcInit == 0, free up the lpABS structure
  244. *
  245. */
  246. STDMETHODIMP_(ULONG) ABS_Release(LPABSTATUS lpABS)
  247. {
  248. LONG lcInit;
  249. /*
  250. * Check to see if lpABS is what we expect
  251. */
  252. if (IsBadReadPtr(lpABS, SIZEOF(ABSTATUS)))
  253. {
  254. /*
  255. * No jump table found
  256. */
  257. return 1;
  258. }
  259. /*
  260. * Check to see that it's the correct jump table
  261. */
  262. if (lpABS->lpVtbl != &vtblABS)
  263. {
  264. /*
  265. * Not my jump table
  266. */
  267. return 1;
  268. }
  269. EnterCriticalSection(&lpABS->cs);
  270. lcInit = --lpABS->lcInit;
  271. LeaveCriticalSection(&lpABS->cs);
  272. if (lcInit == 0)
  273. {
  274. /*
  275. * Get rid of the lpPropData
  276. */
  277. lpABS->lpPropData->lpVtbl->Release(lpABS->lpPropData);
  278. /*
  279. * Delete the critical section
  280. */
  281. DeleteCriticalSection(&lpABS->cs);
  282. /*
  283. * Set the Jump table to NULL. This way the client will find out
  284. * real fast if it's calling a method on a released object. That is,
  285. * the client will crash. Hopefully, this will happen during the
  286. * development stage of the client.
  287. */
  288. lpABS->lpVtbl = NULL;
  289. /*
  290. * Need to free the object
  291. */
  292. lpABS->lpFreeBuff( lpABS );
  293. return 0;
  294. }
  295. return lcInit;
  296. }
  297. /**********************************************************************
  298. *
  299. - ABS_ValidateState
  300. -
  301. * Since I did not set any flags for the property PR_RESOURCE_METHODS
  302. * I don't have to support this method.
  303. *
  304. */
  305. STDMETHODIMP
  306. ABS_ValidateState( LPABSTATUS lpABS,
  307. ULONG ulUIParam,
  308. ULONG ulFlags
  309. )
  310. {
  311. HRESULT hr = ResultFromScode(MAPI_E_NO_SUPPORT);
  312. /*
  313. * Check to see if lpABS is what we expect
  314. */
  315. if ( IsBadReadPtr(lpABS, SIZEOF(ABSTATUS)) ||
  316. lpABS->lpVtbl != &vtblABS
  317. )
  318. {
  319. hr = ResultFromScode(E_INVALIDARG);
  320. goto out;
  321. }
  322. /* Validate other parameters */
  323. if (ulFlags & ~(SUPPRESS_UI
  324. | REFRESH_XP_HEADER_CACHE
  325. | PROCESS_XP_HEADER_CACHE
  326. | FORCE_XP_CONNECT
  327. | FORCE_XP_DISCONNECT
  328. | CONFIG_CHANGED))
  329. {
  330. hr = ResultFromScode(MAPI_E_UNKNOWN_FLAGS);
  331. goto out;
  332. }
  333. out:
  334. DebugTraceResult(ABS_ValidateState, hr);
  335. return hr;
  336. }
  337. /**********************************************************************
  338. *
  339. - ABS_SettingsDialog
  340. -
  341. * Since I did not set any flags for the property PR_RESOURCE_METHODS
  342. * I don't have to support this method.
  343. *
  344. */
  345. STDMETHODIMP
  346. ABS_SettingsDialog( LPABSTATUS lpABS,
  347. ULONG ulUIParam,
  348. ULONG ulFlags
  349. )
  350. {
  351. HRESULT hr = ResultFromScode(MAPI_E_NO_SUPPORT);
  352. /*
  353. * Check to see if lpABS is what we expect
  354. */
  355. if ( IsBadReadPtr(lpABS, SIZEOF(ABSTATUS)) ||
  356. lpABS->lpVtbl != &vtblABS
  357. )
  358. {
  359. hr = ResultFromScode(E_INVALIDARG);
  360. goto out;
  361. }
  362. /* Validate other parameters */
  363. if (ulFlags & ~(UI_READONLY))
  364. {
  365. hr = ResultFromScode(MAPI_E_UNKNOWN_FLAGS);
  366. goto out;
  367. }
  368. out:
  369. DebugTraceResult(ABS_SettingsDialog, hr);
  370. return hr;
  371. }
  372. /**********************************************************************
  373. *
  374. - ABS_ChangePassword
  375. -
  376. * Since I did not set any flags for the property PR_RESOURCE_METHODS
  377. * I don't have to support this method.
  378. *
  379. * Note: in the parameter validation below I chose only check the first 15
  380. * characters of the passwords. This was arbitrary.
  381. */
  382. STDMETHODIMP
  383. ABS_ChangePassword( LPABSTATUS lpABS,
  384. LPTSTR lpOldPass,
  385. LPTSTR lpNewPass,
  386. ULONG ulFlags
  387. )
  388. {
  389. HRESULT hr = ResultFromScode(MAPI_E_NO_SUPPORT);
  390. /*
  391. * Check to see if lpABS is what we expect
  392. */
  393. if ( IsBadReadPtr(lpABS, SIZEOF(ABSTATUS)) ||
  394. lpABS->lpVtbl != &vtblABS
  395. )
  396. {
  397. hr = ResultFromScode(E_INVALIDARG);
  398. goto out;
  399. }
  400. /* Validate other parameters */
  401. if (ulFlags & ~(MAPI_UNICODE))
  402. {
  403. hr = ResultFromScode(MAPI_E_UNKNOWN_FLAGS);
  404. goto out;
  405. }
  406. if ( ulFlags & MAPI_UNICODE )
  407. {
  408. // UNICODE is currently not supported by the sample AB
  409. hr = ResultFromScode( MAPI_E_BAD_CHARWIDTH );
  410. goto out;
  411. }
  412. if (ulFlags)
  413. {
  414. /*
  415. * We're checking UNICODE strings
  416. */
  417. if (IsBadStringPtrW((LPWSTR) lpOldPass, (UINT) 15) ||
  418. IsBadStringPtrW((LPWSTR) lpNewPass, (UINT) 15))
  419. {
  420. hr = ResultFromScode(E_INVALIDARG);
  421. goto out;
  422. }
  423. }
  424. else
  425. {
  426. /*
  427. * We're not checking UNICODE strings
  428. */
  429. if (IsBadStringPtrA((LPSTR) lpOldPass, (UINT) 15) ||
  430. IsBadStringPtrA((LPSTR) lpNewPass, (UINT) 15))
  431. {
  432. hr = ResultFromScode(E_INVALIDARG);
  433. goto out;
  434. }
  435. }
  436. out:
  437. DebugTraceResult(ABS_ChangePassword, hr);
  438. return hr;
  439. }
  440. /**********************************************************************
  441. *
  442. - ABS_FlushQueues
  443. -
  444. * Since I did not set any flags for the property PR_RESOURCE_METHODS
  445. * I don't have to support this method.
  446. *
  447. */
  448. STDMETHODIMP
  449. ABS_FlushQueues( LPABSTATUS lpABS,
  450. ULONG ulUIParam,
  451. ULONG cbTargetTransport,
  452. LPENTRYID lpTargetTransport,
  453. ULONG ulFlags
  454. )
  455. {
  456. HRESULT hr = ResultFromScode(MAPI_E_NO_SUPPORT);
  457. /*
  458. * Check to see if lpABS is what we expect
  459. */
  460. if (IsBadReadPtr(lpABS, SIZEOF(ABSTATUS)) || lpABS->lpVtbl != &vtblABS )
  461. {
  462. hr = ResultFromScode(E_INVALIDARG);
  463. goto out;
  464. }
  465. /* Validate other parameters */
  466. if ( cbTargetTransport &&
  467. ((cbTargetTransport < (ULONG) SIZEOF (ENTRYID)) ||
  468. IsBadReadPtr(lpTargetTransport, (UINT) cbTargetTransport)
  469. )
  470. )
  471. {
  472. hr = ResultFromScode(E_INVALIDARG);
  473. goto out;
  474. }
  475. if (ulFlags & ~(FLUSH_NO_UI
  476. | FLUSH_UPLOAD
  477. | FLUSH_DOWNLOAD
  478. | FLUSH_FORCE))
  479. {
  480. hr = ResultFromScode(MAPI_E_UNKNOWN_FLAGS);
  481. goto out;
  482. }
  483. out:
  484. DebugTraceResult(ABS_FlushQueues, hr);
  485. return hr;
  486. }