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.

4060 lines
118 KiB

  1. /*
  2. * MSVALID.C
  3. *
  4. * Validates Message Store provider call parameters
  5. *
  6. * Important things to note
  7. * ------------------------
  8. *
  9. * Some work has been done to optimize this module for, in particular,
  10. * 16 bit.
  11. *
  12. * e.g. The incoming This pointer has the SS as its selector. We take
  13. * advantage of this by passing it on to the validation routines
  14. * as BASED_STACK, taking 2 bytes not 4. This makes it possible
  15. * to pass it in a register using the __farcall convention.
  16. * Validation functions are then smaller and faster as they do not
  17. * load the This selector into ES, but reference it directly using
  18. * SS.
  19. *
  20. * ALL strings are in code segments, this means that this module
  21. * does not need a DS loaded. Entry and exit from the
  22. * __ValidateParameters call does not need the prolog/epilog
  23. * sequence. If data is used in the future, this needs to change.
  24. *
  25. * All validation routines are declared as NEAR, speeding up the
  26. * validation dispatch, and halving the size of the dispatch table.
  27. *
  28. * Each valididation routine uses an int internally to represent the
  29. * required return code (0 - hrSuccess, 1 - MAPI_E_INVALID_PARAMETER,
  30. * 2 - MAPI_E_UNKNOWN_FLAGS. Using an int saves code on 16bit. The
  31. * return from the validation function is used to lookup the HRESULT
  32. * to return. This table is stored in a code segment.
  33. *
  34. *
  35. */
  36. #include "_apipch.h"
  37. #ifdef WIN16
  38. #pragma SEGMENT(valid)
  39. #endif
  40. /* Data tables in code segments makes the ValidateParameters dispatch quicker
  41. in 16bit, and geting strings out of the data segment saves space in Debug */
  42. #ifdef WIN16
  43. #define BASED_CODE __based(__segname("_CODE"))
  44. #define BASED_STACK __based(__segname("_STACK"))
  45. #else
  46. #define BASED_CODE
  47. #define BASED_STACK
  48. #endif
  49. #if defined(_X86_) || defined(_AMD64_) || defined(_IA64_) || defined( WIN16 )
  50. #define _INTEL_
  51. #endif
  52. #define VALIDATE_CALLTYPE static int NEAR
  53. typedef int (NEAR * ValidateProc)(void BASED_STACK *);
  54. /* Structures to overlay on stack frame to give us access to the parameters */
  55. /* Structure names MUST be in the form 'Method_Params' and 'LPMethod_Params' for the
  56. following macros to work correctly */
  57. #include "structs.h"
  58. /* Function declarations ------------------------------------------------------------------------ */
  59. #define MAKE_VALIDATE_FUNCTION(Method, Interface) VALIDATE_CALLTYPE Interface##_##Method##_Validate(void BASED_STACK *)
  60. /* Empty function for non-debug 'validation' */
  61. #ifndef DEBUG
  62. VALIDATE_CALLTYPE DoNothing_Validate(void BASED_STACK *);
  63. #endif
  64. /* IUnknown */
  65. MAKE_VALIDATE_FUNCTION(QueryInterface, IUnknown);
  66. MAKE_VALIDATE_FUNCTION(AddRef, IUnknown); /* For completness */
  67. MAKE_VALIDATE_FUNCTION(Release, IUnknown); /* For completness */
  68. /* IMAPIProp */
  69. MAKE_VALIDATE_FUNCTION(GetLastError, IMAPIProp);
  70. MAKE_VALIDATE_FUNCTION(SaveChanges, IMAPIProp);
  71. MAKE_VALIDATE_FUNCTION(GetProps, IMAPIProp);
  72. MAKE_VALIDATE_FUNCTION(GetPropList, IMAPIProp);
  73. MAKE_VALIDATE_FUNCTION(OpenProperty, IMAPIProp);
  74. MAKE_VALIDATE_FUNCTION(SetProps, IMAPIProp);
  75. MAKE_VALIDATE_FUNCTION(DeleteProps, IMAPIProp);
  76. MAKE_VALIDATE_FUNCTION(CopyTo, IMAPIProp);
  77. MAKE_VALIDATE_FUNCTION(CopyProps, IMAPIProp);
  78. MAKE_VALIDATE_FUNCTION(GetNamesFromIDs, IMAPIProp);
  79. MAKE_VALIDATE_FUNCTION(GetIDsFromNames, IMAPIProp);
  80. /* IMAPITable */
  81. MAKE_VALIDATE_FUNCTION(GetLastError, IMAPITable);
  82. MAKE_VALIDATE_FUNCTION(Advise, IMAPITable);
  83. MAKE_VALIDATE_FUNCTION(Unadvise, IMAPITable);
  84. MAKE_VALIDATE_FUNCTION(GetStatus, IMAPITable);
  85. MAKE_VALIDATE_FUNCTION(SetColumns, IMAPITable);
  86. MAKE_VALIDATE_FUNCTION(QueryColumns, IMAPITable);
  87. MAKE_VALIDATE_FUNCTION(GetRowCount, IMAPITable);
  88. MAKE_VALIDATE_FUNCTION(SeekRow, IMAPITable);
  89. MAKE_VALIDATE_FUNCTION(SeekRowApprox, IMAPITable);
  90. MAKE_VALIDATE_FUNCTION(QueryPosition, IMAPITable);
  91. MAKE_VALIDATE_FUNCTION(FindRow, IMAPITable);
  92. MAKE_VALIDATE_FUNCTION(Restrict, IMAPITable);
  93. MAKE_VALIDATE_FUNCTION(CreateBookmark, IMAPITable);
  94. MAKE_VALIDATE_FUNCTION(FreeBookmark, IMAPITable);
  95. MAKE_VALIDATE_FUNCTION(SortTable, IMAPITable);
  96. MAKE_VALIDATE_FUNCTION(QuerySortOrder, IMAPITable);
  97. MAKE_VALIDATE_FUNCTION(QueryRows, IMAPITable);
  98. MAKE_VALIDATE_FUNCTION(Abort, IMAPITable);
  99. MAKE_VALIDATE_FUNCTION(ExpandRow, IMAPITable);
  100. MAKE_VALIDATE_FUNCTION(CollapseRow, IMAPITable);
  101. MAKE_VALIDATE_FUNCTION(WaitForCompletion, IMAPITable);
  102. MAKE_VALIDATE_FUNCTION(GetCollapseState, IMAPITable);
  103. MAKE_VALIDATE_FUNCTION(SetCollapseState, IMAPITable);
  104. #ifdef OLD_STUFF
  105. /* IMAPIStatus */
  106. MAKE_VALIDATE_FUNCTION(ValidateState, IMAPIStatus);
  107. MAKE_VALIDATE_FUNCTION(SettingsDialog, IMAPIStatus);
  108. MAKE_VALIDATE_FUNCTION(ChangePassword, IMAPIStatus);
  109. MAKE_VALIDATE_FUNCTION(FlushQueues, IMAPIStatus);
  110. #endif // OLD_STUFF
  111. /* IMAPIContainer */
  112. MAKE_VALIDATE_FUNCTION(GetContentsTable, IMAPIContainer);
  113. MAKE_VALIDATE_FUNCTION(GetHierarchyTable, IMAPIContainer);
  114. MAKE_VALIDATE_FUNCTION(OpenEntry, IMAPIContainer);
  115. MAKE_VALIDATE_FUNCTION(SetSearchCriteria, IMAPIContainer);
  116. MAKE_VALIDATE_FUNCTION(GetSearchCriteria, IMAPIContainer);
  117. /* IABContainer */
  118. MAKE_VALIDATE_FUNCTION(CreateEntry, IABContainer);
  119. MAKE_VALIDATE_FUNCTION(CopyEntries, IABContainer);
  120. MAKE_VALIDATE_FUNCTION(DeleteEntries, IABContainer);
  121. MAKE_VALIDATE_FUNCTION(ResolveNames, IABContainer);
  122. /* IDistList */
  123. MAKE_VALIDATE_FUNCTION(CreateEntry, IDistList);
  124. MAKE_VALIDATE_FUNCTION(CopyEntries, IDistList);
  125. MAKE_VALIDATE_FUNCTION(DeleteEntries, IDistList);
  126. MAKE_VALIDATE_FUNCTION(ResolveNames, IDistList);
  127. /* IMAPIFolder */
  128. MAKE_VALIDATE_FUNCTION(CreateMessage, IMAPIFolder);
  129. MAKE_VALIDATE_FUNCTION(CopyMessages, IMAPIFolder);
  130. MAKE_VALIDATE_FUNCTION(DeleteMessages, IMAPIFolder);
  131. MAKE_VALIDATE_FUNCTION(CreateFolder, IMAPIFolder);
  132. MAKE_VALIDATE_FUNCTION(CopyFolder, IMAPIFolder);
  133. MAKE_VALIDATE_FUNCTION(DeleteFolder, IMAPIFolder);
  134. MAKE_VALIDATE_FUNCTION(SetReadFlags, IMAPIFolder);
  135. MAKE_VALIDATE_FUNCTION(GetMessageStatus, IMAPIFolder);
  136. MAKE_VALIDATE_FUNCTION(SetMessageStatus, IMAPIFolder);
  137. MAKE_VALIDATE_FUNCTION(SaveContentsSort, IMAPIFolder);
  138. MAKE_VALIDATE_FUNCTION(EmptyFolder, IMAPIFolder);
  139. #ifdef OLD_STUFF
  140. /* IMsgStore */
  141. MAKE_VALIDATE_FUNCTION(Advise, IMsgStore);
  142. MAKE_VALIDATE_FUNCTION(Unadvise, IMsgStore);
  143. MAKE_VALIDATE_FUNCTION(CompareEntryIDs, IMsgStore);
  144. MAKE_VALIDATE_FUNCTION(OpenEntry, IMsgStore);
  145. MAKE_VALIDATE_FUNCTION(SetReceiveFolder, IMsgStore);
  146. MAKE_VALIDATE_FUNCTION(GetReceiveFolder, IMsgStore);
  147. MAKE_VALIDATE_FUNCTION(GetReceiveFolderTable, IMsgStore);
  148. MAKE_VALIDATE_FUNCTION(StoreLogoff, IMsgStore);
  149. MAKE_VALIDATE_FUNCTION(AbortSubmit, IMsgStore);
  150. MAKE_VALIDATE_FUNCTION(GetOutgoingQueue, IMsgStore);
  151. MAKE_VALIDATE_FUNCTION(SetLockState, IMsgStore);
  152. MAKE_VALIDATE_FUNCTION(FinishedMsg, IMsgStore);
  153. MAKE_VALIDATE_FUNCTION(NotifyNewMail, IMsgStore);
  154. /* IMessage */
  155. MAKE_VALIDATE_FUNCTION(GetAttachmentTable, IMessage);
  156. MAKE_VALIDATE_FUNCTION(OpenAttach, IMessage);
  157. MAKE_VALIDATE_FUNCTION(CreateAttach, IMessage);
  158. MAKE_VALIDATE_FUNCTION(DeleteAttach, IMessage);
  159. MAKE_VALIDATE_FUNCTION(GetRecipientTable, IMessage);
  160. MAKE_VALIDATE_FUNCTION(ModifyRecipients, IMessage);
  161. MAKE_VALIDATE_FUNCTION(SubmitMessage, IMessage);
  162. MAKE_VALIDATE_FUNCTION(SetReadFlag, IMessage);
  163. /* IABProvider */
  164. MAKE_VALIDATE_FUNCTION(Shutdown, IABProvider);
  165. MAKE_VALIDATE_FUNCTION(Logon, IABProvider);
  166. /* IABLogon */
  167. MAKE_VALIDATE_FUNCTION(GetLastError, IABLogon);
  168. MAKE_VALIDATE_FUNCTION(Logoff, IABLogon);
  169. MAKE_VALIDATE_FUNCTION(OpenEntry, IABLogon);
  170. MAKE_VALIDATE_FUNCTION(CompareEntryIDs, IABLogon);
  171. MAKE_VALIDATE_FUNCTION(Advise, IABLogon);
  172. MAKE_VALIDATE_FUNCTION(Unadvise, IABLogon);
  173. MAKE_VALIDATE_FUNCTION(OpenStatusEntry, IABLogon);
  174. MAKE_VALIDATE_FUNCTION(OpenTemplateID, IABLogon);
  175. MAKE_VALIDATE_FUNCTION(GetOneOffTable, IABLogon);
  176. MAKE_VALIDATE_FUNCTION(PrepareRecips, IABLogon);
  177. /* IXPProvider */
  178. MAKE_VALIDATE_FUNCTION(Shutdown, IXPProvider);
  179. MAKE_VALIDATE_FUNCTION(TransportLogon, IXPProvider);
  180. /* IXPLogon */
  181. MAKE_VALIDATE_FUNCTION(AddressTypes, IXPLogon);
  182. MAKE_VALIDATE_FUNCTION(RegisterOptions, IXPLogon);
  183. MAKE_VALIDATE_FUNCTION(TransportNotify, IXPLogon);
  184. MAKE_VALIDATE_FUNCTION(Idle, IXPLogon);
  185. MAKE_VALIDATE_FUNCTION(TransportLogoff, IXPLogon);
  186. MAKE_VALIDATE_FUNCTION(SubmitMessage, IXPLogon);
  187. MAKE_VALIDATE_FUNCTION(EndMessage, IXPLogon);
  188. MAKE_VALIDATE_FUNCTION(Poll, IXPLogon);
  189. MAKE_VALIDATE_FUNCTION(StartMessage, IXPLogon);
  190. MAKE_VALIDATE_FUNCTION(OpenStatusEntry, IXPLogon);
  191. MAKE_VALIDATE_FUNCTION(ValidateState, IXPLogon);
  192. MAKE_VALIDATE_FUNCTION(FlushQueues, IXPLogon);
  193. /* IMSProvider */
  194. MAKE_VALIDATE_FUNCTION(Shutdown, IMSProvider);
  195. MAKE_VALIDATE_FUNCTION(Logon, IMSProvider);
  196. MAKE_VALIDATE_FUNCTION(SpoolerLogon, IMSProvider);
  197. MAKE_VALIDATE_FUNCTION(CompareStoreIDs, IMSProvider);
  198. /* IMSLogon */
  199. MAKE_VALIDATE_FUNCTION(GetLastError, IMSLogon);
  200. MAKE_VALIDATE_FUNCTION(Logoff, IMSLogon);
  201. MAKE_VALIDATE_FUNCTION(OpenEntry, IMSLogon);
  202. MAKE_VALIDATE_FUNCTION(CompareEntryIDs, IMSLogon);
  203. MAKE_VALIDATE_FUNCTION(Advise, IMSLogon);
  204. MAKE_VALIDATE_FUNCTION(Unadvise, IMSLogon);
  205. MAKE_VALIDATE_FUNCTION(OpenStatusEntry, IMSLogon);
  206. /* IMAPIControl */
  207. MAKE_VALIDATE_FUNCTION(GetLastError, IMAPIControl);
  208. MAKE_VALIDATE_FUNCTION(Activate, IMAPIControl);
  209. MAKE_VALIDATE_FUNCTION(GetState, IMAPIControl);
  210. #endif
  211. /* IStream */
  212. MAKE_VALIDATE_FUNCTION(Read, IStream);
  213. MAKE_VALIDATE_FUNCTION(Write, IStream);
  214. MAKE_VALIDATE_FUNCTION(Seek, IStream);
  215. MAKE_VALIDATE_FUNCTION(SetSize, IStream);
  216. MAKE_VALIDATE_FUNCTION(CopyTo, IStream);
  217. MAKE_VALIDATE_FUNCTION(Commit, IStream);
  218. MAKE_VALIDATE_FUNCTION(Revert, IStream);
  219. MAKE_VALIDATE_FUNCTION(LockRegion, IStream);
  220. MAKE_VALIDATE_FUNCTION(UnlockRegion, IStream);
  221. MAKE_VALIDATE_FUNCTION(Stat, IStream);
  222. MAKE_VALIDATE_FUNCTION(Clone, IStream);
  223. /* IMAPIAdviseSink */
  224. MAKE_VALIDATE_FUNCTION(OnNotify, IMAPIAdviseSink);
  225. /* IWABObject */
  226. MAKE_VALIDATE_FUNCTION(GetLastError, IWABObject);
  227. MAKE_VALIDATE_FUNCTION(AllocateBuffer, IWABObject);
  228. MAKE_VALIDATE_FUNCTION(AllocateMore, IWABObject);
  229. MAKE_VALIDATE_FUNCTION(FreeBuffer, IWABObject);
  230. MAKE_VALIDATE_FUNCTION(Backup, IWABObject);
  231. MAKE_VALIDATE_FUNCTION(Import, IWABObject);
  232. /* Table of validation functions and Offsets of the This member of the Params structure --------- */
  233. typedef struct _tagMethodEntry
  234. {
  235. ValidateProc pfnValidation; // Validation function for this method
  236. #if !defined(_INTEL_) || defined(DEBUG) || defined(_AMD64_) || defined(_IA64_)
  237. UINT cParameterSize; // Expected size of parameters for stack validation
  238. #endif
  239. } METHODENTRY;
  240. #if !defined(_INTEL_) || defined(DEBUG)
  241. #define MAKE_PERM_ENTRY(Method, Interface) { Interface##_##Method##_Validate, sizeof(Interface##_##Method##_Params) }
  242. #else
  243. #define MAKE_PERM_ENTRY(Method, Interface) { Interface##_##Method##_Validate }
  244. #endif
  245. #if defined(DEBUG)
  246. #define MAKE_TEMP_ENTRY(Method, Interface) { Interface##_##Method##_Validate, sizeof(Interface##_##Method##_Params) }
  247. #else
  248. #define MAKE_TEMP_ENTRY(Method, Interface) { DoNothing_Validate }
  249. #endif
  250. METHODENTRY BASED_CODE meMethodTable[] =
  251. {
  252. /* IUnknown */
  253. MAKE_PERM_ENTRY(QueryInterface, IUnknown),
  254. MAKE_PERM_ENTRY(AddRef, IUnknown),
  255. MAKE_PERM_ENTRY(Release, IUnknown),
  256. /* IMAPIProp */
  257. MAKE_PERM_ENTRY(GetLastError, IMAPIProp),
  258. MAKE_PERM_ENTRY(SaveChanges, IMAPIProp),
  259. MAKE_PERM_ENTRY(GetProps, IMAPIProp),
  260. MAKE_PERM_ENTRY(GetPropList, IMAPIProp),
  261. MAKE_PERM_ENTRY(OpenProperty, IMAPIProp),
  262. MAKE_PERM_ENTRY(SetProps, IMAPIProp),
  263. MAKE_PERM_ENTRY(DeleteProps, IMAPIProp),
  264. MAKE_PERM_ENTRY(CopyTo, IMAPIProp),
  265. MAKE_PERM_ENTRY(CopyProps, IMAPIProp),
  266. MAKE_PERM_ENTRY(GetNamesFromIDs, IMAPIProp),
  267. MAKE_PERM_ENTRY(GetIDsFromNames, IMAPIProp),
  268. /* IMAPITable */
  269. MAKE_PERM_ENTRY(GetLastError, IMAPITable),
  270. MAKE_PERM_ENTRY(Advise, IMAPITable),
  271. MAKE_PERM_ENTRY(Unadvise, IMAPITable),
  272. MAKE_PERM_ENTRY(GetStatus, IMAPITable),
  273. MAKE_PERM_ENTRY(SetColumns, IMAPITable),
  274. MAKE_PERM_ENTRY(QueryColumns, IMAPITable),
  275. MAKE_PERM_ENTRY(GetRowCount, IMAPITable),
  276. MAKE_PERM_ENTRY(SeekRow, IMAPITable),
  277. MAKE_PERM_ENTRY(SeekRowApprox, IMAPITable),
  278. MAKE_PERM_ENTRY(QueryPosition, IMAPITable),
  279. MAKE_PERM_ENTRY(FindRow, IMAPITable),
  280. MAKE_PERM_ENTRY(Restrict, IMAPITable),
  281. MAKE_PERM_ENTRY(CreateBookmark, IMAPITable),
  282. MAKE_PERM_ENTRY(FreeBookmark, IMAPITable),
  283. MAKE_PERM_ENTRY(SortTable, IMAPITable),
  284. MAKE_PERM_ENTRY(QuerySortOrder, IMAPITable),
  285. MAKE_PERM_ENTRY(QueryRows, IMAPITable),
  286. MAKE_PERM_ENTRY(Abort, IMAPITable),
  287. MAKE_PERM_ENTRY(ExpandRow, IMAPITable),
  288. MAKE_PERM_ENTRY(CollapseRow, IMAPITable),
  289. MAKE_PERM_ENTRY(WaitForCompletion, IMAPITable),
  290. MAKE_PERM_ENTRY(GetCollapseState, IMAPITable),
  291. MAKE_PERM_ENTRY(SetCollapseState, IMAPITable),
  292. /* IMAPIContainer */
  293. MAKE_PERM_ENTRY(GetContentsTable, IMAPIContainer),
  294. MAKE_PERM_ENTRY(GetHierarchyTable, IMAPIContainer),
  295. MAKE_PERM_ENTRY(OpenEntry, IMAPIContainer),
  296. MAKE_PERM_ENTRY(SetSearchCriteria, IMAPIContainer),
  297. MAKE_PERM_ENTRY(GetSearchCriteria, IMAPIContainer),
  298. /* IABContainer */
  299. MAKE_PERM_ENTRY(CreateEntry, IABContainer),
  300. MAKE_PERM_ENTRY(CopyEntries, IABContainer),
  301. MAKE_PERM_ENTRY(DeleteEntries, IABContainer),
  302. MAKE_PERM_ENTRY(ResolveNames, IABContainer),
  303. /* IDistList same as IABContainer */
  304. MAKE_PERM_ENTRY(CreateEntry, IDistList),
  305. MAKE_PERM_ENTRY(CopyEntries, IDistList),
  306. MAKE_PERM_ENTRY(DeleteEntries, IDistList),
  307. MAKE_PERM_ENTRY(ResolveNames, IDistList),
  308. /* IMAPIFolder */
  309. MAKE_PERM_ENTRY(CreateMessage, IMAPIFolder),
  310. MAKE_PERM_ENTRY(CopyMessages, IMAPIFolder),
  311. MAKE_PERM_ENTRY(DeleteMessages, IMAPIFolder),
  312. MAKE_PERM_ENTRY(CreateFolder, IMAPIFolder),
  313. MAKE_PERM_ENTRY(CopyFolder, IMAPIFolder),
  314. MAKE_PERM_ENTRY(DeleteFolder, IMAPIFolder),
  315. MAKE_PERM_ENTRY(SetReadFlags, IMAPIFolder),
  316. MAKE_PERM_ENTRY(GetMessageStatus, IMAPIFolder),
  317. MAKE_PERM_ENTRY(SetMessageStatus, IMAPIFolder),
  318. MAKE_PERM_ENTRY(SaveContentsSort, IMAPIFolder),
  319. MAKE_PERM_ENTRY(EmptyFolder, IMAPIFolder),
  320. #ifdef OLD_STUFF
  321. /* IMsgStore */
  322. MAKE_PERM_ENTRY(Advise, IMsgStore),
  323. MAKE_PERM_ENTRY(Unadvise, IMsgStore),
  324. MAKE_PERM_ENTRY(CompareEntryIDs, IMsgStore),
  325. MAKE_PERM_ENTRY(OpenEntry, IMsgStore),
  326. MAKE_PERM_ENTRY(SetReceiveFolder, IMsgStore),
  327. MAKE_PERM_ENTRY(GetReceiveFolder, IMsgStore),
  328. MAKE_PERM_ENTRY(GetReceiveFolderTable, IMsgStore),
  329. MAKE_PERM_ENTRY(StoreLogoff, IMsgStore),
  330. MAKE_PERM_ENTRY(AbortSubmit, IMsgStore),
  331. MAKE_PERM_ENTRY(GetOutgoingQueue, IMsgStore),
  332. MAKE_PERM_ENTRY(SetLockState, IMsgStore),
  333. MAKE_PERM_ENTRY(FinishedMsg, IMsgStore),
  334. MAKE_PERM_ENTRY(NotifyNewMail, IMsgStore),
  335. /* IMessage */
  336. MAKE_PERM_ENTRY(GetAttachmentTable, IMessage),
  337. MAKE_PERM_ENTRY(OpenAttach, IMessage),
  338. MAKE_PERM_ENTRY(CreateAttach, IMessage),
  339. MAKE_PERM_ENTRY(DeleteAttach, IMessage),
  340. MAKE_PERM_ENTRY(GetRecipientTable, IMessage),
  341. MAKE_PERM_ENTRY(ModifyRecipients, IMessage),
  342. MAKE_PERM_ENTRY(SubmitMessage, IMessage),
  343. MAKE_PERM_ENTRY(SetReadFlag, IMessage),
  344. /* IABProvider */
  345. MAKE_TEMP_ENTRY(Shutdown, IABProvider),
  346. MAKE_TEMP_ENTRY(Logon, IABProvider),
  347. /* IABLogon */
  348. MAKE_TEMP_ENTRY(GetLastError, IABLogon),
  349. MAKE_TEMP_ENTRY(Logoff, IABLogon),
  350. MAKE_TEMP_ENTRY(OpenEntry, IABLogon),
  351. MAKE_TEMP_ENTRY(CompareEntryIDs, IABLogon),
  352. MAKE_TEMP_ENTRY(Advise, IABLogon),
  353. MAKE_TEMP_ENTRY(Unadvise, IABLogon),
  354. MAKE_TEMP_ENTRY(OpenStatusEntry, IABLogon),
  355. MAKE_TEMP_ENTRY(OpenTemplateID, IABLogon),
  356. MAKE_TEMP_ENTRY(GetOneOffTable, IABLogon),
  357. MAKE_TEMP_ENTRY(PrepareRecips, IABLogon),
  358. /* IXPProvider */
  359. MAKE_TEMP_ENTRY(Shutdown, IXPProvider),
  360. MAKE_TEMP_ENTRY(TransportLogon, IXPProvider),
  361. /* IXPLogon */
  362. MAKE_TEMP_ENTRY(AddressTypes, IXPLogon),
  363. MAKE_TEMP_ENTRY(RegisterOptions, IXPLogon),
  364. MAKE_TEMP_ENTRY(TransportNotify, IXPLogon),
  365. MAKE_TEMP_ENTRY(Idle, IXPLogon),
  366. MAKE_TEMP_ENTRY(TransportLogoff, IXPLogon),
  367. MAKE_TEMP_ENTRY(SubmitMessage, IXPLogon),
  368. MAKE_TEMP_ENTRY(EndMessage, IXPLogon),
  369. MAKE_TEMP_ENTRY(Poll, IXPLogon),
  370. MAKE_TEMP_ENTRY(StartMessage, IXPLogon),
  371. MAKE_TEMP_ENTRY(OpenStatusEntry, IXPLogon),
  372. MAKE_TEMP_ENTRY(ValidateState, IXPLogon),
  373. MAKE_TEMP_ENTRY(FlushQueues, IXPLogon),
  374. /* IMSProvider */
  375. MAKE_TEMP_ENTRY(Shutdown, IMSProvider),
  376. MAKE_TEMP_ENTRY(Logon, IMSProvider),
  377. MAKE_TEMP_ENTRY(SpoolerLogon, IMSProvider),
  378. MAKE_TEMP_ENTRY(CompareStoreIDs, IMSProvider),
  379. /* IMSLogon */
  380. MAKE_TEMP_ENTRY(GetLastError, IMSLogon),
  381. MAKE_TEMP_ENTRY(Logoff, IMSLogon),
  382. MAKE_TEMP_ENTRY(OpenEntry, IMSLogon),
  383. MAKE_TEMP_ENTRY(CompareEntryIDs, IMSLogon),
  384. MAKE_TEMP_ENTRY(Advise, IMSLogon),
  385. MAKE_TEMP_ENTRY(Unadvise, IMSLogon),
  386. MAKE_TEMP_ENTRY(OpenStatusEntry, IMSLogon),
  387. /* IMAPIControl */
  388. MAKE_PERM_ENTRY(GetLastError, IMAPIControl),
  389. MAKE_PERM_ENTRY(Activate, IMAPIControl),
  390. MAKE_PERM_ENTRY(GetState, IMAPIControl),
  391. /* IMAPIStatus */
  392. MAKE_PERM_ENTRY(ValidateState, IMAPIStatus),
  393. MAKE_PERM_ENTRY(SettingsDialog, IMAPIStatus),
  394. MAKE_PERM_ENTRY(ChangePassword, IMAPIStatus),
  395. MAKE_PERM_ENTRY(FlushQueues, IMAPIStatus),
  396. #endif
  397. /* IStream */
  398. MAKE_PERM_ENTRY(Read, IStream),
  399. MAKE_PERM_ENTRY(Write, IStream),
  400. MAKE_PERM_ENTRY(Seek, IStream),
  401. MAKE_PERM_ENTRY(SetSize, IStream),
  402. MAKE_PERM_ENTRY(CopyTo, IStream),
  403. MAKE_PERM_ENTRY(Commit, IStream),
  404. MAKE_PERM_ENTRY(Revert, IStream),
  405. MAKE_PERM_ENTRY(LockRegion, IStream),
  406. MAKE_PERM_ENTRY(UnlockRegion, IStream),
  407. MAKE_PERM_ENTRY(Stat, IStream),
  408. MAKE_PERM_ENTRY(Clone, IStream),
  409. /* IMAPIAdviseSink */
  410. MAKE_PERM_ENTRY(OnNotify, IMAPIAdviseSink),
  411. /* IMAPIProp */
  412. MAKE_PERM_ENTRY(GetLastError, IWABObject),
  413. MAKE_PERM_ENTRY(AllocateBuffer, IWABObject),
  414. MAKE_PERM_ENTRY(AllocateMore, IWABObject),
  415. MAKE_PERM_ENTRY(FreeBuffer, IWABObject),
  416. MAKE_PERM_ENTRY(Backup, IWABObject),
  417. MAKE_PERM_ENTRY(Import, IWABObject),
  418. };
  419. /* Internal utility functions */
  420. #define TAGS_FROM_GET 0x0001 // GetProps
  421. #define TAGS_FROM_SET 0x0002 // SetProps
  422. #define TAGS_FROM_DEL 0x0004 // DeleteProps
  423. #define TAGS_FROM_OPEN 0x0008 // OpenProperty
  424. #define TAGS_FROM_COPY 0x0010 // CopyProps / CopyTo
  425. #define TAGS_FROM_PREP 0x0020 // PrepareRecips
  426. #define TAGS_FROM_SETCOLS 0x0040 // SetColumns
  427. #define TAGS_FROM_ANY 0x0080 // Anything
  428. #define TAGS_FROM_MODRECIP 0x0100 // ModifyRecips
  429. #define TAGS_FROM_RESOLVE 0x0200 // ResolveNames
  430. #define TAGS_FROM_RESTRICT 0x0400 // Restrict
  431. #define TAGS_FROM_NAMEIDS 0x0800 // GetNamesFromIds
  432. static BOOL NEAR FInvalidPTA(UINT uiFlags, LPSPropTagArray lpPTA);
  433. static BOOL NEAR FInvalidPropTags(UINT uiFlags, ULONG ctags, ULONG FAR *pargtags);
  434. static BOOL NEAR FInvalidPvals(UINT uiFlags, ULONG cvals, LPSPropValue pvals);
  435. static BOOL NEAR FBadRgLPMAPINAMEID(ULONG cNames, LPMAPINAMEID *ppNames);
  436. static BOOL NEAR IsBadRestriction(UINT cDepth, LPSRestriction lpRes, BOOL FAR * lpfTooComplex);
  437. static BOOL NEAR IsBadEntryList(LPENTRYLIST lpEntryList);
  438. static BOOL NEAR IsBadSortOrderSet(LPSSortOrderSet lpsos);
  439. static BOOL NEAR IsBadAdrListMR(LPADRLIST pal, ULONG ulFlags);
  440. static BOOL NEAR IsBadAdrEntryMR(LPADRENTRY pae, ULONG ulFlags, UINT iEnt);
  441. static BOOL NEAR IsBadMAPIEntryID(ULONG ulcbEntryID, LPENTRYID lpEntryID);
  442. static BOOL NEAR IsBadABEntryList(LPENTRYLIST lpentrylist);
  443. #define FBadMsgList(lpMsgList) IsBadEntryList(lpMsgList)
  444. #ifdef DEBUG
  445. TCHAR BASED_CODE szStackFrame[] = TEXT("Alleged stack frame is not readable!");
  446. TCHAR BASED_CODE szRowId[] = TEXT("PR_ROWID");
  447. TCHAR BASED_CODE szDispName[] = TEXT("PR_DISPLAY_NAME");
  448. TCHAR BASED_CODE szRecipType[] = TEXT("PR_RECIPIENT_TYPE");
  449. #endif
  450. /*
  451. * Parameter validation dispatch functions
  452. *
  453. * Determine what validation routine to call, get the parameters, call the routine
  454. *
  455. * This function is PASCAL to make the callers setup smaller.
  456. */
  457. /* Disable the 'Segment lost in conversion' warning for ppThis */
  458. #pragma warning(disable:4759)
  459. #define MAX_VAL sizeof(hrResultTable) / sizeof(hrResultTable[0])
  460. #define MAX_ARG 16
  461. HRESULT BASED_CODE hrResultTable[] =
  462. {
  463. hrSuccess,
  464. ResultFromScode(MAPI_E_INVALID_PARAMETER),
  465. ResultFromScode(MAPI_E_UNKNOWN_FLAGS),
  466. ResultFromScode(MAPI_E_TOO_COMPLEX),
  467. ResultFromScode(STG_E_INVALIDPARAMETER)
  468. };
  469. #ifdef _X86_
  470. #ifdef WIN16
  471. HRESULT PASCAL HrValidateParameters( METHODS eMethod, LPVOID FAR *ppFirstArg )
  472. {
  473. #if 0 // Error for WIN16. Just return 0.
  474. __segment segMT = (__segment)((ULONG)meMethodTable >> 16);
  475. __segment segRT = (__segment)((ULONG)hrResultTable >> 16);
  476. METHODENTRY __based(segMT) * pme = (METHODENTRY __based(segMT) *)meMethodTable;
  477. HRESULT __based(segRT) * phr = (HRESULT __based(segRT) *)hrResultTable;
  478. int wResult;
  479. AssertSz(!IsBadReadPtr((LPBYTE) ppFirstArg - sizeof(void FAR *), pme[eMethod].cParameterSize), szStackFrame);
  480. wResult = pme[eMethod].pfnValidation((void BASED_STACK *) ((LPBYTE) ppFirstArg - sizeof(void FAR *)));
  481. Assert((wResult >= 0) && (wResult < MAX_VAL));
  482. return(phr[wResult]);
  483. #else
  484. return 0;
  485. #endif
  486. }
  487. #else
  488. STDAPI HrValidateParameters( METHODS eMethod, LPVOID FAR *ppFirstArg )
  489. {
  490. int wResult;
  491. AssertSz(!IsBadReadPtr((LPBYTE) ppFirstArg - sizeof(void FAR *), meMethodTable[eMethod].cParameterSize), szStackFrame);
  492. wResult = meMethodTable[eMethod].pfnValidation((void BASED_STACK *) ((LPBYTE) ppFirstArg - sizeof(void FAR *)));
  493. Assert((wResult >= 0) && (wResult < MAX_VAL));
  494. return(hrResultTable[wResult]);
  495. }
  496. #endif /* WIN16 */
  497. #else /* !_INTEL_ */
  498. // $MAC - We need to pick up Mac specific functions, these do not work
  499. #ifndef MAC
  500. #define FSPECIALMETHOD(m) ( m == IStream_Seek \
  501. || m == IStream_SetSize \
  502. || m == IStream_CopyTo \
  503. || m == IStream_LockRegion \
  504. || m == IStream_UnlockRegion \
  505. )
  506. static void GetArguments(METHODS eMethod, va_list arglist, LPVOID *rgArg)
  507. {
  508. // Handle methods whose arguments can be of a size other than that of
  509. // an LPVOID. Each argument is grabbed off of the list and laid out
  510. // into the validation structure for the method overlayed on top of
  511. // the argument buffer passed in.
  512. AssertSz(FIsAligned(rgArg), TEXT("GetArguments: Unaligned argument buffer passed in"));
  513. switch( eMethod )
  514. {
  515. case IStream_Seek:
  516. {
  517. LPIStream_Seek_Params p = (LPIStream_Seek_Params) rgArg;
  518. p->This = va_arg(arglist, LPVOID);
  519. p->dlibMove = va_arg(arglist, LARGE_INTEGER);
  520. p->dwOrigin = va_arg(arglist, DWORD);
  521. p->plibNewPosition = va_arg(arglist, ULARGE_INTEGER FAR *);
  522. AssertSz( (MAX_ARG * sizeof(LPVOID)) >= ( (p+1) - p ),
  523. TEXT("Method being validated overflowed argument buffer"));
  524. break;
  525. }
  526. case IStream_SetSize:
  527. {
  528. LPIStream_SetSize_Params p = (LPIStream_SetSize_Params) rgArg;
  529. p->This = va_arg(arglist, LPVOID);
  530. p->libNewSize = va_arg(arglist, ULARGE_INTEGER);
  531. AssertSz( (MAX_ARG * sizeof(LPVOID)) >= ( (p+1) - p ),
  532. TEXT("Method being validated overflowed argument buffer"));
  533. break;
  534. }
  535. case IStream_CopyTo:
  536. {
  537. LPIStream_CopyTo_Params p = (LPIStream_CopyTo_Params) rgArg;
  538. p->This = va_arg(arglist, LPVOID);
  539. p->pstm = va_arg(arglist, IStream FAR *);
  540. p->cb = va_arg(arglist, ULARGE_INTEGER);
  541. p->pcbRead = va_arg(arglist, ULARGE_INTEGER FAR *);
  542. p->pcbWritten = va_arg(arglist, ULARGE_INTEGER FAR *);
  543. AssertSz( (MAX_ARG * sizeof(LPVOID)) >= ( (p+1) - p ),
  544. TEXT("Method being validated overflowed argument buffer"));
  545. break;
  546. }
  547. case IStream_LockRegion:
  548. {
  549. LPIStream_LockRegion_Params p = (LPIStream_LockRegion_Params) rgArg;
  550. p->This = va_arg(arglist, LPVOID);
  551. p->libOffset = va_arg(arglist, ULARGE_INTEGER);
  552. p->cb = va_arg(arglist, ULARGE_INTEGER);
  553. p->dwLockType = va_arg(arglist, DWORD);
  554. AssertSz( (MAX_ARG * sizeof(LPVOID)) >= ( (p+1) - p ),
  555. TEXT("Method being validated overflowed argument buffer"));
  556. break;
  557. }
  558. case IStream_UnlockRegion:
  559. {
  560. LPIStream_UnlockRegion_Params p = (LPIStream_UnlockRegion_Params) rgArg;
  561. p->This = va_arg(arglist, LPVOID);
  562. p->libOffset = va_arg(arglist, ULARGE_INTEGER);
  563. p->cb = va_arg(arglist, ULARGE_INTEGER);
  564. p->dwLockType = va_arg(arglist, DWORD);
  565. AssertSz( (MAX_ARG * sizeof(LPVOID)) >= ( (p+1) - p ),
  566. TEXT("Method being validated overflowed argument buffer"));
  567. break;
  568. }
  569. default:
  570. AssertSz(FALSE, TEXT("Custom argument handling for call being validated NYI"));
  571. break;
  572. }
  573. }
  574. STDAPIV HrValidateParametersV( METHODS eMethod, ... )
  575. {
  576. int wResult;
  577. LPVOID rgArg[MAX_ARG+1]; // +1 is so we can align the beginning
  578. LPVOID *pvarg;
  579. va_list arglist;
  580. // We construct an argument buffer that has all the arguments laid out
  581. // contiguously.
  582. va_start(arglist, eMethod);
  583. // Most of the methods have all arguments the size of LPVOID, so we
  584. // can get all the arguments the same way. Methods that are exceptions
  585. // are detected using a macro and handled using a special function.
  586. // This way the most common cases are handled efficiently.
  587. //
  588. // NOTE: An alternative is to export separate entry points for these
  589. // special methods and have the validation macros call directly into
  590. // them, thus eliminating the need to detect the special case here.
  591. //
  592. if (FSPECIALMETHOD(eMethod))
  593. {
  594. // Since some of the argumentas can be larger than 4 bytes, align
  595. // the argument buffer.
  596. pvarg = (LPVOID *) AlignNatural((ULONG_PTR)((LPVOID)rgArg));
  597. GetArguments(eMethod, arglist, pvarg);
  598. }
  599. else
  600. {
  601. // All arguments in this method are the size of an LPVOID.
  602. // Look up the method table to compute the number of arguments,
  603. // then get each one into our local buffer.
  604. //
  605. UINT cArgs = meMethodTable[eMethod].cParameterSize / sizeof(LPVOID);
  606. AssertSz(cArgs <= MAX_ARG,
  607. TEXT("Method being validated has more arguments than current maximum"));
  608. for ( pvarg = rgArg; cArgs; cArgs--, pvarg++ )
  609. {
  610. *pvarg = va_arg(arglist, LPVOID);
  611. }
  612. // Reset argument pointer to beginning for passing to
  613. // validation routine.
  614. //
  615. pvarg = rgArg;
  616. }
  617. wResult = meMethodTable[eMethod].pfnValidation((void BASED_STACK *) pvarg);
  618. Assert((wResult >= 0) && (wResult < MAX_VAL));
  619. va_end(arglist);
  620. return(hrResultTable[wResult]);
  621. }
  622. STDAPIV HrValidateParametersValist( METHODS eMethod, va_list arglist )
  623. {
  624. int wResult;
  625. LPVOID rgArg[MAX_ARG+1]; // +1 is so we can align the beginning
  626. LPVOID *pvarg;
  627. // We construct an argument buffer that has all the arguments laid out
  628. // contiguously. va_start must have been called by caller and caller will
  629. // call va_end as well.
  630. // Most of the methods have all arguments the size of LPVOID, so we
  631. // can get all the arguments the same way. Methods that are exceptions
  632. // are detected using a macro and handled using a special function.
  633. // This way the most common cases are handled efficiently.
  634. //
  635. // NOTE: An alternative is to export separate entry points for these
  636. // special methods and have the validation macros call directly into
  637. // them, thus eliminating the need to detect the special case here.
  638. //
  639. if (FSPECIALMETHOD(eMethod))
  640. {
  641. // Since some of the argumentas can be larger than 4 bytes, align
  642. // the argument buffer.
  643. pvarg = (LPVOID *) AlignNatural((ULONG_PTR)((LPVOID)rgArg));
  644. GetArguments(eMethod, arglist, pvarg);
  645. }
  646. else
  647. {
  648. // All arguments in this method are the size of an LPVOID.
  649. // Look up the method table to compute the number of arguments,
  650. // then get each one into our local buffer.
  651. //
  652. UINT cArgs = meMethodTable[eMethod].cParameterSize / sizeof(LPVOID);
  653. AssertSz(cArgs <= MAX_ARG,
  654. TEXT("Method being validated has more arguments than current maximum"));
  655. for ( pvarg = rgArg; cArgs; cArgs--, pvarg++ )
  656. {
  657. *pvarg = va_arg(arglist, LPVOID);
  658. }
  659. // Reset argument pointer to beginning for passing to
  660. // validation routine.
  661. //
  662. pvarg = rgArg;
  663. }
  664. wResult = meMethodTable[eMethod].pfnValidation((void BASED_STACK *) pvarg);
  665. Assert((wResult >= 0) && (wResult < MAX_VAL));
  666. return(hrResultTable[wResult]);
  667. }
  668. #endif // !MAC
  669. #endif /* _INTEL_ */
  670. /*
  671. * Obsolete Validation Functions - Valid for X86 only
  672. * Must be kept for backward compatibility.
  673. */
  674. #ifdef WIN16
  675. HRESULT PASCAL __ValidateParameters(METHODS eMethod, void FAR *ppThis)
  676. {
  677. __segment segMT = (__segment)((ULONG)meMethodTable >> 16);
  678. __segment segRT = (__segment)((ULONG)hrResultTable >> 16);
  679. METHODENTRY __based(segMT) * pme = (METHODENTRY __based(segMT) *)meMethodTable;
  680. HRESULT __based(segRT) * phr = (HRESULT __based(segRT) *)hrResultTable;
  681. int wResult;
  682. AssertSz(!IsBadReadPtr(ppThis, pme[eMethod].cParameterSize), szStackFrame);
  683. wResult = pme[eMethod].pfnValidation((void BASED_STACK *) ppThis);
  684. Assert((wResult >= 0) && (wResult < MAX_VAL));
  685. return(phr[wResult]);
  686. }
  687. /* C++ validation, using the first parameter, not the This pointer */
  688. HRESULT PASCAL __CPPValidateParameters(METHODS eMethod, const void FAR *ppFirst)
  689. {
  690. __segment segMT = (__segment)((ULONG)meMethodTable >> 16);
  691. __segment segRT = (__segment)((ULONG)hrResultTable >> 16);
  692. METHODENTRY __based(segMT) * pme = (METHODENTRY __based(segMT) *)meMethodTable;
  693. HRESULT __based(segRT) * phr = (HRESULT __based(segRT) *)hrResultTable;
  694. int wResult;
  695. AssertSz(!IsBadReadPtr((LPBYTE) ppFirst - sizeof(void FAR *), pme[eMethod].cParameterSize), szStackFrame);
  696. wResult = pme[eMethod].pfnValidation((void BASED_STACK *) ((LPBYTE) ppFirst - sizeof(void FAR *)));
  697. Assert((wResult >= 0) && (wResult < MAX_VAL));
  698. return(phr[wResult]);
  699. }
  700. #else
  701. HRESULT STDAPICALLTYPE __ValidateParameters(METHODS eMethod, void *ppThis)
  702. {
  703. #if defined(_AMD64_) || defined(_IA64_)
  704. return 0;
  705. #else
  706. int wResult;
  707. AssertSz(!IsBadReadPtr(ppThis, meMethodTable[eMethod].cParameterSize), szStackFrame);
  708. wResult = meMethodTable[eMethod].pfnValidation((void BASED_STACK *) ppThis);
  709. Assert((wResult >= 0) && (wResult < MAX_VAL));
  710. return(hrResultTable[wResult]);
  711. #endif /* _AMD64_ || _IA64_ */
  712. }
  713. HRESULT STDAPICALLTYPE __CPPValidateParameters(METHODS eMethod, void *ppFirst)
  714. {
  715. #if defined(_AMD64_) || defined(_IA64_)
  716. return 0;
  717. #else
  718. int wResult;
  719. AssertSz(!IsBadReadPtr((LPBYTE) ppFirst - sizeof(void FAR *), meMethodTable[eMethod].cParameterSize), szStackFrame);
  720. wResult = meMethodTable[eMethod].pfnValidation((void BASED_STACK *) ((LPBYTE) ppFirst - sizeof(void FAR *)));
  721. Assert((wResult >= 0) && (wResult < MAX_VAL));
  722. return(hrResultTable[wResult]);
  723. #endif /* _AMD64_ || _IA64_ */
  724. }
  725. #endif
  726. #pragma warning(default:4759)
  727. #pragma warning(disable:4102)
  728. /* Common Validation entry and exit code placed in macros to keep source size small,
  729. and ease maintainability
  730. P is passed in as a void BASED_STACK pointer, local p is the real thing.
  731. This is the only way the BASED_STACK would work! Compiler optimizes Ok */
  732. #define START_FUNC(Method, Interface) \
  733. VALIDATE_CALLTYPE I##Interface##_##Method##_Validate(void BASED_STACK *P) \
  734. { int wResult; \
  735. I##Interface##_##Method##_Params BASED_STACK *p = P;
  736. /* Function bodies get inserted here */
  737. #define END_FUNC(Method, Interface) wResult = 0; ret: return(wResult); }
  738. #ifdef WIN16
  739. #define END_FUNC1(Method, Interface) wResult = 0; return(wResult); }
  740. #endif
  741. /* Macros to make common things easier to maintain and keep source size managable */
  742. /* Forward the validation work on to another validation routine */
  743. #define FORWARD_VALIDATE(FullMethod, p) \
  744. wResult = I##FullMethod##_Validate(p); \
  745. if (wResult) goto ret
  746. //#define DO_ASSERT
  747. #ifdef DO_ASSERT
  748. #define OutputString(psz) NFAssertSz(FALSE, psz)
  749. #define OutputString1(psz,a1) NFAssertSz1(FALSE, psz,a1)
  750. #define OutputString2(psz,a1,a2) NFAssertSz2(FALSE, psz,a1,a2)
  751. #define OutputString3(psz,a1,a2,a3) NFAssertSz3(FALSE, psz,a1,a2,a3)
  752. #define OutputString4(psz,a1,a2,a3,a4) NFAssertSz4(FALSE, psz,a1,a2,a3,a4)
  753. #else
  754. #define OutputString(psz) DebugTrace(psz)
  755. #define OutputString1(psz,a1) DebugTrace(psz,a1)
  756. #define OutputString2(psz,a1,a2) DebugTrace(psz,a1,a2)
  757. #define OutputString3(psz,a1,a2,a3) DebugTrace(psz,a1,a2,a3)
  758. #define OutputString4(psz,a1,a2,a3,a4) DebugTrace(psz,a1,a2,a3,a4)
  759. #endif
  760. /* Helper output macros that put strings in a code segment */
  761. #ifdef DEBUG
  762. #define OutputSz(psz) \
  763. { static TCHAR BASED_CODE lpszTemp[] = psz; \
  764. OutputString(lpszTemp); \
  765. }
  766. #define OutputSz1(psz,a1) \
  767. { static TCHAR BASED_CODE lpszTemp[] = psz; \
  768. OutputString1(lpszTemp, a1); \
  769. }
  770. #define OutputSz2(psz,a1,a2) \
  771. { static TCHAR BASED_CODE lpszTemp[] = psz; \
  772. OutputString2(lpszTemp, a1, a2); \
  773. }
  774. #define OutputSz3(psz,a1,a2,a3) \
  775. { static TCHAR BASED_CODE lpszTemp[] = psz; \
  776. OutputString3(lpszTemp, a1, a2, a3); \
  777. }
  778. #define OutputSz4(psz,a1,a2,a3,a4) \
  779. { static TCHAR BASED_CODE lpszTemp[] = psz; \
  780. OutputString4(lpszTemp, a1, a2, a3, a4); \
  781. }
  782. #else
  783. #define OutputSz(psz)
  784. #define OutputSz1(psz,a1)
  785. #define OutputSz2(psz,a1, a2)
  786. #define OutputSz3(psz,a1, a2, a3)
  787. #define OutputSz4(psz,a1, a2, a3, a4)
  788. #endif
  789. #ifdef DEBUG
  790. /* NOTE: The compiler does not remove the static data here when not DEBUG,
  791. so we have to do it for it! */
  792. /* Check the p->ulFlags member, and report errors */
  793. #define CHECK_FLAGS(Method, Flags) \
  794. if (p->ulFlags & ~(Flags)) \
  795. { \
  796. static TCHAR BASED_CODE lpszTemp[] = TEXT(#Method) TEXT(": ~Flags ") TEXT(#Flags) TEXT(" %08lX.\n"); \
  797. OutputString1(lpszTemp, p->ulFlags); \
  798. wResult = 2; \
  799. goto ret; \
  800. }
  801. /* Return, and report, an invalid parameter */
  802. #define INVALID_PARAMETER(Method, Variable, Text) \
  803. { \
  804. static TCHAR BASED_CODE lpszTemp[] = TEXT(#Method) TEXT(": Param '") TEXT(#Variable) TEXT("' - ") Text TEXT(".\n"); \
  805. OutputString(lpszTemp); \
  806. wResult = 1; \
  807. goto ret; \
  808. }
  809. /* Return, and report, an invalid [out] parameter */
  810. #define INVALID_OUT_PARAMETER(Method, Variable, Text) \
  811. { \
  812. static TCHAR BASED_CODE lpszTemp[] = TEXT(#Method) TEXT(": [Out] Param '") TEXT(#Variable) TEXT("' Bad pointer - ") Text TEXT(".\n"); \
  813. OutputString(lpszTemp); \
  814. wResult = 1; \
  815. goto ret; \
  816. }
  817. #define UNKNOWN_FLAGS(Method, Variable, Text) \
  818. { \
  819. static TCHAR BASED_CODE lpszTemp[] = TEXT(#Method) TEXT(": ") TEXT(#Variable) TEXT(" Unknown flags - ") Text TEXT(".\n"); \
  820. OutputString(lpszTemp); \
  821. wResult = 2; \
  822. goto ret; \
  823. }
  824. #define INVALID_STG_PARAMETER(Method, Variable, Text) \
  825. { \
  826. static TCHAR BASED_CODE lpszTemp[] =TEXT(#Method) TEXT(": Param '") TEXT(#Variable) TEXT("' - ") Text TEXT(".\n"); \
  827. OutputString(lpszTemp); \
  828. wResult = 4; \
  829. goto ret; \
  830. }
  831. /* Return, and report, an invalid [out] parameter */
  832. #define INVALID_STG_OUT_PARAMETER(Method, Variable, Text) \
  833. { \
  834. static TCHAR BASED_CODE lpszTemp[] = TEXT(#Method) TEXT(": [Out] Parameter '") TEXT(#Variable) TEXT("' Bad pointer - ") Text TEXT(".\n"); \
  835. OutputString(lpszTemp); \
  836. wResult = 4; \
  837. goto ret; \
  838. }
  839. #else
  840. /* Check the p->ulFlags member, and report errors */
  841. #define CHECK_FLAGS(Method, Flags) \
  842. if (p->ulFlags & ~(Flags)) \
  843. { \
  844. wResult = 2; \
  845. goto ret; \
  846. }
  847. /* Return, and report, an invalid parameter */
  848. #define INVALID_PARAMETER(Method, Variable, Text) \
  849. { \
  850. wResult = 1; \
  851. goto ret; \
  852. }
  853. /* Return, and report, an invalid [out] parameter */
  854. #define INVALID_OUT_PARAMETER(Method, Variable, Text) \
  855. { \
  856. wResult = 1; \
  857. goto ret; \
  858. }
  859. #define UNKNOWN_FLAGS(Method, Variable, Text) \
  860. { \
  861. wResult = 2; \
  862. goto ret; \
  863. }
  864. #define INVALID_STG_PARAMETER(Method, Variable, Text) \
  865. { \
  866. wResult = 4; \
  867. goto ret; \
  868. }
  869. /* Return, and report, an invalid [out] parameter */
  870. #define INVALID_STG_OUT_PARAMETER(Method, Variable, Text) \
  871. { \
  872. wResult = 4; \
  873. goto ret; \
  874. }
  875. #endif // DEBUG
  876. #define IsBadIfacePtr(param, iface) \
  877. (IsBadReadPtr((param), sizeof(iface)) \
  878. || IsBadReadPtr((param)->lpVtbl, sizeof(iface##Vtbl)))
  879. /* For those functions that are meant to do nothing */
  880. #define DO_NOTHING wResult = 0; goto ret
  881. /* Inline functions */
  882. /* Validation Routines */
  883. #ifndef DEBUG
  884. VALIDATE_CALLTYPE DoNothing_Validate(void BASED_STACK *P)
  885. {
  886. return(0);
  887. }
  888. #endif
  889. /* IUnknown */
  890. START_FUNC(QueryInterface, Unknown)
  891. if (IsBadWritePtr(p->lppNewObject, sizeof(LPVOID)))
  892. INVALID_OUT_PARAMETER(Unknown_QueryInterface, NewObject, TEXT(""));
  893. /* If the pointer is valid, we MUST set to NULL if there is an error later,
  894. better do it now */
  895. *(LPVOID *)p->lppNewObject = NULL;
  896. if (IsBadReadPtr(p->iidInterface, sizeof(IID)))
  897. INVALID_PARAMETER(Unknown_QueryInterface, Interface, TEXT("Bad pointer"));
  898. END_FUNC(QueryInterface, Unknown)
  899. START_FUNC(AddRef, Unknown)
  900. DO_NOTHING;
  901. END_FUNC(AddRef, Unknown)
  902. START_FUNC(Release, Unknown)
  903. DO_NOTHING;
  904. END_FUNC(Release, Unknown)
  905. /* IMAPIProp */
  906. START_FUNC(GetLastError, MAPIProp)
  907. if (!p->lppMAPIError || IsBadWritePtr(p->lppMAPIError, sizeof(LPMAPIERROR)))
  908. INVALID_OUT_PARAMETER(MAPIProp_GetLastError, MAPIError, TEXT(""));
  909. CHECK_FLAGS(MAPIProp_GetLastError, MAPI_UNICODE);
  910. END_FUNC(GetLastError, MAPIProp)
  911. START_FUNC(SaveChanges, MAPIProp)
  912. CHECK_FLAGS(MAPIProp_SaveChanges, MAPI_DEFERRED_ERRORS | KEEP_OPEN_READONLY | KEEP_OPEN_READWRITE | FORCE_SAVE);
  913. if ((p->ulFlags & KEEP_OPEN_READONLY) &&
  914. (p->ulFlags & KEEP_OPEN_READWRITE))
  915. INVALID_PARAMETER(MAPIProp_SaveChanges, Flags, TEXT("Mutually exclusive flags used"));
  916. END_FUNC(SaveChanges, MAPIProp)
  917. START_FUNC(GetProps, MAPIProp)
  918. if (p->lpPropTagArray && FInvalidPTA(TAGS_FROM_GET, p->lpPropTagArray))
  919. INVALID_PARAMETER(IMAPIProp_GetProps, PropTagArray, TEXT(""));
  920. if (p->lpPropTagArray && p->lpPropTagArray->cValues == 0)
  921. INVALID_PARAMETER(IMAPIProp_GetProps, PropTagArray->cValues, TEXT("Can not be zero"));
  922. if (IsBadWritePtr(p->lpcValues, sizeof(ULONG)))
  923. INVALID_OUT_PARAMETER(IMAPIProp_GetProps, Values, TEXT(""));
  924. if (IsBadWritePtr(p->lppPropArray, sizeof(LPSPropValue)))
  925. INVALID_OUT_PARAMETER(IMAPIProp_GetProps, PropArray, TEXT(""));
  926. CHECK_FLAGS(MAPIProp_GetProps, MAPI_UNICODE);
  927. END_FUNC(GetProps, MAPIProp)
  928. START_FUNC(GetPropList, MAPIProp)
  929. if (IsBadWritePtr(p->lppPropTagArray, sizeof(LPSPropTagArray)))
  930. INVALID_OUT_PARAMETER(IMAPIProp_GetPropList, PropTagArray, TEXT(""));
  931. CHECK_FLAGS(MAPIProp_GetPropList, MAPI_UNICODE);
  932. END_FUNC(GetPropList, MAPIProp)
  933. START_FUNC(OpenProperty, MAPIProp)
  934. if (IsBadWritePtr(p->lppUnk, sizeof(LPUNKNOWN)))
  935. INVALID_OUT_PARAMETER(MAPIProp_OpenProperty, Unk, TEXT(""));
  936. if (IsBadReadPtr(p->lpiid, (UINT) sizeof(IID)))
  937. INVALID_PARAMETER(MAPIProp_OpenProperty, iid, TEXT("Bad pointer"));
  938. if (FInvalidPropTags(TAGS_FROM_OPEN, 1, &p->ulPropTag))
  939. INVALID_PARAMETER(MAPIProp_OpenProperty, PropTag, TEXT("PropTag for property to open is bad"));
  940. CHECK_FLAGS(MAPIProp_OpenProperty, MAPI_CREATE | MAPI_MODIFY | MAPI_DEFERRED_ERRORS | STREAM_APPEND);
  941. if ((p->ulFlags & (MAPI_CREATE | MAPI_MODIFY)) == MAPI_CREATE)
  942. INVALID_PARAMETER(MAPIProp_OpenProperty, Flags, TEXT("MAPI_MODIFY must be specified on Create"));
  943. END_FUNC(OpenProperty, MAPIProp)
  944. START_FUNC(SetProps, MAPIProp)
  945. if (FInvalidPvals(TAGS_FROM_SET, p->cValues, p->lpPropArray))
  946. INVALID_PARAMETER(MAPIProp_SetProps, PropValArray, TEXT(""));
  947. if (p->lppProblems && IsBadWritePtr(p->lppProblems, sizeof(LPSPropProblemArray)))
  948. INVALID_OUT_PARAMETER(MAPIProp_SetProps, Problems, TEXT(""));
  949. END_FUNC(SetProps, MAPIProp)
  950. START_FUNC(DeleteProps, MAPIProp)
  951. if (FInvalidPTA(TAGS_FROM_DEL, p->lpPropTagArray))
  952. INVALID_PARAMETER(MAPIProp_DeleteProps, PropTagArray, TEXT(""));
  953. if (p->lpPropTagArray->cValues == 0)
  954. INVALID_PARAMETER(MAPIProp_DeleteProps, PropTagArray, TEXT("Property count of zero"));
  955. if (p->lppProblems && IsBadWritePtr(p->lppProblems, sizeof(LPSPropProblemArray)))
  956. INVALID_OUT_PARAMETER(MAPIProp_DeleteProps, Problems, TEXT(""));
  957. END_FUNC(DeleteProps, MAPIProp)
  958. START_FUNC(CopyTo, MAPIProp)
  959. if (p->lppProblems && IsBadWritePtr(p->lppProblems, sizeof(LPSPropProblemArray)))
  960. INVALID_OUT_PARAMETER(MAPIProp_CopyTo, Problems, TEXT(""));
  961. if (p->lpExcludeProps && FInvalidPTA(TAGS_FROM_COPY, p->lpExcludeProps))
  962. INVALID_PARAMETER(MAPIProp_CopyTo, ExcludeProps, TEXT(""));
  963. if (IsBadReadPtr(p->lpInterface, sizeof(IID)))
  964. INVALID_PARAMETER(MAPIProp_CopyTo, Interface, TEXT("Not readable"));
  965. if (IsBadIfacePtr((LPMAPIPROP) p->lpDestObj, IMAPIProp))
  966. INVALID_PARAMETER(MAPIProp_CopyTo, DestObj, TEXT("Not readable"));
  967. if (p->ciidExclude)
  968. {
  969. if (p->ciidExclude > (UINT_MAX / sizeof(IID)))
  970. INVALID_PARAMETER(MAPIProp_CopyTo, ciidExclude, TEXT("Incorrect size"));
  971. if (IsBadReadPtr(p->rgiidExclude, (UINT)(p->ciidExclude * sizeof(IID))))
  972. INVALID_PARAMETER(MAPIProp_CopyTo, rgiidExclude, TEXT("Not readable"));
  973. }
  974. CHECK_FLAGS(MAPIProp_CopyTo, MAPI_MOVE | MAPI_NOREPLACE | MAPI_DECLINE_OK | MAPI_DIALOG);
  975. // Validate lpProgress and ulUIParam only if MAPI_DIALOG is set.
  976. if ( p->ulFlags & MAPI_DIALOG )
  977. {
  978. if ( p->lpProgress && IsBadIfacePtr(p->lpProgress, IMAPIProgress))
  979. INVALID_PARAMETER(MAPIProp_CopyTo, lpProgress, TEXT("bad address"));
  980. // only validate ulUIParam if lpProgress is NULL.
  981. if ( !p->lpProgress && p->ulUIParam && !IsWindow ((HWND)IntToPtr(p->ulUIParam)))
  982. INVALID_PARAMETER(MAPIProp_CopyTo, ulUIParam, TEXT("bad window"));
  983. }
  984. END_FUNC(CopyTo, MAPIProp)
  985. START_FUNC(CopyProps, MAPIProp)
  986. if (!p->lpIncludeProps || FInvalidPTA(TAGS_FROM_COPY, p->lpIncludeProps))
  987. INVALID_PARAMETER(MAPIProp_CopyProps, IncludeProps, TEXT(""));
  988. if (p->lpProgress && IsBadIfacePtr(p->lpProgress, IMAPIProgress))
  989. INVALID_PARAMETER(MAPIProp_CopyProps, Progress, TEXT("Bad interface"));
  990. if (p->lpInterface && IsBadReadPtr(p->lpInterface, sizeof(IID)))
  991. INVALID_PARAMETER(MAPIProp_CopyProps, Interface, TEXT("Not readable"));
  992. if (IsBadIfacePtr((LPMAPIPROP) p->lpDestObj, IMAPIProp))
  993. INVALID_PARAMETER(MAPIProp_CopyProps, DestObj, TEXT("Not readable"));
  994. if (p->lppProblems && IsBadWritePtr(p->lppProblems, sizeof(LPSPropProblemArray)))
  995. INVALID_OUT_PARAMETER(MAPIProp_CopyProps, Problems, TEXT(""));
  996. CHECK_FLAGS(MAPIProp_CopyProps, MAPI_MOVE | MAPI_NOREPLACE | MAPI_DIALOG | MAPI_DECLINE_OK);
  997. // Validate lpProgress and ulUIParam only if MAPI_DIALOG is set.
  998. if ( p->ulFlags & MAPI_DIALOG )
  999. {
  1000. if ( p->lpProgress && IsBadIfacePtr(p->lpProgress, IMAPIProgress))
  1001. INVALID_PARAMETER(MAPIProp_CopyProps, lpProgress, TEXT("bad address"));
  1002. // only validate ulUIParam if lpProgress is NULL.
  1003. if ( !p->lpProgress && p->ulUIParam && !IsWindow ((HWND)IntToPtr(p->ulUIParam)))
  1004. INVALID_PARAMETER(MAPIProp_CopyProps, ulUIParam, TEXT("bad window"));
  1005. }
  1006. END_FUNC(CopyProps, MAPIProp)
  1007. START_FUNC(GetNamesFromIDs, MAPIProp)
  1008. if (IsBadReadPtr(p->lppPropTags, sizeof(LPSPropTagArray)))
  1009. INVALID_PARAMETER(MAPIProp_GetNamesFromIDs, pPropTags, TEXT("Not readable"));
  1010. if (*(p->lppPropTags) == 0 && IsBadWritePtr(p->lppPropTags, sizeof(LPSPropTagArray)))
  1011. INVALID_PARAMETER(MAPIProp_GetNamesFromIDs, PropTags, TEXT("Not writable"));
  1012. if (*(p->lppPropTags) != 0 && FInvalidPTA(TAGS_FROM_NAMEIDS, *(p->lppPropTags)))
  1013. INVALID_PARAMETER(MAPIProp_GetNamesFromIDs, PropTags, TEXT(""));
  1014. if (*(p->lppPropTags) != 0 && (*(p->lppPropTags))->cValues == 0)
  1015. INVALID_PARAMETER(MAPIProp_GetNamesFromIDs, PropTags, TEXT("cValues is 0"));
  1016. if (p->lpPropSetGuid && IsBadReadPtr(p->lpPropSetGuid, sizeof(GUID)))
  1017. INVALID_PARAMETER(MAPIProp_GetNamesFromIDs, PropSetGuid, TEXT("Not readable"));
  1018. if (IsBadWritePtr(p->lpcPropNames, sizeof(ULONG)))
  1019. INVALID_OUT_PARAMETER(MAPIProp_GetNamesFromIDs, pcPropNames, TEXT(""));
  1020. if (IsBadWritePtr(p->lpppPropNames, sizeof(LPMAPINAMEID *)))
  1021. INVALID_OUT_PARAMETER(MAPIProp_GetNamesFromIDs, pppPropNames, TEXT(""));
  1022. CHECK_FLAGS(MAPIProp_GetNamesFromIDs, MAPI_NO_STRINGS | MAPI_NO_IDS);
  1023. END_FUNC(GetNamesFromIDs, MAPIProp)
  1024. START_FUNC(GetIDsFromNames, MAPIProp)
  1025. if (p->lppPropNames && IsBadReadPtr(p->lppPropNames, sizeof(LPMAPINAMEID)))
  1026. INVALID_PARAMETER(MAPIProp_GetIDsFromNames, ppPropNames, TEXT("Not readable"));
  1027. if (p->lppPropNames && FBadRgLPMAPINAMEID(p->cPropNames, p->lppPropNames))
  1028. INVALID_PARAMETER(MAPIProp_GetIDsFromNames, ppPropNames, TEXT("Not valid"));
  1029. if (IsBadWritePtr(p->lppPropTags, sizeof(LPSPropTagArray)))
  1030. INVALID_OUT_PARAMETER(MAPIProp_GetIDsFromNames, PropTags, TEXT(""));
  1031. CHECK_FLAGS(MAPIProp_GetIDsFromNames, MAPI_CREATE);
  1032. END_FUNC(GetIDsFromNames, MAPIProp)
  1033. /* IMAPITable */
  1034. START_FUNC(GetLastError, MAPITable)
  1035. if (!p->lppMAPIError || IsBadWritePtr(p->lppMAPIError, sizeof(LPMAPIERROR)))
  1036. INVALID_OUT_PARAMETER(MAPITable_GetLastError, MAPIError, TEXT(""));
  1037. CHECK_FLAGS(MAPITable_GetLastError, MAPI_UNICODE);
  1038. END_FUNC(GetLastError, MAPITable)
  1039. START_FUNC(Advise, MAPITable)
  1040. if (p->ulEventMask != fnevTableModified)
  1041. INVALID_PARAMETER(MAPITable_Advise, EventMask, TEXT("Different from fnevTableModified"));
  1042. if (IsBadIfacePtr(p->lpAdviseSink, IMAPIAdviseSink))
  1043. INVALID_PARAMETER(MAPITable_Advise, AdviseSink, TEXT("Invalid interface"));
  1044. if (IsBadWritePtr(p->lpulConnection, sizeof(ULONG)))
  1045. INVALID_OUT_PARAMETER(MAPITable_Advise, Connection, TEXT(""));
  1046. END_FUNC(Advise, MAPITable)
  1047. START_FUNC(Unadvise, MAPITable)
  1048. if (p->ulConnection == 0)
  1049. INVALID_PARAMETER(MAPITable_Unadvise, Connection, TEXT("Cannot be zero"));
  1050. END_FUNC(Unadvise, MAPITable)
  1051. START_FUNC(GetStatus, MAPITable)
  1052. if (IsBadWritePtr(p->lpulTableStatus, sizeof(ULONG)))
  1053. INVALID_OUT_PARAMETER(MAPITable_GetStatus, TableStatus, TEXT(""));
  1054. if (IsBadWritePtr(p->lpulTableType, sizeof(ULONG)))
  1055. INVALID_OUT_PARAMETER(MAPITable_GetStatus, TableType, TEXT(""));
  1056. END_FUNC(GetStatus, MAPITable)
  1057. START_FUNC(SetColumns, MAPITable)
  1058. if (FInvalidPTA(TAGS_FROM_SETCOLS, p->lpPropTagArray))
  1059. INVALID_PARAMETER(MAPITable_SetColumns, PropTagArray, TEXT(""));
  1060. if (p->lpPropTagArray->cValues == 0 )
  1061. INVALID_PARAMETER(MAPITable_SetColumns, PropTagArray->cValues, TEXT("Cannot be zero"));
  1062. CHECK_FLAGS(MAPITable_SetColumns, TBL_NOWAIT | TBL_ASYNC | TBL_BATCH);
  1063. END_FUNC(SetColumns, MAPITable)
  1064. START_FUNC(QueryColumns, MAPITable)
  1065. if (IsBadWritePtr(p->lpPropTagArray, sizeof(LPSPropTagArray)))
  1066. INVALID_OUT_PARAMETER(MAPITable_QueryColumns, PropTagArray, TEXT(""));
  1067. CHECK_FLAGS(MAPITable_QueryColumns, TBL_ALL_COLUMNS);
  1068. END_FUNC(QueryColumns, MAPITable)
  1069. START_FUNC(GetRowCount, MAPITable)
  1070. if (IsBadWritePtr(p->lpulCount, sizeof(ULONG)))
  1071. INVALID_OUT_PARAMETER(MAPITable_GetRowCount, Count, TEXT(""));
  1072. CHECK_FLAGS(MAPITable_GetRowCount, TBL_NOWAIT | TBL_BATCH);
  1073. END_FUNC(GetRowCount, MAPITable)
  1074. START_FUNC(SeekRow, MAPITable)
  1075. if (p->lplRowsSought && IsBadWritePtr(p->lplRowsSought, sizeof(LONG)))
  1076. INVALID_OUT_PARAMETER(MAPITable_SeekRow, RowsSought, TEXT(""));
  1077. END_FUNC(SeekRow, MAPITable)
  1078. START_FUNC(SeekRowApprox, MAPITable)
  1079. if (!p->ulDenominator)
  1080. INVALID_PARAMETER(MAPITable_SeekRowApprox, Denominator, TEXT("Cannot be zero"));
  1081. END_FUNC(SeekRowApprox, MAPITable)
  1082. START_FUNC(QueryPosition, MAPITable)
  1083. if (IsBadWritePtr(p->lpulRow, sizeof(ULONG)))
  1084. INVALID_OUT_PARAMETER(MAPITableQueryPosition, Row, TEXT(""));
  1085. if (IsBadWritePtr(p->lpulNumerator, sizeof(ULONG)))
  1086. INVALID_OUT_PARAMETER(MAPITableQueryPosition, Numerator, TEXT(""));
  1087. if (IsBadWritePtr(p->lpulDenominator, sizeof(ULONG)))
  1088. INVALID_OUT_PARAMETER(MAPITableQueryPosition, Denominator, TEXT(""));
  1089. END_FUNC(QueryPosition, MAPITable)
  1090. START_FUNC(FindRow, MAPITable)
  1091. {
  1092. BOOL fTooComplex;
  1093. if (p->lpRestriction == NULL || IsBadRestriction(0, p->lpRestriction, &fTooComplex))
  1094. INVALID_PARAMETER(MAPITable_FindRow, Restriction, TEXT(""));
  1095. if (fTooComplex)
  1096. {
  1097. wResult = 3;
  1098. goto ret;
  1099. }
  1100. }
  1101. CHECK_FLAGS(MAPITable_FindRow, DIR_BACKWARD);
  1102. END_FUNC(FindRow, MAPITable)
  1103. START_FUNC(Restrict, MAPITable)
  1104. {
  1105. BOOL fTooComplex;
  1106. if (IsBadRestriction(0, p->lpRestriction, &fTooComplex))
  1107. INVALID_PARAMETER(MAPITable_Restrict, Restriction, TEXT(""));
  1108. if (fTooComplex)
  1109. {
  1110. wResult = 3;
  1111. goto ret;
  1112. }
  1113. }
  1114. CHECK_FLAGS(MAPITable_Restrict, TBL_NOWAIT | TBL_ASYNC | TBL_BATCH);
  1115. END_FUNC(Restrict, MAPITable)
  1116. START_FUNC(CreateBookmark, MAPITable)
  1117. if (IsBadWritePtr(p->lpbkPosition, sizeof(BOOKMARK)))
  1118. INVALID_OUT_PARAMETER(MAPITable_CreateBookmark, Position, TEXT(""));
  1119. END_FUNC(CreateBookmark, MAPITable)
  1120. START_FUNC(FreeBookmark, MAPITable)
  1121. DO_NOTHING;
  1122. END_FUNC(FreeBookmark, MAPITable)
  1123. START_FUNC(SortTable, MAPITable)
  1124. if (IsBadSortOrderSet(p->lpSortCriteria))
  1125. INVALID_PARAMETER(MAPITable_SortTable, SortCriteria, TEXT("Bad SortOrderSet"));
  1126. CHECK_FLAGS(MAPITable_SortTable, TBL_NOWAIT | TBL_ASYNC | TBL_BATCH);
  1127. END_FUNC(SortTable, MAPITable)
  1128. START_FUNC(QuerySortOrder, MAPITable)
  1129. if (IsBadWritePtr(p->lppSortCriteria, sizeof(LPSSortOrderSet)))
  1130. INVALID_OUT_PARAMETER(MAPITable_QuerySortOrder, SortCriteria, TEXT(""));
  1131. END_FUNC(QuerySortOrder, MAPITable)
  1132. START_FUNC(QueryRows, MAPITable)
  1133. if (IsBadWritePtr(p->lppRows, sizeof(LPSRowSet)))
  1134. INVALID_OUT_PARAMETER(MAPITable_QueryRows, Rows, TEXT(""));
  1135. if (!p->lRowCount)
  1136. INVALID_PARAMETER(MAPITable_QueryRows, RowCount, TEXT("Zero rows not allowed"));
  1137. CHECK_FLAGS(MAPITable_QueryRows, TBL_NOADVANCE);
  1138. END_FUNC(QueryRows, MAPITable)
  1139. START_FUNC(Abort, MAPITable)
  1140. DO_NOTHING;
  1141. END_FUNC(Abort, MAPITable)
  1142. START_FUNC(ExpandRow, MAPITable)
  1143. // if there is a ulRowCount, lppRows may not be NULL
  1144. if (p->ulRowCount && IsBadWritePtr(p->lppRows, sizeof(LPSRowSet)))
  1145. INVALID_OUT_PARAMETER(MAPITable_ExpandRow, Rows, TEXT(""));
  1146. if (p->lpulMoreRows && IsBadWritePtr(p->lpulMoreRows, sizeof(ULONG)))
  1147. INVALID_OUT_PARAMETER(MAPITable_ExpandRow, MoreRows, TEXT(""));
  1148. if (!p->cbInstanceKey)
  1149. INVALID_PARAMETER(MAPITable_ExpandRow, cbInstanceKey, TEXT("is 0 sized"));
  1150. if (!p->pbInstanceKey)
  1151. INVALID_PARAMETER(MAPITable_ExpandRow, pbInstanceKey, TEXT("is NULL"));
  1152. if (p->cbInstanceKey > UINT_MAX)
  1153. INVALID_PARAMETER(MAPITable_ExpandRow, cbInstanceKey, TEXT("Too big"));
  1154. if (IsBadReadPtr(p->pbInstanceKey, (UINT) p->cbInstanceKey))
  1155. INVALID_PARAMETER(MAPITable_ExpandRow, pbInstanceKey, TEXT("Not readable"));
  1156. CHECK_FLAGS(MAPITable_ExpandRow, 0);
  1157. END_FUNC(ExpandRow, MAPITable)
  1158. START_FUNC(CollapseRow, MAPITable)
  1159. if (p->lpulRowCount && IsBadWritePtr(p->lpulRowCount, sizeof(ULONG)))
  1160. INVALID_OUT_PARAMETER(MAPITable_CollapseRow, RowCount, TEXT(""));
  1161. if (!p->cbInstanceKey)
  1162. INVALID_PARAMETER(MAPITable_CollapseRow, cbInstanceKey, TEXT("is 0 sized"));
  1163. if (!p->pbInstanceKey)
  1164. INVALID_PARAMETER(MAPITable_CollapseRow, pbInstanceKey, TEXT("is NULL"));
  1165. if (p->cbInstanceKey > UINT_MAX)
  1166. INVALID_PARAMETER(MAPITable_CollapseRow, cbInstanceKey, TEXT("Too big"));
  1167. if (IsBadReadPtr(p->pbInstanceKey, (UINT) p->cbInstanceKey))
  1168. INVALID_PARAMETER(MAPITable_CollapseRow, pbInstanceKey, TEXT("Not readable"));
  1169. CHECK_FLAGS(MAPITable_CollapseRow, 0);
  1170. END_FUNC(CollapseRow, MAPITable)
  1171. START_FUNC(WaitForCompletion, MAPITable)
  1172. if (p->lpulTableStatus && IsBadWritePtr(p->lpulTableStatus, sizeof(ULONG)))
  1173. INVALID_OUT_PARAMETER(MAPITable_WaitForCompletion, TableStatus, TEXT(""));
  1174. CHECK_FLAGS(MAPITable_WaitForCompletion, 0);
  1175. END_FUNC(WaitForCompletion, MAPITable)
  1176. START_FUNC(GetCollapseState, MAPITable)
  1177. if (IsBadReadPtr(p->lpbInstanceKey, (UINT) p->cbInstanceKey))
  1178. INVALID_PARAMETER(MAPITable_GetCollapseState, InstanceKey, TEXT("Not readable"));
  1179. if (IsBadWritePtr(p->lpcbCollapseState, sizeof(ULONG)))
  1180. INVALID_OUT_PARAMETER(MAPITable_GetCollapseState, cbCollapseState, TEXT(""));
  1181. if (IsBadWritePtr(p->lppbCollapseState, sizeof(LPBYTE)))
  1182. INVALID_OUT_PARAMETER(MAPITable_GetCollapseState, pbCollapseState, TEXT(""));
  1183. CHECK_FLAGS(MAPITable_GetCollapseState, 0);
  1184. END_FUNC(GetCollapseState, MAPITable)
  1185. START_FUNC(SetCollapseState, MAPITable)
  1186. if (IsBadReadPtr(p->pbCollapseState, (UINT) p->cbCollapseState))
  1187. INVALID_PARAMETER(MAPITable_SetCollapseState, CollapseState, TEXT("Not readable"));
  1188. if (IsBadWritePtr(p->lpbkLocation, sizeof(BOOKMARK)))
  1189. INVALID_OUT_PARAMETER(MAPITable_SetCollapseState, Location, TEXT(""));
  1190. CHECK_FLAGS(MAPITable_SetCollapseState, 0);
  1191. END_FUNC(SetCollapseState, MAPITable)
  1192. #ifdef OLD_STUFF
  1193. /* IMAPIStatus */
  1194. START_FUNC(ValidateState, MAPIStatus)
  1195. CHECK_FLAGS(MAPIStatus_ValidateState, SUPPRESS_UI | REFRESH_XP_HEADER_CACHE | PROCESS_XP_HEADER_CACHE |
  1196. ABORT_XP_HEADER_OPERATION | FORCE_XP_CONNECT | FORCE_XP_DISCONNECT |
  1197. CONFIG_CHANGED | SHOW_XP_SESSION_UI);
  1198. // Validate ulUIParam only if SUPPRESS_UI is clear.
  1199. if (!(p->ulFlags & SUPPRESS_UI))
  1200. {
  1201. if (p->ulUIParam && !IsWindow ((HWND)p->ulUIParam))
  1202. INVALID_PARAMETER(MAPIStatus_ValidateState, ulUIParam, TEXT("bad window"));
  1203. }
  1204. END_FUNC(ValidateState, MAPIStatus)
  1205. START_FUNC(SettingsDialog, MAPIStatus)
  1206. CHECK_FLAGS(MAPIStatus_SettingsDialog, UI_READONLY);
  1207. if (p->ulUIParam && !IsWindow ((HWND)p->ulUIParam))
  1208. INVALID_PARAMETER(MAPIStatus_SettingsDialog, ulUIParam, TEXT("bad window"));
  1209. END_FUNC(SettingsDialog, MAPIStatus)
  1210. START_FUNC(ChangePassword, MAPIStatus)
  1211. if (IsBadStringPtr(p->lpOldPass, (UINT)-1))
  1212. INVALID_PARAMETER(MAPIStatus_ChangePassword, OldPass, TEXT("Bad string"));
  1213. if (IsBadStringPtr(p->lpNewPass, (UINT)-1))
  1214. INVALID_PARAMETER(MAPIStatus_ChangePassword, NewPass, TEXT("Bad string"));
  1215. CHECK_FLAGS(MAPIStatus_ChangePassword, MAPI_UNICODE);
  1216. END_FUNC(ChangePassword, MAPIStatus)
  1217. START_FUNC(FlushQueues, MAPIStatus)
  1218. if (p->cbTargetTransport && (p->cbTargetTransport < (ULONG) sizeof (ENTRYID)))
  1219. INVALID_PARAMETER(MAPIStatus_FlushQueues, cbTargetTransport, TEXT("Incorrect length"));
  1220. if (IsBadReadPtr(p->lpTargetTransport, (UINT) p->cbTargetTransport))
  1221. INVALID_PARAMETER(MAPIStatus_FlushQueues, lpTargetTransport, TEXT("Not readable"));
  1222. CHECK_FLAGS(MAPIStatus_FlushQueues, FLUSH_NO_UI | FLUSH_UPLOAD | FLUSH_DOWNLOAD |
  1223. FLUSH_FORCE | FLUSH_ASYNC_OK);
  1224. // Validate ulUIParam only if FLUSH_NO_UI is clear.
  1225. if (!(p->ulFlags & FLUSH_NO_UI))
  1226. {
  1227. if (p->ulUIParam && !IsWindow ((HWND)p->ulUIParam))
  1228. INVALID_PARAMETER(MAPIStatus_FlushQueues, ulUIParam, TEXT("bad window"));
  1229. }
  1230. END_FUNC(FlushQueues, MAPIStatus)
  1231. #endif // OLD_STUFF
  1232. /* IMAPIContainer */
  1233. START_FUNC(GetContentsTable, MAPIContainer)
  1234. if (IsBadWritePtr(p->lppTable, sizeof(LPMAPITABLE)))
  1235. INVALID_OUT_PARAMETER(MAPIContainer_GetContentsTable, lppTable, TEXT(""));
  1236. CHECK_FLAGS(MAPIContainer_GetContentsTable, MAPI_DEFERRED_ERRORS | MAPI_ASSOCIATED | MAPI_UNICODE);
  1237. END_FUNC(GetContentsTable, MAPIContainer)
  1238. START_FUNC(GetHierarchyTable, MAPIContainer)
  1239. if (IsBadWritePtr(p->lppTable, sizeof(LPMAPITABLE)))
  1240. INVALID_OUT_PARAMETER(MAPIContainer_GetHierarchyTable, lppTable, TEXT(""));
  1241. CHECK_FLAGS(MAPIContainer_GetHierarchyTable, MAPI_DEFERRED_ERRORS | CONVENIENT_DEPTH | MAPI_UNICODE);
  1242. END_FUNC(GetHierarchyTable, MAPIContainer)
  1243. START_FUNC(OpenEntry, MAPIContainer)
  1244. if (p->cbEntryID > UINT_MAX)
  1245. INVALID_PARAMETER(MAPIContainer_OpenEntry, cbEntryID, TEXT("Too big"));
  1246. if (p->cbEntryID && !p->lpEntryID)
  1247. INVALID_PARAMETER(MAPIContainer_OpenEntry, EntryID, TEXT("EntryID is NULL, count not 0"));
  1248. if (p->cbEntryID && (p->cbEntryID < (ULONG) sizeof(ENTRYID)))
  1249. INVALID_PARAMETER(MAPIContainer_OpenEntry, cbEntryID, TEXT("Count too small for EntryID"));
  1250. if (p->cbEntryID && IsBadReadPtr(p->lpEntryID, (UINT) p->cbEntryID))
  1251. INVALID_PARAMETER(MAPIContainer_OpenEntry, EntryID, TEXT("Cannot read EntryID"));
  1252. if (p->lpInterface && IsBadReadPtr(p->lpInterface, sizeof(IID)))
  1253. INVALID_PARAMETER(MAPIContainer_OpenEntry, Interface, TEXT("Interface not readable"));
  1254. if (IsBadWritePtr(p->lpulObjType, sizeof(ULONG)))
  1255. INVALID_OUT_PARAMETER(MAPIContainer_OpenEntry, ObjType, TEXT(""));
  1256. if (IsBadWritePtr(p->lppUnk, sizeof(LPUNKNOWN)))
  1257. INVALID_OUT_PARAMETER(MAPIContainer_OpenEntry, Unk, TEXT(""));
  1258. CHECK_FLAGS(MAPIContainer_OpenEntry, MAPI_MODIFY | MAPI_DEFERRED_ERRORS | MAPI_BEST_ACCESS);
  1259. END_FUNC(OpenEntry, MAPIContainer)
  1260. START_FUNC(SetSearchCriteria, MAPIContainer)
  1261. {
  1262. BOOL fTooComplex;
  1263. if (IsBadRestriction(0, p->lpRestriction, &fTooComplex))
  1264. INVALID_PARAMETER(MAPIContainer_SetSearchCriteria, Restriction, TEXT(""));
  1265. if (fTooComplex)
  1266. {
  1267. wResult = 3;
  1268. goto ret;
  1269. }
  1270. }
  1271. if (p->ulSearchFlags & ~(STOP_SEARCH | RESTART_SEARCH | RECURSIVE_SEARCH |
  1272. SHALLOW_SEARCH | FOREGROUND_SEARCH | BACKGROUND_SEARCH))
  1273. UNKNOWN_FLAGS(MAPIContainer_SetSearchCriteria, SearchFlags, TEXT("STOP_SEARCH | RESTART_SEARCH | RECURSIVE_SEARCH | ")
  1274. TEXT("SHALLOW_SEARCH | FOREGROUND_SEARCH | BACKGROUND_SEARCH"));
  1275. /* Check for a mutual-exclusivity violation in the flags */
  1276. if ( ( (p->ulSearchFlags & STOP_SEARCH)
  1277. && (p->ulSearchFlags & RESTART_SEARCH))
  1278. || ( (p->ulSearchFlags & RECURSIVE_SEARCH)
  1279. && (p->ulSearchFlags & SHALLOW_SEARCH))
  1280. || ( (p->ulSearchFlags & FOREGROUND_SEARCH)
  1281. && (p->ulSearchFlags & BACKGROUND_SEARCH)))
  1282. INVALID_PARAMETER(MAPIContainer_SetSearchCriteria, SearchFlags, TEXT("Mutually exclusive flags used"));
  1283. END_FUNC(SetSearchCriteria, MAPIContainer)
  1284. START_FUNC(GetSearchCriteria, MAPIContainer)
  1285. if (IsBadWritePtr(p->lppRestriction, sizeof(LPSRestriction)))
  1286. INVALID_OUT_PARAMETER(MAPIContainer_GetSearchCriteria, Restriction, TEXT(""));
  1287. if (p->lpulSearchState && IsBadWritePtr(p->lpulSearchState, sizeof(ULONG)))
  1288. INVALID_OUT_PARAMETER(MAPIContainer_GetSearchCriteria, SearchState, TEXT(""));
  1289. if (p->lppContainerList && IsBadWritePtr(p->lppContainerList, sizeof(LPENTRYLIST)))
  1290. INVALID_OUT_PARAMETER(MAPIContainer_GetSearchCriteria, ContainerList, TEXT(""));
  1291. CHECK_FLAGS(MAPIContainer_GetSearchCriteria, MAPI_UNICODE);
  1292. END_FUNC(GetSearchCriteria, MAPIContainer)
  1293. /* IABContainer */
  1294. START_FUNC(CreateEntry, ABContainer)
  1295. if (IsBadMAPIEntryID(p->cbEntryID, p->lpEntryID))
  1296. INVALID_PARAMETER(ABContainer_CreateEntry, EntryID, TEXT("Invalid Entry ID"));
  1297. if (IsBadWritePtr(p->lppMAPIPropEntry, sizeof(LPMAPIPROP)))
  1298. INVALID_OUT_PARAMETER(ABContainer_CreateEntry, MAPIPropEntry, TEXT(""));
  1299. CHECK_FLAGS(ABContainer_CreateEntry, CREATE_CHECK_DUP_STRICT | CREATE_CHECK_DUP_LOOSE | CREATE_REPLACE | CREATE_MERGE);
  1300. END_FUNC(CreateEntry, ABContainer)
  1301. START_FUNC(CopyEntries, ABContainer)
  1302. if (IsBadABEntryList(p->lpEntries))
  1303. INVALID_PARAMETER(ABContainer_CopyEntries, Entries, TEXT("Bad entry list"));
  1304. // Validate lpProgress and ulUIParam only if AB_NO_DIALOG is clear.
  1305. if ( !(p->ulFlags & AB_NO_DIALOG))
  1306. {
  1307. if (p->lpProgress && IsBadIfacePtr(p->lpProgress, IMAPIProgress))
  1308. INVALID_PARAMETER(ABContainer_CopyEntries, lpProgress, TEXT("bad address"));
  1309. // only validate ulUIParam if lpProgress is NULL.
  1310. if ( !p->lpProgress && p->ulUIParam && !IsWindow ((HWND)IntToPtr(p->ulUIParam)))
  1311. INVALID_PARAMETER(ABContainer_CopyEntries, ulUIParam, TEXT("bad window"));
  1312. }
  1313. CHECK_FLAGS(ABContainer_CopyEntries, CREATE_CHECK_DUP_STRICT | CREATE_CHECK_DUP_LOOSE | CREATE_REPLACE | CREATE_MERGE | AB_NO_DIALOG);
  1314. END_FUNC(CopyEntries, ABContainer)
  1315. START_FUNC(DeleteEntries, ABContainer)
  1316. if (IsBadABEntryList(p->lpEntries))
  1317. INVALID_PARAMETER(ABContainer_DeleteEntries, Entries, TEXT("Bad entry list"));
  1318. CHECK_FLAGS(ABContainer_DeleteEntries, 0);
  1319. END_FUNC(DeleteEntries, ABContainer)
  1320. START_FUNC(ResolveNames, ABContainer)
  1321. /* Do nothing for now... */
  1322. CHECK_FLAGS(ABContainer_ResolveNames, MAPI_UNICODE);
  1323. END_FUNC(ResolveNames, ABContainer)
  1324. /* IDistList */
  1325. START_FUNC(CreateEntry, DistList)
  1326. FORWARD_VALIDATE(ABContainer_CreateEntry, p);
  1327. END_FUNC(CreateEntry, DistList)
  1328. START_FUNC(CopyEntries, DistList)
  1329. FORWARD_VALIDATE(ABContainer_CopyEntries, p);
  1330. END_FUNC(CopyEntries, DistList)
  1331. START_FUNC(DeleteEntries, DistList)
  1332. FORWARD_VALIDATE(ABContainer_DeleteEntries, p);
  1333. END_FUNC(DeleteEntries, DistList)
  1334. START_FUNC(ResolveNames, DistList)
  1335. FORWARD_VALIDATE(ABContainer_DeleteEntries, p);
  1336. END_FUNC(ResolveNames, DistList)
  1337. /* IMAPIFolder */
  1338. START_FUNC(CreateMessage, MAPIFolder)
  1339. if (p->lpInterface && IsBadReadPtr(p->lpInterface, sizeof(IID)))
  1340. INVALID_PARAMETER(MAPIFolder_CreateMessage, Interface, TEXT("Not readable"));
  1341. if (IsBadWritePtr(p->lppMessage, sizeof(LPMESSAGE)))
  1342. INVALID_OUT_PARAMETER(MAPIFolder_CreateMessage, Message, TEXT(""));
  1343. CHECK_FLAGS(MAPIFolder_CreateMessage, MAPI_DEFERRED_ERRORS | MAPI_ASSOCIATED);
  1344. END_FUNC(CreateMessage, MAPIFolder)
  1345. START_FUNC(CopyMessages, MAPIFolder)
  1346. if (IsBadIfacePtr((LPMAPIFOLDER) p->lpDestFolder, IMAPIFolder))
  1347. INVALID_PARAMETER(MAPIFolder_CopyMessages, DestFolder, TEXT("Bad object"));
  1348. if (FBadMsgList(p->lpMsgList))
  1349. INVALID_PARAMETER(MAPIFolder_CopyMessages, MsgList, TEXT("Bad list"));
  1350. if (p->lpInterface && IsBadReadPtr(p->lpInterface, sizeof(IID)))
  1351. INVALID_PARAMETER(MAPIFolder_CopyMessages, Interface, TEXT("Not readable"));
  1352. CHECK_FLAGS(MAPIFolder_CopyMessages, MESSAGE_MOVE | MESSAGE_DIALOG | MAPI_DECLINE_OK);
  1353. // Validate lpProgress and ulUIParam only if MESSAGE_DIALOG is set.
  1354. if ( p->ulFlags & MESSAGE_DIALOG )
  1355. {
  1356. if ( p->lpProgress && IsBadIfacePtr(p->lpProgress, IMAPIProgress))
  1357. INVALID_PARAMETER(MAPIFolder_CopyMessages, lpProgress, TEXT("bad address"));
  1358. // only validate ulUIParam if lpProgress is NULL.
  1359. if ( !p->lpProgress && p->ulUIParam && !IsWindow ((HWND)IntToPtr(p->ulUIParam)))
  1360. INVALID_PARAMETER(MAPIFolder_CopyMessages, ulUIParam, TEXT("bad window"));
  1361. }
  1362. END_FUNC(CopyMessages, MAPIFolder)
  1363. START_FUNC(DeleteMessages, MAPIFolder)
  1364. if (FBadMsgList(p->lpMsgList))
  1365. INVALID_PARAMETER(MAPIFolder_DeleteMessages, MsgList, TEXT("Bad list"));
  1366. CHECK_FLAGS(MAPIFolder_DeleteMessages, MESSAGE_DIALOG);
  1367. // Validate lpProgress and ulUIParam only if MESSAGE_DIALOG is set.
  1368. if ( p->ulFlags & MESSAGE_DIALOG )
  1369. {
  1370. if ( p->lpProgress && IsBadIfacePtr(p->lpProgress, IMAPIProgress))
  1371. INVALID_PARAMETER(MAPIFolder_DeleteMessages, lpProgress, TEXT("bad address"));
  1372. // only validate ulUIParam if lpProgress is NULL.
  1373. if ( !p->lpProgress && p->ulUIParam && !IsWindow ((HWND)IntToPtr(p->ulUIParam)))
  1374. INVALID_PARAMETER(MAPIFolder_DeleteMessages, ulUIParam, TEXT("bad window"));
  1375. }
  1376. END_FUNC(DeleteMessages, MAPIFolder)
  1377. START_FUNC(CreateFolder, MAPIFolder)
  1378. if (p->ulFolderType != FOLDER_GENERIC && p->ulFolderType != FOLDER_SEARCH)
  1379. INVALID_PARAMETER(MAPIFolder_CreateFolder, FolderType, TEXT("Unknown type"));
  1380. if (IsBadStringPtr(p->lpszFolderName, (UINT)(-1)))
  1381. INVALID_PARAMETER(MAPIFolder_CreateFolder, FolderName, TEXT("Bad string"));
  1382. if (p->lpszFolderComment && IsBadStringPtr(p->lpszFolderComment, (UINT)(-1)))
  1383. INVALID_PARAMETER(MAPIFolder_CreateFolder, FolderComment, TEXT("Bad string"));
  1384. if (p->lpInterface)
  1385. INVALID_PARAMETER(MAPIFolder_CreateFolder, Interface, TEXT("Must be NULL"));
  1386. if (IsBadWritePtr(p->lppFolder, sizeof(LPMAPIFOLDER)))
  1387. INVALID_OUT_PARAMETER(MAPIFolder_CreateFolder, Folder, TEXT(""));
  1388. CHECK_FLAGS(MAPIFolder_CreateFolder, MAPI_UNICODE | MAPI_DEFERRED_ERRORS | OPEN_IF_EXISTS);
  1389. END_FUNC(CreateFolder, MAPIFolder)
  1390. START_FUNC(CopyFolder, MAPIFolder)
  1391. if (IsBadIfacePtr((LPMAPIFOLDER) p->lpDestFolder, IMAPIFolder))
  1392. INVALID_PARAMETER(MAPIFolder_CopyFolder, DestFolder, TEXT("Bad object"));
  1393. if (p->lpInterface && IsBadReadPtr(p->lpInterface, sizeof(IID)))
  1394. INVALID_PARAMETER(MAPIFolder_CopyMessages, Interface, TEXT("Not readable"));
  1395. if (p->cbEntryID && IsBadReadPtr(p->lpEntryID, (UINT) p->cbEntryID))
  1396. INVALID_PARAMETER(MAPIFolder_CopyFolder, lpEntryID, TEXT("Not readable"));
  1397. if (p->lpszNewFolderName && IsBadStringPtr(p->lpszNewFolderName, (UINT)-1))
  1398. INVALID_PARAMETER(MAPIFolder_CopyFolder, NewFolderName, TEXT("Bad string"));
  1399. CHECK_FLAGS(MAPIFolder_CopyFolder, FOLDER_MOVE | FOLDER_DIALOG | MAPI_DECLINE_OK |
  1400. COPY_SUBFOLDERS | MAPI_UNICODE);
  1401. // Validate lpProgress and ulUIParam only if FOLDER_DIALOG is set.
  1402. if ( p->ulFlags & FOLDER_DIALOG )
  1403. {
  1404. if ( p->lpProgress && IsBadIfacePtr(p->lpProgress, IMAPIProgress))
  1405. INVALID_PARAMETER(MAPIFolder_CopyFolder, lpProgress, TEXT("bad address"));
  1406. // only validate ulUIParam if lpProgress is NULL.
  1407. if ( !p->lpProgress && p->ulUIParam && !IsWindow ((HWND)IntToPtr(p->ulUIParam)))
  1408. INVALID_PARAMETER(MAPIFolder_CopyFolder, ulUIParam, TEXT("bad window"));
  1409. }
  1410. END_FUNC(CopyFolder, MAPIFolder)
  1411. START_FUNC(DeleteFolder, MAPIFolder)
  1412. if (p->cbEntryID > UINT_MAX)
  1413. INVALID_PARAMETER(MAPIFolder_DeleteFolder, cbEntryID, TEXT("Too big"));
  1414. if (p->cbEntryID && IsBadReadPtr(p->lpEntryID, (UINT) p->cbEntryID))
  1415. INVALID_PARAMETER(MAPIFolder_DeleteFolder, lpEntryID, TEXT("Not readable"));
  1416. CHECK_FLAGS(MAPIFolder_DeleteFolder, DEL_MESSAGES | DEL_FOLDERS | FOLDER_DIALOG);
  1417. // Validate lpProgress and ulUIParam only if FOLDER_DIALOG is set.
  1418. if ( p->ulFlags & FOLDER_DIALOG )
  1419. {
  1420. if ( p->lpProgress && IsBadIfacePtr(p->lpProgress, IMAPIProgress))
  1421. INVALID_PARAMETER(MAPIFolder_DeleteFolder, lpProgress, TEXT("bad address"));
  1422. // only validate ulUIParam if lpProgress is NULL.
  1423. if ( !p->lpProgress && p->ulUIParam && !IsWindow ((HWND)IntToPtr(p->ulUIParam)))
  1424. INVALID_PARAMETER(MAPIFolder_DeleteFolder, ulUIParam, TEXT("bad window"));
  1425. }
  1426. END_FUNC(DeleteFolder, MAPIFolder)
  1427. START_FUNC(SetReadFlags, MAPIFolder)
  1428. if ( p->lpMsgList
  1429. && FBadMsgList(p->lpMsgList))
  1430. INVALID_PARAMETER(MAPIFolder_SetReadFlags, MsgList, TEXT("Bad List"));
  1431. CHECK_FLAGS(MAPIFolder_SetReadFlags, GENERATE_RECEIPT_ONLY | SUPPRESS_RECEIPT | FOLDER_DIALOG | CLEAR_READ_FLAG | MAPI_DEFERRED_ERRORS | CLEAR_RN_PENDING | CLEAR_NRN_PENDING);
  1432. // the following flags are mutually exclusive
  1433. if ( ( !!(p->ulFlags & GENERATE_RECEIPT_ONLY)
  1434. + !!(p->ulFlags & SUPPRESS_RECEIPT)
  1435. + !!(p->ulFlags & CLEAR_READ_FLAG)
  1436. + !!( (p->ulFlags & CLEAR_RN_PENDING)
  1437. || (p->ulFlags & CLEAR_NRN_PENDING)))
  1438. > 1)
  1439. INVALID_PARAMETER(MAPIFolder_SetReadFlags, ulFlags, TEXT("Bad Flag Combination"));
  1440. // Validate lpProgress and ulUIParam only if FOLDER_DIALOG is set.
  1441. if ( p->ulFlags & FOLDER_DIALOG )
  1442. {
  1443. if ( p->lpProgress && IsBadIfacePtr(p->lpProgress, IMAPIProgress))
  1444. INVALID_PARAMETER(MAPIFolder_SetReadFlags, lpProgress, TEXT("bad address"));
  1445. // only validate ulUIParam if lpProgress is NULL.
  1446. if ( !p->lpProgress && p->ulUIParam && !IsWindow ((HWND)IntToPtr(p->ulUIParam)))
  1447. INVALID_PARAMETER(MAPIFolder_SetReadFlags, ulUIParam, TEXT("bad window"));
  1448. }
  1449. END_FUNC(SetReadFlags, MAPIFolder)
  1450. START_FUNC(GetMessageStatus, MAPIFolder)
  1451. CHECK_FLAGS(MAPIFolder_GetMessageStatus, 0);
  1452. END_FUNC(GetMessageStatus, MAPIFolder)
  1453. START_FUNC(SetMessageStatus, MAPIFolder)
  1454. if (p->cbEntryID > UINT_MAX)
  1455. INVALID_PARAMETER(MAPIFolder_SetMessageStatus, cbEntryID, TEXT("Too long"));
  1456. if (p->cbEntryID && IsBadReadPtr(p->lpEntryID, (UINT) p->cbEntryID))
  1457. INVALID_PARAMETER(MAPIFolder_SetMessageStatus, lpEntryID, TEXT("Not readable"));
  1458. if (p->lpulOldStatus && IsBadReadPtr(p->lpulOldStatus, sizeof(ULONG)))
  1459. INVALID_OUT_PARAMETER(MAPIFolder_SetMessageStatus, OldStatus, TEXT(""));
  1460. if (p->ulNewStatusMask & ~(0xFFFF0000 | MSGSTATUS_HIGHLIGHTED |
  1461. MSGSTATUS_TAGGED |
  1462. MSGSTATUS_HIDDEN |
  1463. MSGSTATUS_DELMARKED |
  1464. MSGSTATUS_REMOTE_DOWNLOAD |
  1465. MSGSTATUS_REMOTE_DELETE))
  1466. UNKNOWN_FLAGS(MAPIFolder_SetMessageStatus, NewStatusMask, TEXT("0xFFFF0000 | ")
  1467. TEXT("MSGSTATUS_HIGHLIGHTED | MSGSTATUS_TAGGED | ")
  1468. TEXT("MSGSTATUS_HIDDEN | MSGSTATUS_DELMARKED | ")
  1469. TEXT("MSGSTATUS_REMOTE_DOWNLOAD | MSGSTATUS_REMOTE_DELETE"));
  1470. END_FUNC(SetMessageStatus, MAPIFolder)
  1471. START_FUNC(SaveContentsSort, MAPIFolder)
  1472. if (IsBadSortOrderSet(p->lpSortCriteria))
  1473. INVALID_PARAMETER(MAPIFolder_SaveContentsSort, SortCriteria, TEXT("Not readable"));
  1474. CHECK_FLAGS(MAPIFolder_SaveContentsSort, 0);
  1475. END_FUNC(SaveContentsSort, MAPIFolder)
  1476. START_FUNC(EmptyFolder, MAPIFolder)
  1477. CHECK_FLAGS(MAPIFolder_EmptyFolder, DEL_ASSOCIATED | FOLDER_DIALOG);
  1478. // Validate lpProgress and ulUIParam only if FOLDER_DIALOG is set.
  1479. if ( p->ulFlags & FOLDER_DIALOG )
  1480. {
  1481. if ( p->lpProgress && IsBadIfacePtr(p->lpProgress, IMAPIProgress))
  1482. INVALID_PARAMETER(MAPIFolder_EmptyFolder, lpProgress, TEXT("bad address"));
  1483. // only validate ulUIParam if lpProgress is NULL.
  1484. if ( !p->lpProgress && p->ulUIParam && !IsWindow ((HWND)IntToPtr(p->ulUIParam)))
  1485. INVALID_PARAMETER(MAPIFolder_EmptyFolder, ulUIParam, TEXT("bad window"));
  1486. }
  1487. END_FUNC(EmptyFolder, MAPIFolder)
  1488. #ifdef OLD_STUFF
  1489. /* IMsgStore */
  1490. START_FUNC(Advise, MsgStore)
  1491. if (p->cbEntryID > UINT_MAX)
  1492. INVALID_PARAMETER(MsgStore_Advise, cbEntryID, TEXT("Too big"));
  1493. if (p->cbEntryID && IsBadReadPtr(p->lpEntryID, (UINT) p->cbEntryID))
  1494. INVALID_PARAMETER(MsgStore_Advise, lpEntryID, TEXT("Not readable"));
  1495. if (IsBadIfacePtr(p->lpAdviseSink, IMAPIAdviseSink))
  1496. INVALID_PARAMETER(MsgStore_Advise, AdviseSink, TEXT("Bad object"));
  1497. if (IsBadWritePtr(p->lpulConnection, sizeof(ULONG)))
  1498. INVALID_OUT_PARAMETER(MsgStore_Advise, Connection, TEXT(""));
  1499. if (p->ulEventMask & ~(fnevCriticalError | fnevNewMail | fnevObjectCreated
  1500. | fnevObjectDeleted | fnevObjectModified | fnevObjectMoved | fnevObjectCopied | fnevSearchComplete))
  1501. UNKNOWN_FLAGS(MsgStore_Advise, EventMask, TEXT("fnevCriticalError | fnevNewMail | fnevObjectCreated | fnevObjectDeleted | fnevObjectModified |")
  1502. TEXT("fnevObjectMoved | fnevObjectCopied | fnevSearchComplete"));
  1503. END_FUNC(Advise, MsgStore)
  1504. START_FUNC(Unadvise, MsgStore)
  1505. DO_NOTHING;
  1506. END_FUNC(Unadvise, MsgStore)
  1507. START_FUNC(CompareEntryIDs, MsgStore)
  1508. if (p->cbEntryID1 > UINT_MAX)
  1509. INVALID_PARAMETER(MsgStore_CompareEnryIDs, cbEntryID1, TEXT("Too big"));
  1510. if (p->cbEntryID1 && IsBadReadPtr(p->lpEntryID1, (UINT) p->cbEntryID1))
  1511. INVALID_PARAMETER(MsgStore_CompareEntryIDs, lpEntryID1, TEXT("Not readable"));
  1512. if (p->cbEntryID2 > UINT_MAX)
  1513. INVALID_PARAMETER(MsgStore_CompareEnryIDs, cbEntryID2, TEXT("Too big"));
  1514. if (p->cbEntryID2 && IsBadReadPtr(p->lpEntryID2, (UINT) p->cbEntryID2))
  1515. INVALID_PARAMETER(MsgStore_CompareEntryIDs, lpEntryID2, TEXT("Not readable"));
  1516. if (IsBadWritePtr(p->lpulResult, sizeof(ULONG)))
  1517. INVALID_OUT_PARAMETER(MsgStore_CompareEntryIDs, Result, TEXT(""));
  1518. CHECK_FLAGS(MsgStore_CompareEntryIDs, 0);
  1519. END_FUNC(CompareEntryIDs, MsgStore)
  1520. START_FUNC(OpenEntry, MsgStore)
  1521. FORWARD_VALIDATE(MAPIContainer_OpenEntry, p);
  1522. END_FUNC(OpenEntry, MsgStore)
  1523. START_FUNC(SetReceiveFolder, MsgStore)
  1524. if (p->lpszMessageClass && IsBadStringPtr(p->lpszMessageClass, (UINT)-1))
  1525. INVALID_PARAMETER(MsgStore_SetReceiveFolder, MessageClass, TEXT("Bad String"));
  1526. if (p->cbEntryID > UINT_MAX)
  1527. INVALID_PARAMETER(MsgStore_SetReceiveFolder, cbEntryID, TEXT("Too big"));
  1528. if (p->cbEntryID && IsBadReadPtr(p->lpEntryID, (UINT) p->cbEntryID))
  1529. INVALID_PARAMETER(MsgStore_SetReceiveFolder, pbEntryID, TEXT("Not readable"));
  1530. CHECK_FLAGS(MsgStore_SetReceiveFolder, MAPI_UNICODE);
  1531. END_FUNC(SetReceiveFolder, MsgStore)
  1532. START_FUNC(GetReceiveFolder, MsgStore)
  1533. if (p->lpszMessageClass && IsBadStringPtr(p->lpszMessageClass, (UINT)-1))
  1534. INVALID_PARAMETER(MsgStore_GetReceiveFolder, MessageClass, TEXT("Bad String"));
  1535. if (IsBadWritePtr(p->lpcbEntryID, sizeof(ULONG)))
  1536. INVALID_OUT_PARAMETER(MsgStore_GetReceiveFolder, cbEntryID, TEXT(""));
  1537. if (IsBadWritePtr(p->lppEntryID, sizeof(LPENTRYID)))
  1538. INVALID_OUT_PARAMETER(MsgStore_GetReceiveFolder, lpEntryID, TEXT(""));
  1539. if (p->lppszExplicitClass && IsBadWritePtr(p->lppszExplicitClass, sizeof(LPTSTR)))
  1540. INVALID_OUT_PARAMETER(MsgStore_GetReceiveFolder, ExplicitClass, TEXT(""));
  1541. CHECK_FLAGS(MsgStore_GetReceiveFolder, MAPI_UNICODE);
  1542. END_FUNC(GetReceiveFolder, MsgStore)
  1543. START_FUNC(GetReceiveFolderTable, MsgStore)
  1544. if (IsBadWritePtr(p->lppTable, sizeof(LPMAPITABLE)))
  1545. INVALID_OUT_PARAMETER(MsgStore_GetReceiveFolderTable, Table, TEXT(""));
  1546. CHECK_FLAGS(MsgStore_GetReceiveFolderTable, MAPI_DEFERRED_ERRORS | MAPI_UNICODE);
  1547. END_FUNC(GetReceiveFolderTable, MsgStore)
  1548. START_FUNC(StoreLogoff, MsgStore)
  1549. if (IsBadWritePtr(p->lpulFlags, sizeof(ULONG)))
  1550. INVALID_OUT_PARAMETER(MsgStore_StoreLogoff, Flags, TEXT(""));
  1551. if (*(p->lpulFlags) & ~(LOGOFF_NO_WAIT | LOGOFF_ORDERLY | LOGOFF_PURGE |
  1552. LOGOFF_ABORT | LOGOFF_QUIET))
  1553. UNKNOWN_FLAGS(MsgStore_StoreLogoff, Flags, TEXT("LOGOFF_NO_WAIT | LOGOFF_ORDERLY | LOGOFF_PURGE |")
  1554. TEXT(" LOGOFF_ABORT | LOGOFF_QUIET"));
  1555. END_FUNC(StoreLogoff, MsgStore)
  1556. START_FUNC(AbortSubmit, MsgStore)
  1557. if (p->cbEntryID > UINT_MAX)
  1558. INVALID_PARAMETER(MsgStore_AbortSubmit, cbEntryID, TEXT("Too big"));
  1559. if (p->cbEntryID && IsBadReadPtr(p->lpEntryID, (UINT) p->cbEntryID))
  1560. INVALID_PARAMETER(MsgStore_AbortSubmit, lpEntryID, TEXT("Not readable"));
  1561. CHECK_FLAGS(MsgStore_AbortSubmit, 0);
  1562. END_FUNC(AbortSubmit, MsgStore)
  1563. START_FUNC(GetOutgoingQueue, MsgStore)
  1564. CHECK_FLAGS(MsgStore_GetOutgoingQueue, 0);
  1565. END_FUNC(GetOutgoingQueue, MsgStore)
  1566. START_FUNC(SetLockState, MsgStore)
  1567. if (p->ulLockState & ~(MSG_LOCKED | MSG_UNLOCKED))
  1568. UNKNOWN_FLAGS(MsgStore_SetLockState, LockState, TEXT("MSG_LOCKED | MSG_UNLOCKED"));
  1569. END_FUNC(SetLockState, MsgStore)
  1570. START_FUNC(FinishedMsg, MsgStore)
  1571. if (p->cbEntryID > UINT_MAX)
  1572. INVALID_PARAMETER(MsgStore_FinishedMsg, cbEntryID, TEXT("Too big"));
  1573. if (p->cbEntryID && IsBadReadPtr(p->lpEntryID, (UINT) p->cbEntryID))
  1574. INVALID_PARAMETER(MsgStore_FinishedMsg, lpEntryID, TEXT("Not readable"));
  1575. CHECK_FLAGS(MsgStore_FinishedMsg, 0);
  1576. END_FUNC(FinishedMsg, MsgStore)
  1577. START_FUNC(NotifyNewMail, MsgStore)
  1578. if (IsBadReadPtr(p->lpNotification, sizeof(NOTIFICATION)))
  1579. INVALID_PARAMETER(MsgStore_NotifyNewMail, Notification, TEXT("Not readable"));
  1580. if (p->lpNotification->ulEventType != fnevNewMail)
  1581. INVALID_PARAMETER(MsgStore_NotifyNewMail, Notification->EventType, TEXT("Wrong type"));
  1582. END_FUNC(NotifyNewMail, MsgStore)
  1583. /* IMessage */
  1584. START_FUNC(GetAttachmentTable, Message)
  1585. if (IsBadWritePtr(p->lppTable, sizeof(LPMAPITABLE)))
  1586. INVALID_OUT_PARAMETER(Message_GetAttachmentTable, Table, TEXT(""));
  1587. CHECK_FLAGS(Message_GetAttachmentTable, MAPI_DEFERRED_ERRORS | MAPI_UNICODE);
  1588. END_FUNC(GetAttachmentTable, Message)
  1589. START_FUNC(OpenAttach, Message)
  1590. if (p->lpInterface && IsBadReadPtr(p->lpInterface, sizeof(IID)))
  1591. INVALID_PARAMETER(Message_OpenAttach, Interface, TEXT("Not readable"));
  1592. if (IsBadWritePtr(p->lppAttach, sizeof(LPATTACH)))
  1593. INVALID_OUT_PARAMETER(Message_OpenAttach, Attach, TEXT(""));
  1594. CHECK_FLAGS(Messgae_OpenAttach, MAPI_MODIFY | MAPI_DEFERRED_ERRORS | MAPI_BEST_ACCESS);
  1595. END_FUNC(OpenAttach, Message)
  1596. START_FUNC(CreateAttach, Message)
  1597. if (p->lpInterface && IsBadReadPtr(p->lpInterface, sizeof(IID)))
  1598. INVALID_PARAMETER(Message_CreateAttach, Interface, TEXT("Not readable"));
  1599. if (IsBadWritePtr(p->lpulAttachmentNum, sizeof(ULONG)))
  1600. INVALID_OUT_PARAMETER(Message_CreateAttach, AttachmentNum, TEXT(""));
  1601. if (IsBadWritePtr(p->lppAttach, sizeof(LPATTACH)))
  1602. INVALID_OUT_PARAMETER(Message_CreateAttach, Attach, TEXT(""));
  1603. CHECK_FLAGS(Message_CreateAttach, MAPI_DEFERRED_ERRORS);
  1604. END_FUNC(CreateAttach, Message)
  1605. START_FUNC(DeleteAttach, Message)
  1606. CHECK_FLAGS(Message_DeleteAttach, ATTACH_DIALOG);
  1607. // Validate lpProgress and ulUIParam only if ATTACH_DIALOG is set.
  1608. if ( p->ulFlags & ATTACH_DIALOG )
  1609. {
  1610. if ( p->lpProgress && IsBadIfacePtr(p->lpProgress, IMAPIProgress))
  1611. INVALID_PARAMETER(Message_DeleteAttach, lpProgress, TEXT("bad address"));
  1612. // only validate ulUIParam if lpProgress is NULL.
  1613. if ( !p->lpProgress && p->ulUIParam && !IsWindow ((HWND)p->ulUIParam))
  1614. INVALID_PARAMETER(Message_DeleteAttach, ulUIParam, TEXT("bad window"));
  1615. }
  1616. END_FUNC(DeleteAttach, Message)
  1617. START_FUNC(GetRecipientTable, Message)
  1618. if (IsBadWritePtr(p->lppTable, sizeof(LPMAPITABLE)))
  1619. INVALID_OUT_PARAMETER(Message_GetAttachmentTable, Table, TEXT(""));
  1620. CHECK_FLAGS(Message_GetAttachmentTable, MAPI_DEFERRED_ERRORS | MAPI_UNICODE);
  1621. END_FUNC(GetRecipientTable, Message)
  1622. START_FUNC(ModifyRecipients, Message)
  1623. CHECK_FLAGS(Message_ModifyRecipients, MODRECIP_ADD | MODRECIP_MODIFY | MODRECIP_REMOVE);
  1624. {
  1625. /* This mechanism will only work with these three bits. Assert will fail
  1626. if more are encountered.
  1627. The iBitmap is an array of valid bits (1 is valid, 0 is not).
  1628. The flags are adjusted to obtain the bit corresponding to the flags
  1629. value. If the bit in Bitmap is set, then only one of the flags
  1630. was been set. If that bit is not set, the flags are invalid
  1631. iBitmap = 0000 0001 0001 0101 (0x0115)
  1632. */
  1633. UINT iBitmap =
  1634. (1 << 0)
  1635. + (1 << MODRECIP_ADD)
  1636. + (1 << MODRECIP_MODIFY)
  1637. + (1 << MODRECIP_REMOVE);
  1638. Assert(!(p->ulFlags &
  1639. ~(MODRECIP_ADD | MODRECIP_MODIFY | MODRECIP_REMOVE)));
  1640. if (!(iBitmap & (1 << (UINT)(p->ulFlags))))
  1641. INVALID_PARAMETER(Message_ModifyRecipients, Flags,
  1642. TEXT("Inconsistent flags"));
  1643. }
  1644. if (IsBadAdrListMR(p->lpMods, p->ulFlags))
  1645. INVALID_PARAMETER(Message_ModifyRecipients, lpMods, TEXT(""));
  1646. END_FUNC(ModifyRecipients, Message)
  1647. START_FUNC(SubmitMessage, Message)
  1648. CHECK_FLAGS(Message_SubmitMessage, FORCE_SUBMIT);
  1649. END_FUNC(SubmitMessage, Message)
  1650. START_FUNC(SetReadFlag, Message)
  1651. CHECK_FLAGS(Message_SetReadFlag, GENERATE_RECEIPT_ONLY | SUPPRESS_RECEIPT | CLEAR_READ_FLAG | MAPI_DEFERRED_ERRORS | CLEAR_RN_PENDING | CLEAR_NRN_PENDING);
  1652. // the following flags are mutually exclusive
  1653. if ( ( !!(p->ulFlags & GENERATE_RECEIPT_ONLY)
  1654. + !!(p->ulFlags & SUPPRESS_RECEIPT)
  1655. + !!(p->ulFlags & CLEAR_READ_FLAG)
  1656. + !!( (p->ulFlags & CLEAR_RN_PENDING)
  1657. || (p->ulFlags & CLEAR_NRN_PENDING)))
  1658. > 1)
  1659. INVALID_PARAMETER(Message_SetReadFlag, ulFlags, TEXT("Bad Flag Combination"));
  1660. END_FUNC(SetReadFlag, Message)
  1661. /* IABProvider */
  1662. #ifdef DEBUG
  1663. START_FUNC(Shutdown, ABProvider)
  1664. if (IsBadWritePtr(p->lpulFlags, sizeof(ULONG)))
  1665. INVALID_OUT_PARAMETER(ABProvider_Shutdown, Flags, TEXT(""));
  1666. END_FUNC(Shutdown, ABProvider)
  1667. #endif /* DEBUG */
  1668. #ifdef DEBUG
  1669. START_FUNC(Logon, ABProvider)
  1670. if (!p->lpMAPISup)
  1671. INVALID_PARAMETER(ABProvider_Logon, MAPISup, TEXT("Support object needed"));
  1672. if (IsBadWritePtr(p->lpulpcbSecurity, sizeof(ULONG)))
  1673. INVALID_OUT_PARAMETER(ABProvider_Logon, cbSpoolSecurity, TEXT(""));
  1674. if (IsBadWritePtr(p->lppbSecurity, sizeof(LPBYTE)))
  1675. INVALID_OUT_PARAMETER(ABProvider_Logon, pbSecurity, TEXT(""));
  1676. if (IsBadWritePtr(p->lppMapiError, sizeof(LPMAPIERROR)))
  1677. INVALID_OUT_PARAMETER(ABProvider_Logon, MapiError, TEXT(""));
  1678. if (IsBadWritePtr(p->lppABLogon, sizeof(LPABLOGON)))
  1679. INVALID_OUT_PARAMETER(ABProvider_Logon, ABLogon, TEXT(""));
  1680. CHECK_FLAGS(ABProvider_Logon, AB_NO_DIALOG | MAPI_DEFERRED_ERRORS | MAPI_UNICODE);
  1681. // Validate ulUIParam only if AB_NO_DIALOG is clear.
  1682. if (!(p->ulFlags & AB_NO_DIALOG))
  1683. {
  1684. if (p->ulUIParam && !IsWindow ((HWND)p->ulUIParam))
  1685. INVALID_PARAMETER(ABProvider_Logon, ulUIParam, TEXT("bad window"));
  1686. }
  1687. END_FUNC(Logon, ABProvider)
  1688. #endif /* DEBUG */
  1689. /* IABLogon */
  1690. #ifdef DEBUG
  1691. START_FUNC(GetLastError, ABLogon)
  1692. if (!p->lppMAPIError || IsBadWritePtr(p->lppMAPIError, sizeof(LPMAPIERROR)))
  1693. INVALID_OUT_PARAMETER(ABLogon_GetLastError, MAPIError, TEXT(""));
  1694. CHECK_FLAGS(ABLogon_GetLastError, MAPI_UNICODE);
  1695. END_FUNC(GetLastError, ABLogon)
  1696. #endif /* DEBUG */
  1697. #ifdef DEBUG
  1698. START_FUNC(Logoff, ABLogon)
  1699. CHECK_FLAGS(ABLogon_Logoff, 0);
  1700. END_FUNC(Logoff, ABLogon)
  1701. #endif /* DEBUG */
  1702. #ifdef DEBUG
  1703. START_FUNC(OpenEntry, ABLogon)
  1704. if (IsBadMAPIEntryID(p->cbEntryID, p->lpEntryID))
  1705. INVALID_PARAMETER(ABLogon_OpenEntry, EntryID, TEXT("Bad entry ID"));
  1706. if (p->lpInterface && (IsBadReadPtr(p->lpInterface, sizeof(IID))))
  1707. INVALID_PARAMETER(ABLogon_OpenEntry, Interface, TEXT("Not readable"));
  1708. if (IsBadWritePtr(p->lpulObjType, sizeof(ULONG)))
  1709. INVALID_OUT_PARAMETER(ABLogon_OpenEntry, ObjType, TEXT(""));
  1710. if (IsBadWritePtr(p->lppUnk, sizeof(LPUNKNOWN)))
  1711. INVALID_OUT_PARAMETER(ABLogon_OpenEntry, Unk, TEXT(""));
  1712. CHECK_FLAGS(ABLogon_OpenEntry, MAPI_MODIFY | MAPI_DEFERRED_ERRORS | MAPI_BEST_ACCESS);
  1713. END_FUNC(OpenEntry, ABLogon)
  1714. #endif /* DEBUG */
  1715. #ifdef DEBUG
  1716. START_FUNC(CompareEntryIDs, ABLogon)
  1717. FORWARD_VALIDATE(MsgStore_CompareEntryIDs, p);
  1718. END_FUNC(CompareEntryIDs, ABLogon)
  1719. #endif /* DEBUG */
  1720. #ifdef DEBUG
  1721. START_FUNC(Advise, ABLogon)
  1722. if (IsBadIfacePtr(p->lpAdviseSink, IMAPIAdviseSink))
  1723. INVALID_PARAMETER(ABLogon_Advise, AdviseSink, TEXT("Invalid interface"));
  1724. if (IsBadWritePtr(p->lpulConnection, sizeof(ULONG)))
  1725. INVALID_OUT_PARAMETER(ABLogon_Advise, Connection, TEXT(""));
  1726. END_FUNC(Advise, ABLogon)
  1727. #endif /* DEBUG */
  1728. #ifdef DEBUG
  1729. START_FUNC(Unadvise, ABLogon)
  1730. if (p->ulConnection == 0)
  1731. INVALID_PARAMETER(ABLogon_Unadvise, Connection, TEXT("Cannot be zero"));
  1732. END_FUNC(Unadvise, ABLogon)
  1733. #endif /* DEBUG */
  1734. #ifdef DEBUG
  1735. START_FUNC(OpenStatusEntry, ABLogon)
  1736. if (p->lpInterface && IsBadReadPtr(p->lpInterface, (UINT) sizeof(IID)))
  1737. INVALID_PARAMETER(ABLogon_OpenStatusEntry, Interface, TEXT("Not readable"));
  1738. if (IsBadWritePtr(p->lpulObjType, (UINT) sizeof(ULONG FAR *)))
  1739. INVALID_OUT_PARAMETER(ABLogon_OpenStatusEntry, ObjType, TEXT(""));
  1740. if (IsBadWritePtr(p->lppEntry, (UINT) sizeof(LPMAPISTATUS)))
  1741. INVALID_OUT_PARAMETER(ABLogon_OpenStatusEntry, Entry, TEXT(""));
  1742. END_FUNC(OpenStatusEntry, ABLogon)
  1743. #endif /* DEBUG */
  1744. #ifdef DEBUG
  1745. START_FUNC(OpenTemplateID, ABLogon)
  1746. if (IsBadReadPtr(p->lpTemplateID, (UINT) p->cbTemplateID))
  1747. INVALID_PARAMETER(ABLogon_OpenTemplateID, TemplateID, TEXT("Not readable"));
  1748. if (IsBadReadPtr(p->lpMAPIPropData, (UINT) sizeof(LPVOID)))
  1749. INVALID_PARAMETER(ABLogon_OpenTemplateID, MAPIPropData, TEXT("Not readable"));
  1750. if (p->lpInterface && IsBadReadPtr(p->lpInterface, (UINT) sizeof(IID)))
  1751. INVALID_PARAMETER(ABLogon_OpenTemplateID, Interface, TEXT("Not readable"));
  1752. if (IsBadWritePtr(p->lppMAPIPropNew, (UINT) sizeof(LPMAPIPROP)))
  1753. INVALID_OUT_PARAMETER(ABLogon_OpenTemplateID, MAPIPropNew, TEXT(""));
  1754. if (p->lpMAPIPropSibling && IsBadReadPtr(p->lpMAPIPropSibling, (UINT) sizeof(LPVOID)))
  1755. INVALID_PARAMETER(ABLogon_OpenTemplateID, MAPIPropSibling, TEXT("Not readable"));
  1756. END_FUNC(OpenTemplateID, ABLogon)
  1757. #endif /* DEBUG */
  1758. #ifdef DEBUG
  1759. START_FUNC(GetOneOffTable, ABLogon)
  1760. if (IsBadWritePtr(p->lppTable, (UINT) sizeof(LPMAPITABLE)))
  1761. INVALID_OUT_PARAMETER(ABLogon_GetOneOffTable, Table, TEXT(""));
  1762. CHECK_FLAGS(ABLogon_GetOneOffTable, MAPI_UNICODE);
  1763. END_FUNC(GetOneOffTable, ABLogon)
  1764. #endif /* DEBUG */
  1765. #ifdef DEBUG
  1766. START_FUNC(PrepareRecips, ABLogon)
  1767. //$
  1768. END_FUNC(PrepareRecips, ABLogon)
  1769. #endif /* DEBUG */
  1770. /* IXPProvider */
  1771. #ifdef DEBUG
  1772. START_FUNC(Shutdown, XPProvider)
  1773. if (IsBadWritePtr(p->lpulFlags, sizeof(ULONG)))
  1774. INVALID_OUT_PARAMETER(XPProvider_Shutdown, Flags, TEXT(""));
  1775. END_FUNC(Shutdown, XPProvider)
  1776. #endif /* DEBUG */
  1777. #ifdef DEBUG
  1778. START_FUNC(TransportLogon, XPProvider)
  1779. if (!p->lpMAPISup)
  1780. INVALID_PARAMETER(XPProvider_Logon, MAPISup, TEXT("Support object needed"));
  1781. if (IsBadWritePtr(p->lpulFlags, sizeof(ULONG)))
  1782. INVALID_OUT_PARAMETER(XPProvider_Logon, Flags, TEXT(""));
  1783. if (IsBadWritePtr(p->lppMapiError, sizeof(LPMAPIERROR)))
  1784. INVALID_OUT_PARAMETER(XPProvider_Logon, MapiError, TEXT(""));
  1785. if (IsBadWritePtr(p->lppXPLogon, sizeof(LPXPLOGON)))
  1786. INVALID_OUT_PARAMETER(XPProvider_Logon, XPLogon, TEXT(""));
  1787. // Validate ulUIParam only if LOGON_NO_DIALOG is clear.
  1788. if (!(*p->lpulFlags & LOGON_NO_DIALOG))
  1789. {
  1790. if (p->ulUIParam && !IsWindow ((HWND)p->ulUIParam))
  1791. INVALID_PARAMETER(XPProvider_Logon, ulUIParam, TEXT("bad window"));
  1792. }
  1793. END_FUNC(TransportLogon, XPProvider)
  1794. #endif /* DEBUG */
  1795. /* IXPLogon */
  1796. #ifdef DEBUG
  1797. START_FUNC(AddressTypes, XPLogon)
  1798. if (IsBadWritePtr(p->lpulFlags, sizeof(ULONG)))
  1799. INVALID_OUT_PARAMETER(XPLogon_AddressTypes, Flags, TEXT(""));
  1800. if (IsBadWritePtr(p->lpcAdrType, sizeof(ULONG)))
  1801. INVALID_OUT_PARAMETER(XPLogon_AddressTypes, AdrType, TEXT(""));
  1802. if (IsBadWritePtr(p->lpppAdrTypeArray, sizeof(LPTSTR FAR *)))
  1803. INVALID_OUT_PARAMETER(XPLogon_AddressTypes, AdrTypeArray, TEXT(""));
  1804. if (IsBadWritePtr(p->lpcMAPIUID, sizeof(ULONG)))
  1805. INVALID_OUT_PARAMETER(XPLogon_AddressTypes, MAPIUID, TEXT(""));
  1806. if (IsBadWritePtr(p->lpppUIDArray, sizeof(ULONG FAR *)))
  1807. INVALID_OUT_PARAMETER(XPLogon_AddressTypes, UIDArray, TEXT(""));
  1808. END_FUNC(AddressTypes, XPLogon)
  1809. #endif /* DEBUG */
  1810. #ifdef DEBUG
  1811. START_FUNC(RegisterOptions, XPLogon)
  1812. if (IsBadWritePtr(p->lpulFlags, sizeof(ULONG)))
  1813. INVALID_OUT_PARAMETER(XPLogon_RegisterOptions, Flags, TEXT(""));
  1814. if (IsBadWritePtr(p->lpcOptions, sizeof(ULONG)))
  1815. INVALID_OUT_PARAMETER(XPLogon_RegisterOptions, cOptions, TEXT(""));
  1816. if (IsBadWritePtr(p->lppOptions, sizeof(LPOPTIONDATA)))
  1817. INVALID_OUT_PARAMETER(XPLogon_RegisterOptions, pOptions, TEXT(""));
  1818. END_FUNC(RegisterOptions, XPLogon)
  1819. #endif /* DEBUG */
  1820. #ifdef DEBUG
  1821. START_FUNC(TransportNotify, XPLogon)
  1822. if (IsBadWritePtr(p->lpulFlags, sizeof(ULONG)))
  1823. INVALID_OUT_PARAMETER(XPLogon_TransportNotify, Flags, TEXT(""));
  1824. if (p->lppvData && IsBadWritePtr(p->lppvData, sizeof(LPVOID)))
  1825. INVALID_OUT_PARAMETER(XPLogon_TransportNotify, Data, TEXT(""));
  1826. END_FUNC(TransportNotify, XPLogon)
  1827. #endif /* DEBUG */
  1828. #ifdef DEBUG
  1829. START_FUNC(Idle, XPLogon)
  1830. CHECK_FLAGS(XPLogon_Idle, 0);
  1831. END_FUNC(Idle, XPLogon)
  1832. #endif /* DEBUG */
  1833. #ifdef DEBUG
  1834. START_FUNC(TransportLogoff, XPLogon)
  1835. CHECK_FLAGS(XPLogon_Logoff, 0);
  1836. END_FUNC(TransportLogoff, XPLogon)
  1837. #endif /* DEBUG */
  1838. #ifdef DEBUG
  1839. START_FUNC(SubmitMessage, XPLogon)
  1840. END_FUNC(SubmitMessage, XPLogon)
  1841. #endif /* DEBUG */
  1842. #ifdef DEBUG
  1843. START_FUNC(EndMessage, XPLogon)
  1844. END_FUNC(EndMessage, XPLogon)
  1845. #endif /* DEBUG */
  1846. #ifdef DEBUG
  1847. START_FUNC(Poll, XPLogon)
  1848. END_FUNC(Poll, XPLogon)
  1849. #endif /* DEBUG */
  1850. #ifdef DEBUG
  1851. START_FUNC(StartMessage, XPLogon)
  1852. END_FUNC(StartMessage, XPLogon)
  1853. #endif /* DEBUG */
  1854. #ifdef DEBUG
  1855. START_FUNC(OpenStatusEntry, XPLogon)
  1856. END_FUNC(OpenStatusEntry, XPLogon)
  1857. #endif /* DEBUG */
  1858. #ifdef DEBUG
  1859. START_FUNC(ValidateState, XPLogon)
  1860. // Validate ulUIParam only if SUPPRESS_UI is clear.
  1861. if (!(p->ulFlags & SUPPRESS_UI))
  1862. {
  1863. if (p->ulUIParam && !IsWindow ((HWND)p->ulUIParam))
  1864. INVALID_PARAMETER(MAPIStatus_ValidateState, ulUIParam, TEXT("bad window"));
  1865. }
  1866. END_FUNC(ValidateState, XPLogon)
  1867. #endif /* DEBUG */
  1868. #ifdef DEBUG
  1869. START_FUNC(FlushQueues, XPLogon)
  1870. END_FUNC(FlushQueues, XPLogon)
  1871. #endif /* DEBUG */
  1872. /* IMSProvider */
  1873. #ifdef DEBUG
  1874. START_FUNC(Shutdown, MSProvider)
  1875. END_FUNC(Shutdown, MSProvider)
  1876. #endif /* DEBUG */
  1877. #ifdef DEBUG
  1878. START_FUNC(Logon, MSProvider)
  1879. if (!p->lpMAPISup)
  1880. INVALID_PARAMETER(MSProvider_Logon, MAPISup, TEXT("Support object needed"));
  1881. if (p->cbEntryID && IsBadReadPtr(p->lpEntryID, (UINT) p->cbEntryID))
  1882. INVALID_PARAMETER(MSProvider_Logon, EntryID, TEXT("Not readable"));
  1883. if (p->lpInterface && IsBadReadPtr(p->lpInterface, sizeof(GUID)))
  1884. INVALID_PARAMETER(MSProvider_Logon, Interface, TEXT("Bad interface"));
  1885. if (IsBadWritePtr(p->lpcbSpoolSecurity, sizeof(ULONG)))
  1886. INVALID_OUT_PARAMETER(MSProvider_Logon, cbSpoolSecurity, TEXT(""));
  1887. if (IsBadWritePtr(p->lppbSpoolSecurity, sizeof(LPBYTE)))
  1888. INVALID_OUT_PARAMETER(MSProvider_Logon, pbSpoolSecurity, TEXT(""));
  1889. if (IsBadWritePtr(p->lppMapiError, sizeof(LPMAPIERROR)))
  1890. INVALID_OUT_PARAMETER(MSProvider_Logon, MapiError, TEXT(""));
  1891. if (IsBadWritePtr(p->lppMSLogon, sizeof(LPMSLOGON)))
  1892. INVALID_OUT_PARAMETER(MSProvider_Logon, MSLogon, TEXT(""));
  1893. if (IsBadWritePtr(p->lppMDB, sizeof(LPMDB)))
  1894. INVALID_OUT_PARAMETER(MSProvider_Logon, MDB, TEXT(""));
  1895. CHECK_FLAGS(MSProvider_Logon, MDB_TEMPORARY | MDB_NO_MAIL | MDB_WRITE | MDB_NO_DIALOG | MAPI_DEFERRED_ERRORS | MAPI_BEST_ACCESS);
  1896. // Validate ulUIParam only if MDB_NO_DIALOG is clear.
  1897. if (!(p->ulFlags & MDB_NO_DIALOG))
  1898. {
  1899. if (p->ulUIParam && !IsWindow ((HWND)p->ulUIParam))
  1900. INVALID_PARAMETER(MSProvider_Logon, ulUIParam, TEXT("bad window"));
  1901. }
  1902. END_FUNC(Logon, MSProvider)
  1903. #endif /* DEBUG */
  1904. #ifdef DEBUG
  1905. START_FUNC(SpoolerLogon, MSProvider)
  1906. if (!p->lpMAPISup)
  1907. INVALID_PARAMETER(MSProvider_Logon, MAPISup, TEXT("Support object needed"));
  1908. if (p->cbEntryID && IsBadReadPtr(p->lpEntryID, (UINT) p->cbEntryID))
  1909. INVALID_PARAMETER(MSProvider_Logon, EntryID, TEXT("Not readable"));
  1910. if (p->lpInterface && IsBadReadPtr(p->lpInterface, sizeof(GUID)))
  1911. INVALID_PARAMETER(MSProvider_Logon, Interface, TEXT("Bad interface"));
  1912. if (IsBadReadPtr(p->lpbSpoolSecurity, (UINT) p->cbSpoolSecurity))
  1913. INVALID_PARAMETER(MSProvider_Logon, pbSpoolSecurity, TEXT("Not readable"));
  1914. if (IsBadWritePtr(p->lppMapiError, sizeof(LPMAPIERROR)))
  1915. INVALID_OUT_PARAMETER(MSProvider_Logon, MapiError, TEXT(""));
  1916. if (IsBadWritePtr(p->lppMSLogon, sizeof(LPMSLOGON)))
  1917. INVALID_OUT_PARAMETER(MSProvider_Logon, MSLogon, TEXT(""));
  1918. if (IsBadWritePtr(p->lppMDB, sizeof(LPMDB)))
  1919. INVALID_OUT_PARAMETER(MSProvider_Logon, MDB, TEXT(""));
  1920. CHECK_FLAGS(MSProvider_SpoolerLogon, MDB_TEMPORARY | MDB_WRITE | MDB_NO_DIALOG | MAPI_DEFERRED_ERRORS | MAPI_UNICODE);
  1921. END_FUNC(SpoolerLogon, MSProvider)
  1922. #endif /* DEBUG */
  1923. #ifdef DEBUG
  1924. START_FUNC(CompareStoreIDs, MSProvider)
  1925. FORWARD_VALIDATE(MsgStore_CompareEntryIDs, p);
  1926. END_FUNC(CompareStoreIDs, MSProvider)
  1927. #endif /* DEBUG */
  1928. /* IMSLogon */
  1929. #ifdef DEBUG
  1930. START_FUNC(GetLastError, MSLogon)
  1931. if (!p->lppMAPIError || IsBadWritePtr(p->lppMAPIError, sizeof(LPMAPIERROR)))
  1932. INVALID_OUT_PARAMETER(MSLogon_GetLastError, MAPIError, TEXT(""));
  1933. CHECK_FLAGS(MSLogon_GetLastError, MAPI_UNICODE);
  1934. END_FUNC(GetLastError, MSLogon)
  1935. #endif /* DEBUG */
  1936. #ifdef DEBUG
  1937. START_FUNC(Logoff, MSLogon)
  1938. if (IsBadWritePtr(p->lpulFlags, sizeof(ULONG)))
  1939. INVALID_OUT_PARAMETER(MSLogon_Logoff, Flags, TEXT(""));
  1940. END_FUNC(Logoff, MSLogon)
  1941. #endif /* DEBUG */
  1942. #ifdef DEBUG
  1943. START_FUNC(OpenEntry, MSLogon)
  1944. END_FUNC(OpenEntry, MSLogon)
  1945. #endif /* DEBUG */
  1946. #ifdef DEBUG
  1947. START_FUNC(CompareEntryIDs, MSLogon)
  1948. FORWARD_VALIDATE(MsgStore_CompareEntryIDs, p);
  1949. END_FUNC(CompareEntryIDs, MSLogon)
  1950. #endif /* DEBUG */
  1951. #ifdef DEBUG
  1952. START_FUNC(Advise, MSLogon)
  1953. END_FUNC(Advise, MSLogon)
  1954. #endif /* DEBUG */
  1955. #ifdef DEBUG
  1956. START_FUNC(Unadvise, MSLogon)
  1957. END_FUNC(Unadvise, MSLogon)
  1958. #endif /* DEBUG */
  1959. #ifdef DEBUG
  1960. START_FUNC(OpenStatusEntry, MSLogon)
  1961. if (p->lpInterface && IsBadReadPtr(p->lpInterface, (UINT) sizeof(IID)))
  1962. INVALID_PARAMETER(MSLogon_OpenStatusEntry, Interface, TEXT("Not readable"));
  1963. if (IsBadWritePtr(p->lpulObjType, (UINT) sizeof(ULONG FAR *)))
  1964. INVALID_OUT_PARAMETER(MSLogon_OpenStatusEntry, ObjType, TEXT(""));
  1965. if (IsBadWritePtr(p->lppEntry, (UINT) sizeof(LPMAPISTATUS)))
  1966. INVALID_OUT_PARAMETER(MSLogon_OpenStatusEntry, Entry, TEXT(""));
  1967. CHECK_FLAGS(MSLogon_OpenStatusEntry, MAPI_MODIFY);
  1968. END_FUNC(OpenStatusEntry, MSLogon)
  1969. #endif /* DEBUG */
  1970. /* IMAPIControl */
  1971. START_FUNC(GetLastError, MAPIControl)
  1972. if (!p->lppMAPIError || IsBadWritePtr(p->lppMAPIError, sizeof(LPMAPIERROR)))
  1973. INVALID_OUT_PARAMETER(MAPIControl_GetLastError, MAPIError, TEXT(""));
  1974. CHECK_FLAGS(MAPIControl_GetLastError, MAPI_UNICODE);
  1975. END_FUNC(GetLastError, MAPIControl)
  1976. START_FUNC(Activate, MAPIControl)
  1977. CHECK_FLAGS(MAPIControl_Activate, 0);
  1978. END_FUNC(Activate, MAPIControl)
  1979. START_FUNC(GetState, MAPIControl)
  1980. if (IsBadWritePtr(p->lpulState, sizeof(ULONG)))
  1981. INVALID_OUT_PARAMETER(MAPIControl_GetState, State, TEXT(""));
  1982. CHECK_FLAGS(MAPIControl_Activate, 0);
  1983. END_FUNC(GetState, MAPIControl)
  1984. #endif
  1985. /* IStream */
  1986. START_FUNC(Read, Stream)
  1987. if (p->pcbRead)
  1988. {
  1989. if (IsBadWritePtr(p->pcbRead, sizeof(ULONG)))
  1990. INVALID_STG_OUT_PARAMETER(Stream_Read, cbRead, TEXT("Not writable"));
  1991. // Must zero *pcbRead even if there are subsequent errors
  1992. *p->pcbRead = 0;
  1993. }
  1994. if (IsBadHugeWritePtr((VOID HUGEP *) (p->pv), p->cb))
  1995. INVALID_STG_PARAMETER(Stream_Read, pv, TEXT("Not writable"));
  1996. END_FUNC(Read, Stream)
  1997. START_FUNC(Write, Stream)
  1998. if (p->pcbWritten)
  1999. {
  2000. if (IsBadWritePtr(p->pcbWritten, sizeof(ULONG)))
  2001. INVALID_STG_OUT_PARAMETER(Stream_Write, cbWritten, TEXT("Not writable"));
  2002. // Must zero *pcbWritten even if there are subsequent errors
  2003. *p->pcbWritten = 0;
  2004. }
  2005. if (IsBadHugeReadPtr((VOID HUGEP *) (p->pv), p->cb))
  2006. INVALID_STG_OUT_PARAMETER(Stream_Write, pv, TEXT("Not readable"));
  2007. END_FUNC(Write, Stream)
  2008. START_FUNC(Seek, Stream)
  2009. if (p->dwOrigin > STREAM_SEEK_END)
  2010. INVALID_STG_PARAMETER(Stream_Seek, Origin, TEXT("Too big"));
  2011. if (p->plibNewPosition && IsBadWritePtr(p->plibNewPosition, sizeof(ULARGE_INTEGER)))
  2012. INVALID_STG_OUT_PARAMETER(Stream_Seek, NewPosition, TEXT(""));
  2013. END_FUNC(Seek, Stream)
  2014. START_FUNC(SetSize, Stream)
  2015. DO_NOTHING;
  2016. END_FUNC(SetSize, Stream)
  2017. START_FUNC(CopyTo, Stream)
  2018. if (IsBadReadPtr(p->pstm, sizeof(IStream *)))
  2019. INVALID_STG_PARAMETER(Stream_CopyTo, pstm, TEXT("Bad destination"));
  2020. if (IsBadReadPtr(p->pstm->lpVtbl, sizeof(IStreamVtbl)))
  2021. INVALID_STG_PARAMETER(Stream_CopyTo, pstm, TEXT("Bad destination"));
  2022. if (p->pcbRead && IsBadWritePtr(p->pcbRead, sizeof(ULARGE_INTEGER)))
  2023. INVALID_STG_OUT_PARAMETER(Stream_CopyTo, Read, TEXT(""));
  2024. if (p->pcbWritten && IsBadWritePtr(p->pcbWritten, sizeof(ULARGE_INTEGER)))
  2025. INVALID_STG_OUT_PARAMETER(Stream_CopyTo, Written, TEXT(""));
  2026. END_FUNC(CopyTo, Stream)
  2027. START_FUNC(Commit, Stream)
  2028. DO_NOTHING;
  2029. END_FUNC(Commit, Stream)
  2030. START_FUNC(Revert, Stream)
  2031. DO_NOTHING;
  2032. END_FUNC(Revert, Stream)
  2033. START_FUNC(LockRegion, Stream)
  2034. DO_NOTHING;
  2035. END_FUNC(LockRegion, Stream)
  2036. START_FUNC(UnlockRegion, Stream)
  2037. DO_NOTHING;
  2038. END_FUNC(UnlockRegion, Stream)
  2039. START_FUNC(Stat, Stream)
  2040. if (IsBadWritePtr(p->pstatstg, sizeof(STATSTG)))
  2041. INVALID_STG_OUT_PARAMETER(Stream_Stat, pstatstg, TEXT(""));
  2042. END_FUNC(Stat, Stream)
  2043. START_FUNC(Clone, Stream)
  2044. if (IsBadWritePtr(p->ppstm, sizeof(IStream *)))
  2045. INVALID_STG_OUT_PARAMETER(Stream_Clone, ppstm, TEXT(""));
  2046. // Zero out argument if it passes validation
  2047. *p->ppstm = 0;
  2048. END_FUNC(Clone, Stream)
  2049. /* IMAPIAdviseSink */
  2050. START_FUNC(OnNotify, MAPIAdviseSink)
  2051. if (!p->cNotif)
  2052. INVALID_PARAMETER(MAPIAdviseSink_OnNotify, cNotif, TEXT("Cannot be zero"));
  2053. if (p->cNotif > UINT_MAX/sizeof(NOTIFICATION))
  2054. INVALID_PARAMETER(MAPIAdviseSink_OnNotify, cNotif, TEXT("Too big"));
  2055. if (!p->lpNotifications || IsBadReadPtr(p->lpNotifications, sizeof(LPNOTIFICATION)))
  2056. INVALID_PARAMETER(MAPIAdviseSink_OnNotify, lpNotifications, TEXT("Not readable"));
  2057. END_FUNC(OnNotify, MAPIAdviseSink)
  2058. /* IWABObject */
  2059. START_FUNC(GetLastError, WABObject)
  2060. if (!p->lppMAPIError || IsBadWritePtr(p->lppMAPIError, sizeof(LPMAPIERROR)))
  2061. INVALID_OUT_PARAMETER(WABObject_GetLastError, MAPIError, TEXT(""));
  2062. CHECK_FLAGS(WABObject_GetLastError, MAPI_UNICODE);
  2063. END_FUNC(GetLastError, WABObject)
  2064. START_FUNC(AllocateBuffer, WABObject)
  2065. IF_WIN32(END_FUNC(AllocateBuffer, WABObject))
  2066. IF_WIN16(END_FUNC1(AllocateBuffer, WABObject))
  2067. START_FUNC(AllocateMore, WABObject)
  2068. IF_WIN32(END_FUNC(AllocateMore, WABObject))
  2069. IF_WIN16(END_FUNC1(AllocateMore, WABObject))
  2070. START_FUNC(FreeBuffer, WABObject)
  2071. IF_WIN32(END_FUNC(FreeBuffer, WABObject))
  2072. IF_WIN16(END_FUNC1(FreeBuffer, WABObject))
  2073. START_FUNC(Backup, WABObject)
  2074. IF_WIN32(END_FUNC(Backup, WABObject))
  2075. IF_WIN16(END_FUNC1(Backup, WABObject))
  2076. START_FUNC(Import, WABObject)
  2077. IF_WIN32(END_FUNC(Import, WABObject))
  2078. IF_WIN16(END_FUNC1(Import, WABObject))
  2079. /* Internal Utility Functions */
  2080. /*
  2081. * FInvalidPTA
  2082. *
  2083. * Checks an entire PTA for readability, then the individual Prop Tags
  2084. */
  2085. static BOOL NEAR FInvalidPTA(UINT uiFlags, LPSPropTagArray pPTA)
  2086. {
  2087. if ( IsBadReadPtr(pPTA, CbNewSPropTagArray(0))
  2088. || IsBadReadPtr(pPTA, CbSPropTagArray(pPTA)))
  2089. {
  2090. OutputSz( TEXT("PropTagArray is not readable.\n"));
  2091. return TRUE;
  2092. }
  2093. else
  2094. return (FInvalidPropTags(uiFlags, pPTA->cValues, (ULONG FAR *) (pPTA->aulPropTag)));
  2095. }
  2096. #ifdef DEBUG
  2097. static LPTSTR NEAR SzFromTags(UINT uiFlags)
  2098. {
  2099. #define RETURNSTR(sz) { static TCHAR BASED_CODE lpszTemp[] = sz; return(lpszTemp); }
  2100. switch (uiFlags)
  2101. {
  2102. case TAGS_FROM_GET: RETURNSTR( TEXT("GetProps")); break;
  2103. case TAGS_FROM_SET: RETURNSTR( TEXT("SetProps")); break;
  2104. case TAGS_FROM_DEL: RETURNSTR( TEXT("DeleteProps")); break;
  2105. case TAGS_FROM_OPEN: RETURNSTR( TEXT("OpenProperty")); break;
  2106. case TAGS_FROM_COPY: RETURNSTR( TEXT("CopyProps/To")); break;
  2107. case TAGS_FROM_PREP: RETURNSTR( TEXT("PrepareRecips")); break;
  2108. case TAGS_FROM_SETCOLS: RETURNSTR( TEXT("SetColumns")); break;
  2109. case TAGS_FROM_ANY: RETURNSTR( TEXT("Any")); break;
  2110. case TAGS_FROM_MODRECIP: RETURNSTR( TEXT("ModifyRecipients")); break;
  2111. case TAGS_FROM_RESOLVE: RETURNSTR( TEXT("ResolveNames")); break;
  2112. default: RETURNSTR( TEXT("Unknown!")); break;
  2113. }
  2114. }
  2115. #endif // DEBUG
  2116. /*
  2117. * FInvalidPropTags
  2118. *
  2119. * Cycles through a PTA checking the individual Prop Tags for validity
  2120. * based on the passed in flag
  2121. *
  2122. */
  2123. static BOOL NEAR FInvalidPropTags(UINT uiFlags, ULONG ctags, ULONG FAR *pargtags)
  2124. {
  2125. #ifdef DEBUG
  2126. ULONG cTotalTags = ctags;
  2127. #endif
  2128. while (ctags--)
  2129. {
  2130. ULONG ulPT;
  2131. UINT uiPropType;
  2132. ulPT = *pargtags++;
  2133. if (ulPT == PR_NULL)
  2134. if (uiFlags & TAGS_FROM_OPEN)
  2135. {
  2136. OutputSz1( TEXT("Tag %ld is PR_NULL for OpenProperty.\n"), cTotalTags - ctags);
  2137. return(TRUE);
  2138. }
  2139. else
  2140. continue;
  2141. /* Property ID validation occurs here */
  2142. if ((UINT) PROP_ID(ulPT) == PROP_ID_NULL)
  2143. {
  2144. OutputSz1( TEXT("Tag %ld is PROP_ID_NULL.\n"), cTotalTags - ctags);
  2145. return(TRUE);
  2146. }
  2147. if ((UINT) PROP_ID(ulPT) == PROP_ID_INVALID)
  2148. {
  2149. OutputSz1( TEXT("Tag %ld is PROP_ID_INVALID.\n"), cTotalTags - ctags);
  2150. return(TRUE);
  2151. }
  2152. /* Property type validation follows */
  2153. /* Don't validate property type for nameid mapping */
  2154. if (uiFlags & (TAGS_FROM_NAMEIDS))
  2155. continue;
  2156. /* Disable MVI for SetColumns */
  2157. if ((uiFlags & (TAGS_FROM_SETCOLS | TAGS_FROM_ANY)) && ((UINT) PROP_TYPE(ulPT) & MV_FLAG))
  2158. uiPropType = (UINT) (PROP_TYPE(ulPT) & ~MVI_FLAG);
  2159. else
  2160. uiPropType = (UINT) (PROP_TYPE(ulPT) & ~MV_FLAG);
  2161. switch (uiPropType)
  2162. {
  2163. case (UINT) PT_I2:
  2164. case (UINT) PT_LONG:
  2165. case (UINT) PT_R4:
  2166. case (UINT) PT_DOUBLE:
  2167. case (UINT) PT_CURRENCY:
  2168. case (UINT) PT_APPTIME:
  2169. case (UINT) PT_BOOLEAN:
  2170. case (UINT) PT_I8:
  2171. case (UINT) PT_STRING8:
  2172. case (UINT) PT_UNICODE:
  2173. case (UINT) PT_SYSTIME:
  2174. case (UINT) PT_CLSID:
  2175. case (UINT) PT_BINARY:
  2176. break;
  2177. case (UINT) PT_UNSPECIFIED:
  2178. if (uiFlags & (TAGS_FROM_SET | TAGS_FROM_OPEN | TAGS_FROM_SETCOLS | TAGS_FROM_MODRECIP))
  2179. {
  2180. #ifdef DEBUG
  2181. OutputSz2( TEXT("Tag %ld is PT_UNSPECIFIED for %s.\n"),
  2182. cTotalTags - ctags,
  2183. SzFromTags(uiFlags));
  2184. #endif
  2185. return(TRUE);
  2186. }
  2187. break;
  2188. case (UINT) PT_NULL:
  2189. OutputSz1( TEXT("Tag %ld is PT_NULL.\n"), cTotalTags - ctags);
  2190. return(TRUE);
  2191. break;
  2192. case (UINT) PT_ERROR:
  2193. if (uiFlags & ~(TAGS_FROM_SET | TAGS_FROM_MODRECIP))
  2194. {
  2195. #ifdef DEBUG
  2196. OutputSz2( TEXT("Tag %ld is PT_ERROR for %s.\n"),
  2197. cTotalTags - ctags,
  2198. SzFromTags(uiFlags));
  2199. #endif
  2200. return(TRUE);
  2201. }
  2202. break;
  2203. case (UINT) PT_OBJECT:
  2204. if (uiFlags & (TAGS_FROM_SET | TAGS_FROM_MODRECIP | TAGS_FROM_RESOLVE))
  2205. {
  2206. #ifdef DEBUG
  2207. OutputSz2( TEXT("Tag %ld is PT_OBJECT for %s.\n"),
  2208. cTotalTags - ctags,
  2209. SzFromTags(uiFlags));
  2210. #endif
  2211. return(TRUE);
  2212. }
  2213. break;
  2214. default:
  2215. {
  2216. OutputSz2( TEXT("Tag %ld does not have a valid type %04X.\n"),
  2217. cTotalTags - ctags, (UINT) (PROP_TYPE(ulPT) & ~MV_FLAG));
  2218. return(TRUE);
  2219. }
  2220. }
  2221. }
  2222. return(FALSE);
  2223. }
  2224. /*
  2225. * FInvalidPvals
  2226. *
  2227. * Purpose:
  2228. * determine if any of the pvals in the given array are invalid
  2229. *
  2230. * Arguments:
  2231. * cvals count of values in the following array
  2232. * pvals the array of pvals
  2233. *
  2234. * Returns:
  2235. * TRUE if any of the pvals are invalid
  2236. * FALSE if all of the pvals are valid
  2237. */
  2238. static BOOL NEAR FInvalidPvals(UINT uiFlags, ULONG cvals, LPSPropValue pvals)
  2239. {
  2240. #ifdef DEBUG
  2241. ULONG cTotalVals = cvals;
  2242. UINT cTotalMVVals;
  2243. #endif
  2244. if (cvals == 0)
  2245. {
  2246. OutputSz( TEXT("PropVal count is zero.\n"));
  2247. return(TRUE);
  2248. }
  2249. if (cvals > (UINT_MAX / sizeof(SPropValue)))
  2250. {
  2251. OutputSz( TEXT("PropVal count too big.\n"));
  2252. return(TRUE);
  2253. }
  2254. if (IsBadReadPtr(pvals, (UINT)(cvals * sizeof(SPropValue))))
  2255. {
  2256. OutputSz( TEXT("PropVal array not readable.\n"));
  2257. return(TRUE);
  2258. }
  2259. while (cvals--)
  2260. {
  2261. ULONG tag = pvals->ulPropTag;
  2262. if (!(uiFlags & TAGS_FROM_RESTRICT))
  2263. {
  2264. if (FInvalidPropTags(uiFlags, 1, &tag))
  2265. {
  2266. OutputSz1( TEXT("PropTag %ld not valid.\n"), cTotalVals - cvals);
  2267. return(TRUE);
  2268. }
  2269. }
  2270. if (tag & MV_FLAG)
  2271. {
  2272. UINT cbEnt;
  2273. UINT cvalsMV;
  2274. tag &= ~MV_FLAG;
  2275. switch ((UINT) PROP_TYPE(tag))
  2276. {
  2277. case (UINT) PT_I2:
  2278. cbEnt = sizeof(WORD);
  2279. break;
  2280. case (UINT) PT_LONG:
  2281. case (UINT) PT_R4:
  2282. case (UINT) PT_STRING8:
  2283. case (UINT) PT_UNICODE:
  2284. cbEnt = sizeof(LONG);
  2285. break;
  2286. case (UINT) PT_DOUBLE:
  2287. case (UINT) PT_CURRENCY:
  2288. case (UINT) PT_APPTIME:
  2289. case (UINT) PT_SYSTIME:
  2290. case (UINT) PT_BINARY:
  2291. case (UINT) PT_I8:
  2292. cbEnt = sizeof(LARGE_INTEGER);
  2293. break;
  2294. case (UINT) PT_CLSID:
  2295. cbEnt = sizeof(GUID);
  2296. break;
  2297. default:
  2298. TrapSz( TEXT("Shouldn't get here"));
  2299. return(TRUE);
  2300. }
  2301. if (pvals->Value.MVi.cValues == 0)
  2302. {
  2303. OutputSz1( TEXT("Multi-Valued PropVal %ld has zero cValues.\n"), cTotalVals - cvals);
  2304. return(TRUE);
  2305. }
  2306. if (pvals->Value.MVi.cValues > (UINT_MAX / cbEnt))
  2307. {
  2308. OutputSz1( TEXT("Multi-Valued PropVal %ld has cValues too large.\n"), cTotalVals - cvals);
  2309. return(TRUE);
  2310. }
  2311. if (IsBadReadPtr(pvals->Value.MVi.lpi, (UINT)(cbEnt * pvals->Value.MVi.cValues)))
  2312. {
  2313. OutputSz1( TEXT("Multi-Valued PropVal %ld not readable.\n"), cTotalVals - cvals);
  2314. return(TRUE);
  2315. }
  2316. cvalsMV = (UINT) pvals->Value.MVi.cValues;
  2317. #ifdef DEBUG
  2318. cTotalMVVals = cvalsMV;
  2319. #endif
  2320. switch ((UINT) PROP_TYPE(tag))
  2321. {
  2322. case (UINT) PT_STRING8:
  2323. {
  2324. LPSTR * ppszA = pvals->Value.MVszA.lppszA;
  2325. for (; cvalsMV > 0; --cvalsMV, ++ppszA)
  2326. if (IsBadStringPtrA(*ppszA, (UINT)(-1)))
  2327. {
  2328. OutputSz2( TEXT("Multi-Valued STRING8 PropVal %ld [%d] is bad string.\n"),
  2329. cTotalVals - cvals, cTotalMVVals - cvalsMV);
  2330. return(TRUE);
  2331. }
  2332. break;
  2333. }
  2334. case (UINT) PT_UNICODE:
  2335. {
  2336. UNALIGNED LPWSTR * ppszW = pvals->Value.MVszW.lppszW;
  2337. for (; cvalsMV > 0; --cvalsMV, ++ppszW)
  2338. if (IsBadStringPtrW(*ppszW, (UINT)(-1)))
  2339. {
  2340. OutputSz2( TEXT("Multi-Valued UNICODE PropVal %ld [%d] is bad string.\n"),
  2341. cTotalVals - cvals, cTotalMVVals - cvalsMV);
  2342. return(TRUE);
  2343. }
  2344. break;
  2345. }
  2346. case (UINT) PT_BINARY:
  2347. {
  2348. UNALIGNED SBinary * pbin = pvals->Value.MVbin.lpbin;
  2349. for (; cvalsMV > 0; --cvalsMV, ++pbin)
  2350. {
  2351. if ( pbin->cb > 0
  2352. && ( pbin->cb > UINT_MAX
  2353. || IsBadReadPtr(pbin->lpb, (UINT)pbin->cb)))
  2354. {
  2355. OutputSz2( TEXT("Multi-Valued BINARY PropVal %ld [%d] not readable.\n"),
  2356. cTotalVals - cvals, cTotalMVVals - cvalsMV);
  2357. return(TRUE);
  2358. }
  2359. }
  2360. break;
  2361. }
  2362. }
  2363. }
  2364. else
  2365. {
  2366. switch ((UINT) PROP_TYPE(tag))
  2367. {
  2368. case (UINT) PT_BINARY:
  2369. if ( pvals->Value.bin.cb > UINT_MAX
  2370. || IsBadReadPtr(pvals->Value.bin.lpb,
  2371. (UINT)pvals->Value.bin.cb))
  2372. {
  2373. OutputSz1( TEXT("BINARY PropVal %ld not readable.\n"),
  2374. cTotalVals - cvals);
  2375. return(TRUE);
  2376. }
  2377. break;
  2378. case (UINT) PT_STRING8:
  2379. if (IsBadStringPtrA(pvals->Value.lpszA, (UINT)(-1)))
  2380. {
  2381. OutputSz1( TEXT("STRING8 PropVal %ld not valid string.\n"),
  2382. cTotalVals - cvals);
  2383. return(TRUE);
  2384. }
  2385. break;
  2386. case (UINT) PT_UNICODE:
  2387. if (IsBadStringPtrW(pvals->Value.lpszW, ((UINT)(-1))))
  2388. {
  2389. OutputSz1( TEXT("UNICODE PropVal %ld not valid string.\n"),
  2390. cTotalVals - cvals);
  2391. return(TRUE);
  2392. }
  2393. break;
  2394. case (UINT) PT_CLSID:
  2395. if (IsBadReadPtr(pvals->Value.lpguid, sizeof(GUID)))
  2396. {
  2397. OutputSz1( TEXT("CLSID PropVal %ld not readable.\n"), cTotalVals - cvals);
  2398. return(TRUE);
  2399. }
  2400. break;
  2401. }
  2402. }
  2403. pvals++;
  2404. }
  2405. return (FALSE);
  2406. }
  2407. /*
  2408. * FBadRgLPMAPINAMEID
  2409. *
  2410. */
  2411. static BOOL NEAR FBadRgLPMAPINAMEID(ULONG cNames, LPMAPINAMEID *ppNames)
  2412. {
  2413. LPMAPINAMEID pName;
  2414. #ifdef DEBUG
  2415. ULONG cTotalNames = cNames;
  2416. #endif
  2417. if (cNames > (UINT_MAX / sizeof(LPMAPINAMEID)))
  2418. {
  2419. OutputSz( TEXT("Too many names\n"));
  2420. return(TRUE);
  2421. }
  2422. if (IsBadReadPtr(ppNames, (UINT)(cNames * sizeof(LPMAPINAMEID))))
  2423. {
  2424. OutputSz( TEXT("Name array not readable\n"));
  2425. return(TRUE);
  2426. }
  2427. for (; cNames-- > 0; ++ppNames)
  2428. {
  2429. pName = *ppNames;
  2430. if (IsBadReadPtr(pName, sizeof(MAPINAMEID)))
  2431. {
  2432. OutputSz1( TEXT("Name not readable [%ld]\n"), cTotalNames - cNames);
  2433. return(TRUE);
  2434. }
  2435. if (IsBadReadPtr(pName->lpguid, sizeof(GUID)))
  2436. {
  2437. OutputSz1( TEXT("GUID in name not readable [%ld]\n"), cTotalNames - cNames);
  2438. return(TRUE);
  2439. }
  2440. if (pName->ulKind == MNID_ID)
  2441. continue;
  2442. if (pName->ulKind != MNID_STRING)
  2443. {
  2444. OutputSz1( TEXT("Name type not MNID_STRING [%ld]\n"), cTotalNames - cNames);
  2445. return(TRUE);
  2446. }
  2447. if (IsBadStringPtrW(pName->Kind.lpwstrName, (UINT)-1))
  2448. {
  2449. OutputSz1( TEXT("Name text is bad string [%ld]\n"), cTotalNames - cNames);
  2450. return(TRUE);
  2451. }
  2452. }
  2453. return(FALSE);
  2454. }
  2455. /*============================================================================
  2456. - IsBadRestriction()
  2457. -
  2458. * Returns TRUE if the specified restriction or any of its
  2459. * sub-restrictions are invalid, FALSE otherwise.
  2460. *
  2461. * Stop processing when MAX_DEPTH reached, but do not fail.
  2462. *
  2463. * //$BUG Not completely useful until it's non-recursive....
  2464. *
  2465. * Parameters:
  2466. * cDepth in Current depth of processing
  2467. * lpres in Restriction to validate.
  2468. */
  2469. #define MAX_DEPTH 20
  2470. static BOOL NEAR IsBadRestriction(UINT cDepth, LPSRestriction lpres, BOOL FAR *fTooComplex)
  2471. {
  2472. *fTooComplex = (cDepth > MAX_DEPTH);
  2473. if (*fTooComplex)
  2474. {
  2475. OutputSz1( TEXT("WARNING: Maximum restriction depth reached (%d).\n"), MAX_DEPTH);
  2476. return(FALSE);
  2477. }
  2478. else
  2479. cDepth++;
  2480. /* Handle full restriction of NULL, but not sub-restriction */
  2481. if ((cDepth == 1) && (lpres == NULL))
  2482. return(FALSE);
  2483. if (IsBadReadPtr(lpres, sizeof(SRestriction)))
  2484. {
  2485. OutputSz( TEXT("Restriction not readable.\n"));
  2486. return(TRUE);
  2487. }
  2488. AssertSz(lpres->rt == (UINT) lpres->rt, TEXT("16bit optimzation for restriction type is now invalid!"));
  2489. switch ((UINT) lpres->rt)
  2490. {
  2491. default:
  2492. {
  2493. OutputSz1( TEXT("Unknown restriction type rt = %04X.\n"), (UINT) lpres->rt);
  2494. return(TRUE);
  2495. }
  2496. case (UINT) RES_AND:
  2497. case (UINT) RES_OR:
  2498. {
  2499. LPSRestriction lpresT;
  2500. lpresT = lpres->res.resAnd.lpRes + lpres->res.resAnd.cRes;
  2501. while ( lpresT-- > lpres->res.resAnd.lpRes )
  2502. if ( IsBadRestriction(cDepth, lpresT, fTooComplex) )
  2503. {
  2504. OutputSz1( TEXT("Restriction: Bad %s part.\n"), lpres->rt == RES_AND ? TEXT("AND") : TEXT("OR"));
  2505. return(TRUE);
  2506. }
  2507. return FALSE;
  2508. }
  2509. case (UINT) RES_NOT:
  2510. case (UINT) RES_COMMENT:
  2511. // Ignore the PropValue list for comments
  2512. if (IsBadRestriction(cDepth, lpres->res.resComment.lpRes, fTooComplex))
  2513. {
  2514. OutputSz1( TEXT("Restriction: Bad %s part.\n"), lpres->rt == RES_NOT ? TEXT("NOT") : TEXT("COMMENT"));
  2515. return(TRUE);
  2516. }
  2517. else
  2518. return(FALSE);
  2519. case (UINT) RES_CONTENT:
  2520. if (lpres->res.resContent.ulFuzzyLevel &
  2521. ~(ULONG)(FL_SUBSTRING | FL_LOOSE | FL_PREFIX |
  2522. FL_IGNORECASE | FL_IGNORENONSPACE | FL_LOOSE))
  2523. {
  2524. OutputSz( TEXT("Restriction: Bad CONTENT part - Invalid Fuzzy Level.\n"));
  2525. return(TRUE);
  2526. }
  2527. // Fall throught
  2528. case (UINT) RES_PROPERTY:
  2529. AssertSz(RELOP_LT == 0 && RELOP_RE == 6, TEXT("RELOP definitions changed"));
  2530. if ( lpres->rt == RES_PROPERTY
  2531. && ((UINT) lpres->res.resProperty.relop > (UINT) RELOP_RE))
  2532. {
  2533. OutputSz1( TEXT("Restriction: Bad %s part. - RELOP unknown RELOP\n"), lpres->rt == RES_PROPERTY ? TEXT("PROPERTY") : TEXT("CONTENT"));
  2534. return(TRUE);
  2535. }
  2536. if (FInvalidPropTags(TAGS_FROM_ANY, 1, &(lpres->res.resProperty.ulPropTag)))
  2537. {
  2538. OutputSz1( TEXT("Restriction: Bad %s part. - Invalid PropTag\n"), lpres->rt == RES_PROPERTY ? TEXT("PROPERTY") : TEXT("CONTENT"));
  2539. return(TRUE);
  2540. }
  2541. else if (FInvalidPvals(TAGS_FROM_RESTRICT, 1, lpres->res.resProperty.lpProp))
  2542. {
  2543. OutputSz1( TEXT("Restriction: Bad %s part. - Invalid PropVal\n"), lpres->rt == RES_PROPERTY ? TEXT("PROPERTY") : TEXT("CONTENT"));
  2544. return(TRUE);
  2545. }
  2546. else if ( PROP_TYPE(lpres->res.resProperty.ulPropTag) != PROP_TYPE(lpres->res.resProperty.lpProp->ulPropTag)
  2547. // It is legal to have MV <-> SV and MVI <-> SV comparisons
  2548. // It is legal but probably too complex to have MV <-> MV
  2549. // comparisons. Anything else is bad.
  2550. && (PROP_TYPE(lpres->res.resContent.ulPropTag) & ~MVI_FLAG) != PROP_TYPE(lpres->res.resContent.lpProp->ulPropTag))
  2551. {
  2552. OutputSz1( TEXT("Restriction: Bad %s part. - PropTag and PropVal have incompatible Types\n"),
  2553. lpres->rt == RES_PROPERTY ? TEXT("PROPERTY") : TEXT("CONTENT"));
  2554. return(TRUE);
  2555. }
  2556. else
  2557. return(FALSE);
  2558. case (UINT) RES_COMPAREPROPS:
  2559. AssertSz(RELOP_LT == 0 && RELOP_RE == 6, TEXT("RELOP definitions changed"));
  2560. if ((UINT) lpres->res.resCompareProps.relop > (UINT) RELOP_RE)
  2561. {
  2562. OutputSz( TEXT("Restriction: Bad COMPAREPROPS part - RELOP unknown RELOP.\n"));
  2563. return(TRUE);
  2564. }
  2565. else if (FInvalidPropTags(TAGS_FROM_ANY, 1, &(lpres->res.resCompareProps.ulPropTag1)))
  2566. {
  2567. OutputSz( TEXT("Restriction: Bad COMPAREPROPS part - Invalid PropTag - PropTag 1.\n"));
  2568. return(TRUE);
  2569. }
  2570. else if (FInvalidPropTags(TAGS_FROM_ANY, 1, &(lpres->res.resCompareProps.ulPropTag2)))
  2571. {
  2572. OutputSz( TEXT("Restriction: Bad COMPAREPROPS part - Invalid PropTag - PropTag 2.\n"));
  2573. return(TRUE);
  2574. }
  2575. else
  2576. return(FALSE);
  2577. case (UINT) RES_BITMASK:
  2578. if ((lpres->res.resBitMask.relBMR != BMR_EQZ &&
  2579. lpres->res.resBitMask.relBMR != BMR_NEZ) ||
  2580. FInvalidPropTags(TAGS_FROM_ANY, 1, &(lpres->res.resBitMask.ulPropTag)))
  2581. {
  2582. OutputSz( TEXT("Restriction: Bad PROPERTY part.\n"));
  2583. return(TRUE);
  2584. }
  2585. else
  2586. return(FALSE);
  2587. case (UINT) RES_SIZE:
  2588. AssertSz(RELOP_LT == 0 && RELOP_RE == 6, TEXT("RELOP definitions changed"));
  2589. if ((UINT) lpres->res.resSize.relop > (UINT) RELOP_RE)
  2590. {
  2591. OutputSz( TEXT("Restriction: Bad SIZE part - RELOP unknown RELOP.\n"));
  2592. return(TRUE);
  2593. }
  2594. else if (FInvalidPropTags(TAGS_FROM_ANY, 1, &(lpres->res.resSize.ulPropTag)))
  2595. {
  2596. OutputSz( TEXT("Restriction: Bad SIZE part - Invalid PropTag.\n"));
  2597. return(TRUE);
  2598. }
  2599. else
  2600. return(FALSE);
  2601. case (UINT) RES_EXIST:
  2602. // Reserved structure members and type of proptag are ignored...
  2603. return FALSE;
  2604. case (UINT) RES_SUBRESTRICTION:
  2605. if ((PROP_TYPE(lpres->res.resSub.ulSubObject) != PT_OBJECT) ||
  2606. IsBadRestriction(cDepth, lpres->res.resSub.lpRes, fTooComplex))
  2607. {
  2608. OutputSz( TEXT("Restriction: Bad SUBRESTRICTION part.\n"));
  2609. return(TRUE);
  2610. }
  2611. else
  2612. return(FALSE);
  2613. }
  2614. }
  2615. static BOOL NEAR IsBadEntryList(LPENTRYLIST lpEntryList)
  2616. {
  2617. ULONG cCount;
  2618. if (IsBadReadPtr(lpEntryList, sizeof(ENTRYLIST)))
  2619. {
  2620. OutputSz( TEXT("Entry list not readable.\n"));
  2621. return(TRUE);
  2622. }
  2623. for (cCount = 0; cCount < lpEntryList->cValues; cCount++)
  2624. {
  2625. if (IsBadReadPtr(&(lpEntryList->lpbin[cCount]), sizeof(SBinary)))
  2626. {
  2627. OutputSz( TEXT("Entry list: Binary element not readable.\n"));
  2628. return(TRUE);
  2629. }
  2630. if (IsBadReadPtr(lpEntryList->lpbin[cCount].lpb, (UINT) lpEntryList->lpbin[cCount].cb))
  2631. {
  2632. OutputSz( TEXT("Entry list: Binary data not readable.\n"));
  2633. return(TRUE);
  2634. }
  2635. }
  2636. return(FALSE);
  2637. }
  2638. static BOOL NEAR IsBadSortOrderSet(LPSSortOrderSet lpsos)
  2639. {
  2640. LPSSortOrder lpso;
  2641. // Validate sort order set itself
  2642. #ifndef MAC
  2643. // These are no-ops on the MAC
  2644. if ( IsBadReadPtr(lpsos, (size_t)CbNewSSortOrderSet(0)) ||
  2645. IsBadReadPtr(lpsos, (size_t)CbSSortOrderSet(lpsos)))
  2646. #else
  2647. if ((long)lpsos < 0)
  2648. #endif
  2649. {
  2650. OutputSz( TEXT("FBadSortOrderSet() - Bad sort order set struct\n") );
  2651. return TRUE;
  2652. }
  2653. if (lpsos->cExpanded > lpsos->cCategories)
  2654. {
  2655. OutputSz2( TEXT("FBadSortOrderSet() - lpsos->cExpanded = 0x%08lX is greater than ")
  2656. TEXT("lpsos->cCategories = 0x%08lX\n"), lpsos->cExpanded,
  2657. lpsos->cCategories);
  2658. return TRUE;
  2659. }
  2660. if (lpsos->cCategories > lpsos->cSorts)
  2661. {
  2662. OutputSz2( TEXT("FBadSortOrderSet() - lpsos->cCategories = 0x%08lX is greater than ")
  2663. TEXT("lpsos->cSorts = 0x%08lX\n"), lpsos->cCategories,
  2664. lpsos->cSorts);
  2665. return TRUE;
  2666. }
  2667. // Validate each sort order in the set
  2668. lpso = lpsos->aSort + lpsos->cSorts;
  2669. while ( lpso-- > lpsos->aSort )
  2670. {
  2671. // If a column set was specified, make sure the proptag in
  2672. // each sort order refers to a column in the column set.
  2673. //
  2674. // DCR 978: Disallow PT_ERROR columns.
  2675. if (((UINT) PROP_TYPE(lpso->ulPropTag) == (UINT) PT_ERROR) ||
  2676. FInvalidPropTags(TAGS_FROM_ANY, 1, &(lpso->ulPropTag)))
  2677. {
  2678. OutputSz1( TEXT("FBadSortOrderSet() - Bad sort column 0x%08lX\n"),
  2679. lpso->ulPropTag);
  2680. return TRUE;
  2681. }
  2682. // Make sure only the ascending/descending/or linked bit is set
  2683. if (lpso->ulOrder &
  2684. ~(TABLE_SORT_DESCEND | TABLE_SORT_ASCEND |
  2685. (lpsos->cCategories ? TABLE_SORT_COMBINE : 0)))
  2686. {
  2687. OutputSz1( TEXT("FBadSortOrderSet() - Bad sort order 0x%08lX\n"),
  2688. lpso->ulOrder);
  2689. return TRUE;
  2690. }
  2691. }
  2692. return FALSE;
  2693. }
  2694. static BOOL NEAR IsBadAdrListMR(LPADRLIST pal, ULONG ulFlags)
  2695. {
  2696. LPADRENTRY paeMic;
  2697. LPADRENTRY paeMax;
  2698. UINT iEnt;
  2699. if ( IsBadReadPtr(pal, CbNewADRLIST(0))
  2700. || IsBadReadPtr(pal, CbADRLIST(pal)))
  2701. {
  2702. OutputSz( TEXT("AdrList not readable\n"));
  2703. return(TRUE);
  2704. }
  2705. paeMic = pal->aEntries;
  2706. paeMax = pal->aEntries + pal->cEntries;
  2707. for (iEnt = 0; paeMic < paeMax; paeMic++, iEnt++)
  2708. {
  2709. // ignore a completely empty prop val array.
  2710. if (paeMic->rgPropVals && IsBadAdrEntryMR(paeMic, ulFlags, iEnt))
  2711. return(TRUE);
  2712. }
  2713. return(FALSE);
  2714. }
  2715. #define MRF_ROWID 0x0001
  2716. #define MRF_DISPLAY_NAME 0x0002
  2717. #define MRF_RECIPIENT_TYPE 0x0004
  2718. static BOOL NEAR IsBadAdrEntryMR(LPADRENTRY pae, ULONG ulFlags, UINT iEnt)
  2719. {
  2720. LPSPropValue pvalMic;
  2721. LPSPropValue pvalMax;
  2722. UINT uiFlags, uiFlag;
  2723. LPSPropValue rgPropVals;
  2724. ULONG cValues;
  2725. rgPropVals = pae->rgPropVals;
  2726. cValues = pae->cValues;
  2727. if (FInvalidPvals(TAGS_FROM_MODRECIP, cValues, rgPropVals))
  2728. {
  2729. OutputSz1( TEXT("Message_ModifyRecipients: Invalid AdrEntry #%d\n"), iEnt);
  2730. return(TRUE);
  2731. }
  2732. pvalMic = rgPropVals;
  2733. pvalMax = rgPropVals + cValues;
  2734. uiFlags = 0;
  2735. for (; pvalMic < pvalMax; pvalMic++)
  2736. {
  2737. switch (pvalMic->ulPropTag)
  2738. {
  2739. case PR_ROWID: uiFlag = MRF_ROWID; break;
  2740. case PR_DISPLAY_NAME_A:
  2741. case PR_DISPLAY_NAME_W: uiFlag = MRF_DISPLAY_NAME; break;
  2742. case PR_RECIPIENT_TYPE: uiFlag = MRF_RECIPIENT_TYPE; break;
  2743. default: uiFlag = 0; break;
  2744. }
  2745. if (uiFlags & uiFlag)
  2746. {
  2747. OutputSz2( TEXT("Message_ModifyRecipients: AdrEntry #%d has more than ")
  2748. TEXT("one %s\n"), iEnt,
  2749. (uiFlag == MRF_ROWID) ? (LPSTR)szRowId :
  2750. ((uiFlag == MRF_DISPLAY_NAME) ?
  2751. (LPSTR)szDispName : (LPSTR)szRecipType));
  2752. return(TRUE);
  2753. }
  2754. uiFlags |= uiFlag;
  2755. }
  2756. switch (ulFlags)
  2757. {
  2758. case 0: // Zero means delete all entries, then ADD these
  2759. case MODRECIP_ADD:
  2760. // Don't care if they supply PR_ROWID for ADD -- we'll ignore it
  2761. if ((uiFlags & (MRF_DISPLAY_NAME|MRF_RECIPIENT_TYPE)) !=
  2762. (MRF_DISPLAY_NAME|MRF_RECIPIENT_TYPE)) {
  2763. OutputSz1( TEXT("Message_ModifyRecipients: Must supply ")
  2764. TEXT("PR_DISPLAY_NAME and PR_RECIPIENT_TYPE in AdrEntry #%d ")
  2765. TEXT("for MODRECIP_ADD\n"), iEnt);
  2766. return(TRUE);
  2767. }
  2768. break;
  2769. case MODRECIP_MODIFY:
  2770. if (uiFlags != (MRF_ROWID|MRF_DISPLAY_NAME|MRF_RECIPIENT_TYPE))
  2771. {
  2772. OutputSz1( TEXT("Message_ModifyRecipients: Must supply PR_ROWID, ")
  2773. TEXT("PR_DISPLAY_NAME, and PR_RECIPIENT_TYPE in AdrEntry #%d ")
  2774. TEXT("for MODRECIP_MODIFY\n"), iEnt);
  2775. return(TRUE);
  2776. }
  2777. break;
  2778. case MODRECIP_REMOVE:
  2779. if ((uiFlags & MRF_ROWID) == 0)
  2780. {
  2781. OutputSz1( TEXT("Message_ModifyRecipients: Must supply PR_ROWID ")
  2782. TEXT("in AdrEntry #%d for MODRECIP_REMOVE\n"), iEnt);
  2783. return(TRUE);
  2784. }
  2785. break;
  2786. }
  2787. return(FALSE);
  2788. }
  2789. static BOOL NEAR IsBadMAPIEntryID(ULONG ulcbEntryID, LPENTRYID lpEntryID)
  2790. {
  2791. BOOL lbRet = TRUE;
  2792. if ((UINT) ulcbEntryID > UINT_MAX)
  2793. goto ret;
  2794. if (IsBadReadPtr(lpEntryID, (size_t) ulcbEntryID))
  2795. goto ret;
  2796. lbRet = FALSE;
  2797. ret:
  2798. return(lbRet);
  2799. }
  2800. /*============================================================================
  2801. - FBadABEntryList()
  2802. -
  2803. * Returns TRUE if the specified entrylist is invalid.
  2804. *
  2805. * Parameters:
  2806. * lpentrylist in Entrylist to validate.
  2807. */
  2808. static BOOL NEAR IsBadABEntryList(LPENTRYLIST lpentrylist)
  2809. {
  2810. LPSBinary lpbin;
  2811. if ( IsBadReadPtr(lpentrylist,sizeof(ENTRYLIST)) ||
  2812. IsBadReadPtr(lpentrylist->lpbin,(size_t)(lpentrylist->cValues * sizeof(SBinary))) )
  2813. return TRUE;
  2814. lpbin = lpentrylist->lpbin + lpentrylist->cValues;
  2815. while (lpbin-- > lpentrylist->lpbin)
  2816. if (IsBadMAPIEntryID(lpbin->cb, (LPENTRYID) lpbin->lpb))
  2817. return TRUE;
  2818. return FALSE;
  2819. }
  2820. /* External definitions */
  2821. STDAPI_(ULONG)
  2822. FBadRestriction(LPSRestriction lpres)
  2823. {
  2824. BOOL fTooComplex;
  2825. return(IsBadRestriction(0, lpres, &fTooComplex));
  2826. }
  2827. STDAPI_(BOOL)
  2828. FBadEntryList(LPENTRYLIST lpEntryList)
  2829. {
  2830. return(IsBadEntryList(lpEntryList));
  2831. }
  2832. STDAPI_(BOOL)
  2833. FBadDelPTA(LPSPropTagArray lpPropTagArray)
  2834. {
  2835. return(FInvalidPTA(TAGS_FROM_DEL, lpPropTagArray));
  2836. }
  2837. STDAPI_(ULONG)
  2838. FBadSortOrderSet(LPSSortOrderSet lpsos)
  2839. {
  2840. return(IsBadSortOrderSet(lpsos));
  2841. }