1190 lines
28 KiB
C
1190 lines
28 KiB
C
/*****************************************************************************
|
|
*
|
|
* OsUtil.c
|
|
*
|
|
* Copyright (c) 1996 Microsoft Corporation. All Rights Reserved.
|
|
*
|
|
* Abstract:
|
|
* Various OS dependent utility functions
|
|
*
|
|
* Contents:
|
|
*
|
|
* History:
|
|
*
|
|
* vlads 11/05/1996 created
|
|
*****************************************************************************/
|
|
/*
|
|
#include <windows.h>
|
|
#include <windowsx.h>
|
|
#include <objbase.h>
|
|
#include <regstr.h>
|
|
#include <setupapi.h>
|
|
#include <cfgmgr32.h>
|
|
#include <devguid.h>
|
|
#include <stdio.h>
|
|
|
|
#include <stilog.h>
|
|
#include <stiregi.h>
|
|
|
|
#include <sti.h>
|
|
#include <stierr.h>
|
|
#include <stiusd.h>
|
|
#include "wia.h"
|
|
#include "stipriv.h"
|
|
#include "stiapi.h"
|
|
#include "stirc.h"
|
|
#include "debug.h"
|
|
|
|
*/
|
|
#include "sticomm.h"
|
|
|
|
#define DbgFl DbgFlUtil
|
|
|
|
|
|
BOOL WINAPI
|
|
OSUtil_IsPlatformUnicode()
|
|
{
|
|
OSVERSIONINFOA ver;
|
|
BOOL bReturn = FALSE;
|
|
|
|
ZeroX(ver);
|
|
ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
|
|
|
|
// Just always call the ANSI function
|
|
if(!GetVersionExA(&ver)) {
|
|
DebugOutPtszV(DbgFl, TEXT("Unable to determinte platform -- setting flag to ANSI"));
|
|
bReturn = FALSE;
|
|
}
|
|
else {
|
|
switch(ver.dwPlatformId) {
|
|
|
|
case VER_PLATFORM_WIN32_WINDOWS:
|
|
bReturn = FALSE;
|
|
break;
|
|
|
|
case VER_PLATFORM_WIN32_NT:
|
|
bReturn = TRUE;
|
|
break;
|
|
|
|
default:
|
|
bReturn = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Keep the compiler happy
|
|
return bReturn;
|
|
|
|
} // endproc OSUtil_IsUnicodePlatform
|
|
|
|
HRESULT WINAPI
|
|
OSUtil_GetAnsiString(
|
|
LPSTR * ppszAnsi,
|
|
LPCWSTR lpszWide
|
|
)
|
|
{
|
|
HRESULT hres;
|
|
int cbStrLen;
|
|
|
|
if (!lpszWide) {
|
|
*ppszAnsi = NULL;
|
|
return S_OK;
|
|
}
|
|
|
|
// We can use WideToChar to figure out exact resultant width
|
|
cbStrLen = 2*(OSUtil_StrLenW(lpszWide)+1);
|
|
|
|
hres = AllocCbPpv(cbStrLen, ppszAnsi);
|
|
|
|
if (!*ppszAnsi) {
|
|
DebugOutPtszV(DbgFl, TEXT("could not get ansi string -- out of memory"));
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
|
|
UToA(*ppszAnsi,cbStrLen,lpszWide);
|
|
|
|
return S_OK;
|
|
|
|
} // OSUtil_GetAnsiString
|
|
|
|
HRESULT WINAPI
|
|
OSUtil_GetWideString(
|
|
LPWSTR *ppszWide,
|
|
LPCSTR pszAnsi
|
|
)
|
|
{
|
|
HRESULT hres;
|
|
int cbStrLen;
|
|
|
|
if (!pszAnsi) {
|
|
*ppszWide = NULL;
|
|
return S_OK;
|
|
}
|
|
|
|
// We can use WideToChar to figure out exact resultant width
|
|
cbStrLen = 2*(lstrlenA(pszAnsi)+1);
|
|
|
|
hres = AllocCbPpv(cbStrLen, (PPV)ppszWide);
|
|
|
|
if (!*ppszWide) {
|
|
DebugOutPtszV(DbgFl,TEXT("Could not get unicode string -- out of memory"));
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
|
|
AToU(*ppszWide,cbStrLen,pszAnsi);
|
|
|
|
return S_OK;
|
|
|
|
} // OSUtil_GetWideString
|
|
|
|
|
|
HINSTANCE
|
|
OSUtil_LoadLibraryW(
|
|
LPCWSTR lpszWFileName
|
|
)
|
|
{
|
|
|
|
HINSTANCE hinstRet = NULL;
|
|
if (g_NoUnicodePlatform) {
|
|
|
|
CHAR *pFileNameA = NULL;
|
|
|
|
if ( SUCCEEDED(OSUtil_GetAnsiString(&pFileNameA,lpszWFileName))) {
|
|
hinstRet = LoadLibraryA(pFileNameA);
|
|
FreePpv(&pFileNameA);
|
|
}
|
|
else {
|
|
DebugOutPtszV(DbgFl,TEXT("Failed in LoadLibraryW"));
|
|
}
|
|
}
|
|
else {
|
|
hinstRet = LoadLibraryW(lpszWFileName);
|
|
}
|
|
|
|
return hinstRet;
|
|
|
|
} // OSUtil_LoadLibrary
|
|
|
|
|
|
/*
|
|
// There seems to be no getproc addressW
|
|
FARPROC
|
|
WINAPI
|
|
OSUtil_GetProcAddress(HMODULE hModule,LPCTSTR lpProcName)
|
|
{
|
|
#ifndef UNICODE
|
|
|
|
return GetProcAddress(hModule,lpProcNameW);
|
|
|
|
#else
|
|
|
|
FARPROC pProcAddr = NULL;
|
|
CHAR *pProcNameA = NULL;
|
|
|
|
|
|
if ( SUCCEEDED(OSUtil_GetAnsiString(&pProcNameA,lpProcName))) {
|
|
pProcAddr = GetProcAddress(hModule,pProcNameA);
|
|
FreePpv(&pProcNameA);
|
|
}
|
|
else {
|
|
DebugOutPtszV(DbgFl,TEXT("Failed in GetProcAddress "));
|
|
}
|
|
|
|
return pProcAddr;
|
|
|
|
#endif
|
|
|
|
} // OSUtil_GetProcAddress
|
|
*/
|
|
|
|
LONG
|
|
WINAPI
|
|
OSUtil_RegOpenKeyExW(
|
|
HKEY hKey,
|
|
LPCWSTR lpszKeyStrW,
|
|
DWORD dwReserved,
|
|
REGSAM samDesired,
|
|
PHKEY phkResult)
|
|
{
|
|
|
|
LONG lRet = 0L;
|
|
if (g_NoUnicodePlatform) {
|
|
|
|
CHAR *lpszKeyStrA = NULL;
|
|
|
|
if ( SUCCEEDED(OSUtil_GetAnsiString(&lpszKeyStrA,lpszKeyStrW))) {
|
|
lRet = RegOpenKeyExA(hKey,lpszKeyStrA,dwReserved,samDesired,phkResult);
|
|
FreePpv(&lpszKeyStrA);
|
|
}
|
|
else {
|
|
DebugOutPtszV(DbgFl,TEXT("Failed in RegOpenKeyExW"));
|
|
lRet = ERROR_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
else {
|
|
lRet = RegOpenKeyExW(hKey,lpszKeyStrW,dwReserved,samDesired,phkResult);
|
|
}
|
|
|
|
return (lRet);
|
|
}
|
|
|
|
LONG WINAPI
|
|
OSUtil_RegDeleteValueW(
|
|
HKEY hKey,
|
|
LPWSTR lpszValueNameW
|
|
)
|
|
{
|
|
long lRet = NOERROR;
|
|
|
|
if (g_NoUnicodePlatform) {
|
|
|
|
CHAR *lpszValueNameA = NULL;
|
|
|
|
if ( SUCCEEDED(OSUtil_GetAnsiString(&lpszValueNameA,lpszValueNameW))) {
|
|
|
|
lRet = RegDeleteValueA(hKey, lpszValueNameA);
|
|
FreePpv(&lpszValueNameA);
|
|
}
|
|
else {
|
|
DebugOutPtszV(DbgFl,TEXT("Failed in RegDeleteValueKeyW"));
|
|
lRet = ERROR_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
else {
|
|
lRet = RegDeleteValueW(hKey, lpszValueNameW);
|
|
}
|
|
|
|
return lRet;
|
|
|
|
}
|
|
|
|
LONG
|
|
WINAPI
|
|
OSUtil_RegCreateKeyExW(
|
|
HKEY hKey,
|
|
LPWSTR lpszSubKeyW, DWORD dwReserved, LPWSTR lpszClassW,
|
|
DWORD dwOptions,
|
|
REGSAM samDesired, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
|
|
PHKEY phkResult,
|
|
LPDWORD lpdwDisposition
|
|
)
|
|
{
|
|
LPSTR lpszSubKeyA = NULL;
|
|
LPSTR lpszClassA = NULL;
|
|
long lRet = NOERROR;
|
|
|
|
|
|
if (g_NoUnicodePlatform) {
|
|
|
|
if ( SUCCEEDED(OSUtil_GetAnsiString(&lpszClassA,lpszClassW)) &&
|
|
SUCCEEDED(OSUtil_GetAnsiString(&lpszSubKeyA,lpszSubKeyW))) {
|
|
|
|
lRet = RegCreateKeyExA(hKey, lpszSubKeyA, dwReserved, lpszClassA, dwOptions,
|
|
samDesired, lpSecurityAttributes, phkResult, lpdwDisposition);
|
|
|
|
FreePpv(&lpszSubKeyA);
|
|
FreePpv(&lpszClassA);
|
|
|
|
}
|
|
else {
|
|
DebugOutPtszV(DbgFl,TEXT("Failed in RegCreateKeyExW"));
|
|
lRet = ERROR_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
else {
|
|
lRet = RegCreateKeyExW(hKey, lpszSubKeyW, dwReserved, lpszClassW, dwOptions,
|
|
samDesired, lpSecurityAttributes, phkResult, lpdwDisposition);
|
|
}
|
|
|
|
return lRet;
|
|
|
|
}
|
|
|
|
|
|
LONG WINAPI
|
|
OSUtil_RegQueryValueExW(
|
|
HKEY hKey,
|
|
LPCWSTR lpszValueNameW,
|
|
DWORD *pdwType,
|
|
BYTE* lpData,
|
|
DWORD *pcbData,
|
|
BOOL fUnicodeCaller // =FALSE
|
|
)
|
|
{
|
|
long lRet = NOERROR;
|
|
DWORD cbDataGiven = *pcbData ;
|
|
|
|
if (g_NoUnicodePlatform || !fUnicodeCaller) {
|
|
|
|
CHAR *lpszValueNameA = NULL;
|
|
|
|
if ( SUCCEEDED(OSUtil_GetAnsiString(&lpszValueNameA,lpszValueNameW))) {
|
|
|
|
lRet = RegQueryValueExA( hKey,
|
|
lpszValueNameA,
|
|
NULL,
|
|
pdwType,
|
|
lpData,
|
|
pcbData );
|
|
|
|
FreePpv(&lpszValueNameA);
|
|
|
|
#if 1
|
|
//
|
|
// The string came back as ANSI but we need UNICODE. Conversion in place
|
|
// is not allowed, so do it with second buffer
|
|
//
|
|
|
|
if ( fUnicodeCaller && (NOERROR == lRet) && (*pdwType == REG_SZ)) {
|
|
|
|
LPWSTR pwszWideData = NULL;
|
|
DWORD dwNewSize = *pcbData * sizeof(WCHAR);
|
|
HRESULT hres;
|
|
|
|
if (cbDataGiven >= dwNewSize ) {
|
|
|
|
hres = OSUtil_GetWideString(&pwszWideData,lpData);
|
|
if (SUCCEEDED(hres) && pwszWideData) {
|
|
|
|
memcpy(lpData,pwszWideData,dwNewSize);
|
|
FreePpv(&pwszWideData);
|
|
|
|
}
|
|
else {
|
|
lRet = GetLastError();
|
|
}
|
|
}
|
|
|
|
else {
|
|
lRet = ERROR_MORE_DATA;
|
|
}
|
|
|
|
*pcbData *= sizeof(WCHAR);
|
|
}
|
|
|
|
#endif
|
|
}
|
|
else {
|
|
DebugOutPtszV(DbgFl,TEXT("Failed in RegDeleteValueKeyW"));
|
|
lRet = ERROR_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
else {
|
|
lRet = RegQueryValueExW( hKey,
|
|
lpszValueNameW,
|
|
NULL,
|
|
pdwType,
|
|
lpData,
|
|
pcbData );
|
|
|
|
}
|
|
|
|
return lRet;
|
|
}
|
|
|
|
LONG WINAPI
|
|
OSUtil_RegSetValueExW(
|
|
HKEY hKey,
|
|
LPCWSTR lpszValueNameW,
|
|
DWORD dwType,
|
|
BYTE* lpData,
|
|
DWORD cbData,
|
|
BOOL fUnicodeCaller // =FALSE
|
|
)
|
|
{
|
|
long lRet = NOERROR;
|
|
|
|
if (g_NoUnicodePlatform || !fUnicodeCaller) {
|
|
|
|
CHAR *lpszValueNameA = NULL;
|
|
|
|
if ( SUCCEEDED(OSUtil_GetAnsiString(&lpszValueNameA,lpszValueNameW))) {
|
|
|
|
lRet = RegSetValueExA(hKey,
|
|
lpszValueNameA,
|
|
0,
|
|
dwType,
|
|
lpData,
|
|
cbData);
|
|
|
|
FreePpv(&lpszValueNameA);
|
|
}
|
|
else {
|
|
DebugOutPtszV(DbgFl,TEXT("Failed in RegDeleteValueKeyW"));
|
|
lRet = ERROR_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
else {
|
|
lRet = RegSetValueExW( hKey,
|
|
(LPVOID)lpszValueNameW,
|
|
0,
|
|
dwType,
|
|
lpData,
|
|
cbData);
|
|
}
|
|
|
|
return lRet;
|
|
}
|
|
|
|
|
|
DWORD ReadRegistryDwordW( HKEY hkey,
|
|
LPCWSTR pszValueNameW,
|
|
DWORD dwDefaultValue )
|
|
{
|
|
DWORD err = NOERROR;
|
|
DWORD dwBuffer = 0;
|
|
DWORD cbBuffer = sizeof(dwBuffer);
|
|
DWORD dwType;
|
|
|
|
if( hkey != NULL ) {
|
|
|
|
if (g_NoUnicodePlatform) {
|
|
|
|
CHAR *pszValueNameA = NULL;
|
|
|
|
dwType = REG_DWORD;
|
|
|
|
if ( SUCCEEDED(OSUtil_GetAnsiString(&pszValueNameA,pszValueNameW))) {
|
|
|
|
err = RegQueryValueExA( hkey,
|
|
pszValueNameA,
|
|
NULL,
|
|
&dwType,
|
|
(LPBYTE)&dwBuffer,
|
|
&cbBuffer );
|
|
|
|
FreePpv(&pszValueNameA);
|
|
}
|
|
else {
|
|
DebugOutPtszV(DbgFl,TEXT("Failed in ReadRegistryDwordW "));
|
|
err = ERROR_INVALID_PARAMETER;
|
|
}
|
|
} else {
|
|
|
|
err = RegQueryValueExW( hkey,
|
|
pszValueNameW,
|
|
NULL,
|
|
&dwType,
|
|
(LPBYTE)&dwBuffer,
|
|
&cbBuffer );
|
|
|
|
}
|
|
|
|
if( ( err == NO_ERROR ) &&
|
|
( ( dwType == REG_DWORD ) || ( dwType == REG_BINARY ) )
|
|
) {
|
|
dwDefaultValue = dwBuffer;
|
|
}
|
|
}
|
|
|
|
return dwDefaultValue;
|
|
|
|
} // ReadRegistryDwordW()
|
|
|
|
|
|
|
|
DWORD
|
|
WriteRegistryDwordW(
|
|
IN HKEY hkey,
|
|
IN LPCWSTR pszValueNameW,
|
|
IN DWORD dwValue)
|
|
{
|
|
DWORD err = NOERROR;
|
|
|
|
if ( hkey == NULL || pszValueNameW == NULL) {
|
|
|
|
err = ( ERROR_INVALID_PARAMETER);
|
|
|
|
} else {
|
|
|
|
if (g_NoUnicodePlatform) {
|
|
|
|
CHAR *pszValueNameA = NULL;
|
|
|
|
if ( SUCCEEDED(OSUtil_GetAnsiString(&pszValueNameA,pszValueNameW))) {
|
|
|
|
err = RegSetValueExA( hkey,pszValueNameA,0,REG_DWORD,(LPBYTE ) &dwValue,sizeof( dwValue));
|
|
|
|
FreePpv(&pszValueNameA);
|
|
}
|
|
else {
|
|
DebugOutPtszV(DbgFl,TEXT("Failed in ReadRegistryDwordW "));
|
|
err = ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
}
|
|
else {
|
|
err = RegSetValueExW( hkey,(LPVOID)pszValueNameW,0,REG_DWORD,(LPBYTE ) &dwValue,sizeof( dwValue));
|
|
}
|
|
}
|
|
|
|
return ( err);
|
|
} // WriteRegistryDwordW()
|
|
|
|
|
|
|
|
DWORD
|
|
WriteRegistryStringA(
|
|
IN HKEY hkey,
|
|
IN LPCSTR pszValueName,
|
|
IN LPCSTR pszValue,
|
|
IN DWORD cbValue,
|
|
IN DWORD fdwType)
|
|
{
|
|
DWORD err = NOERROR;
|
|
|
|
if ( hkey == NULL ||
|
|
pszValueName == NULL ||
|
|
cbValue == 0 ) {
|
|
|
|
err = ERROR_INVALID_PARAMETER;
|
|
} else {
|
|
|
|
err = RegSetValueExA(
|
|
hkey,
|
|
pszValueName,
|
|
0,
|
|
fdwType,
|
|
(LPBYTE ) pszValue,
|
|
cbValue); // + 1 for null character
|
|
}
|
|
|
|
return ( err);
|
|
} // WriteRegistryStringA()
|
|
|
|
|
|
DWORD
|
|
WriteRegistryStringW(
|
|
IN HKEY hkey,
|
|
IN LPCWSTR pszValueNameW,
|
|
IN LPCWSTR pszValueW,
|
|
IN DWORD cbValue,
|
|
IN DWORD fdwType)
|
|
{
|
|
DWORD err = NOERROR;
|
|
DWORD le;
|
|
|
|
if ( hkey == NULL ||
|
|
pszValueNameW == NULL ||
|
|
cbValue == 0 ) {
|
|
|
|
err = ERROR_INVALID_PARAMETER;
|
|
} else {
|
|
|
|
if (g_NoUnicodePlatform) {
|
|
err = ERROR_INVALID_PARAMETER;
|
|
|
|
if ( (fdwType == REG_SZ) || (fdwType == REG_EXPAND_SZ)) {
|
|
|
|
LPSTR lpszAnsi = NULL;
|
|
LPSTR lpszAnsiName = NULL;
|
|
|
|
if ( SUCCEEDED(OSUtil_GetAnsiString(&lpszAnsi,pszValueW)) &&
|
|
SUCCEEDED(OSUtil_GetAnsiString(&lpszAnsiName,pszValueNameW))
|
|
) {
|
|
|
|
err = WriteRegistryStringA(hkey,
|
|
lpszAnsiName,
|
|
lpszAnsi,
|
|
(lstrlenA(lpszAnsi)+1)*sizeof(CHAR),
|
|
fdwType);
|
|
|
|
}
|
|
|
|
FreePpv(&lpszAnsi);
|
|
FreePpv(&lpszAnsiName);
|
|
}
|
|
else {
|
|
ValidateF(FALSE,("Wrong registry value type in WriteRegistryStringW"));
|
|
err = ERROR_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
else {
|
|
err = RegSetValueExW(
|
|
hkey,
|
|
pszValueNameW,
|
|
0,
|
|
fdwType,
|
|
(LPBYTE ) pszValueW,
|
|
cbValue);
|
|
le = GetLastError();
|
|
}
|
|
}
|
|
|
|
return ( err);
|
|
} // WriteRegistryStringW()
|
|
|
|
HRESULT
|
|
ReadRegistryStringA(
|
|
HKEY hkey,
|
|
LPCWSTR pszValueNameW,
|
|
LPCWSTR pszDefaultValueW,
|
|
BOOL fExpand,
|
|
LPWSTR * ppwszResult
|
|
)
|
|
{
|
|
WCHAR * pszBuffer1 = NULL;
|
|
WCHAR * pszBuffer2 = NULL;
|
|
DWORD cbBuffer;
|
|
DWORD dwType;
|
|
DWORD err = NOERROR;
|
|
|
|
CHAR *pszValueNameA = NULL;
|
|
|
|
if (!ppwszResult) {
|
|
return STIERR_INVALID_PARAM;
|
|
}
|
|
|
|
*ppwszResult = NULL;
|
|
|
|
if ( !SUCCEEDED(OSUtil_GetAnsiString(&pszValueNameA,pszValueNameW))) {
|
|
return STIERR_INVALID_PARAM;
|
|
}
|
|
|
|
//
|
|
// Determine the buffer size.
|
|
//
|
|
|
|
pszBuffer1 = NULL;
|
|
pszBuffer2 = NULL;
|
|
cbBuffer = 0;
|
|
|
|
if( hkey == NULL ) {
|
|
|
|
//
|
|
// Pretend the key wasn't found.
|
|
//
|
|
|
|
err = ERROR_FILE_NOT_FOUND;
|
|
}
|
|
else {
|
|
|
|
err = RegQueryValueExA( hkey,
|
|
pszValueNameA,
|
|
NULL,
|
|
&dwType,
|
|
NULL,
|
|
&cbBuffer );
|
|
|
|
if( ( err == NO_ERROR ) || ( err == ERROR_MORE_DATA ) ) {
|
|
if( ( dwType != REG_SZ ) &&
|
|
( dwType != REG_MULTI_SZ ) &&
|
|
( dwType != REG_EXPAND_SZ ) ) {
|
|
//
|
|
// Type mismatch, registry data NOT a string.
|
|
// Use default.
|
|
//
|
|
|
|
err = ERROR_FILE_NOT_FOUND;
|
|
}
|
|
else {
|
|
//
|
|
// Item found, allocate a buffer.
|
|
//
|
|
|
|
if (!SUCCEEDED(AllocCbPpv(2*cbBuffer+sizeof(WCHAR),&pszBuffer1)) ){
|
|
err = GetLastError();
|
|
}
|
|
else {
|
|
//
|
|
// Now read the value into the buffer.
|
|
//
|
|
|
|
//if (g_NoUnicodePlatform) {
|
|
|
|
DWORD dwType;
|
|
err = RegQueryValueExA( hkey,
|
|
pszValueNameA,
|
|
NULL,
|
|
&dwType,
|
|
(LPBYTE)pszBuffer1,
|
|
&cbBuffer );
|
|
|
|
//
|
|
// The string came back as ANSI but we need UNICODE. Conversion in place
|
|
// is not allowed, so do it with second buffer
|
|
//
|
|
|
|
if (SUCCEEDED(AllocCbPpv(2*cbBuffer+sizeof(WCHAR),&pszBuffer2))){
|
|
|
|
AToU(pszBuffer2,cbBuffer,(LPSTR)pszBuffer1);
|
|
memcpy(pszBuffer1,pszBuffer2,2*cbBuffer+sizeof(WCHAR));
|
|
|
|
FreePpv(&pszBuffer2);
|
|
|
|
//
|
|
// Truncate returned string to MAX_REG_CHAR characters
|
|
// (only for REG_SZ)
|
|
//
|
|
|
|
if ((dwType == REG_SZ) && (cbBuffer >= MAX_REG_CHAR)) {
|
|
pszBuffer1[MAX_REG_CHAR] = L'\0';
|
|
}
|
|
|
|
}
|
|
//}
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
FreePpv(&pszValueNameA);
|
|
|
|
//if( err == ERROR_FILE_NOT_FOUND ) {
|
|
if( err != NOERROR ) {
|
|
|
|
//
|
|
// Item not found, use empty string (L"") as value
|
|
//
|
|
|
|
err = NO_ERROR;
|
|
|
|
if( pszDefaultValueW != NULL ) {
|
|
|
|
if (!SUCCEEDED(AllocCbPpv((OSUtil_StrLenW(L"") + 1) * sizeof(WCHAR),&pszBuffer1))) {
|
|
err = GetLastError();
|
|
}
|
|
else {
|
|
OSUtil_lstrcpyW( pszBuffer1, L"" );
|
|
}
|
|
}
|
|
}
|
|
|
|
if( err != NO_ERROR )
|
|
{
|
|
//
|
|
// Tragic error reading registry, abort now.
|
|
//
|
|
|
|
goto ErrorCleanup;
|
|
}
|
|
|
|
//
|
|
// pszBuffer1 holds the registry value. Now expand
|
|
// the environment strings if necessary.
|
|
//
|
|
|
|
if( !fExpand ) {
|
|
*ppwszResult = pszBuffer1;
|
|
return S_OK;
|
|
}
|
|
|
|
#if 0
|
|
|
|
// Does not work on Win95 ?
|
|
//
|
|
// Returns number of characters
|
|
//
|
|
cbBuffer = ExpandEnvironmentStrings( pszBuffer1,
|
|
NULL,
|
|
0 );
|
|
|
|
if (!SUCCEEDED(OSUtil_GetAnsiString(&pszBuffer2, (cbBuffer+1)*sizeof(TCHAR) ))){
|
|
goto ErrorCleanup;
|
|
}
|
|
|
|
if( ExpandEnvironmentStrings( pszBuffer1,
|
|
pszBuffer2,
|
|
cbBuffer ) > cbBuffer ) {
|
|
goto ErrorCleanup;
|
|
}
|
|
|
|
//
|
|
// pszBuffer2 now contains the registry value with
|
|
// environment strings expanded.
|
|
//
|
|
|
|
FreePpv(&pszBuffer1);
|
|
|
|
return pszBuffer2;
|
|
#endif
|
|
|
|
ErrorCleanup:
|
|
|
|
//
|
|
// Something tragic happend; free any allocated buffers
|
|
// and return NULL to the caller, indicating failure.
|
|
//
|
|
FreePpv(&pszValueNameA);
|
|
FreePpv(&pszBuffer1);
|
|
FreePpv(&pszBuffer2);
|
|
|
|
return HRESULT_FROM_WIN32(err);
|
|
|
|
}
|
|
HRESULT
|
|
ReadRegistryStringW(
|
|
HKEY hkey,
|
|
LPCWSTR pszValueNameW,
|
|
LPCWSTR pszDefaultValueW,
|
|
BOOL fExpand,
|
|
LPWSTR * ppwszResult
|
|
)
|
|
{
|
|
WCHAR * pszBuffer1 = NULL;
|
|
DWORD cbBuffer;
|
|
DWORD dwType;
|
|
DWORD err = NOERROR;
|
|
|
|
if (!ppwszResult) {
|
|
return STIERR_INVALID_PARAM;
|
|
}
|
|
|
|
*ppwszResult = NULL;
|
|
|
|
//
|
|
// Determine the buffer size.
|
|
//
|
|
|
|
pszBuffer1 = NULL;
|
|
cbBuffer = 0;
|
|
|
|
if( hkey == NULL ) {
|
|
|
|
//
|
|
// Pretend the key wasn't found.
|
|
//
|
|
|
|
err = ERROR_FILE_NOT_FOUND;
|
|
}
|
|
else {
|
|
|
|
err = RegQueryValueExW( hkey,
|
|
pszValueNameW,
|
|
NULL,
|
|
&dwType,
|
|
NULL,
|
|
&cbBuffer );
|
|
|
|
if( ( err == NO_ERROR ) || ( err == ERROR_MORE_DATA ) ) {
|
|
if( ( dwType != REG_SZ ) &&
|
|
( dwType != REG_MULTI_SZ ) &&
|
|
( dwType != REG_EXPAND_SZ ) ) {
|
|
//
|
|
// Type mismatch, registry data NOT a string.
|
|
// Use default.
|
|
//
|
|
|
|
err = ERROR_FILE_NOT_FOUND;
|
|
}
|
|
else {
|
|
//
|
|
// Item found, allocate a buffer.
|
|
//
|
|
|
|
if (!SUCCEEDED(AllocCbPpv(cbBuffer+sizeof(WCHAR),&pszBuffer1)) ){
|
|
err = GetLastError();
|
|
}
|
|
else {
|
|
//
|
|
// Now read the value into the buffer.
|
|
//
|
|
|
|
DWORD dwType;
|
|
err = RegQueryValueExW( hkey,
|
|
pszValueNameW,
|
|
NULL,
|
|
&dwType,
|
|
(LPBYTE)pszBuffer1,
|
|
&cbBuffer );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if( err != NOERROR ) {
|
|
|
|
//
|
|
// Item not found, use empty string (L"") as value
|
|
//
|
|
|
|
err = NO_ERROR;
|
|
|
|
if( pszDefaultValueW != NULL ) {
|
|
|
|
if (!SUCCEEDED(AllocCbPpv((OSUtil_StrLenW(L"") + 1) * sizeof(WCHAR),&pszBuffer1))) {
|
|
err = GetLastError();
|
|
}
|
|
else {
|
|
OSUtil_lstrcpyW( pszBuffer1, L"" );
|
|
}
|
|
}
|
|
}
|
|
|
|
if( err != NO_ERROR )
|
|
{
|
|
//
|
|
// Tragic error reading registry, abort now.
|
|
//
|
|
|
|
goto ErrorCleanup;
|
|
}
|
|
|
|
//
|
|
// pszBuffer1 holds the registry value. Now expand
|
|
// the environment strings if necessary.
|
|
//
|
|
|
|
if( !fExpand ) {
|
|
*ppwszResult = pszBuffer1;
|
|
return S_OK;
|
|
}
|
|
|
|
ErrorCleanup:
|
|
|
|
//
|
|
// Something tragic happend; free any allocated buffers
|
|
// and return NULL to the caller, indicating failure.
|
|
//
|
|
FreePpv(&pszBuffer1);
|
|
|
|
return HRESULT_FROM_WIN32(err);
|
|
|
|
}
|
|
|
|
HANDLE
|
|
WINAPI
|
|
OSUtil_CreateFileW(
|
|
LPCWSTR lpszFileNameW,
|
|
DWORD dwDesiredAccess,
|
|
DWORD dwShareMode,
|
|
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
|
|
DWORD dwCreationDisposition,
|
|
DWORD dwFlagsAndAttributes,
|
|
HANDLE hTemplateFile
|
|
)
|
|
{
|
|
|
|
HANDLE hRet = INVALID_HANDLE_VALUE;
|
|
|
|
if (g_NoUnicodePlatform) {
|
|
|
|
CHAR *pFileNameA = NULL;
|
|
|
|
if ( SUCCEEDED(OSUtil_GetAnsiString(&pFileNameA,lpszFileNameW))) {
|
|
|
|
hRet = CreateFileA(pFileNameA,
|
|
dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,
|
|
dwFlagsAndAttributes,hTemplateFile);
|
|
FreePpv(&pFileNameA);
|
|
}
|
|
else {
|
|
DebugOutPtszV(DbgFl,TEXT("Failed in LoadLibraryW"));
|
|
hRet = INVALID_HANDLE_VALUE;
|
|
}
|
|
}
|
|
else {
|
|
hRet = CreateFileW(lpszFileNameW,
|
|
dwDesiredAccess,dwShareMode,lpSecurityAttributes,dwCreationDisposition,
|
|
dwFlagsAndAttributes,hTemplateFile);
|
|
}
|
|
|
|
return hRet;
|
|
|
|
} // OSUtil_LoadLibrary
|
|
|
|
HRESULT
|
|
WINAPI
|
|
ExtractCommandLineArgumentW(
|
|
LPCSTR lpszSwitchName,
|
|
LPWSTR pwszSwitchValue
|
|
)
|
|
{
|
|
HRESULT hres;
|
|
|
|
LPSTR lpszCommandLine;
|
|
LPSTR lpszSwitch;
|
|
LPSTR pszT;
|
|
|
|
DWORD cch;
|
|
|
|
lpszCommandLine = GetCommandLineA();
|
|
|
|
if (!lpszCommandLine || !*lpszCommandLine) {
|
|
return STIERR_GENERIC;
|
|
}
|
|
|
|
if (!pwszSwitchValue) {
|
|
return STIERR_GENERIC;
|
|
}
|
|
|
|
// Search for switch with given name
|
|
lpszSwitch = strstr(lpszCommandLine,lpszSwitchName);
|
|
if (!lpszSwitch ) {
|
|
return STIERR_GENERIC;
|
|
}
|
|
|
|
lpszSwitch += lstrlenA(lpszSwitchName);
|
|
if (*lpszSwitch != ':') {
|
|
return STIERR_GENERIC;
|
|
}
|
|
lpszSwitch=CharNextA(lpszSwitch);
|
|
|
|
// Skip till space
|
|
pszT = lpszSwitch;
|
|
while (*pszT && *pszT > ' ') {
|
|
pszT = CharNextA(pszT);
|
|
}
|
|
|
|
cch = MultiByteToWideChar(CP_ACP, 0,
|
|
lpszSwitch, (INT)(pszT-lpszSwitch),
|
|
pwszSwitchValue,STI_MAX_INTERNAL_NAME_LENGTH
|
|
);
|
|
pwszSwitchValue[cch] = L'\0';
|
|
|
|
hres = (cch) ? STI_OK : HRESULT_FROM_WIN32(GetLastError());
|
|
|
|
return hres;
|
|
|
|
}
|
|
|
|
HRESULT
|
|
WINAPI
|
|
ExtractCommandLineArgumentA(
|
|
LPCSTR lpszSwitchName,
|
|
LPSTR pszSwitchValue
|
|
)
|
|
{
|
|
HRESULT hres;
|
|
|
|
LPSTR lpszCommandLine;
|
|
LPSTR lpszSwitch;
|
|
LPSTR pszT;
|
|
|
|
DWORD cch;
|
|
|
|
lpszCommandLine = GetCommandLineA();
|
|
|
|
if (!lpszCommandLine || !*lpszCommandLine) {
|
|
return STIERR_GENERIC;
|
|
}
|
|
|
|
if (!pszSwitchValue) {
|
|
return STIERR_GENERIC;
|
|
}
|
|
|
|
// Search for switch with given name
|
|
lpszSwitch = strstr(lpszCommandLine,lpszSwitchName);
|
|
if (!lpszSwitch ) {
|
|
return STIERR_GENERIC;
|
|
}
|
|
|
|
lpszSwitch += lstrlenA(lpszSwitchName);
|
|
if (*lpszSwitch != ':') {
|
|
return STIERR_GENERIC;
|
|
}
|
|
lpszSwitch=CharNextA(lpszSwitch);
|
|
|
|
// Skip till space
|
|
pszT = lpszSwitch;
|
|
while (*pszT && *pszT > ' ') {
|
|
pszT = CharNextA(pszT);
|
|
}
|
|
|
|
cch = min((INT)(pszT-lpszSwitch),STI_MAX_INTERNAL_NAME_LENGTH);
|
|
memcpy(pszSwitchValue,lpszSwitch,cch);
|
|
pszSwitchValue[cch] = L'\0';
|
|
|
|
hres = (cch) ? STI_OK : STIERR_INVALID_PARAM;
|
|
|
|
return hres;
|
|
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* @doc INTERNAL
|
|
*
|
|
* @func HRESULT | DupEventHandle |
|
|
*
|
|
* Duplicate an event handle intra-process-ly. If the incoming
|
|
* handle is NULL, then so is the output handle (and the call
|
|
* succeeds).
|
|
*
|
|
* @parm HANDLE | h |
|
|
*
|
|
* Source handle.
|
|
*
|
|
* @parm LPHANDLE | phOut |
|
|
*
|
|
* Receives output handle.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
HRESULT EXTERNAL
|
|
DupEventHandle(HANDLE h, LPHANDLE phOut)
|
|
{
|
|
HRESULT hres;
|
|
EnterProc(DupEventHandle, (_ "p", h));
|
|
|
|
if (h) {
|
|
HANDLE hProcessMe = GetCurrentProcess();
|
|
if (DuplicateHandle(hProcessMe, h, hProcessMe, phOut,
|
|
EVENT_MODIFY_STATE, 0, 0)) {
|
|
hres = S_OK;
|
|
} else {
|
|
hres = hresLe(GetLastError());
|
|
}
|
|
} else {
|
|
*phOut = h;
|
|
hres = S_OK;
|
|
}
|
|
|
|
ExitOleProc();
|
|
return hres;
|
|
}
|
|
|
|
void
|
|
WINAPI
|
|
StiLogTrace(
|
|
DWORD dwMessageType,
|
|
DWORD idMessage,
|
|
...
|
|
)
|
|
{
|
|
va_list list;
|
|
va_start (list, idMessage);
|
|
|
|
if(g_hStiFileLog) {
|
|
|
|
TCHAR *pchBuff = NULL;
|
|
DWORD cch;
|
|
|
|
HMODULE hm;
|
|
DWORD dwError;
|
|
|
|
pchBuff = NULL;
|
|
|
|
hm = GetModuleHandleA("STI.dll") ;
|
|
|
|
cch = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
|
FORMAT_MESSAGE_MAX_WIDTH_MASK |
|
|
FORMAT_MESSAGE_FROM_HMODULE,
|
|
hm,
|
|
idMessage,
|
|
0,
|
|
(LPTSTR) &pchBuff,
|
|
1024,
|
|
(va_list *)&list
|
|
);
|
|
|
|
dwError = GetLastError();
|
|
|
|
if (cch && pchBuff) {
|
|
ReportStiLogMessage(g_hStiFileLog,
|
|
dwMessageType,
|
|
pchBuff);
|
|
}
|
|
|
|
if (pchBuff) {
|
|
LocalFree(pchBuff);
|
|
}
|
|
|
|
}
|
|
|
|
va_end(list);
|
|
}
|
|
|
|
|