📄 winceutils.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
#include "WinCEUtils.h"
#include <stdlib.h>
#ifdef UNDER_CE
#include <intsafe.h>
#endif
const LPCTSTR k_szRegSoap = TEXT("Software\\Microsoft\\Soap");
class DummyMarshal : public IMarshal
{
public:
DummyMarshal(IUnknown *punkCtrl);
ULONG STDMETHODCALLTYPE AddRef();
ULONG STDMETHODCALLTYPE Release();
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppv);
HRESULT STDMETHODCALLTYPE GetUnmarshalClass(REFIID riid,void * pv,DWORD dwDestContext,void * pvDestContext,DWORD mshlflags,CLSID * pCid ) {ASSERT(FALSE); return E_NOTIMPL;}
HRESULT STDMETHODCALLTYPE GetMarshalSizeMax(REFIID riid,void *pv,DWORD dwDestContext,void * pvDestContext,DWORD mshlflags,ULONG * pSize ) {ASSERT(FALSE); return E_NOTIMPL;}
HRESULT STDMETHODCALLTYPE MarshalInterface(IStream *pStm,REFIID riid,void *pv,DWORD dwDestContext,void *pvDestContext,DWORD mshlflags ) {ASSERT(FALSE); return E_NOTIMPL;}
HRESULT STDMETHODCALLTYPE UnmarshalInterface(IStream * pStm,REFIID riid,void ** ppv ) {ASSERT(FALSE); return E_NOTIMPL;}
HRESULT STDMETHODCALLTYPE ReleaseMarshalData(IStream * pStm ) {ASSERT(FALSE); return E_NOTIMPL;}
HRESULT STDMETHODCALLTYPE DisconnectObject(DWORD dwReserved ) {ASSERT(FALSE); return E_NOTIMPL;}
private:
IUnknown *punkCtrl;
ULONG _refCount;
};
HRESULT (*g_pfn_CoCreateFreeThreadedMarshaler)(LPUNKNOWN punkOuter, LPUNKNOWN * ppunkMarshaler ) = NULL;
HRESULT CoCreateFreeThreadedMarshalerE(
LPUNKNOWN punkOuter,
LPUNKNOWN * ppunkMarshaler )
{
HRESULT hr = E_INVALIDARG;
static BOOL fInited = FALSE;
if(!fInited)
{
//NOTE: we statically link against ole32.dll so its okay
// that we FreeLibrary and keep a pointer to the
// CoCreateFreeThreadedMarshaler function
HINSTANCE hInstOLE32DLL = LoadLibrary (L"ole32.dll");
fInited = TRUE;
g_pfn_CoCreateFreeThreadedMarshaler = NULL;
//
// See if we can get the FTM from ole32.dll
//
if(NULL != hInstOLE32DLL)
{
g_pfn_CoCreateFreeThreadedMarshaler = (HRESULT (*)(LPUNKNOWN, LPUNKNOWN *))GetProcAddress (hInstOLE32DLL, L"CoCreateFreeThreadedMarshaler");
FreeLibrary(hInstOLE32DLL);
}
}
//
// See if we can get the FTM from ole32.dll
//
if(NULL != g_pfn_CoCreateFreeThreadedMarshaler)
{
return g_pfn_CoCreateFreeThreadedMarshaler(punkOuter, ppunkMarshaler);
}
//
// If we *CANT* get it from ole32.dll, give them a dummy object
//
*ppunkMarshaler = NULL;
hr = E_OUTOFMEMORY;
DummyMarshal *pDummy = new DummyMarshal(punkOuter);
if(NULL != pDummy)
{
*ppunkMarshaler = pDummy;
hr = S_OK;
}
return hr;
}
// --> rather than pulling 'environment' variable from
// environment, use the registry
DWORD GetEnvironmentVariableW(
LPCTSTR lpName, // environment variable name
LPTSTR lpBuffer, // buffer for variable value
DWORD nSize // size of buffer
)
{
HKEY hServiceKey;
DWORD dwRes;
if ((ERROR_SUCCESS == (dwRes = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
k_szRegSoap, 0, KEY_QUERY_VALUE, &hServiceKey))))
{
DWORD dwType;
DWORD dwSize = nSize;
if((ERROR_SUCCESS == (dwRes = RegQueryValueEx(hServiceKey,
lpName, NULL, &dwType, (LPBYTE)lpBuffer,
&dwSize))))
{
if(dwType != REG_SZ)
return 0;
return dwSize - 1; //chop the NULL (to conform to GetEnvirVar spec)
}
else if(dwRes == ERROR_MORE_DATA)
return dwSize;
RegCloseKey(hServiceKey);
}
return 0;
}
DWORD GetEnvironmentVariableA
(
LPCSTR name,
LPSTR value,
DWORD size
)
{
WCHAR wName[_MAX_PATH];
if(_MAX_PATH <= size || -1 == mbstowcs(wName, name, size))
return 0;
//convert 'name' to a wide char
WCHAR *pTempBuf = new WCHAR[size];
if(!pTempBuf)
return 0;
DWORD retSize = GetEnvironmentVariableW(wName, pTempBuf, size);
if(retSize == 0)
{
delete [] pTempBuf;
return 0;
}
if(-1 == wcstombs(value, pTempBuf, retSize+1))
{
delete [] pTempBuf;
return 0;
}
delete [] pTempBuf;
return retSize;
}
DWORD
WINAPI
My_GetModuleFileNameA(
HMODULE hModule,
LPSTR lpFilename,
DWORD nSize
)
{
PREFAST_SUPPRESS(12011,"nSize is always handled by callers to be about MAX_PATH, limited buffer size")
WCHAR *fName = new WCHAR[nSize + 1];
if(!fName)
return 0;
DWORD dwRet = GetModuleFileName(hModule, fName, nSize);
if(0 != dwRet)
{
size_t i;
if(-1 == (i = wcstombs(lpFilename, fName, nSize)))
dwRet = 0;
else
lpFilename[i] = NULL;
}
delete [] fName;
return dwRet;
}
HANDLE
WINAPI
My_CreateFileA(
LPCSTR lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile
)
{
WCHAR buf[_MAX_PATH];
mbstowcs(buf, lpFileName, _MAX_PATH);
return CreateFile(
buf,
dwDesiredAccess,
dwShareMode,
lpSecurityAttributes,
dwCreationDisposition,
dwFlagsAndAttributes,
hTemplateFile);
}
HMODULE
WINAPI
My_LoadLibraryExA(
LPCSTR lpLibFileName,
HANDLE hFile,
DWORD dwFlags
)
{
if(dwFlags == LOAD_WITH_ALTERED_SEARCH_PATH)
dwFlags = 0;
WCHAR buf[_MAX_PATH];
mbstowcs(buf, lpLibFileName, _MAX_PATH);
return LoadLibraryEx(
buf,
hFile,
dwFlags);
}
LONG
My_RegCreateKeyExA (
HKEY hKey,
LPCSTR lpSubKey,
DWORD Reserved,
LPSTR lpClass,
DWORD dwOptions,
REGSAM samDesired,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
PHKEY phkResult,
LPDWORD lpdwDisposition
)
{
WCHAR wcDest[_MAX_PATH];
WCHAR *pwcDest = wcDest;
if(lpSubKey)
{
if(-1 == mbstowcs(wcDest, lpSubKey, _MAX_PATH))
return ERROR_BAD_ARGUMENTS;
}
else
pwcDest = NULL;
WCHAR wcDest2[_MAX_PATH];
WCHAR *pwcDest2 = wcDest2;
if(lpClass)
{
if(-1 == mbstowcs(wcDest2, lpClass, _MAX_PATH))
return ERROR_BAD_ARGUMENTS;
}
else
pwcDest2 = NULL;
return RegCreateKeyEx (
hKey,
pwcDest,
Reserved,
pwcDest2,
dwOptions,
samDesired,
lpSecurityAttributes,
phkResult,
lpdwDisposition);
}
LONG
APIENTRY
My_RegDeleteKeyA (
HKEY hKey,
LPCSTR lpSubKey
)
{
WCHAR wcDest[_MAX_PATH];
if(-1 == mbstowcs(wcDest, lpSubKey, _MAX_PATH))
return ERROR_BAD_ARGUMENTS;
return RegDeleteKey (
hKey,
wcDest);
}
LONG
My_RegEnumKeyExA (
HKEY hKey,
DWORD dwIndex,
LPSTR lpName,
LPDWORD lpcbName,
LPDWORD lpReserved,
LPSTR lpClass,
LPDWORD lpcbClass,
PFILETIME lpftLastWriteTime
)
{
//verify incoming params
if(!lpName || !lpcbName)
{
ASSERT(FALSE);
return ERROR_BAD_ARGUMENTS;
}
DWORD dwNameSize = *lpcbName;
DWORD dwClassSize;
WCHAR *wcName = new WCHAR[dwNameSize];
WCHAR *wcClass = NULL;
LONG ret;
if(!wcName)
{
ASSERT(FALSE);
ret = ERROR_NOT_ENOUGH_MEMORY;
goto Done;
}
if(lpcbClass)
{
dwClassSize = *lpcbClass;
wcClass = new WCHAR[dwClassSize];
if(!wcClass)
{
ret = ERROR_NOT_ENOUGH_MEMORY;
goto Done;
}
}
ret = RegEnumKeyEx (
hKey,
dwIndex,
wcName,
lpcbName,
lpReserved,
wcClass,
lpcbClass,
lpftLastWriteTime);
if(ERROR_SUCCESS != ret)
goto Done;
if(-1 == wcstombs(lpName,wcName, dwNameSize))
{
ret = ERROR_BAD_ARGUMENTS;
goto Done;
}
if(lpcbClass)
{
if(-1 == wcstombs(lpClass, wcClass, dwClassSize))
{
ret = ERROR_BAD_ARGUMENTS;
goto Done;
}
}
Done:
if(wcName)
delete [] wcName;
if(wcClass)
delete [] wcClass;
return ret;
}
LONG
My_RegSetValueExA (
HKEY hKey,
LPCSTR lpValueName,
DWORD Reserved,
DWORD dwType,
CONST BYTE* lpData,
DWORD cbData
)
{
WCHAR wcDest[_MAX_PATH];
WCHAR *pwcDest = wcDest;
if(lpValueName)
{
if(-1 == mbstowcs(wcDest, lpValueName, _MAX_PATH))
return ERROR_BAD_ARGUMENTS;
}
else
pwcDest = NULL;
//if the data type is a string, convert it to unicode
if(dwType == REG_SZ)
{
WCHAR dta[_MAX_PATH];
size_t stSize;
if(_MAX_PATH <= cbData || -1 == (stSize = mbstowcs(dta, (char *)lpData, cbData)))
return ERROR_BAD_ARGUMENTS;
dta[stSize] = NULL;
return RegSetValueEx (
hKey,
pwcDest,
Reserved,
dwType,
(UCHAR *)dta,
(stSize+1) * 2);
}
else
{
return RegSetValueEx (
hKey,
pwcDest,
Reserved,
dwType,
lpData,
cbData);
}
}
void * __cdecl bsearch (
const void *key,
const void *base,
size_t num,
size_t width,
int (__cdecl *compare)(const void *, const void *)
)
{
char *lo = (char *)base;
char *hi = (char *)base + (num - 1) * width;
char *mid;
unsigned int half;
int result;
while (lo <= hi)
if (half = num / 2)
{
mid = lo + (num & 1 ? half : (half - 1)) * width;
if (!(result = (*compare)(key,mid)))
return(mid);
else if (result < 0)
{
hi = mid - width;
num = num & 1 ? half : half-1;
}
else {
lo = mid + width;
num = half;
}
}
else if (num)
return((*compare)(key,lo) ? NULL : lo);
else
break;
return(NULL);
}
//**********************************************************************
//
// VarDecCmp - Decimal Compare
//
//**********************************************************************
typedef union {
DWORDLONG int64;
struct {
#if HP_BIGENDIAN
ULONG Hi;
ULONG Lo;
#else
ULONG Lo;
ULONG Hi;
#endif
};
} SPLIT64;
#define COPYDEC(dest, src) {(dest).signscale = (src).signscale; (dest).Hi32 = (src).Hi32; (dest).Lo64 = (src).Lo64;}
#define DEC_SCALE_MAX 28
#define POWER10_MAX 9
ULONG rgulPower10[POWER10_MAX+1] = {1, 10, 100, 1000, 10000, 100000, 1000000,
10000000, 100000000, 1000000000};
static const ULONG ulTenToNine = 1000000000;
#define Div64by32(num, den) ((ULONG)((DWORDLONG)(num) / (ULONG)(den)))
#define Mod64by32(num, den) ((ULONG)((DWORDLONG)(num) % (ULONG)(den)))
inline DWORDLONG DivMod64by32(DWORDLONG num, ULONG den)
{
SPLIT64 sdl;
sdl.Lo = Div64by32(num, den);
sdl.Hi = Mod64by32(num, den);
return sdl.int64;
}
/***
* ScaleResult
*
* Entry:
* rgulRes - Array of ULONGs with value, least-significant first.
* iHiRes - Index of last non-zero value in rgulRes.
* iScale - Scale factor for this value, range 0 - 2 * DEC_SCALE_MAX
*
* Purpose:
* See if we need to scale the result to fit it in 96 bits.
* Perform needed scaling. Adjust scale factor accordingly.
*
* Exit:
* rgulRes updated in place, always 3 ULONGs.
* New scale factor returned, -1 if overflow error.
*
***********************************************************************/
int ScaleResult(ULONG *rgulRes, int iHiRes, int iScale)
{
int iNewScale;
int iCur;
ULONG ulPwr;
ULONG ulTmp;
ULONG ulSticky;
SPLIT64 sdlTmp;
// See if we need to scale the result. The combined scale must
// be <= DEC_SCALE_MAX and the upper 96 bits must be zero.
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -