2 * MAPI Utility functions
4 * Copyright 2004 Jon Griffiths
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #define NONAMELESSUNION
24 #define NONAMELESSSTRUCT
32 #include "wine/debug.h"
33 #include "wine/unicode.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(mapi);
39 /**************************************************************************
40 * ScInitMapiUtil (MAPI32.33)
42 * Initialise Mapi utility functions.
45 * ulReserved [I] Reserved, pass 0.
48 * Success: S_OK. Mapi utility functions may be called.
49 * Failure: MAPI_E_INVALID_PARAMETER, if ulReserved is not 0.
52 * Your application does not need to call this function unless it does not
53 * call MAPIInitialize()/MAPIUninitialize().
55 SCODE WINAPI ScInitMapiUtil(ULONG ulReserved)
57 FIXME("(0x%08lx)stub!\n", ulReserved);
59 return MAPI_E_INVALID_PARAMETER;
63 /**************************************************************************
64 * DeinitMapiUtil (MAPI32.34)
66 * Uninitialise Mapi utility functions.
75 * Your application does not need to call this function unless it does not
76 * call MAPIInitialize()/MAPIUninitialize().
78 VOID WINAPI DeinitMapiUtil(void)
83 typedef LPVOID *LPMAPIALLOCBUFFER;
85 /**************************************************************************
86 * MAPIAllocateBuffer (MAPI32.12)
87 * MAPIAllocateBuffer@8 (MAPI32.13)
89 * Allocate a block of memory.
92 * cbSize [I] Size of the block to allocate in bytes
93 * lppBuffer [O] Destination for pointer to allocated memory
96 * Success: S_OK. *lppBuffer is filled with a pointer to a memory block of
97 * length cbSize bytes.
98 * Failure: MAPI_E_INVALID_PARAMETER, if lppBuffer is NULL.
99 * MAPI_E_NOT_ENOUGH_MEMORY, if the memory allocation fails.
102 * Memory allocated with this function should be freed with MAPIFreeBuffer().
103 * Further allocations of memory may be linked to the pointer returned using
104 * MAPIAllocateMore(). Linked allocations are freed when the initial pointer
107 SCODE WINAPI MAPIAllocateBuffer(ULONG cbSize, LPVOID *lppBuffer)
109 LPMAPIALLOCBUFFER lpBuff;
111 TRACE("(%ld,%p)\n", cbSize, lppBuffer);
116 lpBuff = (LPMAPIALLOCBUFFER)HeapAlloc(GetProcessHeap(), 0, cbSize + sizeof(*lpBuff));
118 return MAPI_E_NOT_ENOUGH_MEMORY;
120 TRACE("initial allocation:%p, returning %p\n", lpBuff, lpBuff + 1);
126 /**************************************************************************
127 * MAPIAllocateMore (MAPI32.14)
128 * MAPIAllocateMore@12 (MAPI32.15)
130 * Allocate a block of memory linked to a previous allocation.
133 * cbSize [I] Size of the block to allocate in bytes
134 * lpOrig [I] Initial allocation to link to, from MAPIAllocateBuffer()
135 * lppBuffer [O] Destination for pointer to allocated memory
138 * Success: S_OK. *lppBuffer is filled with a pointer to a memory block of
139 * length cbSize bytes.
140 * Failure: MAPI_E_INVALID_PARAMETER, if lpOrig or lppBuffer is invalid.
141 * MAPI_E_NOT_ENOUGH_MEMORY, if memory allocation fails.
144 * Memory allocated with this function and stored in *lppBuffer is freed
145 * when lpOrig is passed to MAPIFreeBuffer(). It should not be freed independently.
147 SCODE WINAPI MAPIAllocateMore(ULONG cbSize, LPVOID lpOrig, LPVOID *lppBuffer)
149 LPMAPIALLOCBUFFER lpBuff = lpOrig;
151 TRACE("(%ld,%p,%p)\n", cbSize, lpOrig, lppBuffer);
153 if (!lppBuffer || !lpBuff || !--lpBuff)
156 /* Find the last allocation in the chain */
159 TRACE("linked:%p->%p\n", lpBuff, *lpBuff);
163 if (SUCCEEDED(MAPIAllocateBuffer(cbSize, lppBuffer)))
165 *lpBuff = ((LPMAPIALLOCBUFFER)*lppBuffer) - 1;
166 TRACE("linking %p->%p\n", lpBuff, *lpBuff);
168 return *lppBuffer ? S_OK : MAPI_E_NOT_ENOUGH_MEMORY;
171 /**************************************************************************
172 * MAPIFreeBuffer (MAPI32.16)
173 * MAPIFreeBuffer@4 (MAPI32.17)
175 * Free a block of memory and any linked allocations associated with it.
178 * lpBuffer [I] Memory to free, returned from MAPIAllocateBuffer()
183 ULONG WINAPI MAPIFreeBuffer(LPVOID lpBuffer)
185 LPMAPIALLOCBUFFER lpBuff = lpBuffer;
187 TRACE("(%p)\n", lpBuffer);
189 if (lpBuff && --lpBuff)
193 LPVOID lpFree = lpBuff;
197 TRACE("linked:%p->%p, freeing %p\n", lpFree, lpBuff, lpFree);
198 HeapFree(GetProcessHeap(), 0, lpFree);
204 /*************************************************************************
205 * HrThisThreadAdviseSink@8 (MAPI32.42)
207 * Ensure that an advise sink is only notified in its originating thread.
210 * lpSink [I] IMAPIAdviseSink interface to be protected
211 * lppNewSink [I] Destination for wrapper IMAPIAdviseSink interface
214 * Success: S_OK. *lppNewSink contains a new sink to use in place of lpSink.
215 * Failure: E_INVALIDARG, if any parameter is invalid.
217 HRESULT WINAPI HrThisThreadAdviseSink(LPMAPIADVISESINK lpSink, LPMAPIADVISESINK* lppNewSink)
219 FIXME("(%p,%p)semi-stub\n", lpSink, lppNewSink);
221 if (!lpSink || !lppNewSink)
224 /* Don't wrap the sink for now, just copy it */
225 *lppNewSink = lpSink;
226 IMAPIAdviseSink_AddRef(lpSink);
230 /*************************************************************************
231 * SwapPlong@8 (MAPI32.47)
233 * Swap the bytes in a ULONG array.
236 * lpData [O] Array to swap bytes in
237 * ulLen [I] Number of ULONG element to swap the bytes of
242 VOID WINAPI SwapPlong(PULONG lpData, ULONG ulLen)
246 for (i = 0; i < ulLen; i++)
247 lpData[i] = RtlUlongByteSwap(lpData[i]);
250 /*************************************************************************
251 * SwapPword@8 (MAPI32.48)
253 * Swap the bytes in a USHORT array.
256 * lpData [O] Array to swap bytes in
257 * ulLen [I] Number of USHORT element to swap the bytes of
262 VOID WINAPI SwapPword(PUSHORT lpData, ULONG ulLen)
266 for (i = 0; i < ulLen; i++)
267 lpData[i] = RtlUshortByteSwap(lpData[i]);
270 /**************************************************************************
271 * MNLS_lstrlenW@4 (MAPI32.62)
273 * Calculate the length of a Unicode string.
276 * lpszStr [I] String to calculate the length of
279 * The length of lpszStr in Unicode characters.
281 ULONG WINAPI MNLS_lstrlenW(LPCWSTR lpszStr)
283 TRACE("(%s)\n", debugstr_w(lpszStr));
284 return strlenW(lpszStr);
287 /*************************************************************************
288 * MNLS_lstrcmpW@8 (MAPI32.63)
290 * Compare two Unicode strings.
293 * lpszLeft [I] First string to compare
294 * lpszRight [I] Second string to compare
297 * An integer less than, equal to or greater than 0, indicating that
298 * lpszLeft is less than, the same, or greater than lpszRight.
300 INT WINAPI MNLS_lstrcmpW(LPCWSTR lpszLeft, LPCWSTR lpszRight)
302 TRACE("(%s,%s)\n", debugstr_w(lpszLeft), debugstr_w(lpszRight));
303 return strcmpW(lpszLeft, lpszRight);
306 /*************************************************************************
307 * MNLS_lstrcpyW@8 (MAPI32.64)
309 * Copy a Unicode string to another string.
312 * lpszDest [O] Destination string
313 * lpszSrc [I] Source string
316 * The length lpszDest in Unicode characters.
318 ULONG WINAPI MNLS_lstrcpyW(LPWSTR lpszDest, LPCWSTR lpszSrc)
322 TRACE("(%p,%s)\n", lpszDest, debugstr_w(lpszSrc));
323 len = (strlenW(lpszSrc) + 1) * sizeof(WCHAR);
324 memcpy(lpszDest, lpszSrc, len);
328 /*************************************************************************
329 * MNLS_CompareStringW@12 (MAPI32.65)
331 * Compare two Unicode strings.
334 * dwCp [I] Code page for the comparison
335 * lpszLeft [I] First string to compare
336 * lpszRight [I] Second string to compare
339 * CSTR_LESS_THAN, CSTR_EQUAL or CSTR_GREATER_THAN, indicating that
340 * lpszLeft is less than, the same, or greater than lpszRight.
342 INT WINAPI MNLS_CompareStringW(DWORD dwCp, LPCWSTR lpszLeft, LPCWSTR lpszRight)
346 TRACE("0x%08lx,%s,%s\n", dwCp, debugstr_w(lpszLeft), debugstr_w(lpszRight));
347 ret = MNLS_lstrcmpW(lpszLeft, lpszRight);
348 return ret < 0 ? CSTR_LESS_THAN : ret ? CSTR_GREATER_THAN : CSTR_EQUAL;
352 /**************************************************************************
353 * FtAddFt@16 (MAPI32.121)
355 * Add two FILETIME's together.
358 * ftLeft [I] FILETIME to add to ftRight
359 * ftRight [I] FILETIME to add to ftLeft
362 * The sum of ftLeft and ftRight
364 LONGLONG WINAPI MAPI32_FtAddFt(FILETIME ftLeft, FILETIME ftRight)
366 LONGLONG *pl = (LONGLONG*)&ftLeft, *pr = (LONGLONG*)&ftRight;
371 /**************************************************************************
372 * FtSubFt@16 (MAPI32.123)
374 * Subtract two FILETIME's together.
377 * ftLeft [I] Initial FILETIME
378 * ftRight [I] FILETIME to subtract from ftLeft
381 * The remainder after ftRight is subtracted from ftLeft.
383 LONGLONG WINAPI MAPI32_FtSubFt(FILETIME ftLeft, FILETIME ftRight)
385 LONGLONG *pl = (LONGLONG*)&ftLeft, *pr = (LONGLONG*)&ftRight;
390 /**************************************************************************
391 * FtMulDw@12 (MAPI32.124)
393 * Multiply a FILETIME by a DWORD.
396 * dwLeft [I] DWORD to multiply with ftRight
397 * ftRight [I] FILETIME to multiply with dwLeft
400 * The product of dwLeft and ftRight
402 LONGLONG WINAPI MAPI32_FtMulDw(DWORD dwLeft, FILETIME ftRight)
404 LONGLONG *pr = (LONGLONG*)&ftRight;
406 return (LONGLONG)dwLeft * (*pr);
409 /**************************************************************************
410 * FtMulDwDw@8 (MAPI32.125)
412 * Multiply two DWORD, giving the result as a FILETIME.
415 * dwLeft [I] DWORD to multiply with dwRight
416 * dwRight [I] DWORD to multiply with dwLeft
419 * The product of ftMultiplier and ftMultiplicand as a FILETIME.
421 LONGLONG WINAPI MAPI32_FtMulDwDw(DWORD dwLeft, DWORD dwRight)
423 return (LONGLONG)dwLeft * (LONGLONG)dwRight;
426 /**************************************************************************
427 * FtNegFt@8 (MAPI32.126)
432 * ft [I] FILETIME to negate
435 * The negation of ft.
437 LONGLONG WINAPI MAPI32_FtNegFt(FILETIME ft)
439 LONGLONG *p = (LONGLONG*)&ft;
444 /**************************************************************************
445 * UlAddRef@4 (MAPI32.128)
447 * Add a reference to an object.
450 * lpUnk [I] Object to add a reference to.
453 * The new reference count of the object, or 0 if lpUnk is NULL.
456 * See IUnknown_AddRef.
458 ULONG WINAPI UlAddRef(void *lpUnk)
460 TRACE("(%p)\n", lpUnk);
464 return IUnknown_AddRef((LPUNKNOWN)lpUnk);
467 /**************************************************************************
468 * UlRelease@4 (MAPI32.129)
470 * Remove a reference from an object.
473 * lpUnk [I] Object to remove reference from.
476 * The new reference count of the object, or 0 if lpUnk is NULL. If lpUnk is
477 * non-NULL and this function returns 0, the object pointed to by lpUnk has
481 * See IUnknown_Release.
483 ULONG WINAPI UlRelease(void *lpUnk)
485 TRACE("(%p)\n", lpUnk);
489 return IUnknown_Release((LPUNKNOWN)lpUnk);
492 /*************************************************************************
493 * OpenStreamOnFile@24 (MAPI32.147)
495 * Create a stream on a file.
498 * lpAlloc [I] Memory allocation function
499 * lpFree [I] Memory free function
500 * ulFlags [I] Flags controlling the opening process
501 * lpszPath [I] Path of file to create stream on
502 * lpszPrefix [I] Prefix of the temporary file name (if ulFlags includes SOF_UNIQUEFILENAME)
503 * lppStream [O] Destination for created stream
506 * Success: S_OK. lppStream contains the new stream object
507 * Failure: E_INVALIDARG if any parameter is invalid, or an HRESULT error code
508 * describing the error.
510 HRESULT WINAPI OpenStreamOnFile(LPALLOCATEBUFFER lpAlloc, LPFREEBUFFER lpFree,
511 ULONG ulFlags, LPWSTR lpszPath, LPWSTR lpszPrefix,
514 WCHAR szBuff[MAX_PATH];
515 DWORD dwMode = STGM_READWRITE, dwAttributes = 0;
518 TRACE("(%p,%p,0x%08lx,%s,%s,%p)\n", lpAlloc, lpFree, ulFlags,
519 debugstr_a((LPSTR)lpszPath), debugstr_a((LPSTR)lpszPrefix), lppStream);
524 if (ulFlags & SOF_UNIQUEFILENAME)
526 FIXME("Should generate a temporary name\n");
530 if (!lpszPath || !lppStream)
533 /* FIXME: Should probably munge mode and attributes, and should handle
534 * Unicode arguments (I assume MAPI_UNICODE is set in ulFlags if
535 * we are being passed Unicode strings; MSDN doesn't say).
536 * This implementation is just enough for Outlook97 to start.
538 MultiByteToWideChar(CP_ACP, 0, (LPSTR)lpszPath, -1, szBuff, MAX_PATH);
539 hRet = SHCreateStreamOnFileEx(szBuff, dwMode, dwAttributes, TRUE,
545 /*************************************************************************
546 * cmc_query_configuration (MAPI32.235)
548 * Retrieves the configuration information for the installed CMC
551 * session [I] MAPI session handle
552 * item [I] Enumerated variable that identifies which
553 * configuration information is being requested
554 * reference [O] Buffer where configuration information is written
555 * config_extensions[I/O] Path of file to create stream on
560 CMC_return_code WINAPI cmc_query_configuration(
561 CMC_session_id session,
563 CMC_buffer reference,
564 CMC_extension *config_extensions)
567 return CMC_E_NOT_SUPPORTED;