Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenutil.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
1.7.6.1
|