ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

util.c
Go to the documentation of this file.
00001 /*
00002  * MAPI Utility functions
00003  *
00004  * Copyright 2004 Jon Griffiths
00005  * Copyright 2009 Owen Rudge for CodeWeavers
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00020  */
00021 
00022 #include <stdarg.h>
00023 #include <stdio.h>
00024 
00025 #define COBJMACROS
00026 #define NONAMELESSUNION
00027 #define NONAMELESSSTRUCT
00028 #include "windef.h"
00029 #include "winbase.h"
00030 #include "winreg.h"
00031 #include "winuser.h"
00032 #include "winerror.h"
00033 #include "winternl.h"
00034 #include "objbase.h"
00035 #include "shlwapi.h"
00036 #include "wine/debug.h"
00037 #include "wine/unicode.h"
00038 #include "mapival.h"
00039 #include "xcmc.h"
00040 #include "msi.h"
00041 #include "util.h"
00042 
00043 WINE_DEFAULT_DEBUG_CHANNEL(mapi);
00044 
00045 static const BYTE digitsToHex[] = {
00046   0,1,2,3,4,5,6,7,8,9,0xff,0xff,0xff,0xff,0xff,0xff,0xff,10,11,12,13,14,15,
00047   0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
00048   0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,10,11,12,13,
00049   14,15 };
00050 
00051 MAPI_FUNCTIONS mapiFunctions;
00052 
00053 /**************************************************************************
00054  *  ScInitMapiUtil (MAPI32.33)
00055  *
00056  * Initialise Mapi utility functions.
00057  *
00058  * PARAMS
00059  *  ulReserved [I] Reserved, pass 0.
00060  *
00061  * RETURNS
00062  *  Success: S_OK. Mapi utility functions may be called.
00063  *  Failure: MAPI_E_INVALID_PARAMETER, if ulReserved is not 0.
00064  *
00065  * NOTES
00066  *  Your application does not need to call this function unless it does not
00067  *  call MAPIInitialize()/MAPIUninitialize().
00068  */
00069 SCODE WINAPI ScInitMapiUtil(ULONG ulReserved)
00070 {
00071     if (mapiFunctions.ScInitMapiUtil)
00072         return mapiFunctions.ScInitMapiUtil(ulReserved);
00073 
00074     FIXME("(0x%08x)stub!\n", ulReserved);
00075     if (ulReserved)
00076         return MAPI_E_INVALID_PARAMETER;
00077     return S_OK;
00078 }
00079 
00080 /**************************************************************************
00081  *  DeinitMapiUtil (MAPI32.34)
00082  *
00083  * Uninitialise Mapi utility functions.
00084  *
00085  * PARAMS
00086  *  None.
00087  *
00088  * RETURNS
00089  *  Nothing.
00090  *
00091  * NOTES
00092  *  Your application does not need to call this function unless it does not
00093  *  call MAPIInitialize()/MAPIUninitialize().
00094  */
00095 VOID WINAPI DeinitMapiUtil(void)
00096 {
00097     if (mapiFunctions.DeinitMapiUtil)
00098         mapiFunctions.DeinitMapiUtil();
00099     else
00100         FIXME("()stub!\n");
00101 }
00102 
00103 typedef LPVOID *LPMAPIALLOCBUFFER;
00104 
00105 /**************************************************************************
00106  *  MAPIAllocateBuffer   (MAPI32.12)
00107  *  MAPIAllocateBuffer@8 (MAPI32.13)
00108  *
00109  * Allocate a block of memory.
00110  *
00111  * PARAMS
00112  *  cbSize    [I] Size of the block to allocate in bytes
00113  *  lppBuffer [O] Destination for pointer to allocated memory
00114  *
00115  * RETURNS
00116  *  Success: S_OK. *lppBuffer is filled with a pointer to a memory block of
00117  *           length cbSize bytes.
00118  *  Failure: MAPI_E_INVALID_PARAMETER, if lppBuffer is NULL.
00119  *           MAPI_E_NOT_ENOUGH_MEMORY, if the memory allocation fails.
00120  *
00121  * NOTES
00122  *  Memory allocated with this function should be freed with MAPIFreeBuffer().
00123  *  Further allocations of memory may be linked to the pointer returned using
00124  *  MAPIAllocateMore(). Linked allocations are freed when the initial pointer
00125  *  is feed.
00126  */
00127 SCODE WINAPI MAPIAllocateBuffer(ULONG cbSize, LPVOID *lppBuffer)
00128 {
00129     LPMAPIALLOCBUFFER lpBuff;
00130 
00131     TRACE("(%d,%p)\n", cbSize, lppBuffer);
00132 
00133     if (mapiFunctions.MAPIAllocateBuffer)
00134         return mapiFunctions.MAPIAllocateBuffer(cbSize, lppBuffer);
00135 
00136     if (!lppBuffer)
00137         return E_INVALIDARG;
00138 
00139     lpBuff = HeapAlloc(GetProcessHeap(), 0, cbSize + sizeof(*lpBuff));
00140     if (!lpBuff)
00141         return MAPI_E_NOT_ENOUGH_MEMORY;
00142 
00143     TRACE("initial allocation:%p, returning %p\n", lpBuff, lpBuff + 1);
00144     *lpBuff++ = NULL;
00145     *lppBuffer = lpBuff;
00146     return S_OK;
00147 }
00148 
00149 /**************************************************************************
00150  *  MAPIAllocateMore    (MAPI32.14)
00151  *  MAPIAllocateMore@12 (MAPI32.15)
00152  *
00153  * Allocate a block of memory linked to a previous allocation.
00154  *
00155  * PARAMS
00156  *  cbSize    [I] Size of the block to allocate in bytes
00157  *  lpOrig    [I] Initial allocation to link to, from MAPIAllocateBuffer()
00158  *  lppBuffer [O] Destination for pointer to allocated memory
00159  *
00160  * RETURNS
00161  *  Success: S_OK. *lppBuffer is filled with a pointer to a memory block of
00162  *           length cbSize bytes.
00163  *  Failure: MAPI_E_INVALID_PARAMETER, if lpOrig or lppBuffer is invalid.
00164  *           MAPI_E_NOT_ENOUGH_MEMORY, if memory allocation fails.
00165  *
00166  * NOTES
00167  *  Memory allocated with this function and stored in *lppBuffer is freed
00168  *  when lpOrig is passed to MAPIFreeBuffer(). It should not be freed independently.
00169  */
00170 SCODE WINAPI MAPIAllocateMore(ULONG cbSize, LPVOID lpOrig, LPVOID *lppBuffer)
00171 {
00172     LPMAPIALLOCBUFFER lpBuff = lpOrig;
00173 
00174     TRACE("(%d,%p,%p)\n", cbSize, lpOrig, lppBuffer);
00175 
00176     if (mapiFunctions.MAPIAllocateMore)
00177         return mapiFunctions.MAPIAllocateMore(cbSize, lpOrig, lppBuffer);
00178 
00179     if (!lppBuffer || !lpBuff || !--lpBuff)
00180         return E_INVALIDARG;
00181 
00182     /* Find the last allocation in the chain */
00183     while (*lpBuff)
00184     {
00185         TRACE("linked:%p->%p\n", lpBuff, *lpBuff);
00186         lpBuff = *lpBuff;
00187     }
00188 
00189     if (SUCCEEDED(MAPIAllocateBuffer(cbSize, lppBuffer)))
00190     {
00191         *lpBuff = ((LPMAPIALLOCBUFFER)*lppBuffer) - 1;
00192         TRACE("linking %p->%p\n", lpBuff, *lpBuff);
00193     }
00194     return *lppBuffer ? S_OK : MAPI_E_NOT_ENOUGH_MEMORY;
00195 }
00196 
00197 /**************************************************************************
00198  *  MAPIFreeBuffer   (MAPI32.16)
00199  *  MAPIFreeBuffer@4 (MAPI32.17)
00200  *
00201  * Free a block of memory and any linked allocations associated with it.
00202  *
00203  * PARAMS
00204  *  lpBuffer [I] Memory to free, returned from MAPIAllocateBuffer()
00205  *
00206  * RETURNS
00207  *  S_OK.
00208  */
00209 ULONG WINAPI MAPIFreeBuffer(LPVOID lpBuffer)
00210 {
00211     LPMAPIALLOCBUFFER lpBuff = lpBuffer;
00212 
00213     TRACE("(%p)\n", lpBuffer);
00214 
00215     if (mapiFunctions.MAPIFreeBuffer)
00216         return mapiFunctions.MAPIFreeBuffer(lpBuffer);
00217 
00218     if (lpBuff && --lpBuff)
00219     {
00220         while (lpBuff)
00221         {
00222             LPVOID lpFree = lpBuff;
00223 
00224             lpBuff = *lpBuff;
00225 
00226             TRACE("linked:%p->%p, freeing %p\n", lpFree, lpBuff, lpFree);
00227             HeapFree(GetProcessHeap(), 0, lpFree);
00228         }
00229     }
00230     return S_OK;
00231 }
00232 
00233 /**************************************************************************
00234  *  WrapProgress@20 (MAPI32.41)
00235  */
00236 HRESULT WINAPI WrapProgress(PVOID unk1, PVOID unk2, PVOID unk3, PVOID unk4, PVOID unk5)
00237 {
00238     /* Native does not implement this function */
00239     return MAPI_E_NO_SUPPORT;
00240 }
00241 
00242 /*************************************************************************
00243  * HrThisThreadAdviseSink@8 (MAPI32.42)
00244  *
00245  * Ensure that an advise sink is only notified in its originating thread.
00246  *
00247  * PARAMS
00248  *  lpSink     [I] IMAPIAdviseSink interface to be protected
00249  *  lppNewSink [I] Destination for wrapper IMAPIAdviseSink interface
00250  *
00251  * RETURNS
00252  * Success: S_OK. *lppNewSink contains a new sink to use in place of lpSink.
00253  * Failure: E_INVALIDARG, if any parameter is invalid.
00254  */
00255 HRESULT WINAPI HrThisThreadAdviseSink(LPMAPIADVISESINK lpSink, LPMAPIADVISESINK* lppNewSink)
00256 {
00257     if (mapiFunctions.HrThisThreadAdviseSink)
00258         return mapiFunctions.HrThisThreadAdviseSink(lpSink, lppNewSink);
00259 
00260     FIXME("(%p,%p)semi-stub\n", lpSink, lppNewSink);
00261 
00262     if (!lpSink || !lppNewSink)
00263         return E_INVALIDARG;
00264 
00265     /* Don't wrap the sink for now, just copy it */
00266     *lppNewSink = lpSink;
00267     IMAPIAdviseSink_AddRef(lpSink);
00268     return S_OK;
00269 }
00270 
00271 /*************************************************************************
00272  * FBinFromHex (MAPI32.44)
00273  *
00274  * Create an array of binary data from a string.
00275  *
00276  * PARAMS
00277  *  lpszHex [I] String to convert to binary data
00278  *  lpOut   [O] Destination for resulting binary data
00279  *
00280  * RETURNS
00281  *  Success: TRUE. lpOut contains the decoded binary data.
00282  *  Failure: FALSE, if lpszHex does not represent a binary string.
00283  *
00284  * NOTES
00285  *  - lpOut must be at least half the length of lpszHex in bytes.
00286  *  - Although the Mapi headers prototype this function as both
00287  *    Ascii and Unicode, there is only one (Ascii) implementation. This
00288  *    means that lpszHex is treated as an Ascii string (i.e. a single NUL
00289  *    character in the byte stream terminates the string).
00290  */
00291 BOOL WINAPI FBinFromHex(LPWSTR lpszHex, LPBYTE lpOut)
00292 {
00293     LPSTR lpStr = (LPSTR)lpszHex;
00294 
00295     TRACE("(%p,%p)\n", lpszHex, lpOut);
00296 
00297     while (*lpStr)
00298     {
00299         if (lpStr[0] < '0' || lpStr[0] > 'f' || digitsToHex[lpStr[0] - '0'] == 0xff ||
00300             lpStr[1] < '0' || lpStr[1] > 'f' || digitsToHex[lpStr[1] - '0'] == 0xff)
00301             return FALSE;
00302 
00303         *lpOut++ = (digitsToHex[lpStr[0] - '0'] << 4) | digitsToHex[lpStr[1] - '0'];
00304         lpStr += 2;
00305     }
00306     return TRUE;
00307 }
00308 
00309 /*************************************************************************
00310  * HexFromBin (MAPI32.45)
00311  *
00312  * Create a string from an array of binary data.
00313  *
00314  * PARAMS
00315  *  lpHex   [I] Binary data to convert to string
00316  *  iCount  [I] Length of lpHex in bytes
00317  *  lpszOut [O] Destination for resulting hex string
00318  *
00319  * RETURNS
00320  *  Nothing.
00321  *
00322  * NOTES
00323  *  - lpszOut must be at least 2 * iCount + 1 bytes characters long.
00324  *  - Although the Mapi headers prototype this function as both
00325  *    Ascii and Unicode, there is only one (Ascii) implementation. This
00326  *    means that the resulting string is not properly NUL terminated
00327  *    if the caller expects it to be a Unicode string.
00328  */
00329 void WINAPI HexFromBin(LPBYTE lpHex, int iCount, LPWSTR lpszOut)
00330 {
00331     static const char hexDigits[] = { "0123456789ABCDEF" };
00332     LPSTR lpStr = (LPSTR)lpszOut;
00333 
00334     TRACE("(%p,%d,%p)\n", lpHex, iCount, lpszOut);
00335 
00336     while (iCount-- > 0)
00337     {
00338         *lpStr++ = hexDigits[*lpHex >> 4];
00339         *lpStr++ = hexDigits[*lpHex & 0xf];
00340         lpHex++;
00341     }
00342     *lpStr = '\0';
00343 }
00344 
00345 /*************************************************************************
00346  * SwapPlong@8 (MAPI32.47)
00347  *
00348  * Swap the bytes in a ULONG array.
00349  *
00350  * PARAMS
00351  *  lpData [O] Array to swap bytes in
00352  *  ulLen  [I] Number of ULONG element to swap the bytes of
00353  *
00354  * RETURNS
00355  *  Nothing.
00356  */
00357 VOID WINAPI SwapPlong(PULONG lpData, ULONG ulLen)
00358 {
00359     ULONG i;
00360 
00361     for (i = 0; i < ulLen; i++)
00362         lpData[i] = RtlUlongByteSwap(lpData[i]);
00363 }
00364 
00365 /*************************************************************************
00366  * SwapPword@8 (MAPI32.48)
00367  *
00368  * Swap the bytes in a USHORT array.
00369  *
00370  * PARAMS
00371  *  lpData [O] Array to swap bytes in
00372  *  ulLen  [I] Number of USHORT element to swap the bytes of
00373  *
00374  * RETURNS
00375  *  Nothing.
00376  */
00377 VOID WINAPI SwapPword(PUSHORT lpData, ULONG ulLen)
00378 {
00379     ULONG i;
00380 
00381     for (i = 0; i < ulLen; i++)
00382         lpData[i] = RtlUshortByteSwap(lpData[i]);
00383 }
00384 
00385 /**************************************************************************
00386  *  MNLS_lstrlenW@4 (MAPI32.62)
00387  *
00388  * Calculate the length of a Unicode string.
00389  *
00390  * PARAMS
00391  *  lpszStr [I] String to calculate the length of
00392  *
00393  * RETURNS
00394  *  The length of lpszStr in Unicode characters.
00395  */
00396 ULONG WINAPI MNLS_lstrlenW(LPCWSTR lpszStr)
00397 {
00398     TRACE("(%s)\n", debugstr_w(lpszStr));
00399     return strlenW(lpszStr);
00400 }
00401 
00402 /*************************************************************************
00403  * MNLS_lstrcmpW@8 (MAPI32.63)
00404  *
00405  * Compare two Unicode strings.
00406  *
00407  * PARAMS
00408  *  lpszLeft  [I] First string to compare
00409  *  lpszRight [I] Second string to compare
00410  *
00411  * RETURNS
00412  *  An integer less than, equal to or greater than 0, indicating that
00413  *  lpszLeft is less than, the same, or greater than lpszRight.
00414  */
00415 INT WINAPI MNLS_lstrcmpW(LPCWSTR lpszLeft, LPCWSTR lpszRight)
00416 {
00417     TRACE("(%s,%s)\n", debugstr_w(lpszLeft), debugstr_w(lpszRight));
00418     return strcmpW(lpszLeft, lpszRight);
00419 }
00420 
00421 /*************************************************************************
00422  * MNLS_lstrcpyW@8 (MAPI32.64)
00423  *
00424  * Copy a Unicode string to another string.
00425  *
00426  * PARAMS
00427  *  lpszDest [O] Destination string
00428  *  lpszSrc  [I] Source string
00429  *
00430  * RETURNS
00431  *  The length lpszDest in Unicode characters.
00432  */
00433 ULONG WINAPI MNLS_lstrcpyW(LPWSTR lpszDest, LPCWSTR lpszSrc)
00434 {
00435     ULONG len;
00436 
00437     TRACE("(%p,%s)\n", lpszDest, debugstr_w(lpszSrc));
00438     len = (strlenW(lpszSrc) + 1) * sizeof(WCHAR);
00439     memcpy(lpszDest, lpszSrc, len);
00440     return len;
00441 }
00442 
00443 /*************************************************************************
00444  * MNLS_CompareStringW@12 (MAPI32.65)
00445  *
00446  * Compare two Unicode strings.
00447  *
00448  * PARAMS
00449  *  dwCp      [I] Code page for the comparison
00450  *  lpszLeft  [I] First string to compare
00451  *  lpszRight [I] Second string to compare
00452  *
00453  * RETURNS
00454  *  CSTR_LESS_THAN, CSTR_EQUAL or CSTR_GREATER_THAN, indicating that
00455  *  lpszLeft is less than, the same, or greater than lpszRight.
00456  */
00457 INT WINAPI MNLS_CompareStringW(DWORD dwCp, LPCWSTR lpszLeft, LPCWSTR lpszRight)
00458 {
00459     INT ret;
00460 
00461     TRACE("0x%08x,%s,%s\n", dwCp, debugstr_w(lpszLeft), debugstr_w(lpszRight));
00462     ret = MNLS_lstrcmpW(lpszLeft, lpszRight);
00463     return ret < 0 ? CSTR_LESS_THAN : ret ? CSTR_GREATER_THAN : CSTR_EQUAL;
00464 }
00465 
00466 /**************************************************************************
00467  *  FEqualNames@8 (MAPI32.72)
00468  *
00469  * Compare two Mapi names.
00470  *
00471  * PARAMS
00472  *  lpName1 [I] First name to compare to lpName2
00473  *  lpName2 [I] Second name to compare to lpName1
00474  *
00475  * RETURNS
00476  *  TRUE, if the names are the same,
00477  *  FALSE, Otherwise.
00478  */
00479 BOOL WINAPI FEqualNames(LPMAPINAMEID lpName1, LPMAPINAMEID lpName2)
00480 {
00481     TRACE("(%p,%p)\n", lpName1, lpName2);
00482 
00483     if (!lpName1 || !lpName2 ||
00484         !IsEqualGUID(lpName1->lpguid, lpName2->lpguid) ||
00485         lpName1->ulKind != lpName2->ulKind)
00486         return FALSE;
00487 
00488     if (lpName1->ulKind == MNID_STRING)
00489         return !strcmpW(lpName1->Kind.lpwstrName, lpName2->Kind.lpwstrName);
00490 
00491     return lpName1->Kind.lID == lpName2->Kind.lID ? TRUE : FALSE;
00492 }
00493 
00494 /**************************************************************************
00495  *  IsBadBoundedStringPtr@8 (MAPI32.71)
00496  *
00497  * Determine if a string pointer is valid.
00498  *
00499  * PARAMS
00500  *  lpszStr [I] String to check
00501  *  ulLen   [I] Maximum length of lpszStr
00502  *
00503  * RETURNS
00504  *  TRUE, if lpszStr is invalid or longer than ulLen,
00505  *  FALSE, otherwise.
00506  */
00507 BOOL WINAPI IsBadBoundedStringPtr(LPCSTR lpszStr, ULONG ulLen)
00508 {
00509     if (!lpszStr || IsBadStringPtrA(lpszStr, -1) || strlen(lpszStr) >= ulLen)
00510         return TRUE;
00511     return FALSE;
00512 }
00513 
00514 /**************************************************************************
00515  *  FtAddFt@16 (MAPI32.121)
00516  *
00517  * Add two FILETIME's together.
00518  *
00519  * PARAMS
00520  *  ftLeft  [I] FILETIME to add to ftRight
00521  *  ftRight [I] FILETIME to add to ftLeft
00522  *
00523  * RETURNS
00524  *  The sum of ftLeft and ftRight
00525  */
00526 LONGLONG WINAPI MAPI32_FtAddFt(FILETIME ftLeft, FILETIME ftRight)
00527 {
00528     LONGLONG *pl = (LONGLONG*)&ftLeft, *pr = (LONGLONG*)&ftRight;
00529 
00530     return *pl + *pr;
00531 }
00532 
00533 /**************************************************************************
00534  *  FtSubFt@16 (MAPI32.123)
00535  *
00536  * Subtract two FILETIME's together.
00537  *
00538  * PARAMS
00539  *  ftLeft  [I] Initial FILETIME
00540  *  ftRight [I] FILETIME to subtract from ftLeft
00541  *
00542  * RETURNS
00543  *  The remainder after ftRight is subtracted from ftLeft.
00544  */
00545 LONGLONG WINAPI MAPI32_FtSubFt(FILETIME ftLeft, FILETIME ftRight)
00546 {
00547     LONGLONG *pl = (LONGLONG*)&ftLeft, *pr = (LONGLONG*)&ftRight;
00548 
00549     return *pr - *pl;
00550 }
00551 
00552 /**************************************************************************
00553  *  FtMulDw@12 (MAPI32.124)
00554  *
00555  * Multiply a FILETIME by a DWORD.
00556  *
00557  * PARAMS
00558  *  dwLeft  [I] DWORD to multiply with ftRight
00559  *  ftRight [I] FILETIME to multiply with dwLeft
00560  *
00561  * RETURNS
00562  *  The product of dwLeft and ftRight
00563  */
00564 LONGLONG WINAPI MAPI32_FtMulDw(DWORD dwLeft, FILETIME ftRight)
00565 {
00566     LONGLONG *pr = (LONGLONG*)&ftRight;
00567 
00568     return (LONGLONG)dwLeft * (*pr);
00569 }
00570 
00571 /**************************************************************************
00572  *  FtMulDwDw@8 (MAPI32.125)
00573  *
00574  * Multiply two DWORD, giving the result as a FILETIME.
00575  *
00576  * PARAMS
00577  *  dwLeft  [I] DWORD to multiply with dwRight
00578  *  dwRight [I] DWORD to multiply with dwLeft
00579  *
00580  * RETURNS
00581  *  The product of ftMultiplier and ftMultiplicand as a FILETIME.
00582  */
00583 LONGLONG WINAPI MAPI32_FtMulDwDw(DWORD dwLeft, DWORD dwRight)
00584 {
00585     return (LONGLONG)dwLeft * (LONGLONG)dwRight;
00586 }
00587 
00588 /**************************************************************************
00589  *  FtNegFt@8 (MAPI32.126)
00590  *
00591  * Negate a FILETIME.
00592  *
00593  * PARAMS
00594  *  ft [I] FILETIME to negate
00595  *
00596  * RETURNS
00597  *  The negation of ft.
00598  */
00599 LONGLONG WINAPI MAPI32_FtNegFt(FILETIME ft)
00600 {
00601     LONGLONG *p = (LONGLONG*)&ft;
00602 
00603     return - *p;
00604 }
00605 
00606 /**************************************************************************
00607  *  UlAddRef@4 (MAPI32.128)
00608  *
00609  * Add a reference to an object.
00610  *
00611  * PARAMS
00612  *  lpUnk [I] Object to add a reference to.
00613  *
00614  * RETURNS
00615  *  The new reference count of the object, or 0 if lpUnk is NULL.
00616  *
00617  * NOTES
00618  * See IUnknown_AddRef.
00619  */
00620 ULONG WINAPI UlAddRef(void *lpUnk)
00621 {
00622     TRACE("(%p)\n", lpUnk);
00623 
00624     if (!lpUnk)
00625         return 0UL;
00626     return IUnknown_AddRef((LPUNKNOWN)lpUnk);
00627 }
00628 
00629 /**************************************************************************
00630  *  UlRelease@4 (MAPI32.129)
00631  *
00632  * Remove a reference from an object.
00633  *
00634  * PARAMS
00635  *  lpUnk [I] Object to remove reference from.
00636  *
00637  * RETURNS
00638  *  The new reference count of the object, or 0 if lpUnk is NULL. If lpUnk is
00639  *  non-NULL and this function returns 0, the object pointed to by lpUnk has
00640  *  been released.
00641  *
00642  * NOTES
00643  * See IUnknown_Release.
00644  */
00645 ULONG WINAPI UlRelease(void *lpUnk)
00646 {
00647     TRACE("(%p)\n", lpUnk);
00648 
00649     if (!lpUnk)
00650         return 0UL;
00651     return IUnknown_Release((LPUNKNOWN)lpUnk);
00652 }
00653 
00654 /**************************************************************************
00655  *  UFromSz@4 (MAPI32.133)
00656  *
00657  * Read an integer from a string
00658  *
00659  * PARAMS
00660  *  lpszStr [I] String to read the integer from.
00661  *
00662  * RETURNS
00663  *  Success: The integer read from lpszStr.
00664  *  Failure: 0, if the first character in lpszStr is not 0-9.
00665  *
00666  * NOTES
00667  *  This function does not accept whitespace and stops at the first non-digit
00668  *  character.
00669  */
00670 UINT WINAPI UFromSz(LPCSTR lpszStr)
00671 {
00672     ULONG ulRet = 0;
00673 
00674     TRACE("(%s)\n", debugstr_a(lpszStr));
00675 
00676     if (lpszStr)
00677     {
00678         while (*lpszStr >= '0' && *lpszStr <= '9')
00679         {
00680             ulRet = ulRet * 10 + (*lpszStr - '0');
00681             lpszStr++;
00682         }
00683     }
00684     return ulRet;
00685 }
00686 
00687 /*************************************************************************
00688  * OpenStreamOnFile@24 (MAPI32.147)
00689  *
00690  * Create a stream on a file.
00691  *
00692  * PARAMS
00693  *  lpAlloc    [I] Memory allocation function
00694  *  lpFree     [I] Memory free function
00695  *  ulFlags    [I] Flags controlling the opening process
00696  *  lpszPath   [I] Path of file to create stream on
00697  *  lpszPrefix [I] Prefix of the temporary file name (if ulFlags includes SOF_UNIQUEFILENAME)
00698  *  lppStream  [O] Destination for created stream
00699  *
00700  * RETURNS
00701  * Success: S_OK. lppStream contains the new stream object
00702  * Failure: E_INVALIDARG if any parameter is invalid, or an HRESULT error code
00703  *          describing the error.
00704  */
00705 HRESULT WINAPI OpenStreamOnFile(LPALLOCATEBUFFER lpAlloc, LPFREEBUFFER lpFree,
00706                                 ULONG ulFlags, LPWSTR lpszPath, LPWSTR lpszPrefix,
00707                                 LPSTREAM *lppStream)
00708 {
00709     WCHAR szBuff[MAX_PATH];
00710     DWORD dwMode = STGM_READWRITE, dwAttributes = 0;
00711     HRESULT hRet;
00712 
00713     TRACE("(%p,%p,0x%08x,%s,%s,%p)\n", lpAlloc, lpFree, ulFlags,
00714           debugstr_a((LPSTR)lpszPath), debugstr_a((LPSTR)lpszPrefix), lppStream);
00715 
00716     if (mapiFunctions.OpenStreamOnFile)
00717         return mapiFunctions.OpenStreamOnFile(lpAlloc, lpFree, ulFlags, lpszPath, lpszPrefix, lppStream);
00718 
00719     if (lppStream)
00720         *lppStream = NULL;
00721 
00722     if (ulFlags & SOF_UNIQUEFILENAME)
00723     {
00724         FIXME("Should generate a temporary name\n");
00725         return E_INVALIDARG;
00726     }
00727 
00728     if (!lpszPath || !lppStream)
00729         return E_INVALIDARG;
00730 
00731     /* FIXME: Should probably munge mode and attributes, and should handle
00732      *        Unicode arguments (I assume MAPI_UNICODE is set in ulFlags if
00733      *        we are being passed Unicode strings; MSDN doesn't say).
00734      *        This implementation is just enough for Outlook97 to start.
00735      */
00736     MultiByteToWideChar(CP_ACP, 0, (LPSTR)lpszPath, -1, szBuff, MAX_PATH);
00737     hRet = SHCreateStreamOnFileEx(szBuff, dwMode, dwAttributes, TRUE,
00738                                   NULL, lppStream);
00739     return hRet;
00740 }
00741 
00742 /*************************************************************************
00743  * UlFromSzHex@4 (MAPI32.155)
00744  *
00745  * Read an integer from a hexadecimal string.
00746  *
00747  * PARAMS
00748  *  lpSzHex [I] String containing the hexadecimal number to read
00749  *
00750  * RETURNS
00751  * Success: The number represented by lpszHex.
00752  * Failure: 0, if lpszHex does not contain a hex string.
00753  *
00754  * NOTES
00755  *  This function does not accept whitespace and stops at the first non-hex
00756  *  character.
00757  */
00758 ULONG WINAPI UlFromSzHex(LPCWSTR lpszHex)
00759 {
00760     LPCSTR lpStr = (LPCSTR)lpszHex;
00761     ULONG ulRet = 0;
00762 
00763     TRACE("(%s)\n", debugstr_a(lpStr));
00764 
00765     while (*lpStr)
00766     {
00767         if (lpStr[0] < '0' || lpStr[0] > 'f' || digitsToHex[lpStr[0] - '0'] == 0xff ||
00768             lpStr[1] < '0' || lpStr[1] > 'f' || digitsToHex[lpStr[1] - '0'] == 0xff)
00769             break;
00770 
00771         ulRet = ulRet * 16 + ((digitsToHex[lpStr[0] - '0'] << 4) | digitsToHex[lpStr[1] - '0']);
00772         lpStr += 2;
00773     }
00774     return ulRet;
00775 }
00776 
00777 /************************************************************************
00778  * FBadEntryList@4 (MAPI32.190)
00779  *
00780  * Determine is an entry list is invalid.
00781  *
00782  * PARAMS
00783  *  lpEntryList [I] List to check
00784  *
00785  * RETURNS
00786  *  TRUE, if lpEntryList is invalid,
00787  *  FALSE, otherwise.
00788  */
00789 BOOL WINAPI FBadEntryList(LPENTRYLIST lpEntryList)
00790 {
00791     ULONG i;
00792 
00793     if (IsBadReadPtr(lpEntryList, sizeof(*lpEntryList)) ||
00794         IsBadReadPtr(lpEntryList->lpbin,
00795                      lpEntryList->cValues * sizeof(*lpEntryList->lpbin)))
00796         return TRUE;
00797 
00798     for (i = 0; i < lpEntryList->cValues; i++)
00799         if(IsBadReadPtr(lpEntryList->lpbin[i].lpb, lpEntryList->lpbin[i].cb))
00800             return TRUE;
00801 
00802     return FALSE;
00803 }
00804 
00805 /*************************************************************************
00806  * CbOfEncoded@4 (MAPI32.207)
00807  *
00808  * Return the length of an encoded string.
00809  *
00810  * PARAMS
00811  *  lpSzEnc [I] Encoded string to get the length of.
00812  *
00813  * RETURNS
00814  * The length of the encoded string in bytes.
00815  */
00816 ULONG WINAPI CbOfEncoded(LPCSTR lpszEnc)
00817 {
00818     ULONG ulRet = 0;
00819 
00820     TRACE("(%s)\n", debugstr_a(lpszEnc));
00821 
00822     if (lpszEnc)
00823         ulRet = (((strlen(lpszEnc) | 3) >> 2) + 1) * 3;
00824     return ulRet;
00825 }
00826 
00827 /*************************************************************************
00828  * cmc_query_configuration (MAPI32.235)
00829  *
00830  * Retrieves the configuration information for the installed CMC
00831  *
00832  * PARAMS
00833  *  session          [I]   MAPI session handle
00834  *  item             [I]   Enumerated variable that identifies which 
00835  *                         configuration information is being requested
00836  *  reference        [O]   Buffer where configuration information is written
00837  *  config_extensions[I/O] Path of file to create stream on
00838  *
00839  * RETURNS
00840  * A CMD define
00841  */
00842 CMC_return_code WINAPI cmc_query_configuration(
00843   CMC_session_id session,
00844   CMC_enum item,
00845   CMC_buffer reference,
00846   CMC_extension  *config_extensions)
00847 {
00848     FIXME("stub\n");
00849     return CMC_E_NOT_SUPPORTED;
00850 }
00851 
00852 /**************************************************************************
00853  *  FGetComponentPath   (MAPI32.254)
00854  *  FGetComponentPath@20 (MAPI32.255)
00855  *
00856  * Return the installed component path, usually to the private mapi32.dll.
00857  *
00858  * PARAMS
00859  *  component       [I] Component ID
00860  *  qualifier       [I] Application LCID
00861  *  dll_path        [O] returned component path
00862  *  dll_path_length [I] component path length
00863  *  install         [I] install mode
00864  *
00865  * RETURNS
00866  *  Success: TRUE.
00867  *  Failure: FALSE.
00868  *
00869  * NOTES
00870  *  Previously documented in Q229700 "How to locate the correct path
00871  *  to the Mapisvc.inf file in Microsoft Outlook".
00872  */
00873 BOOL WINAPI FGetComponentPath(LPCSTR component, LPCSTR qualifier, LPSTR dll_path,
00874                               DWORD dll_path_length, BOOL install)
00875 {
00876     BOOL ret = FALSE;
00877     HMODULE hmsi;
00878 
00879     TRACE("%s %s %p %u %d\n", component, qualifier, dll_path, dll_path_length, install);
00880 
00881     if (mapiFunctions.FGetComponentPath)
00882         return mapiFunctions.FGetComponentPath(component, qualifier, dll_path, dll_path_length, install);
00883 
00884     dll_path[0] = 0;
00885 
00886     hmsi = LoadLibraryA("msi.dll");
00887     if (hmsi)
00888     {
00889         UINT (WINAPI *pMsiProvideQualifiedComponentA)(LPCSTR, LPCSTR, DWORD, LPSTR, LPDWORD);
00890 
00891         pMsiProvideQualifiedComponentA = (void *)GetProcAddress(hmsi, "MsiProvideQualifiedComponentA");
00892         if (pMsiProvideQualifiedComponentA)
00893         {
00894             static const char * const fmt[] = { "%d\\NT", "%d\\95", "%d" };
00895             char lcid_ver[20];
00896             UINT i;
00897 
00898             for (i = 0; i < sizeof(fmt)/sizeof(fmt[0]); i++)
00899             {
00900                 /* FIXME: what's the correct behaviour here? */
00901                 if (!qualifier || qualifier == lcid_ver)
00902                 {
00903                     sprintf(lcid_ver, fmt[i], GetUserDefaultUILanguage());
00904                     qualifier = lcid_ver;
00905                 }
00906 
00907                 if (pMsiProvideQualifiedComponentA(component, qualifier,
00908                         install ? INSTALLMODE_DEFAULT : INSTALLMODE_EXISTING,
00909                         dll_path, &dll_path_length) == ERROR_SUCCESS)
00910                 {
00911                     ret = TRUE;
00912                     break;
00913                 }
00914 
00915                 if (qualifier != lcid_ver) break;
00916             }
00917         }
00918         FreeLibrary(hmsi);
00919     }
00920     return ret;
00921 }
00922 
00923 /**************************************************************************
00924  *  HrQueryAllRows   (MAPI32.75)
00925  */
00926 HRESULT WINAPI HrQueryAllRows(LPMAPITABLE lpTable, LPSPropTagArray lpPropTags,
00927     LPSRestriction lpRestriction, LPSSortOrderSet lpSortOrderSet,
00928     LONG crowsMax, LPSRowSet *lppRows)
00929 {
00930     if (mapiFunctions.HrQueryAllRows)
00931         return mapiFunctions.HrQueryAllRows(lpTable, lpPropTags, lpRestriction, lpSortOrderSet, crowsMax, lppRows);
00932 
00933     FIXME("(%p, %p, %p, %p, %d, %p): stub\n", lpTable, lpPropTags, lpRestriction, lpSortOrderSet, crowsMax, lppRows);
00934     *lppRows = NULL;
00935     return MAPI_E_CALL_FAILED;
00936 }
00937 
00938 static HMODULE mapi_provider;
00939 static HMODULE mapi_ex_provider;
00940 
00941 /**************************************************************************
00942  *  load_mapi_provider
00943  *
00944  * Attempts to load a MAPI provider from the specified registry key.
00945  *
00946  * Returns a handle to the loaded module in `mapi_provider' if successful.
00947  */
00948 static void load_mapi_provider(HKEY hkeyMail, LPCWSTR valueName, HMODULE *mapi_provider)
00949 {
00950     static const WCHAR mapi32_dll[] = {'m','a','p','i','3','2','.','d','l','l',0 };
00951 
00952     DWORD dwType, dwLen = 0;
00953     LPWSTR dllPath;
00954 
00955     /* Check if we have a value set for DLLPath */
00956     if ((RegQueryValueExW(hkeyMail, valueName, NULL, &dwType, NULL, &dwLen) == ERROR_SUCCESS) &&
00957         ((dwType == REG_SZ) || (dwType == REG_EXPAND_SZ)) && (dwLen > 0))
00958     {
00959         dllPath = HeapAlloc(GetProcessHeap(), 0, dwLen);
00960 
00961         if (dllPath)
00962         {
00963             RegQueryValueExW(hkeyMail, valueName, NULL, NULL, (LPBYTE)dllPath, &dwLen);
00964 
00965             /* Check that this value doesn't refer to mapi32.dll (eg, as Outlook does) */
00966             if (lstrcmpiW(dllPath, mapi32_dll) != 0)
00967             {
00968                 if (dwType == REG_EXPAND_SZ)
00969                 {
00970                     DWORD dwExpandLen;
00971                     LPWSTR dllPathExpanded;
00972 
00973                     /* Expand the path if necessary */
00974                     dwExpandLen = ExpandEnvironmentStringsW(dllPath, NULL, 0);
00975                     dllPathExpanded = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * dwExpandLen + 1);
00976 
00977                     if (dllPathExpanded)
00978                     {
00979                         ExpandEnvironmentStringsW(dllPath, dllPathExpanded, dwExpandLen + 1);
00980 
00981                         HeapFree(GetProcessHeap(), 0, dllPath);
00982                         dllPath = dllPathExpanded;
00983                     }
00984                 }
00985 
00986                 /* Load the DLL */
00987                 TRACE("loading %s\n", debugstr_w(dllPath));
00988                 *mapi_provider = LoadLibraryW(dllPath);
00989             }
00990 
00991             HeapFree(GetProcessHeap(), 0, dllPath);
00992         }
00993     }
00994 }
00995 
00996 /**************************************************************************
00997  *  load_mapi_providers
00998  *
00999  * Scans the registry for MAPI providers and attempts to load a Simple and
01000  * Extended MAPI library.
01001  *
01002  * Returns TRUE if at least one library loaded, FALSE otherwise.
01003  */
01004 void load_mapi_providers(void)
01005 {
01006     static const WCHAR regkey_mail[] = {
01007         'S','o','f','t','w','a','r','e','\\','C','l','i','e','n','t','s','\\',
01008         'M','a','i','l',0 };
01009 
01010     static const WCHAR regkey_dllpath[] = {'D','L','L','P','a','t','h',0 };
01011     static const WCHAR regkey_dllpath_ex[] = {'D','L','L','P','a','t','h','E','x',0 };
01012     static const WCHAR regkey_backslash[] = { '\\', 0 };
01013 
01014     HKEY hkeyMail;
01015     DWORD dwType, dwLen = 0;
01016     LPWSTR appName = NULL, appKey = NULL;
01017 
01018     TRACE("()\n");
01019 
01020     /* Open the Mail key */
01021     if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, regkey_mail, 0, KEY_READ, &hkeyMail) != ERROR_SUCCESS)
01022         return;
01023 
01024     /* Check if we have a default value set, and the length of it */
01025     if ((RegQueryValueExW(hkeyMail, NULL, NULL, &dwType, NULL, &dwLen) != ERROR_SUCCESS) ||
01026         !((dwType == REG_SZ) || (dwType == REG_EXPAND_SZ)) || (dwLen == 0))
01027         goto cleanUp;
01028 
01029     appName = HeapAlloc(GetProcessHeap(), 0, dwLen);
01030 
01031     if (!appName)
01032         goto cleanUp;
01033 
01034     /* Get the value, and get the path to the app key */
01035     RegQueryValueExW(hkeyMail, NULL, NULL, NULL, (LPBYTE)appName, &dwLen);
01036 
01037     TRACE("appName: %s\n", debugstr_w(appName));
01038 
01039     appKey = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * (lstrlenW(regkey_mail) +
01040         lstrlenW(regkey_backslash) + lstrlenW(appName) + 1));
01041 
01042     if (!appKey)
01043         goto cleanUp;
01044 
01045     lstrcpyW(appKey, regkey_mail);
01046     lstrcatW(appKey, regkey_backslash);
01047     lstrcatW(appKey, appName);
01048 
01049     RegCloseKey(hkeyMail);
01050 
01051     TRACE("appKey: %s\n", debugstr_w(appKey));
01052 
01053     /* Open the app's key */
01054     if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, appKey, 0, KEY_READ, &hkeyMail) != ERROR_SUCCESS)
01055         goto cleanUp;
01056 
01057     /* Try to load the providers */
01058     load_mapi_provider(hkeyMail, regkey_dllpath, &mapi_provider);
01059     load_mapi_provider(hkeyMail, regkey_dllpath_ex, &mapi_ex_provider);
01060 
01061     /* Now try to load our function pointers */
01062     ZeroMemory(&mapiFunctions, sizeof(mapiFunctions));
01063 
01064     /* Simple MAPI functions */
01065     if (mapi_provider)
01066     {
01067         mapiFunctions.MAPIAddress = (void*) GetProcAddress(mapi_provider, "MAPIAddress");
01068         mapiFunctions.MAPIDeleteMail = (void*) GetProcAddress(mapi_provider, "MAPIDeleteMail");
01069         mapiFunctions.MAPIDetails = (void*) GetProcAddress(mapi_provider, "MAPIDetails");
01070         mapiFunctions.MAPIFindNext = (void*) GetProcAddress(mapi_provider, "MAPIFindNext");
01071         mapiFunctions.MAPILogoff = (void*) GetProcAddress(mapi_provider, "MAPILogoff");
01072         mapiFunctions.MAPILogon = (void*) GetProcAddress(mapi_provider, "MAPILogon");
01073         mapiFunctions.MAPIReadMail = (void*) GetProcAddress(mapi_provider, "MAPIReadMail");
01074         mapiFunctions.MAPIResolveName = (void*) GetProcAddress(mapi_provider, "MAPIResolveName");
01075         mapiFunctions.MAPISaveMail = (void*) GetProcAddress(mapi_provider, "MAPISaveMail");
01076         mapiFunctions.MAPISendDocuments = (void*) GetProcAddress(mapi_provider, "MAPISendDocuments");
01077         mapiFunctions.MAPISendMail = (void*) GetProcAddress(mapi_provider, "MAPISendMail");
01078     }
01079 
01080     /* Extended MAPI functions */
01081     if (mapi_ex_provider)
01082     {
01083         mapiFunctions.MAPIInitialize = (void*) GetProcAddress(mapi_ex_provider, "MAPIInitialize");
01084         mapiFunctions.MAPILogonEx = (void*) GetProcAddress(mapi_ex_provider, "MAPILogonEx");
01085         mapiFunctions.MAPIUninitialize = (void*) GetProcAddress(mapi_ex_provider, "MAPIUninitialize");
01086 
01087         mapiFunctions.DeinitMapiUtil = (void*) GetProcAddress(mapi_ex_provider, "DeinitMapiUtil@0");
01088         mapiFunctions.DllCanUnloadNow = (void*) GetProcAddress(mapi_ex_provider, "DllCanUnloadNow");
01089         mapiFunctions.DllGetClassObject = (void*) GetProcAddress(mapi_ex_provider, "DllGetClassObject");
01090         mapiFunctions.FGetComponentPath = (void*) GetProcAddress(mapi_ex_provider, "FGetComponentPath");
01091         mapiFunctions.HrThisThreadAdviseSink = (void*) GetProcAddress(mapi_ex_provider, "HrThisThreadAdviseSink@8");
01092         mapiFunctions.HrQueryAllRows = (void*) GetProcAddress(mapi_ex_provider, "HrQueryAllRows@24");
01093         mapiFunctions.MAPIAdminProfiles = (void*) GetProcAddress(mapi_ex_provider, "MAPIAdminProfiles");
01094         mapiFunctions.MAPIAllocateBuffer = (void*) GetProcAddress(mapi_ex_provider, "MAPIAllocateBuffer");
01095         mapiFunctions.MAPIAllocateMore = (void*) GetProcAddress(mapi_ex_provider, "MAPIAllocateMore");
01096         mapiFunctions.MAPIFreeBuffer = (void*) GetProcAddress(mapi_ex_provider, "MAPIFreeBuffer");
01097         mapiFunctions.MAPIGetDefaultMalloc = (void*) GetProcAddress(mapi_ex_provider, "MAPIGetDefaultMalloc@0");
01098         mapiFunctions.MAPIOpenLocalFormContainer = (void *) GetProcAddress(mapi_ex_provider, "MAPIOpenLocalFormContainer");
01099         mapiFunctions.OpenStreamOnFile = (void*) GetProcAddress(mapi_ex_provider, "OpenStreamOnFile@24");
01100         mapiFunctions.ScInitMapiUtil = (void*) GetProcAddress(mapi_ex_provider, "ScInitMapiUtil@4");
01101     }
01102 
01103 cleanUp:
01104     RegCloseKey(hkeyMail);
01105     HeapFree(GetProcessHeap(), 0, appKey);
01106     HeapFree(GetProcessHeap(), 0, appName);
01107 }
01108 
01109 /**************************************************************************
01110  *  unload_mapi_providers
01111  *
01112  * Unloads any loaded MAPI libraries.
01113  */
01114 void unload_mapi_providers(void)
01115 {
01116     TRACE("()\n");
01117 
01118     FreeLibrary(mapi_provider);
01119     FreeLibrary(mapi_ex_provider);
01120 }

Generated on Sat May 26 2012 04:20:43 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.