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

📄 utilities.cpp

📁 用于在线office文档编辑的控件。可以在线新建文档、修改文档
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/***************************************************************************
 * UTILITIES.CPP
 *
 * Shared helper functions and routines.
 *
 *  Copyright ?999-2004; Microsoft Corporation. All rights reserved.
 *  Written by Microsoft Developer Support Office Integration (PSS DSOI)
 * 
 *  This code is provided via KB 311765 as a sample. It is not a formal
 *  product and has not been tested with all containers or servers. Use it
 *  for educational purposes only. See the EULA.TXT file included in the
 *  KB download for full terms of use and restrictions.
 *
 *  THIS CODE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
 *  EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
 *  WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
 *
 ***************************************************************************/
#include "dsoframer.h"
#include <afxwin.h>
#include <tchar.h>
#include <wininet.h>
#include <afxinet.h>
////////////////////////////////////////////////////////////////////////
// Core Utility Functions
//
////////////////////////////////////////////////////////////////////////
// Heap Allocation (Private Heap)
//
extern HANDLE v_hPrivateHeap;
STDAPI_(LPVOID) DsoMemAlloc(DWORD cbSize)
{
    CHECK_NULL_RETURN(v_hPrivateHeap, NULL);
    return HeapAlloc(v_hPrivateHeap, HEAP_ZERO_MEMORY, cbSize);
}

STDAPI_(void) DsoMemFree(LPVOID ptr)
{
    if ((v_hPrivateHeap) && (ptr))
        HeapFree(v_hPrivateHeap, 0, ptr);
}


int __cdecl _purecall(){__asm{int 3}; return 0;}

////////////////////////////////////////////////////////////////////////
// Global String Functions
//
////////////////////////////////////////////////////////////////////////
// DsoConvertToUnicodeEx
//
STDAPI DsoConvertToUnicodeEx(LPCSTR pszMbcsString, DWORD cbMbcsLen, LPWSTR pwszUnicode, DWORD cbUniLen, UINT uiCodePage)
{
	DWORD cbRet;
	UINT iCode = CP_ACP;

	if (IsValidCodePage(uiCodePage))
		iCode = uiCodePage;

	CHECK_NULL_RETURN(pwszUnicode,    E_POINTER);
	pwszUnicode[0] = L'\0';

	CHECK_NULL_RETURN(pszMbcsString,  E_POINTER);
	CHECK_NULL_RETURN(cbMbcsLen,      E_INVALIDARG);
	CHECK_NULL_RETURN(cbUniLen,       E_INVALIDARG);

	cbRet = MultiByteToWideChar(iCode, 0, pszMbcsString, cbMbcsLen, pwszUnicode, cbUniLen);
	if (cbRet == 0)	return E_WIN32_LASTERROR;

	pwszUnicode[cbRet] = L'\0';
	return S_OK;
}

////////////////////////////////////////////////////////////////////////
// DsoConvertToMBCSEx
//
STDAPI DsoConvertToMBCSEx(LPCWSTR pwszUnicodeString, DWORD cbUniLen, LPSTR pszMbcsString, DWORD cbMbcsLen, UINT uiCodePage)
{
	DWORD cbRet;
	UINT iCode = CP_ACP;

	if (IsValidCodePage(uiCodePage))
		iCode = uiCodePage;

	CHECK_NULL_RETURN(pszMbcsString,     E_POINTER);
	pszMbcsString[0] = L'\0';

	CHECK_NULL_RETURN(pwszUnicodeString, E_POINTER);
	CHECK_NULL_RETURN(cbMbcsLen,         E_INVALIDARG);
	CHECK_NULL_RETURN(cbUniLen,          E_INVALIDARG);

	cbRet = WideCharToMultiByte(iCode, 0, pwszUnicodeString, -1, pszMbcsString, cbMbcsLen, NULL, NULL);
	if (cbRet == 0)	return E_WIN32_LASTERROR;

	pszMbcsString[cbRet] = '\0';
	return S_OK;
}

////////////////////////////////////////////////////////////////////////
// DsoConvertToLPWSTR
//
//  Takes a MBCS string and returns a LPWSTR allocated on private heap.
//
STDAPI_(LPWSTR) DsoConvertToLPWSTR(LPCSTR pszMbcsString)
{
	LPWSTR pwsz = NULL;
	UINT cblen, cbnew;

	if ((pszMbcsString) && 
        ((cblen = lstrlen(pszMbcsString)) > 0))
	{
		cbnew = ((cblen + 1) * sizeof(WCHAR));
		if ((pwsz = (LPWSTR)DsoMemAlloc(cbnew)) != NULL) 
		{
			if (FAILED(DsoConvertToUnicodeEx(pszMbcsString, cblen, pwsz, cbnew, GetACP())))
            {
			    DsoMemFree(pwsz);
                pwsz = NULL;
            }
		}
	}

	return pwsz;
}
////////////////////////////////////////////////////////////////////////
// DsoConvertToMBCS
//
//  Takes a WCHAR string and returns a LPSTR on the private heap.
//
STDAPI_(LPSTR) DsoConvertToMBCS(LPCWSTR pwszUnicodeString)
{
	LPSTR psz = NULL;
	UINT cblen, cbnew;

    if ((pwszUnicodeString) && 
        ((cblen = lstrlenW(pwszUnicodeString)) > 0))
	{
		cbnew = ((cblen + 1) * sizeof(WCHAR));
		if ((psz = (LPSTR)DsoMemAlloc(cbnew)) != NULL) 
		{
			if (FAILED(DsoConvertToMBCSEx(pwszUnicodeString, cblen, psz, cbnew, GetACP())))
            {
			    DsoMemFree(psz); psz = NULL;
            }
		}
	}

	return psz;
}

////////////////////////////////////////////////////////////////////////
// DsoConvertToBSTR
//
//  Takes a MBCS string and returns a BSTR. NULL is returned if the 
//  function fails or the string is empty.
//
STDAPI_(BSTR) DsoConvertToBSTR(LPCSTR pszMbcsString)
{
	BSTR bstr = NULL;
    LPWSTR pwsz = DsoConvertToLPWSTR(pszMbcsString);
	if (pwsz)
	{
	    bstr = SysAllocString(pwsz);
	    DsoMemFree(pwsz);
    }
	return bstr;
}

////////////////////////////////////////////////////////////////////////
// DsoConvertToLPOLESTR
//
//  Returns Unicode string in COM Task Memory (CoTaskMemAlloc).
//
STDAPI_(LPWSTR) DsoConvertToLPOLESTR(LPCWSTR pwszUnicodeString)
{
	LPWSTR pwsz;
	UINT cblen;

	CHECK_NULL_RETURN(pwszUnicodeString, NULL);
	cblen = lstrlenW(pwszUnicodeString);

    pwsz = (LPWSTR)CoTaskMemAlloc((cblen * sizeof(WCHAR)) + 2);
    if (pwsz)
    {
        memcpy(pwsz, pwszUnicodeString, (cblen * sizeof(WCHAR)));
        pwsz[cblen] = L'\0'; // Make sure it is NULL terminated.
    }

    return pwsz;
}

////////////////////////////////////////////////////////////////////////
// DsoCopyString
//
//  Duplicates the string into private heap string.
//
STDAPI_(LPWSTR) DsoCopyString(LPCWSTR pwszString)
{
	LPWSTR pwsz;
	UINT cblen;

	CHECK_NULL_RETURN(pwszString, NULL);
	cblen = lstrlenW(pwszString);

    pwsz = (LPWSTR)DsoMemAlloc((cblen * sizeof(WCHAR)) + 2);
    if (pwsz)
    {
        memcpy(pwsz, pwszString, (cblen * sizeof(WCHAR)));
        pwsz[cblen] = L'\0'; // Make sure it is NULL terminated.
    }

    return pwsz;
}

////////////////////////////////////////////////////////////////////////
// DsoCopyStringCat
//
STDAPI_(LPWSTR) DsoCopyStringCat(LPCWSTR pwszString1, LPCWSTR pwszString2)
{return DsoCopyStringCatEx(pwszString1, 1, &pwszString2);}

////////////////////////////////////////////////////////////////////////
// DsoCopyStringCatEx
//
//  Duplicates the string into private heap string and appends one or more
//  strings to the end (concatenation). 
//
STDAPI_(LPWSTR) DsoCopyStringCatEx(LPCWSTR pwszBaseString, UINT cStrs, LPCWSTR *ppwszStrs)
{
	LPWSTR pwsz;
	UINT i, cblenb, cblent;
    UINT *pcblens;

 // We assume you have a base string to start with. If not, we return NULL...
    if ((pwszBaseString == NULL) || 
        ((cblenb = lstrlenW(pwszBaseString)) < 1))
        return NULL;

 // If we have nothing to append, just do a plain copy...
    if ((cStrs == 0) || (ppwszStrs == NULL))
        return DsoCopyString(pwszBaseString);

 // Determine the size of the final string by finding the lengths
 // of each. We create an array of sizes to use later on...
    cblent = cblenb;
    pcblens = new UINT[cStrs];
    CHECK_NULL_RETURN(pcblens,  NULL);

    for (i = 0; i < cStrs; i++)
    {
        pcblens[i] =  lstrlenW(ppwszStrs[i]);
        cblent += pcblens[i];
    }

 // If we have data to append, create the new string and append the
 // data by copying them in place. We expect UTF-16 Unicode strings
 // for this to work, but this should be normal...
	if (cblent > cblenb)
    {
	    pwsz = (LPWSTR)DsoMemAlloc(((cblent + 1) * sizeof(WCHAR)));
	    CHECK_NULL_RETURN(pwsz,   NULL);

	    memcpy(pwsz, pwszBaseString, (cblenb * sizeof(WCHAR)));
        cblent = cblenb;

        for (i = 0; i < cStrs; i++)
        {
		    memcpy((pwsz + cblent), ppwszStrs[i], (pcblens[i] * sizeof(WCHAR)));
            cblent += pcblens[i];
        }
    }
    else pwsz = DsoCopyString(pwszBaseString);

    delete [] pcblens;
	return pwsz;
}

////////////////////////////////////////////////////////////////////////
// DsoCLSIDtoLPSTR
//
STDAPI_(LPSTR) DsoCLSIDtoLPSTR(REFCLSID clsid)
{
	LPSTR psz = NULL;
	LPWSTR pwsz;
	if (SUCCEEDED(StringFromCLSID(clsid, &pwsz)))
	{
		psz = DsoConvertToMBCS(pwsz);
		CoTaskMemFree(pwsz);
	}
    return psz;
}


///////////////////////////////////////////////////////////////////////////////////
// DsoCompareStringsEx
//
//  Calls CompareString API using Unicode version (if available on OS). Otherwise,
//  we have to thunk strings down to MBCS to compare. This is fairly inefficient for
//  Win9x systems that don't handle Unicode, but hey...this is only a sample.
//
STDAPI_(UINT) DsoCompareStringsEx(LPCWSTR pwsz1, INT cch1, LPCWSTR pwsz2, INT cch2)
{
	UINT iret;
	LCID lcid = GetThreadLocale();
	UINT cblen1, cblen2;

 // Check that valid parameters are passed and then contain somethimg...
    if ((pwsz1 == NULL) || (cch1 == 0) || 
        ((cblen1 = ((cch1 > 0) ? cch1 : lstrlenW(pwsz1))) == 0))
		return CSTR_LESS_THAN;

	if ((pwsz2 == NULL) || (cch2 == 0) || 
        ((cblen2 = ((cch2 > 0) ? cch2 : lstrlenW(pwsz2))) == 0))
		return CSTR_GREATER_THAN;

 // If the string is of the same size, then we do quick compare to test for
 // equality (this is slightly faster than calling the API, but only if we
 // expect the calls to find an equal match)...
	if (cblen1 == cblen2)
	{
		for (iret = 0; iret < cblen1; iret++)
		{
			if (pwsz1[iret] == pwsz2[iret])
				continue;

			if (((pwsz1[iret] >= 'A') && (pwsz1[iret] <= 'Z')) &&
				((pwsz1[iret] + ('a' - 'A')) == pwsz2[iret]))
				continue;

			if (((pwsz2[iret] >= 'A') && (pwsz2[iret] <= 'Z')) &&
				((pwsz2[iret] + ('a' - 'A')) == pwsz1[iret]))
				continue;

			break; // don't continue if we can't quickly match...
		}

		// If we made it all the way, then they are equal...
		if (iret == cblen1)
			return CSTR_EQUAL;
	}

 // Now ask the OS to check the strings and give us its read. (We prefer checking
 // in Unicode since this is faster and we may have strings that can't be thunked
 // down to the local ANSI code page)...
	if (v_fUnicodeAPI)
	{
		iret = CompareStringW(lcid, NORM_IGNORECASE | NORM_IGNOREWIDTH, pwsz1, cblen1, pwsz2, cblen2);
	}
	else
	{
	 // If we are on Win9x, we don't have much of choice (thunk the call)...
		LPSTR psz1 = DsoConvertToMBCS(pwsz1);
		LPSTR psz2 = DsoConvertToMBCS(pwsz2);
		iret = CompareStringA(lcid, NORM_IGNORECASE, psz1, -1, psz2, -1);
		DsoMemFree(psz2);
		DsoMemFree(psz1);
	}

	return iret;
}


////////////////////////////////////////////////////////////////////////
// URL Helpers
//
////////////////////////////////////////////////////////////////////////
// General Functions (checks to see if we can recognize type)
//
STDAPI_(BOOL) LooksLikeUNC(LPCWSTR pwsz)
{
	return ((pwsz) && (*pwsz == L'\\') && (*(pwsz + 1) == L'\\') && (*(pwsz + 2) != L'\\'));
}

STDAPI_(BOOL) LooksLikeLocalFile(LPCWSTR pwsz)
{
	return ((pwsz) && 
        (((*pwsz > 64) && (*pwsz < 91)) || ((*pwsz > 96) && (*pwsz < 123))) &&
        (*(pwsz + 1) == L':') && (*(pwsz + 2) == L'\\'));
}

STDAPI_(BOOL) LooksLikeHTTP(LPCWSTR pwsz)
{
	return ((pwsz) && ((*pwsz == L'H') || (*pwsz == L'h')) &&
		((*(pwsz + 1) == L'T') || (*(pwsz + 1) == L't')) &&
		((*(pwsz + 2) == L'T') || (*(pwsz + 2) == L't')) &&
		((*(pwsz + 3) == L'P') || (*(pwsz + 3) == L'p')) &&
		((*(pwsz + 4) == L':') || (((*(pwsz + 4) == L'S') || (*(pwsz + 4) == L's')) && (*(pwsz + 5) == L':'))));
}

STDAPI_(BOOL) LooksLikeFTP(LPCWSTR pwsz)
{
	return ((pwsz) && ((*pwsz == L'F') || (*pwsz == L'f')) &&
		((*(pwsz + 1) == L'T') || (*(pwsz + 1) == L't')) &&
		((*(pwsz + 2) == L'P') || (*(pwsz + 2) == L'p')) &&
		((*(pwsz + 3) == L':') ));
}
////////////////////////////////////////////////////////////////////////
// GetTempPathForURLDownload
//
//  Constructs a temp path for a downloaded file. Note we scan the URL 
//  to find the name of the file so we can use its exention for server 
//  association (in case it is a non-docfile -- like RTF) and also 
//  create our own subfolder to try and avoid name conflicts in temp
//  folder itself. 
//
STDAPI_(BOOL) GetTempPathForURLDownload(WCHAR* pwszURL, WCHAR** ppwszLocalFile)
{
	DWORD  dw;
	LPWSTR pwszTPath = NULL;
	LPWSTR pwszTFile = NULL;
	CHAR   szTmpPath[MAX_PATH];

 // Do a little parameter checking and find length of the URL...
	if (!(pwszURL) || ((dw = lstrlenW(pwszURL)) < 6) ||
		!(LooksLikeHTTP(pwszURL)) || !(ppwszLocalFile))
		return FALSE;

	*ppwszLocalFile = NULL;

	if (GetTempPath(MAX_PATH, szTmpPath))
	{
		DWORD dwtlen = lstrlen(szTmpPath);
		if (dwtlen > 0 && szTmpPath[dwtlen-1] != '\\')
			lstrcat(szTmpPath, "\\");

		lstrcat(szTmpPath, "DSOWebOffice");

		if (CreateDirectory(szTmpPath, NULL) || GetLastError() == ERROR_ALREADY_EXISTS)
		{
			lstrcat(szTmpPath, "\\");
			pwszTPath = DsoConvertToLPWSTR(szTmpPath);
		}
	}

	if (pwszTPath)
	{
		if (pwszTFile = DsoCopyString(pwszURL))
		{
			LPWSTR pwszT = pwszTFile;
			while (*(++pwszT))
				if (*pwszT == L'?'){*pwszT = L'\0'; break;}

			while (*(--pwszT))
				if (*pwszT == L'/'){++pwszT; break;}

			*ppwszLocalFile = DsoCopyStringCat(pwszTPath, pwszT);

			DsoMemFree(pwszTFile);
		}

		DsoMemFree(pwszTPath);
	}

	return (BOOL)(*ppwszLocalFile);
}

////////////////////////////////////////////////////////////////////////
// URLDownloadFile
//
//  Does a simple URLMON download of file (no save back to server allowed),
//  and no dependent files will be downloaded (just one temp file). 
//
#include "dsoframer.h" 
#include "msoffice.h"
#include <atlbase.h>
#include <atlconv.h>
#include <afxdisp.h>
#define toHex(x) (((BYTE)(x)) > 9 ? (BYTE)((BYTE)(x) + 55) : (BYTE)((BYTE)(x) + 48))
STDAPI URLDownloadFile(LPUNKNOWN punk, WCHAR* pwszURL, WCHAR* pwszLocalFile)
{
/*    typedef HRESULT (WINAPI *PFN_URLDTFW)(LPUNKNOWN, LPCWSTR, LPCWSTR, DWORD, LPUNKNOWN);
    static PFN_URLDTFW pfnURLDownloadToFileW = NULL;
    HMODULE hUrlmon;

    if (pfnURLDownloadToFileW == NULL)
    {
        if (hUrlmon = LoadLibrary("URLMON.DLL"))
            pfnURLDownloadToFileW = (PFN_URLDTFW)GetProcAddress(hUrlmon, "URLDownloadToFileW");

⌨️ 快捷键说明

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