📄 ncbase.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.
//
//+---------------------------------------------------------------------------
//
// Microsoft Windows
//
// File: N C B A S E . C P P
//
// Contents: Basic common code.
//
// Notes: Pollute this under penalty of death.
//
//----------------------------------------------------------------------------
#include <pch.h>
#pragma hdrstop
#include "ncbase.h"
#include "ncdebug.h"
//+---------------------------------------------------------------------------
//
// Function: AddRefObj
//
// Purpose: AddRef's the object pointed to by punk by calling
// punk->AddRef();
//
// Arguments:
// punk [in] Object to be AddRef'd. Can be NULL.
//
// Returns: Result of AddRef call.
//
// Notes: Using this function to AddRef an object will reduce
// our code size.
//
ULONG
AddRefObj (
IUnknown* punk) NOTHROW
{
return (punk) ? punk->AddRef () : 0;
}
//+---------------------------------------------------------------------------
//
// Function: ReleaseObj
//
// Purpose: Releases the object pointed to by punk by calling
// punk->Release();
//
// Arguments:
// punk [in] Object to be released. Can be NULL.
//
// Returns: Result of Release call.
//
// Notes: Using this function to release a (possibly NULL) object will
// reduce our code size.
//
ULONG
ReleaseObj (
IUnknown* punk) NOTHROW
{
return (punk) ? punk->Release () : 0;
}
//+--------------------------------------------------------------------------
//
// Function: DwWin32ErrorFromHr
//
// Purpose: Converts the HRESULT to a Win32 error or SetupApi error.
//
// Arguments:
// hr [in] The HRESULT to convert
//
// Returns: Converted DWORD value.
//
// Notes:
//
DWORD
DwWin32ErrorFromHr (
HRESULT hr) NOTHROW
{
DWORD dw = ERROR_SUCCESS;
// All success codes convert to ERROR_SUCCESS so we only need to handle
// failures.
if (FAILED(hr))
{
DWORD dwFacility = HRESULT_FACILITY(hr);
if (FACILITY_WIN32 == dwFacility)
{
dw = HRESULT_CODE(hr);
}
else if (FACILITY_ITF == dwFacility)
{
dw = ERROR_GEN_FAILURE;
}
else
{
// cannot convert it
AssertSz(FALSE, "Facility was not SETUP or WIN32!");
dw = hr;
}
}
return dw;
}
//+---------------------------------------------------------------------------
//
// Function: HrFromLastWin32Error
//
// Purpose: Converts the GetLastError() Win32 call into a proper HRESULT.
//
// Arguments:
// (none)
//
// Returns: Converted HRESULT value.
//
// Notes: This is not inline as it actually generates quite a bit of
// code.
// If GetLastError returns an error that looks like a SetupApi
// error, this function will convert the error to an HRESULT
// with FACILITY_SETUP instead of FACILITY_WIN32
//
HRESULT
HrFromLastWin32Error () NOTHROW
{
DWORD dwError = GetLastError();
HRESULT hr;
// This test is testing SetupApi errors only (this is
// temporary because the new HRESULT_FROM_SETUPAPI macro will
// do the entire conversion)
if (dwError & (APPLICATION_ERROR_MASK | ERROR_SEVERITY_ERROR))
{
hr = HRESULT_FROM_SETUPAPI(dwError);
}
else
{
hr = HRESULT_FROM_WIN32(dwError);
}
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: HrGetProcAddress
//
// Purpose: Loads a libray and returns the address of a procedure within
// the library
//
// Arguments:
// hModule [in] The handle to the library module instance
// pszaFunction [in] Function to retrieve
// ppfn [out] Address of szFunction
//
// Returns: S_OK if successful, Win32 converted error if failure.
//
// Notes:
//
HRESULT
HrGetProcAddress (
HMODULE hModule,
PCSTR pszaFunction,
FARPROC* ppfn)
{
Assert(hModule);
Assert(pszaFunction);
Assert(ppfn);
HRESULT hr = S_OK;
#ifdef UNDER_CE
WCHAR szwFunction[64];
int cch = strlen(pszaFunction)+1;
if (cch > sizeof(szwFunction)/sizeof(WCHAR))
return DISP_E_BUFFERTOOSMALL;
mbstowcs(szwFunction, pszaFunction,cch );
*ppfn = GetProcAddressW(hModule, szwFunction);
#else
*ppfn = GetProcAddress(hModule, pszaFunction);
#endif
if (!*ppfn)
{
hr = HrFromLastWin32Error();
TraceTag(ttidError, "HrGetProcAddress failed: szFunction: %s",
pszaFunction);
}
TraceError("HrGetProcAddress", hr);
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: HrLoadLibAndGetProcs
//
// Purpose: Load a dynamic link library and the addresses of one or
// more procedures within that library.
//
// Arguments:
// pszLibPath [in] Path to the DLL to load.
// cFunctions [in] Number of procedures to load.
// apszaFunctionNames [in] Array of function names. (Must be 'cFunctions'
// of them.)
// phmod [out] Returned handle to the loaded module.
// apfn [out] Array of returned pointers to the procedures
// loaded. (Must be 'cFunctions' of them.)
//
// Returns: S_OK if all procedures were loaded, S_FALSE if only
// some of them were, or a Win32 error code. If only
// one procedure is to be loaded and it is not, S_FALSE will
// not be returned, rather, the reason for why the single
// procedure could not be loaded will be returned. This allows
// HrLoadLibAndGetProc to be implemented using this function.
//
// Notes: phmod should be freed by the caller using FreeLibrary if
// the return value is S_OK.
//
HRESULT
HrLoadLibAndGetProcs (
PCTSTR pszLibPath,
UINT cFunctions,
const PCSTR* apszaFunctionNames,
HMODULE* phmod,
FARPROC* apfn)
{
Assert (pszLibPath);
Assert (cFunctions);
Assert (apszaFunctionNames);
Assert (phmod);
Assert (apfn);
HRESULT hr = S_OK;
// Load the module and initialize the output parameters.
//
HMODULE hmod = LoadLibrary(pszLibPath);
*phmod = hmod;
ZeroMemory (apfn, cFunctions * sizeof(FARPROC));
if (hmod)
{
// Get the proc address of each function.
//
for (UINT i = 0; i < cFunctions; i++)
{
apfn[i] = NULL;
hr = HrGetProcAddress (hmod, apszaFunctionNames[i], &apfn[i]);
if (!apfn[i])
{
// Couldn't load all functions. We'll be returning S_FALSE
// (if their are more than one function.)
//
hr = S_FALSE;
TraceTag (ttidError, "HrLoadLibAndGetProcs: GetProcAddress "
"for '%s' failed.",
apszaFunctionNames[i]);
}
}
// If we're only loading one function, and it failed,
// return the failure.
//
if ((1 == cFunctions) && !apfn[0])
{
hr = HrFromLastWin32Error ();
FreeLibrary (hmod);
}
}
else
{
hr = HrFromLastWin32Error ();
TraceTag (ttidError, "HrLoadLibAndGetProcs: LoadLibraryW (%S) failed.",
pszLibPath);
}
TraceError ("HrLoadLibAndGetProcs", hr);
return hr;
}
//+---------------------------------------------------------------------------
//
// Function: FFileExists
//
// Purpose: Check for file existance. Returns TRUE if file is present,
// FALSE otherwise (duh).
//
// Arguments:
// pszFileName [in] File name to check for.
//
// Returns:
//
// Notes:
//
BOOL FFileExists(LPTSTR pszFileName)
{
BOOL fReturn = TRUE;
HANDLE hFile = NULL;
hFile = CreateFile(
pszFileName,
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
DWORD dwLastError = GetLastError();
if (dwLastError != ERROR_FILE_NOT_FOUND)
{
AssertSz(FALSE, "FFileExists failed for some reason other than FILE_NOT_FOUND");
}
fReturn = FALSE;
goto Exit;
}
Exit:
if (hFile)
{
CloseHandle(hFile);
hFile = NULL;
}
return fReturn;
}
//+---------------------------------------------------------------------------
//
// Function: GenerateUUID64
//
// Purpose: Generate a 64-bit UUID. 64-bit UUIDs are easier to deal with than the traditional
// 128-bit GUIDS and seem to offer adequate uniqueness. Odds of collision in million member universe < 1 in 4 million.
//
// Arguments:
// none
//
// Returns:
// 64-bit uid. This does not need to meet the randomness requirements of a true random number generator, since its okay if
// successive uuids are correlated.
//
// Notes:
//
LONGLONG GenerateUUID64(void)
{
LONGLONG uuid;
SYSTEMTIME systime;
static int count;
union {
LONGLONG llfiletime;
FILETIME filetime;
} lltime;
GetSystemTime(&systime);
SystemTimeToFileTime(&systime,&lltime.filetime);
uuid = CeGetRandomSeed();
uuid ^= lltime.llfiletime;
// the count is to ensure that successive calls will get different uuids
// even if both CeGetRandomSeed and SystemTime are unchanged
uuid += ++count;
return uuid;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -