You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
777 lines
20 KiB
777 lines
20 KiB
//+-------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1992 - 2000
|
|
//
|
|
// File: Util.cpp
|
|
//
|
|
// Contents: Generic utility functions and classes for dscmd
|
|
//
|
|
// History: 01-Oct-2000 JeffJon Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
#include "pch.h"
|
|
|
|
#include "util.h"
|
|
|
|
#ifdef DBG
|
|
|
|
//
|
|
// Globals
|
|
//
|
|
CDebugSpew DebugSpew;
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Member: CDebugSpew::EnterFunction
|
|
//
|
|
// Synopsis: Outputs "Enter " followed by the function name (or any passed
|
|
// in string) and then calls Indent so that any output is indented
|
|
//
|
|
// Arguments: [nDebugLevel - IN] : the level at which this output should
|
|
// be spewed
|
|
// [pszFunction - IN] : a string to output to the console which
|
|
// is proceeded by "Entering "
|
|
//
|
|
// Returns:
|
|
//
|
|
// History: 01-Oct-2000 JeffJon Created
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
void CDebugSpew::EnterFunction(UINT nDebugLevel, PCWSTR pszFunction)
|
|
{
|
|
//
|
|
// Verify input parameter
|
|
//
|
|
if (!pszFunction)
|
|
{
|
|
ASSERT(pszFunction);
|
|
return;
|
|
}
|
|
|
|
CComBSTR sbstrOutput(L"Entering ");
|
|
sbstrOutput += pszFunction;
|
|
|
|
//
|
|
// Output the debug spew
|
|
//
|
|
Output(nDebugLevel, sbstrOutput);
|
|
|
|
//
|
|
// Indent
|
|
//
|
|
Indent();
|
|
}
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Member: CDebugSpew::LeaveFunction
|
|
//
|
|
// Synopsis: Outputs "Exit " followed by the function name (or any passed
|
|
// in string) and then calls Outdent
|
|
//
|
|
// Arguments: [nDebugLevel - IN] : the level at which this output should
|
|
// be spewed
|
|
// [pszFunction - IN] : a string to output to the console which
|
|
// is proceeded by "Leaving "
|
|
//
|
|
// Returns:
|
|
//
|
|
// History: 01-Oct-2000 JeffJon Created
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
void CDebugSpew::LeaveFunction(UINT nDebugLevel, PCWSTR pszFunction)
|
|
{
|
|
//
|
|
// Verify input parameter
|
|
//
|
|
if (!pszFunction)
|
|
{
|
|
ASSERT(pszFunction);
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Outdent
|
|
//
|
|
Outdent();
|
|
|
|
CComBSTR sbstrOutput(L"Leaving ");
|
|
sbstrOutput += pszFunction;
|
|
|
|
//
|
|
// Output the debug spew
|
|
//
|
|
Output(nDebugLevel, sbstrOutput);
|
|
}
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Member: CDebugSpew::LeaveFunctionHr
|
|
//
|
|
// Synopsis: Outputs "Exit " followed by the function name (or any passed
|
|
// in string), the HRESULT return value, and then calls Outdent
|
|
//
|
|
// Arguments: [nDebugLevel - IN] : the level at which this output should
|
|
// be spewed
|
|
// [pszFunction - IN] : a string to output to the console which
|
|
// is proceeded by "Leaving "
|
|
// [hr - IN] : the HRESULT result value that is being
|
|
// returned by the function
|
|
//
|
|
// Returns:
|
|
//
|
|
// History: 01-Oct-2000 JeffJon Created
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
void CDebugSpew::LeaveFunctionHr(UINT nDebugLevel, PCWSTR pszFunction, HRESULT hr)
|
|
{
|
|
//
|
|
// Verify input parameter
|
|
//
|
|
if (!pszFunction)
|
|
{
|
|
ASSERT(pszFunction);
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Outdent
|
|
//
|
|
Outdent();
|
|
|
|
CComBSTR sbstrOutput(L"Leaving ");
|
|
sbstrOutput += pszFunction;
|
|
|
|
//
|
|
// Append the return value
|
|
//
|
|
WCHAR pszReturn[30];
|
|
//Security Review:Enough buffer is provided.
|
|
wsprintf(pszReturn, L" returning 0x%x", hr);
|
|
|
|
sbstrOutput += pszReturn;
|
|
|
|
//
|
|
// Output the debug spew
|
|
//
|
|
Output(nDebugLevel, sbstrOutput);
|
|
}
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Member: OsName
|
|
//
|
|
// Synopsis: Returns a readable string of the platform
|
|
//
|
|
// Arguments: [refInfo IN] : reference the OS version info structure
|
|
// retrieved from GetVersionEx()
|
|
//
|
|
// Returns: PWSTR : returns a pointer to static text describing the
|
|
// platform. The returned string does not have to
|
|
// be freed.
|
|
//
|
|
// History: 20-Dec-2000 JeffJon Created
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
PWSTR OsName(const OSVERSIONINFO& refInfo)
|
|
{
|
|
switch (refInfo.dwPlatformId)
|
|
{
|
|
case VER_PLATFORM_WIN32s:
|
|
{
|
|
return L"Win32s on Windows 3.1";
|
|
}
|
|
case VER_PLATFORM_WIN32_WINDOWS:
|
|
{
|
|
switch (refInfo.dwMinorVersion)
|
|
{
|
|
case 0:
|
|
{
|
|
return L"Windows 95";
|
|
}
|
|
case 1:
|
|
{
|
|
return L"Windows 98";
|
|
}
|
|
default:
|
|
{
|
|
return L"Windows 9X";
|
|
}
|
|
}
|
|
}
|
|
case VER_PLATFORM_WIN32_NT:
|
|
{
|
|
return L"Windows NT";
|
|
}
|
|
default:
|
|
{
|
|
ASSERT(false);
|
|
break;
|
|
}
|
|
}
|
|
return L"Some Unknown Windows Version";
|
|
}
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Member: CDebugSpew::SpewHeader
|
|
//
|
|
// Synopsis: Outputs debug information like command line and build info
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// History: 20-Dec-2000 JeffJon Created
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
void CDebugSpew::SpewHeader()
|
|
{
|
|
//
|
|
// First output the command line
|
|
//
|
|
PWSTR pszCommandLine = GetCommandLine();
|
|
if (pszCommandLine)
|
|
{
|
|
Output(MINIMAL_LOGGING,
|
|
L"Command line: %s",
|
|
GetCommandLine());
|
|
}
|
|
|
|
//
|
|
// Output the module being used
|
|
//
|
|
do // false loop
|
|
{
|
|
//
|
|
// Get the file path
|
|
//
|
|
WCHAR pszFileName[MAX_PATH + 1];
|
|
::ZeroMemory(pszFileName, sizeof(pszFileName));
|
|
|
|
//Security Review:If the path is MAX_PATH long, API will return MAX_PATH and won't
|
|
//NULL terminate, but we are fine since we allocated buffer of size MAX_PATH + 1
|
|
//and set it to Zero
|
|
if (::GetModuleFileNameW(::GetModuleHandle(NULL), pszFileName, MAX_PATH) == 0)
|
|
{
|
|
break;
|
|
}
|
|
|
|
Output(MINIMAL_LOGGING,
|
|
L"Module: %s",
|
|
pszFileName);
|
|
|
|
//
|
|
// get the file attributes
|
|
//
|
|
WIN32_FILE_ATTRIBUTE_DATA attr;
|
|
::ZeroMemory(&attr, sizeof(attr));
|
|
|
|
if (::GetFileAttributesEx(pszFileName, GetFileExInfoStandard, &attr) == 0)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
// convert the filetime to a system time
|
|
//
|
|
FILETIME localtime;
|
|
::FileTimeToLocalFileTime(&attr.ftLastWriteTime, &localtime);
|
|
SYSTEMTIME systime;
|
|
::FileTimeToSystemTime(&localtime, &systime);
|
|
|
|
//
|
|
// output the timestamp
|
|
//
|
|
Output(MINIMAL_LOGGING,
|
|
L"Timestamp: %2d/%2d/%4d %2d:%2d:%d.%d",
|
|
systime.wMonth,
|
|
systime.wDay,
|
|
systime.wYear,
|
|
systime.wHour,
|
|
systime.wMinute,
|
|
systime.wSecond,
|
|
systime.wMilliseconds);
|
|
} while (false);
|
|
|
|
//
|
|
// Get the system info
|
|
//
|
|
OSVERSIONINFO info;
|
|
info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
|
|
|
BOOL success = ::GetVersionEx(&info);
|
|
ASSERT(success);
|
|
|
|
//
|
|
// Get the Whistler build lab version
|
|
//
|
|
CComBSTR sbstrLabInfo;
|
|
|
|
do // false loop
|
|
{
|
|
HKEY key = 0;
|
|
LONG err = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
|
L"Software\\Microsoft\\Windows NT\\CurrentVersion",
|
|
0,
|
|
KEY_READ,
|
|
&key);
|
|
if (err != ERROR_SUCCESS)
|
|
{
|
|
break;
|
|
}
|
|
|
|
WCHAR buf[MAX_PATH + 1];
|
|
::ZeroMemory(buf, sizeof(buf));
|
|
|
|
DWORD type = 0;
|
|
DWORD bufSize = sizeof(WCHAR)*MAX_PATH;
|
|
//NTRAID#NTBUG9-573572-2002/05/24, yanggao, bufSize is the size in bytes according to RegQueryValueEx.
|
|
//In order to terminate the returned value, give it value sizeof(WCHAR)*MAX_PATH.
|
|
|
|
//Security Review: when buffers match the exact length of data
|
|
//value data is not null terminated.
|
|
//NTRAID#NTBUG9-573572-2002/03/12-hiteshr
|
|
err = ::RegQueryValueEx(key,
|
|
L"BuildLab",
|
|
0,
|
|
&type,
|
|
reinterpret_cast<BYTE*>(buf),
|
|
&bufSize);
|
|
if (err != ERROR_SUCCESS)
|
|
{
|
|
break;
|
|
}
|
|
|
|
sbstrLabInfo = buf;
|
|
} while (false);
|
|
|
|
Output(MINIMAL_LOGGING,
|
|
L"Build: %s %d.%d build %d %s (BuildLab:%s)",
|
|
OsName(info),
|
|
info.dwMajorVersion,
|
|
info.dwMinorVersion,
|
|
info.dwBuildNumber,
|
|
info.szCSDVersion,
|
|
sbstrLabInfo);
|
|
|
|
//
|
|
// Output a blank line to separate the header from the rest of the output
|
|
//
|
|
Output(MINIMAL_LOGGING,
|
|
L"\r\n");
|
|
}
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Member: CDebugSpew::Output
|
|
//
|
|
// Synopsis: Outputs the passed in string to stdout proceeded by the number
|
|
// of spaces specified by GetIndent()
|
|
//
|
|
// Arguments: [nDebugLevel - IN] : the level at which this output should
|
|
// be spewed
|
|
// [pszOutput - IN] : a format string to output to the console
|
|
// [... - IN] : a variable argument list to be formatted
|
|
// into pszOutput similar to wprintf
|
|
//
|
|
// Returns:
|
|
//
|
|
// History: 01-Oct-2000 JeffJon Created
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
void CDebugSpew::Output(UINT nDebugLevel, PCWSTR pszOutput, ...)
|
|
{
|
|
if (nDebugLevel <= GetDebugLevel())
|
|
{
|
|
//
|
|
// Verify parameters
|
|
//
|
|
if (!pszOutput)
|
|
{
|
|
ASSERT(pszOutput);
|
|
return;
|
|
}
|
|
|
|
va_list args;
|
|
va_start(args, pszOutput);
|
|
|
|
WCHAR szBuffer[1024];
|
|
|
|
//Security Review:Check for the return value of function and also
|
|
//consider replacing it with strsafe api.
|
|
//NTRAID#NTBUG9-573602-2002/03/12-hiteshr
|
|
if(FAILED(StringCchVPrintf(szBuffer, sizeof(szBuffer)/sizeof(szBuffer[0]), pszOutput, args)))
|
|
return;
|
|
|
|
CComBSTR sbstrOutput;
|
|
|
|
//
|
|
// Insert the spaces for the indent
|
|
//
|
|
for (UINT nCount = 0; nCount < GetIndent(); nCount++)
|
|
{
|
|
sbstrOutput += L" ";
|
|
}
|
|
|
|
//
|
|
// Append the output string
|
|
//
|
|
sbstrOutput += szBuffer;
|
|
|
|
//
|
|
// Output the results
|
|
//
|
|
WriteStandardOut(L"%s\r\n", sbstrOutput);
|
|
|
|
va_end(args);
|
|
}
|
|
}
|
|
|
|
#endif // DBG
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Macro: MyA2WHelper
|
|
//
|
|
// Synopsis: Converts a string from Ansi to Unicode in the OEM codepage
|
|
//
|
|
// Arguments: [lpa - IN] : Ansi string to be converted
|
|
// [acp - IN] : the codepage to use
|
|
//
|
|
// Returns: PWSTR : the Unicode string in the OEM codepage. Caller
|
|
// must free the returned pointer using delete[]
|
|
//
|
|
// History: 04-Oct-2000 JeffJon Created
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
inline PWSTR WINAPI MyA2WHelper(LPCSTR lpa, UINT acp)
|
|
{
|
|
ASSERT(lpa != NULL);
|
|
|
|
// Use MultiByteToWideChar without a buffer to find out the required
|
|
// size
|
|
|
|
PWSTR wideString = 0;
|
|
|
|
int result = MultiByteToWideChar(acp, 0, lpa, -1, 0, 0);
|
|
if (result)
|
|
{
|
|
wideString = new WCHAR[result];
|
|
if (wideString)
|
|
{
|
|
result = MultiByteToWideChar(acp, 0, lpa, -1, wideString, result);
|
|
}
|
|
}
|
|
return wideString;
|
|
}
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Function: _UnicodeToOemConvert
|
|
//
|
|
// Synopsis: takes the passed in string (pszUnicode) and converts it to
|
|
// the OEM code page
|
|
//
|
|
// Arguments: [pszUnicode - IN] : the string to be converted
|
|
// [sbstrOemUnicode - OUT] : the converted string
|
|
//
|
|
// Returns:
|
|
//
|
|
// History: 04-Oct-2000 JeffJon Created
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
void _UnicodeToOemConvert(PCWSTR pszUnicode, CComBSTR& sbstrOemUnicode)
|
|
{
|
|
|
|
if (!pszUnicode)
|
|
{
|
|
ASSERT(pszUnicode);
|
|
return;
|
|
}
|
|
|
|
// Use WideCharToMultiByte without a buffer to find out
|
|
// the required size
|
|
|
|
int result =
|
|
WideCharToMultiByte(
|
|
CP_OEMCP,
|
|
0,
|
|
pszUnicode,
|
|
-1,
|
|
0,
|
|
0,
|
|
0,
|
|
0);
|
|
|
|
if (result)
|
|
{
|
|
// Now allocate and convert the string
|
|
|
|
PSTR pszOemAnsi = new CHAR[result];
|
|
if (pszOemAnsi)
|
|
{
|
|
ZeroMemory(pszOemAnsi, result * sizeof(CHAR));
|
|
|
|
result =
|
|
WideCharToMultiByte(
|
|
CP_OEMCP,
|
|
0,
|
|
pszUnicode,
|
|
-1,
|
|
pszOemAnsi,
|
|
result * sizeof(CHAR),
|
|
0,
|
|
0);
|
|
|
|
ASSERT(result);
|
|
|
|
//
|
|
// convert it back to WCHAR on OEM CP
|
|
//
|
|
PWSTR oemUnicode = MyA2WHelper(pszOemAnsi, CP_OEMCP);
|
|
if (oemUnicode)
|
|
{
|
|
sbstrOemUnicode = oemUnicode;
|
|
delete[] oemUnicode;
|
|
oemUnicode = 0;
|
|
}
|
|
delete[] pszOemAnsi;
|
|
pszOemAnsi = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Function: SpewAttrs(ADS_ATTR_INFO* pCreateAttrs, DWORD dwNumAttrs);
|
|
//
|
|
// Synopsis: Uses the DEBUG_OUTPUT macro to output the attributes and the
|
|
// values specified
|
|
//
|
|
// Arguments: [pAttrs - IN] : The ADS_ATTR_INFO
|
|
// [dwNumAttrs - IN] : The number of attributes in pAttrs
|
|
//
|
|
// Returns:
|
|
//
|
|
// History: 04-Oct-2000 JeffJon Created
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
#ifdef DBG
|
|
void SpewAttrs(ADS_ATTR_INFO* pAttrs, DWORD dwNumAttrs)
|
|
{
|
|
for (DWORD dwAttrIdx = 0; dwAttrIdx < dwNumAttrs; dwAttrIdx++)
|
|
{
|
|
if (pAttrs[dwAttrIdx].dwADsType == ADSTYPE_DN_STRING ||
|
|
pAttrs[dwAttrIdx].dwADsType == ADSTYPE_CASE_EXACT_STRING ||
|
|
pAttrs[dwAttrIdx].dwADsType == ADSTYPE_CASE_IGNORE_STRING ||
|
|
pAttrs[dwAttrIdx].dwADsType == ADSTYPE_PRINTABLE_STRING)
|
|
{
|
|
for (DWORD dwValueIdx = 0; dwValueIdx < pAttrs[dwAttrIdx].dwNumValues; dwValueIdx++)
|
|
{
|
|
if (pAttrs[dwAttrIdx].pADsValues[dwValueIdx].CaseIgnoreString)
|
|
{
|
|
DEBUG_OUTPUT(FULL_LOGGING, L" %s = %s",
|
|
pAttrs[dwAttrIdx].pszAttrName,
|
|
pAttrs[dwAttrIdx].pADsValues[dwValueIdx].CaseIgnoreString);
|
|
}
|
|
else
|
|
{
|
|
DEBUG_OUTPUT(FULL_LOGGING, L" %s = value being cleared",
|
|
pAttrs[dwAttrIdx].pszAttrName);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif // DBG
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Function: litow
|
|
//
|
|
// Synopsis:
|
|
//
|
|
// Arguments: [li - IN] : reference to large integer to be converted to string
|
|
// [sResult - OUT] : Gets the output string
|
|
// Returns: void
|
|
//
|
|
// History: 25-Sep-2000 hiteshr Created
|
|
// Copied from dsadmin code base, changed work with CComBSTR
|
|
//---------------------------------------------------------------------------
|
|
|
|
void litow(LARGE_INTEGER& li, CComBSTR& sResult)
|
|
{
|
|
LARGE_INTEGER n;
|
|
n.QuadPart = li.QuadPart;
|
|
|
|
if (n.QuadPart == 0)
|
|
{
|
|
sResult = L"0";
|
|
}
|
|
else
|
|
{
|
|
CComBSTR sNeg;
|
|
sResult = L"";
|
|
if (n.QuadPart < 0)
|
|
{
|
|
sNeg = CComBSTR(L'-');
|
|
n.QuadPart *= -1;
|
|
}
|
|
while (n.QuadPart > 0)
|
|
{
|
|
WCHAR ch[2];
|
|
ch[0] = static_cast<WCHAR>(L'0' + static_cast<WCHAR>(n.QuadPart % 10));
|
|
ch[1] = L'\0';
|
|
sResult += ch;
|
|
n.QuadPart = n.QuadPart / 10;
|
|
}
|
|
sResult += sNeg;
|
|
}
|
|
|
|
//Reverse the string
|
|
//Security Review:256 is good enough for largest LARGE_INTEGER.
|
|
//But since limit of string is known, a good case for using strsafe api.
|
|
//NTRAID#NTBUG9-577081-2002/03/12-hiteshr
|
|
WCHAR szTemp[256];
|
|
if(SUCCEEDED(StringCchCopy(szTemp, 256, sResult)))
|
|
{
|
|
LPWSTR pStart,pEnd;
|
|
pStart = szTemp;
|
|
//Security Review Done.
|
|
pEnd = pStart + wcslen(pStart) -1;
|
|
while(pStart < pEnd)
|
|
{
|
|
WCHAR ch = *pStart;
|
|
*pStart++ = *pEnd;
|
|
*pEnd-- = ch;
|
|
}
|
|
|
|
sResult = szTemp;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Function: EncryptPasswordString
|
|
//
|
|
// Synopsis:Encrypts a password.
|
|
//
|
|
// Arguments:[pszPassword - IN] : Input Password. Input password must be
|
|
// smaller than MAX_PASSWORD_LENGTH chars in length. Function
|
|
// doesnot modify this string.
|
|
//
|
|
// [pEncryptedDataBlob - OUT] : Gets the output encrypted
|
|
// datablob.
|
|
// Returns: HRESULT
|
|
//
|
|
// History: 27-March-2002 hiteshr Created
|
|
//---------------------------------------------------------------------------
|
|
HRESULT
|
|
EncryptPasswordString(IN LPCWSTR pszPassword,
|
|
OUT DATA_BLOB *pEncryptedDataBlob)
|
|
{
|
|
|
|
if(!pszPassword || !pEncryptedDataBlob)
|
|
{
|
|
ASSERT(pszPassword);
|
|
ASSERT(pEncryptedDataBlob);
|
|
return E_POINTER;
|
|
}
|
|
|
|
HRESULT hr = S_OK;
|
|
do
|
|
{
|
|
|
|
//Vaidate the length of input password. MAX_PASSWORD_LENGTH includes terminating
|
|
//NULL character.
|
|
size_t len = 0;
|
|
hr = StringCchLength(pszPassword,
|
|
MAX_PASSWORD_LENGTH,
|
|
&len);
|
|
if(FAILED(hr))
|
|
{
|
|
hr = E_INVALIDARG;
|
|
break;
|
|
}
|
|
|
|
|
|
DATA_BLOB inDataBlob;
|
|
|
|
inDataBlob.pbData = (BYTE*)pszPassword;
|
|
inDataBlob.cbData = (DWORD)(len + 1)*sizeof(WCHAR);
|
|
|
|
//Encrypt data
|
|
if(!CryptProtectData(&inDataBlob,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
CRYPTPROTECT_UI_FORBIDDEN,
|
|
pEncryptedDataBlob))
|
|
{
|
|
pEncryptedDataBlob->pbData = NULL;
|
|
DWORD dwErr = GetLastError();
|
|
hr = HRESULT_FROM_WIN32(dwErr);
|
|
break;
|
|
}
|
|
|
|
}while(0);
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Function: DecryptPasswordString
|
|
//
|
|
// Synopsis: Decrypt encrypted password data.
|
|
//
|
|
// Arguments: [pEncryptedDataBlob- IN] : Input encrypted password data.
|
|
// [ppszPassword - OUT] :Gets the output decrypted password.
|
|
// This must be freed using LocalFree
|
|
// Returns: HRESULT
|
|
//
|
|
// History: 27-March-2002 hiteshr Created
|
|
//---------------------------------------------------------------------------
|
|
HRESULT
|
|
DecryptPasswordString(IN const DATA_BLOB* pEncryptedDataBlob,
|
|
OUT LPWSTR *ppszPassword)
|
|
{
|
|
if(!pEncryptedDataBlob || !ppszPassword)
|
|
{
|
|
ASSERT(pEncryptedDataBlob);
|
|
ASSERT(ppszPassword);
|
|
return E_POINTER;
|
|
}
|
|
|
|
HRESULT hr = S_OK;
|
|
do
|
|
{
|
|
|
|
DATA_BLOB decryptedDataBlob;
|
|
if(!CryptUnprotectData((DATA_BLOB*)pEncryptedDataBlob,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
CRYPTPROTECT_UI_FORBIDDEN,
|
|
&decryptedDataBlob))
|
|
{
|
|
DWORD dwErr = GetLastError();
|
|
hr = HRESULT_FROM_WIN32(dwErr);
|
|
break;
|
|
}
|
|
|
|
*ppszPassword = (LPWSTR)decryptedDataBlob.pbData;
|
|
}while(0);
|
|
|
|
return hr;
|
|
}
|
|
|