⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 util.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * MAPI Utility functions
 *
 * Copyright 2004 Jon Griffiths
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include <stdarg.h>
#include <stdio.h>

#define COBJMACROS
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "winuser.h"
#include "winerror.h"
#include "winternl.h"
#include "objbase.h"
#include "shlwapi.h"
#include "wine/debug.h"
#include "wine/unicode.h"
#include "mapival.h"
#include "xcmc.h"
#include "msi.h"

WINE_DEFAULT_DEBUG_CHANNEL(mapi);

static const BYTE digitsToHex[] = {
  0,1,2,3,4,5,6,7,8,9,0xff,0xff,0xff,0xff,0xff,0xff,0xff,10,11,12,13,14,15,
  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,10,11,12,13,
  14,15 };

/**************************************************************************
 *  ScInitMapiUtil (MAPI32.33)
 *
 * Initialise Mapi utility functions.
 *
 * PARAMS
 *  ulReserved [I] Reserved, pass 0.
 *
 * RETURNS
 *  Success: S_OK. Mapi utility functions may be called.
 *  Failure: MAPI_E_INVALID_PARAMETER, if ulReserved is not 0.
 *
 * NOTES
 *  Your application does not need to call this function unless it does not
 *  call MAPIInitialize()/MAPIUninitialize().
 */
SCODE WINAPI ScInitMapiUtil(ULONG ulReserved)
{
    FIXME("(0x%08x)stub!\n", ulReserved);
    if (ulReserved)
        return MAPI_E_INVALID_PARAMETER;
    return S_OK;
}

/**************************************************************************
 *  DeinitMapiUtil (MAPI32.34)
 *
 * Uninitialise Mapi utility functions.
 *
 * PARAMS
 *  None.
 *
 * RETURNS
 *  Nothing.
 *
 * NOTES
 *  Your application does not need to call this function unless it does not
 *  call MAPIInitialize()/MAPIUninitialize().
 */
VOID WINAPI DeinitMapiUtil(void)
{
    FIXME("()stub!\n");
}

typedef LPVOID *LPMAPIALLOCBUFFER;

/**************************************************************************
 *  MAPIAllocateBuffer   (MAPI32.12)
 *  MAPIAllocateBuffer@8 (MAPI32.13)
 *
 * Allocate a block of memory.
 *
 * PARAMS
 *  cbSize    [I] Size of the block to allocate in bytes
 *  lppBuffer [O] Destination for pointer to allocated memory
 *
 * RETURNS
 *  Success: S_OK. *lppBuffer is filled with a pointer to a memory block of
 *           length cbSize bytes.
 *  Failure: MAPI_E_INVALID_PARAMETER, if lppBuffer is NULL.
 *           MAPI_E_NOT_ENOUGH_MEMORY, if the memory allocation fails.
 *
 * NOTES
 *  Memory allocated with this function should be freed with MAPIFreeBuffer().
 *  Further allocations of memory may be linked to the pointer returned using
 *  MAPIAllocateMore(). Linked allocations are freed when the initial pointer
 *  is feed.
 */
SCODE WINAPI MAPIAllocateBuffer(ULONG cbSize, LPVOID *lppBuffer)
{
    LPMAPIALLOCBUFFER lpBuff;

    TRACE("(%d,%p)\n", cbSize, lppBuffer);

    if (!lppBuffer)
        return E_INVALIDARG;

    lpBuff = HeapAlloc(GetProcessHeap(), 0, cbSize + sizeof(*lpBuff));
    if (!lpBuff)
        return MAPI_E_NOT_ENOUGH_MEMORY;

    TRACE("initial allocation:%p, returning %p\n", lpBuff, lpBuff + 1);
    *lpBuff++ = NULL;
    *lppBuffer = lpBuff;
    return S_OK;
}

/**************************************************************************
 *  MAPIAllocateMore    (MAPI32.14)
 *  MAPIAllocateMore@12 (MAPI32.15)
 *
 * Allocate a block of memory linked to a previous allocation.
 *
 * PARAMS
 *  cbSize    [I] Size of the block to allocate in bytes
 *  lpOrig    [I] Initial allocation to link to, from MAPIAllocateBuffer()
 *  lppBuffer [O] Destination for pointer to allocated memory
 *
 * RETURNS
 *  Success: S_OK. *lppBuffer is filled with a pointer to a memory block of
 *           length cbSize bytes.
 *  Failure: MAPI_E_INVALID_PARAMETER, if lpOrig or lppBuffer is invalid.
 *           MAPI_E_NOT_ENOUGH_MEMORY, if memory allocation fails.
 *
 * NOTES
 *  Memory allocated with this function and stored in *lppBuffer is freed
 *  when lpOrig is passed to MAPIFreeBuffer(). It should not be freed independently.
 */
SCODE WINAPI MAPIAllocateMore(ULONG cbSize, LPVOID lpOrig, LPVOID *lppBuffer)
{
    LPMAPIALLOCBUFFER lpBuff = lpOrig;

    TRACE("(%d,%p,%p)\n", cbSize, lpOrig, lppBuffer);

    if (!lppBuffer || !lpBuff || !--lpBuff)
        return E_INVALIDARG;

    /* Find the last allocation in the chain */
    while (*lpBuff)
    {
        TRACE("linked:%p->%p\n", lpBuff, *lpBuff);
        lpBuff = *lpBuff;
    }

    if (SUCCEEDED(MAPIAllocateBuffer(cbSize, lppBuffer)))
    {
        *lpBuff = ((LPMAPIALLOCBUFFER)*lppBuffer) - 1;
        TRACE("linking %p->%p\n", lpBuff, *lpBuff);
    }
    return *lppBuffer ? S_OK : MAPI_E_NOT_ENOUGH_MEMORY;
}

/**************************************************************************
 *  MAPIFreeBuffer   (MAPI32.16)
 *  MAPIFreeBuffer@4 (MAPI32.17)
 *
 * Free a block of memory and any linked allocations associated with it.
 *
 * PARAMS
 *  lpBuffer [I] Memory to free, returned from MAPIAllocateBuffer()
 *
 * RETURNS
 *  S_OK.
 */
ULONG WINAPI MAPIFreeBuffer(LPVOID lpBuffer)
{
    LPMAPIALLOCBUFFER lpBuff = lpBuffer;

    TRACE("(%p)\n", lpBuffer);

    if (lpBuff && --lpBuff)
    {
        while (lpBuff)
        {
            LPVOID lpFree = lpBuff;

            lpBuff = *lpBuff;

            TRACE("linked:%p->%p, freeing %p\n", lpFree, lpBuff, lpFree);
            HeapFree(GetProcessHeap(), 0, lpFree);
        }
    }
    return S_OK;
}

/**************************************************************************
 *  WrapProgress@20 (MAPI32.41)
 */
HRESULT WINAPI WrapProgress(PVOID unk1, PVOID unk2, PVOID unk3, PVOID unk4, PVOID unk5)
{
    /* Native does not implement this function */
    return MAPI_E_NO_SUPPORT;
}

/*************************************************************************
 * HrThisThreadAdviseSink@8 (MAPI32.42)
 *
 * Ensure that an advise sink is only notified in its originating thread.
 *
 * PARAMS
 *  lpSink     [I] IMAPIAdviseSink interface to be protected
 *  lppNewSink [I] Destination for wrapper IMAPIAdviseSink interface
 *
 * RETURNS
 * Success: S_OK. *lppNewSink contains a new sink to use in place of lpSink.
 * Failure: E_INVALIDARG, if any parameter is invalid.
 */
HRESULT WINAPI HrThisThreadAdviseSink(LPMAPIADVISESINK lpSink, LPMAPIADVISESINK* lppNewSink)
{
    FIXME("(%p,%p)semi-stub\n", lpSink, lppNewSink);

    if (!lpSink || !lppNewSink)
        return E_INVALIDARG;

    /* Don't wrap the sink for now, just copy it */
    *lppNewSink = lpSink;
    IMAPIAdviseSink_AddRef(lpSink);
    return S_OK;
}

/*************************************************************************
 * FBinFromHex (MAPI32.44)
 *
 * Create an array of binary data from a string.
 *
 * PARAMS
 *  lpszHex [I] String to convert to binary data
 *  lpOut   [O] Destination for resulting binary data
 *
 * RETURNS
 *  Success: TRUE. lpOut contains the decoded binary data.
 *  Failure: FALSE, if lpszHex does not represent a binary string.
 *
 * NOTES
 *  - lpOut must be at least half the length of lpszHex in bytes.
 *  - Although the Mapi headers prototype this function as both
 *    Ascii and Unicode, there is only one (Ascii) implementation. This
 *    means that lpszHex is treated as an Ascii string (i.e. a single NUL
 *    character in the byte stream terminates the string).
 */
BOOL WINAPI FBinFromHex(LPWSTR lpszHex, LPBYTE lpOut)
{
    LPSTR lpStr = (LPSTR)lpszHex;

    TRACE("(%p,%p)\n", lpszHex, lpOut);

    while (*lpStr)
    {
        if (lpStr[0] < '0' || lpStr[0] > 'f' || digitsToHex[lpStr[0] - '0'] == 0xff ||
            lpStr[1] < '0' || lpStr[1] > 'f' || digitsToHex[lpStr[1] - '0'] == 0xff)
            return FALSE;

        *lpOut++ = (digitsToHex[lpStr[0] - '0'] << 4) | digitsToHex[lpStr[1] - '0'];
        lpStr += 2;
    }
    return TRUE;
}

/*************************************************************************
 * HexFromBin (MAPI32.45)
 *
 * Create a string from an array of binary data.
 *
 * PARAMS
 *  lpHex   [I] Binary data to convert to string
 *  iCount  [I] Length of lpHex in bytes
 *  lpszOut [O] Destination for resulting hex string
 *
 * RETURNS
 *  Nothing.
 *
 * NOTES
 *  - lpszOut must be at least 2 * iCount + 1 bytes characters long.
 *  - Although the Mapi headers prototype this function as both
 *    Ascii and Unicode, there is only one (Ascii) implementation. This
 *    means that the resulting string is not properly NUL terminated
 *    if the caller expects it to be a Unicode string.
 */
void WINAPI HexFromBin(LPBYTE lpHex, int iCount, LPWSTR lpszOut)
{
    static const char hexDigits[] = { "0123456789ABCDEF" };
    LPSTR lpStr = (LPSTR)lpszOut;

    TRACE("(%p,%d,%p)\n", lpHex, iCount, lpszOut);

    while (iCount-- > 0)
    {
        *lpStr++ = hexDigits[*lpHex >> 4];
        *lpStr++ = hexDigits[*lpHex & 0xf];
        lpHex++;
    }
    *lpStr = '\0';
}

/*************************************************************************
 * SwapPlong@8 (MAPI32.47)
 *
 * Swap the bytes in a ULONG array.
 *
 * PARAMS
 *  lpData [O] Array to swap bytes in
 *  ulLen  [I] Number of ULONG element to swap the bytes of
 *
 * RETURNS
 *  Nothing.
 */
VOID WINAPI SwapPlong(PULONG lpData, ULONG ulLen)
{
    ULONG i;

    for (i = 0; i < ulLen; i++)
        lpData[i] = RtlUlongByteSwap(lpData[i]);
}

/*************************************************************************
 * SwapPword@8 (MAPI32.48)
 *
 * Swap the bytes in a USHORT array.
 *
 * PARAMS
 *  lpData [O] Array to swap bytes in
 *  ulLen  [I] Number of USHORT element to swap the bytes of
 *
 * RETURNS
 *  Nothing.
 */
VOID WINAPI SwapPword(PUSHORT lpData, ULONG ulLen)
{
    ULONG i;

    for (i = 0; i < ulLen; i++)
        lpData[i] = RtlUshortByteSwap(lpData[i]);
}

/**************************************************************************
 *  MNLS_lstrlenW@4 (MAPI32.62)
 *
 * Calculate the length of a Unicode string.
 *
 * PARAMS
 *  lpszStr [I] String to calculate the length of
 *
 * RETURNS
 *  The length of lpszStr in Unicode characters.
 */
ULONG WINAPI MNLS_lstrlenW(LPCWSTR lpszStr)
{
    TRACE("(%s)\n", debugstr_w(lpszStr));
    return strlenW(lpszStr);
}

/*************************************************************************
 * MNLS_lstrcmpW@8 (MAPI32.63)
 *
 * Compare two Unicode strings.
 *
 * PARAMS
 *  lpszLeft  [I] First string to compare
 *  lpszRight [I] Second string to compare
 *
 * RETURNS
 *  An integer less than, equal to or greater than 0, indicating that
 *  lpszLeft is less than, the same, or greater than lpszRight.
 */
INT WINAPI MNLS_lstrcmpW(LPCWSTR lpszLeft, LPCWSTR lpszRight)
{
    TRACE("(%s,%s)\n", debugstr_w(lpszLeft), debugstr_w(lpszRight));
    return strcmpW(lpszLeft, lpszRight);
}

/*************************************************************************
 * MNLS_lstrcpyW@8 (MAPI32.64)
 *
 * Copy a Unicode string to another string.
 *
 * PARAMS
 *  lpszDest [O] Destination string
 *  lpszSrc  [I] Source string
 *
 * RETURNS
 *  The length lpszDest in Unicode characters.
 */
ULONG WINAPI MNLS_lstrcpyW(LPWSTR lpszDest, LPCWSTR lpszSrc)
{
    ULONG len;

    TRACE("(%p,%s)\n", lpszDest, debugstr_w(lpszSrc));
    len = (strlenW(lpszSrc) + 1) * sizeof(WCHAR);
    memcpy(lpszDest, lpszSrc, len);
    return len;
}

/*************************************************************************
 * MNLS_CompareStringW@12 (MAPI32.65)
 *
 * Compare two Unicode strings.
 *
 * PARAMS
 *  dwCp      [I] Code page for the comparison
 *  lpszLeft  [I] First string to compare
 *  lpszRight [I] Second string to compare
 *
 * RETURNS
 *  CSTR_LESS_THAN, CSTR_EQUAL or CSTR_GREATER_THAN, indicating that
 *  lpszLeft is less than, the same, or greater than lpszRight.
 */
INT WINAPI MNLS_CompareStringW(DWORD dwCp, LPCWSTR lpszLeft, LPCWSTR lpszRight)
{
    INT ret;

    TRACE("0x%08x,%s,%s\n", dwCp, debugstr_w(lpszLeft), debugstr_w(lpszRight));
    ret = MNLS_lstrcmpW(lpszLeft, lpszRight);
    return ret < 0 ? CSTR_LESS_THAN : ret ? CSTR_GREATER_THAN : CSTR_EQUAL;
}

/**************************************************************************
 *  FEqualNames@8 (MAPI32.72)
 *
 * Compare two Mapi names.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -