2103 lines
66 KiB
C++
2103 lines
66 KiB
C++
//--------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1999 - 2000.
|
|
//
|
|
// File: scansys
|
|
//
|
|
// Contents: Scan system settings.
|
|
//
|
|
//---------------------------------------------------------------
|
|
|
|
#include <scanhead.cxx>
|
|
#pragma hdrstop
|
|
|
|
#include <common.hxx>
|
|
#include <stdio.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <errno.h>
|
|
#include <io.h>
|
|
#include <objerror.h>
|
|
#include <scanstate.hxx>
|
|
|
|
#include <winuser.h>
|
|
#include <winnetwk.h>
|
|
#include <winspool.h>
|
|
#include <lmerr.h>
|
|
#include <lmaccess.h>
|
|
|
|
// We need to define WINVER to a pre-2000 definition in order to
|
|
// pull in the right structure definitions and sizes for correct
|
|
// operation on 9x and NT.
|
|
#undef WINVER
|
|
#define WINVER 0x400
|
|
|
|
#include <ras.h>
|
|
#include <raserror.h>
|
|
#include "bothchar.hxx"
|
|
#include "scansys.hxx"
|
|
|
|
//---------------------------------------------------------------
|
|
|
|
const CHAR SHARES[] = "[NetShares]\r\n";
|
|
const CHAR PRINTERS[] = "[Printers]\r\n";
|
|
const CHAR RAS[] = "[RAS]\r\n";
|
|
|
|
#define LINEBUFSIZE 1024
|
|
|
|
// longest ip address is: XXX.XXX.XXX.XXX\0
|
|
#define MAX_IP_ADDRESS 16
|
|
|
|
const CHAR REGKEY_TIMEZONE[] = "System\\CurrentControlSet\\Control\\TimeZoneInformation";
|
|
const CHAR REGVAL_TIMEZONE[] = "StandardName";
|
|
const CHAR REGKEY_VERSION[] = "Software\\Microsoft\\Windows NT\\CurrentVersion";
|
|
const CHAR REGKEY_VERSION_9x[] = "Software\\Microsoft\\Windows\\CurrentVersion";
|
|
const CHAR REGVAL_FULLNAME[] = "RegisteredOwner";
|
|
const CHAR REGVAL_ORGNAME[] = "RegisteredOrganization";
|
|
|
|
const CHAR REGKEY_RAS[] = "System\\CurrentControlSet\\Services\\RemoteAccess";
|
|
|
|
const CHAR SCRNSAVE[] = "SCRNSAVE.EXE";
|
|
|
|
const CHAR REGKEY_NT4_PBK[] = "Software\\Microsoft\\RAS Phonebook";
|
|
const CHAR REGVAL_NT4_PRS_PBK_LOC[] = "PersonalPhonebookFile";
|
|
const CHAR REGVAL_NT4_ALT_PBK_LOC[] = "AlternatePhonebookPath";
|
|
|
|
const CHAR RAS_NT4_RAS_PATH[] = "system32\\ras";
|
|
const CHAR RAS_NT4_SYSTEM_PHONEBOOK[] = "rasphone.pbk";
|
|
|
|
#define ChkErr(s) if ((dwErr = (s)) != ERROR_SUCCESS) goto Err;
|
|
|
|
//+---------------------------------------------------------------------------
|
|
// Types
|
|
// RAS api functions
|
|
typedef DWORD
|
|
(*MRasEnumEntries)(
|
|
IN LPCSTR reserved,
|
|
IN LPCSTR lpszPhonebook,
|
|
OUT LPRASENTRYNAMEA lprasentryname,
|
|
OUT LPDWORD lpcb,
|
|
OUT LPDWORD lpcEntries);
|
|
typedef DWORD
|
|
(*MRasGetEntryProperties)(
|
|
IN LPCSTR lpszPhonebook,
|
|
IN LPCSTR lpszEntry,
|
|
OUT LPRASENTRYA lpRasEntry,
|
|
OUT LPDWORD lpdwEntryInfoSize,
|
|
OUT LPBYTE lpbDeviceInfo,
|
|
OUT LPDWORD lpdwDeviceInfoSize);
|
|
typedef DWORD
|
|
(*MRasGetEntryDialParams)(
|
|
IN LPCSTR lpszPhonebook,
|
|
OUT LPRASDIALPARAMSA lprasdialparams,
|
|
OUT LPBOOL lpfPassword);
|
|
|
|
//+---------------------------------------------------------------------------
|
|
// Statics
|
|
static MRasEnumEntries GRasEnumEntries = NULL;
|
|
static MRasGetEntryProperties GRasGetEntryProperties = NULL;
|
|
static MRasGetEntryDialParams GRasGetEntryDialParams = NULL;
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: InitializeRasApi
|
|
//
|
|
// Synopsis: Loads rasapi32.dll if it exists
|
|
//
|
|
// Arguments: none
|
|
//
|
|
// Returns: Appropriate status code
|
|
//
|
|
// History: 24-Feb-00 Jay Thaler Created
|
|
DWORD InitializeRasApi()
|
|
{
|
|
DWORD result = ERROR_SUCCESS;
|
|
HINSTANCE rasdll;
|
|
|
|
// Load rasapi32.dll
|
|
rasdll = LoadLibraryA( "rasapi32.dll" );
|
|
if (rasdll == NULL)
|
|
{
|
|
result = GetLastError();
|
|
if (DebugOutput)
|
|
{
|
|
Win32Printf(STDERR, "Warning: rasapi32.dll not loaded: %d\r\n", result);
|
|
}
|
|
goto cleanup;
|
|
}
|
|
|
|
GRasEnumEntries = (MRasEnumEntries)GetProcAddress(rasdll, "RasEnumEntriesA");
|
|
if (GRasEnumEntries == NULL)
|
|
{
|
|
result = GetLastError();
|
|
goto cleanup;
|
|
}
|
|
|
|
GRasGetEntryProperties = (MRasGetEntryProperties)GetProcAddress(rasdll, "RasGetEntryPropertiesA");
|
|
if (GRasGetEntryProperties == NULL)
|
|
{
|
|
result = GetLastError();
|
|
goto cleanup;
|
|
}
|
|
|
|
GRasGetEntryDialParams = (MRasGetEntryDialParams)GetProcAddress(rasdll, "RasGetEntryDialParamsA");
|
|
if (GRasGetEntryDialParams == NULL)
|
|
{
|
|
result = GetLastError();
|
|
goto cleanup;
|
|
}
|
|
|
|
cleanup:
|
|
if (result != ERROR_SUCCESS)
|
|
{
|
|
GRasEnumEntries = NULL;
|
|
GRasGetEntryProperties = NULL;
|
|
GRasGetEntryDialParams = NULL;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: GetInfField
|
|
//
|
|
// Synopsis: returns an allocated string for current line field #N
|
|
//
|
|
// Arguments: [ppBuffer] -- output buffer
|
|
// [pContext] -- INF file context
|
|
// [nArg] -- argument field number
|
|
//
|
|
// Returns: Appropriate status code
|
|
//
|
|
// History: 20-Sep-99 HenryLee Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
DWORD GetInfField (TCHAR **ppBuffer, INFCONTEXT *pContext, DWORD nArg)
|
|
{
|
|
ULONG len = 0;
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
TCHAR *buffer;
|
|
|
|
*ppBuffer = NULL;
|
|
if (!SetupGetStringField ( pContext, nArg, NULL, 0, &len ))
|
|
return ERROR_BAD_FORMAT;
|
|
|
|
// Allocate a buffer.
|
|
buffer = (TCHAR *) malloc( len*sizeof(TCHAR) );
|
|
if (buffer == NULL)
|
|
{
|
|
dwErr = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
else
|
|
{
|
|
if (!SetupGetStringField ( pContext, nArg, buffer, len, &len ))
|
|
{
|
|
free( buffer );
|
|
dwErr = ERROR_BAD_FORMAT;
|
|
}
|
|
else *ppBuffer = buffer;
|
|
}
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: LogFormatError
|
|
//
|
|
// Synopsis: logs error message in current locale
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: Appropriate status code
|
|
//
|
|
// History: 20-Sep-99 HenryLee Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
DWORD LogFormatError (DWORD dwErr)
|
|
{
|
|
DWORD dwRet = ERROR_SUCCESS;
|
|
TCHAR *pcs = NULL;
|
|
|
|
if (0 != FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM |
|
|
FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL,
|
|
dwErr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
(TCHAR*) &pcs, 0, NULL))
|
|
{
|
|
dwRet = Win32Printf (LogFile, "%s\r\n", pcs);
|
|
LocalFree (pcs);
|
|
}
|
|
else dwRet = GetLastError();
|
|
|
|
return dwRet;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: ScanGenerateEncryptKey
|
|
//
|
|
// Synopsis: decode the RAS address BLOB
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: Appropriate status code
|
|
//
|
|
// History: 20-Sep-99 HenryLee Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
BYTE ScanGenerateEncryptKey (CHAR *szKey)
|
|
{
|
|
BYTE bKey;
|
|
BYTE* pKey;
|
|
|
|
for (bKey = 0, pKey = (BYTE*)szKey; *pKey != 0; pKey++)
|
|
{
|
|
bKey += *pKey;
|
|
};
|
|
|
|
return bKey;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: ScanDecryptEntry
|
|
//
|
|
// Synopsis: decode the RAS address BLOB
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: Appropriate status code
|
|
//
|
|
// History: 20-Sep-99 HenryLee Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
void ScanDecryptEntry (CHAR * szEntry, BYTE * pEnt, DWORD cb)
|
|
{
|
|
// Generate the encryption key from the entry name
|
|
BYTE bKey = ScanGenerateEncryptKey(szEntry);
|
|
|
|
// Encrypt the address entry one byte at a time
|
|
for (;cb > 0; cb--, pEnt++)
|
|
{
|
|
*pEnt ^= bKey;
|
|
};
|
|
return;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: IsRasInstalled
|
|
//
|
|
// Synopsis: determines if RAS is installed
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: Appropriate status code
|
|
//
|
|
// History: 20-Sep-99 HenryLee Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
BOOL IsRasInstalled ()
|
|
{
|
|
HKEY hKey = NULL;
|
|
if (ERROR_SUCCESS == RegOpenKeyExA(HKEY_LOCAL_MACHINE,
|
|
REGKEY_RAS,
|
|
NULL,
|
|
KEY_READ,
|
|
&hKey))
|
|
{
|
|
RegCloseKey (hKey);
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
DWORD RasReadIpAddress(HINF h,
|
|
const TCHAR *pszEntryName,
|
|
const TCHAR *pszKeyName,
|
|
RASIPADDR *lpIpAddr)
|
|
{
|
|
BOOL fSuccess;
|
|
INFCONTEXT IpAddrLine;
|
|
TCHAR szIpAddr[MAX_IP_ADDRESS];
|
|
DWORD dwAddr1, dwAddr2, dwAddr3, dwAddr4;
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
|
|
fSuccess = SetupFindFirstLine(h,
|
|
pszEntryName,
|
|
pszKeyName,
|
|
&IpAddrLine);
|
|
|
|
if (fSuccess == FALSE)
|
|
{
|
|
dwErr = GetLastError();
|
|
Win32PrintfResource(LogFile, IDS_RAS_ENTRY_NOT_MIGRATED, pszEntryName);
|
|
if (DebugOutput)
|
|
{
|
|
Win32Printf(LogFile,
|
|
"SetupFindFirstLine: Error %d looking for %s[%s]\r\n",
|
|
dwErr, pszEntryName, pszKeyName);
|
|
}
|
|
goto cleanup;
|
|
}
|
|
|
|
fSuccess = SetupGetStringField(&IpAddrLine, 1, szIpAddr, MAX_IP_ADDRESS, 0);
|
|
if (fSuccess == FALSE)
|
|
{
|
|
dwErr = GetLastError();
|
|
Win32PrintfResource(LogFile, IDS_RAS_ENTRY_NOT_MIGRATED, pszEntryName);
|
|
if (DebugOutput)
|
|
{
|
|
Win32Printf(LogFile,
|
|
"SetupGetStringField: Error %d reading %s[%s]\r\n",
|
|
dwErr, pszEntryName, pszKeyName);
|
|
}
|
|
goto cleanup;
|
|
}
|
|
if (_stscanf(szIpAddr, "%d.%d.%d.%d",
|
|
&dwAddr1, &dwAddr2, &dwAddr3, &dwAddr4) != 4)
|
|
{
|
|
if (DebugOutput)
|
|
{
|
|
Win32Printf(LogFile,
|
|
"szIpAddr for %s[%s] is not an address: %s\r\n",
|
|
pszEntryName, pszKeyName, szIpAddr);
|
|
}
|
|
dwErr = ERROR_BAD_FORMAT;
|
|
goto cleanup;
|
|
}
|
|
lpIpAddr->a = (BYTE)dwAddr1;
|
|
lpIpAddr->b = (BYTE)dwAddr2;
|
|
lpIpAddr->c = (BYTE)dwAddr3;
|
|
lpIpAddr->d = (BYTE)dwAddr4;
|
|
|
|
cleanup:
|
|
return dwErr;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
DWORD ScanRasPhonebook( HANDLE h, LPCTSTR lpPbkFileName )
|
|
{
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
LPRASENTRYNAMEA lpRasEntryName;
|
|
DWORD i = 0;
|
|
DWORD dwRasEntrySize = 0;
|
|
DWORD dwRasEntryNameSize = 0;
|
|
DWORD dwBufferSize = 0;
|
|
DWORD cEntries = 0;
|
|
LPRASENTRYA lpRasEntry = NULL;
|
|
RASDIALPARAMSA RasDialParams;
|
|
BOOL bPasswordRead = FALSE;
|
|
HINF hPbkFile = INVALID_HANDLE_VALUE;
|
|
|
|
// Make sure the file exists
|
|
if(GetFileAttributes(lpPbkFileName) == -1)
|
|
{
|
|
ChkErr( GetLastError() );
|
|
}
|
|
|
|
lpRasEntryName = (LPRASENTRYNAMEA)GlobalAlloc(GPTR, sizeof(RASENTRYNAMEA));
|
|
lpRasEntryName->dwSize = sizeof(RASENTRYNAMEA); // Should be 264 when WINVER < 0x500
|
|
|
|
dwErr = GRasEnumEntries(NULL,
|
|
lpPbkFileName,
|
|
lpRasEntryName,
|
|
&dwRasEntryNameSize,
|
|
&cEntries);
|
|
if (dwErr == ERROR_INVALID_SIZE || dwErr == ERROR_BUFFER_TOO_SMALL )
|
|
{
|
|
lpRasEntryName = (LPRASENTRYNAMEA)GlobalAlloc(GPTR, dwRasEntryNameSize);
|
|
if ( cEntries > 1 )
|
|
{
|
|
lpRasEntryName->dwSize = dwRasEntryNameSize / cEntries;
|
|
}
|
|
else
|
|
{
|
|
lpRasEntryName->dwSize = dwRasEntryNameSize;
|
|
}
|
|
dwErr = GRasEnumEntries(NULL,
|
|
lpPbkFileName,
|
|
lpRasEntryName,
|
|
&dwRasEntryNameSize,
|
|
&cEntries);
|
|
}
|
|
|
|
if (dwErr != ERROR_SUCCESS)
|
|
{
|
|
// The resource file specifies %1!d! which requires an int argument in this case
|
|
Win32PrintfResource (LogFile, IDS_RAS_CANNOT_ENUM, dwErr);
|
|
goto Err;
|
|
}
|
|
|
|
for(i=0; i < cEntries; i++)
|
|
{
|
|
// Read size needed
|
|
GRasGetEntryProperties(lpPbkFileName,
|
|
lpRasEntryName->szEntryName,
|
|
NULL,
|
|
&dwRasEntrySize,
|
|
NULL,
|
|
0);
|
|
|
|
if (lpRasEntry == NULL)
|
|
{
|
|
lpRasEntry = (LPRASENTRYA)malloc(dwRasEntrySize);
|
|
}
|
|
else if (dwRasEntrySize > dwBufferSize)
|
|
{
|
|
lpRasEntry = (LPRASENTRYA)realloc(lpRasEntry, dwRasEntrySize);
|
|
dwBufferSize = dwRasEntrySize;
|
|
}
|
|
|
|
ZeroMemory( lpRasEntry, dwBufferSize );
|
|
lpRasEntry->dwSize = sizeof(RASENTRYA);
|
|
|
|
dwErr = GRasGetEntryProperties( lpPbkFileName,
|
|
lpRasEntryName->szEntryName,
|
|
lpRasEntry,
|
|
&dwRasEntrySize,
|
|
NULL,
|
|
0 );
|
|
if (dwErr != ERROR_SUCCESS)
|
|
{
|
|
// Log Error
|
|
Win32PrintfResource (LogFile, IDS_RAS_ENTRY_NOT_MIGRATED, lpRasEntryName->szEntryName);
|
|
if (DebugOutput)
|
|
{
|
|
Win32Printf(LogFile, "RasGetEntryProperties: Error %d\r\n", dwErr );
|
|
}
|
|
goto Err;
|
|
}
|
|
|
|
if ((lpPbkFileName != NULL) &&
|
|
(lpRasEntry->dwFramingProtocol == RASFP_Slip))
|
|
{
|
|
|
|
// We read from a PBK file (not Win9x) and we're using SLIP.
|
|
// This means the ipAddress, DNS addresses, and WINS addresses
|
|
// were probably lost. Those bastards!
|
|
UINT dwErrorLine;
|
|
|
|
hPbkFile = SetupOpenInfFile(lpPbkFileName,
|
|
NULL,
|
|
INF_STYLE_OLDNT | INF_STYLE_WIN4,
|
|
&dwErrorLine);
|
|
if (hPbkFile == INVALID_HANDLE_VALUE)
|
|
{
|
|
dwErr = GetLastError();
|
|
Win32PrintfResource(LogFile, IDS_RAS_ENTRY_NOT_MIGRATED,
|
|
lpRasEntryName->szEntryName);
|
|
if (DebugOutput)
|
|
{
|
|
Win32Printf(LogFile,
|
|
"SetupOpenInfFile: Error 0x%X opening %s, line %d\r\n",
|
|
dwErr, lpPbkFileName, dwErrorLine );
|
|
}
|
|
goto Err;
|
|
}
|
|
|
|
// Check IpAddress
|
|
if ((*(DWORD*)&lpRasEntry->ipaddr) == 0 )
|
|
{
|
|
ChkErr( RasReadIpAddress(hPbkFile,
|
|
lpRasEntryName->szEntryName,
|
|
TEXT("IpAddress"),
|
|
&(lpRasEntry->ipaddr)) );
|
|
}
|
|
if ((*(DWORD*)&lpRasEntry->ipaddr) != 0 )
|
|
{
|
|
lpRasEntry->dwfOptions |= RASEO_SpecificIpAddr;
|
|
}
|
|
|
|
// Check ipaddrDns
|
|
if ((*(DWORD*)&lpRasEntry->ipaddrDns) == 0 )
|
|
{
|
|
ChkErr( RasReadIpAddress(hPbkFile,
|
|
lpRasEntryName->szEntryName,
|
|
TEXT("IpDnsAddress"),
|
|
&(lpRasEntry->ipaddrDns)) );
|
|
}
|
|
if ((*(DWORD*)&lpRasEntry->ipaddrDns) != 0 )
|
|
{
|
|
lpRasEntry->dwfOptions |= RASEO_SpecificNameServers;
|
|
}
|
|
|
|
// Check ipaddrDnsAlt
|
|
if ((*(DWORD*)&lpRasEntry->ipaddrDnsAlt) == 0 )
|
|
{
|
|
ChkErr( RasReadIpAddress(hPbkFile,
|
|
lpRasEntryName->szEntryName,
|
|
TEXT("IpDns2Address"),
|
|
&(lpRasEntry->ipaddrDnsAlt)) );
|
|
}
|
|
if ((*(DWORD*)&lpRasEntry->ipaddrDnsAlt) != 0 )
|
|
{
|
|
lpRasEntry->dwfOptions |= RASEO_SpecificNameServers;
|
|
}
|
|
|
|
// Check ipaddrWins
|
|
if ((*(DWORD*)&lpRasEntry->ipaddrWins) == 0 )
|
|
{
|
|
ChkErr( RasReadIpAddress(hPbkFile,
|
|
lpRasEntryName->szEntryName,
|
|
TEXT("IpWinsAddress"),
|
|
&(lpRasEntry->ipaddrWins)) );
|
|
}
|
|
if ((*(DWORD*)&lpRasEntry->ipaddrWins) != 0 )
|
|
{
|
|
lpRasEntry->dwfOptions |= RASEO_SpecificNameServers;
|
|
}
|
|
|
|
// Check ipaddrWinsAlt
|
|
if ((*(DWORD*)&lpRasEntry->ipaddrWinsAlt) == 0 )
|
|
{
|
|
ChkErr( RasReadIpAddress(hPbkFile,
|
|
lpRasEntryName->szEntryName,
|
|
TEXT("IpWins2Address"),
|
|
&(lpRasEntry->ipaddrWinsAlt)) );
|
|
}
|
|
if ((*(DWORD*)&lpRasEntry->ipaddrWinsAlt) != 0 )
|
|
{
|
|
lpRasEntry->dwfOptions |= RASEO_SpecificNameServers;
|
|
}
|
|
}
|
|
|
|
ChkErr (Win32Printf(h, "\"%s\",", lpRasEntryName->szEntryName) );
|
|
ChkErr (Win32Printf(h, "0x%0X,", lpRasEntry->dwfOptions ) );
|
|
ChkErr (Win32Printf(h, "%d,", lpRasEntry->dwCountryID ) );
|
|
ChkErr (Win32Printf(h, "%d,", lpRasEntry->dwCountryCode ) );
|
|
ChkErr (Win32Printf(h, "\"%s\",", lpRasEntry->szAreaCode ) );
|
|
ChkErr (Win32Printf(h, "\"%s\",", lpRasEntry->szLocalPhoneNumber) );
|
|
ChkErr (Win32Printf(h, "%d,", 0) ); // lpRasEntry->dwAlternateOffset
|
|
ChkErr (Win32Printf(h, "0x%08X,", lpRasEntry->ipaddr ) );
|
|
ChkErr (Win32Printf(h, "0x%08X,", lpRasEntry->ipaddrDns ) );
|
|
ChkErr (Win32Printf(h, "0x%08X,", lpRasEntry->ipaddrDnsAlt) );
|
|
ChkErr (Win32Printf(h, "0x%08X,", lpRasEntry->ipaddrWins ) );
|
|
ChkErr (Win32Printf(h, "0x%08X,", lpRasEntry->ipaddrWinsAlt) );
|
|
ChkErr (Win32Printf(h, "%d,", lpRasEntry->dwFrameSize ) );
|
|
ChkErr (Win32Printf(h, "%d,", lpRasEntry->dwfNetProtocols ) );
|
|
ChkErr (Win32Printf(h, "%d,", lpRasEntry->dwFramingProtocol) );
|
|
ChkErr (Win32Printf(h, "\"%s\",", lpRasEntry->szScript ) );
|
|
ChkErr (Win32Printf(h, "\"%s\",", lpRasEntry->szAutodialDll ) );
|
|
ChkErr (Win32Printf(h, "\"%s\",", lpRasEntry->szAutodialFunc ) );
|
|
ChkErr (Win32Printf(h, "\"%s\",", lpRasEntry->szDeviceType ) );
|
|
ChkErr (Win32Printf(h, "\"%s\",", lpRasEntry->szDeviceName ) );
|
|
ChkErr (Win32Printf(h, "\"%s\",", lpRasEntry->szX25PadType ) );
|
|
ChkErr (Win32Printf(h, "\"%s\",", lpRasEntry->szX25Address ) );
|
|
ChkErr (Win32Printf(h, "\"%s\",", lpRasEntry->szX25Facilities ) );
|
|
ChkErr (Win32Printf(h, "\"%s\",", lpRasEntry->szX25UserData ) );
|
|
ChkErr (Win32Printf(h, "%d,", lpRasEntry->dwChannels ) );
|
|
|
|
ZeroMemory( &RasDialParams, sizeof(RASDIALPARAMSA) );
|
|
|
|
lstrcpyA( RasDialParams.szEntryName, lpRasEntryName->szEntryName);
|
|
RasDialParams.dwSize = sizeof(RASDIALPARAMSA);
|
|
|
|
dwErr = GRasGetEntryDialParams( lpPbkFileName,
|
|
&RasDialParams,
|
|
&bPasswordRead );
|
|
if ( dwErr != ERROR_SUCCESS )
|
|
{
|
|
Win32PrintfResource (LogFile, IDS_RAS_ENTRY_NOT_MIGRATED, lpRasEntryName->szEntryName);
|
|
if (DebugOutput)
|
|
{
|
|
Win32Printf(LogFile, "RasGetDialParams: Error %d\n", dwErr );
|
|
}
|
|
goto Err;
|
|
}
|
|
|
|
ChkErr (Win32Printf(h, "%s,", RasDialParams.szPhoneNumber ) );
|
|
ChkErr (Win32Printf(h, "%s,", RasDialParams.szCallbackNumber ) );
|
|
ChkErr (Win32Printf(h, "%s,", RasDialParams.szUserName ) );
|
|
ChkErr (Win32Printf(h, "%s,", RasDialParams.szPassword ) );
|
|
ChkErr (Win32Printf(h, "%s\r\n", RasDialParams.szDomain) );
|
|
|
|
lpRasEntryName++;
|
|
}
|
|
|
|
Err:
|
|
|
|
if (hPbkFile != INVALID_HANDLE_VALUE)
|
|
SetupCloseInfFile(hPbkFile);
|
|
|
|
Win32Printf(h, "\r\n" );
|
|
if (lpRasEntry != NULL)
|
|
free (lpRasEntry);
|
|
|
|
if (lpRasEntryName != NULL)
|
|
GlobalFree (lpRasEntryName);
|
|
return dwErr;
|
|
}
|
|
|
|
DWORD ScanRasPerPhonebook (HANDLE h)
|
|
{
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
CHAR szValue[LINEBUFSIZE];
|
|
CHAR szPbkFileName[MAX_PATH];
|
|
TCHAR szWinDir[MAX_PATH];
|
|
|
|
if (Win9x)
|
|
{
|
|
// System phonebook
|
|
dwErr = ScanRasPhonebook( h, NULL );
|
|
if (ERROR_CANNOT_OPEN_PHONEBOOK == dwErr)
|
|
{
|
|
// 9x stores Ras in the registry. If it can't find the registry,
|
|
// assume there are no Ras connections that need migrating.
|
|
dwErr = ERROR_SUCCESS;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Scan system pbk
|
|
dwErr = GetWindowsDirectory(szWinDir, MAX_PATH );
|
|
if (dwErr <= 0 || dwErr > MAX_PATH)
|
|
{
|
|
if (Verbose)
|
|
{
|
|
Win32Printf(LogFile,
|
|
"Error: Could not retrieve Windows directory: %d\r\n",
|
|
dwErr);
|
|
}
|
|
goto Err;
|
|
}
|
|
|
|
if ( (_tcslen(szWinDir) +
|
|
_tcslen(RAS_NT4_RAS_PATH) +
|
|
_tcslen(RAS_NT4_SYSTEM_PHONEBOOK) + 3) > MAX_PATH )
|
|
{
|
|
Win32PrintfResource(LogFile,
|
|
IDS_FILENAME_TOOLONG,
|
|
RAS_NT4_SYSTEM_PHONEBOOK);
|
|
if (Verbose)
|
|
{
|
|
Win32Printf(STDERR,
|
|
"Error: Too Long Phonebook Filename: %s\\%s\\%s\r\n",
|
|
szWinDir,
|
|
RAS_NT4_RAS_PATH,
|
|
RAS_NT4_SYSTEM_PHONEBOOK);
|
|
}
|
|
dwErr = ERROR_FILENAME_EXCED_RANGE;
|
|
goto Err;
|
|
}
|
|
|
|
sprintf( szPbkFileName, "%s\\%s\\%s",
|
|
szWinDir, RAS_NT4_RAS_PATH, RAS_NT4_SYSTEM_PHONEBOOK );
|
|
// Make sure the file exists
|
|
dwErr = GetFileAttributes(szPbkFileName);
|
|
if (-1 == dwErr)
|
|
{
|
|
dwErr = GetLastError();
|
|
if (dwErr == ERROR_FILE_NOT_FOUND ||
|
|
dwErr == ERROR_PATH_NOT_FOUND)
|
|
{
|
|
// This phonebook file doesn't exist, which is fine. Just skip it.
|
|
dwErr = ERROR_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
goto Err;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ChkErr( ScanRasPhonebook( h, szPbkFileName ) );
|
|
}
|
|
|
|
// Scan personal pbk
|
|
dwErr = ScanReadKey (HKEY_CURRENT_USER,
|
|
(CHAR*) REGKEY_NT4_PBK,
|
|
(CHAR*) REGVAL_NT4_PRS_PBK_LOC,
|
|
(CHAR*) szValue, sizeof(szValue));
|
|
if ( dwErr == ERROR_SUCCESS && szValue[0] != '\0')
|
|
{
|
|
if ( (_tcslen(szWinDir) +
|
|
_tcslen(RAS_NT4_RAS_PATH) +
|
|
_tcslen(szValue) + 3) > MAX_PATH )
|
|
{
|
|
Win32PrintfResource(LogFile,
|
|
IDS_FILENAME_TOOLONG,
|
|
szValue);
|
|
if (Verbose)
|
|
{
|
|
Win32Printf(STDERR,
|
|
"Error: Too Long Phonebook Filename: %s\\%s\\%s\r\n",
|
|
szWinDir,
|
|
RAS_NT4_RAS_PATH,
|
|
szValue);
|
|
}
|
|
dwErr = ERROR_FILENAME_EXCED_RANGE;
|
|
goto Err;
|
|
}
|
|
|
|
sprintf( szPbkFileName, "%s\\%s\\%s", szWinDir, RAS_NT4_RAS_PATH, szValue );
|
|
|
|
// Make sure the file exists
|
|
dwErr = GetFileAttributes(szPbkFileName);
|
|
if (-1 == dwErr)
|
|
{
|
|
dwErr = GetLastError();
|
|
if (dwErr == ERROR_FILE_NOT_FOUND ||
|
|
dwErr == ERROR_PATH_NOT_FOUND)
|
|
{
|
|
// This phonebook file doesn't exist. Just skip it
|
|
dwErr = ERROR_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
goto Err;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ChkErr( ScanRasPhonebook( h, szPbkFileName ) );
|
|
}
|
|
}
|
|
else if (dwErr == ERROR_FILE_NOT_FOUND)
|
|
{
|
|
// Just because there is no personal pbk defined in the registry doesn't
|
|
// mean there was a fatal error. Just skip it and move on with life.
|
|
dwErr = ERROR_SUCCESS;
|
|
}
|
|
else if (dwErr != ERROR_SUCCESS)
|
|
{
|
|
if (DebugOutput)
|
|
{
|
|
Win32Printf(LogFile, "ScanReadKey for personal PBK returned %d\r\n", dwErr);
|
|
}
|
|
goto Err;
|
|
}
|
|
|
|
// Scan alternate pbk
|
|
dwErr = ScanReadKey (HKEY_CURRENT_USER,
|
|
(CHAR*) REGKEY_NT4_PBK,
|
|
(CHAR*) REGVAL_NT4_ALT_PBK_LOC,
|
|
(CHAR*) szValue, sizeof(szValue));
|
|
if ( dwErr == ERROR_SUCCESS && szValue[0] != '\0')
|
|
{
|
|
// Make sure the file exists
|
|
dwErr = GetFileAttributes(szValue);
|
|
if (-1 == dwErr)
|
|
{
|
|
dwErr = GetLastError();
|
|
if (dwErr == ERROR_FILE_NOT_FOUND ||
|
|
dwErr == ERROR_PATH_NOT_FOUND)
|
|
{
|
|
// This phonebook file doesn't exist. Just skip it.
|
|
dwErr = ERROR_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
return dwErr;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ChkErr( ScanRasPhonebook( h, szValue ) );
|
|
}
|
|
}
|
|
else if (dwErr == ERROR_FILE_NOT_FOUND)
|
|
{
|
|
// Just because there is no alternate pbk defined in the registry doesn't
|
|
// mean there was a fatal error. Just skip it and move on with life.
|
|
dwErr = ERROR_SUCCESS;
|
|
}
|
|
else if ( dwErr != ERROR_SUCCESS )
|
|
{
|
|
if (DebugOutput)
|
|
{
|
|
Win32Printf(LogFile, "ScanReadKey for alternate pbk returned: %d\r\n", dwErr);
|
|
}
|
|
goto Err;
|
|
}
|
|
}
|
|
|
|
Err:
|
|
return dwErr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: ScanRasSettings
|
|
//
|
|
// Synopsis: scans RAS settings for current user
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: Appropriate status code
|
|
//
|
|
// History: 20-Sep-99 HenryLee Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
DWORD ScanRasSettings (HANDLE h)
|
|
{
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
|
|
if (IsRasInstalled())
|
|
{
|
|
ChkErr (Win32Printf (h, (CHAR *) RAS));
|
|
ChkErr (ScanRasPerPhonebook (h));
|
|
}
|
|
Err:
|
|
return dwErr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: ScanEnumerateShares
|
|
//
|
|
// Synopsis: lists public (non-system) network shares
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: Appropriate status code
|
|
//
|
|
// History: 20-Sep-99 HenryLee Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
DWORD ScanEnumerateShares (HANDLE h)
|
|
{
|
|
|
|
short nLevel = (short) (Win9x ? 50 : 502);
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
const int MAX_ENTRIES = 64;
|
|
|
|
ScanNetShareEnumNT pNetShareEnum = NULL;
|
|
ScanNetShareEnum9x pNetShareEnum9x = NULL;
|
|
ScanNetAccessEnum9x pNetAccessEnum9x = NULL;
|
|
|
|
HINSTANCE hInst = LoadLibraryA (Win9x ? "svrapi.dll" : "netapi32.dll");
|
|
if (hInst == 0)
|
|
{
|
|
ChkErr (ERROR_INVALID_DLL);
|
|
}
|
|
|
|
ChkErr (Win32Printf (h, (CHAR *) SHARES));
|
|
if (Win9x)
|
|
{
|
|
USHORT cbBuffer;
|
|
USHORT nEntriesRead = 0;
|
|
USHORT nTotalEntries = 0;
|
|
USHORT i;
|
|
static _share_info_50 pBuf[MAX_ENTRIES];
|
|
_share_info_50* pTmpBuf = NULL;
|
|
|
|
cbBuffer = MAX_ENTRIES * sizeof(_share_info_50);
|
|
|
|
pNetShareEnum9x = (ScanNetShareEnum9x) GetProcAddress (hInst,
|
|
"NetShareEnum");
|
|
if (pNetShareEnum9x == NULL)
|
|
{
|
|
ChkErr (ERROR_INVALID_DLL);
|
|
}
|
|
pNetAccessEnum9x = (ScanNetAccessEnum9x) GetProcAddress (hInst,
|
|
"NetAccessEnum");
|
|
if (pNetAccessEnum9x == NULL)
|
|
{
|
|
ChkErr (ERROR_INVALID_DLL);
|
|
}
|
|
|
|
//
|
|
// Call the NetShareEnum function to list the
|
|
// shares, specifying information level 50.
|
|
//
|
|
dwErr = (*pNetShareEnum9x)(NULL,
|
|
(short) nLevel,
|
|
(char *) pBuf,
|
|
cbBuffer,
|
|
&nEntriesRead,
|
|
&nTotalEntries);
|
|
|
|
if (dwErr == ERROR_SUCCESS)
|
|
{
|
|
if (nTotalEntries > 0 && nEntriesRead != nTotalEntries)
|
|
ChkErr (ERROR_MORE_DATA);
|
|
|
|
for (i = 0; i < nEntriesRead; i++)
|
|
{
|
|
DWORD dwPerms = 0;
|
|
pTmpBuf = &pBuf[i];
|
|
|
|
// Require share to be a user-defined, persistent disk share
|
|
if ((pTmpBuf->shi50_flags & SHI50F_SYSTEM) ||
|
|
!(pTmpBuf->shi50_flags & SHI50F_PERSIST) ||
|
|
pTmpBuf->shi50_type != STYPE_DISKTREE )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (pTmpBuf->shi50_flags & SHI50F_RDONLY)
|
|
dwPerms = ACCESS_READ;
|
|
else if (pTmpBuf->shi50_flags & SHI50F_FULL)
|
|
dwPerms = ACCESS_ALL;
|
|
//
|
|
// Display the information for each entry retrieved.
|
|
//
|
|
ChkErr (Win32Printf (h, "%s, %s, %d, %s\r\n",
|
|
pTmpBuf->shi50_netname, pTmpBuf->shi50_path,
|
|
dwPerms, pTmpBuf->shi50_remark));
|
|
|
|
//
|
|
// Process custom access permissions
|
|
//
|
|
if ((pTmpBuf->shi50_flags & SHI50F_ACCESSMASK) ==
|
|
SHI50F_ACCESSMASK)
|
|
{
|
|
static CHAR AccessInfoBuf[16384];
|
|
WORD wItemsAvail, wItemsRead;
|
|
access_info_2 *pai;
|
|
access_list_2 *pal;
|
|
|
|
dwErr = (*pNetAccessEnum9x) (NULL,
|
|
pTmpBuf->shi50_path,
|
|
0,
|
|
2,
|
|
AccessInfoBuf,
|
|
sizeof (AccessInfoBuf),
|
|
&wItemsRead,
|
|
&wItemsAvail
|
|
);
|
|
|
|
if (dwErr != NERR_ACFNotLoaded)
|
|
{
|
|
BOOL LostCustomAccess = FALSE;
|
|
if (dwErr == ERROR_SUCCESS)
|
|
{
|
|
pai = (access_info_2 *) AccessInfoBuf;
|
|
pal = (access_list_2 *) (&pai[1]);
|
|
|
|
for (int i = 0 ; i < pai->acc2_count ; i++)
|
|
{
|
|
#if 0
|
|
// turn off custom access support
|
|
// implementation is incomplete
|
|
if (pal->acl2_access & READ_ACCESS_FLAGS)
|
|
Win32Printf (h, " %s, read\r\n",
|
|
pal->acl2_ugname);
|
|
else if(pal->acl2_access & FULL_ACCESS_FLAGS)
|
|
Win32Printf (h, " %s, full\r\n",
|
|
pal->acl2_ugname);
|
|
else
|
|
#endif
|
|
LostCustomAccess = TRUE;
|
|
|
|
pal++;
|
|
}
|
|
if (LostCustomAccess)
|
|
Win32Printf (LogFile, "Warning custom access"
|
|
" not migrated %s\r\n",
|
|
pTmpBuf->shi50_netname);
|
|
pTmpBuf->shi50_flags |= SHI50F_ACLS;
|
|
}
|
|
else ChkErr (dwErr);
|
|
}
|
|
}
|
|
if (!(pTmpBuf->shi50_flags & SHI50F_ACLS) &&
|
|
(pTmpBuf->shi50_rw_password[0] ||
|
|
pTmpBuf->shi50_ro_password[0]))
|
|
{
|
|
Win32PrintfResource (LogFile,
|
|
IDS_SHARE_PASSWORD_NOT_MIGRATED,
|
|
pTmpBuf->shi50_netname);
|
|
}
|
|
}
|
|
}
|
|
else if (dwErr == NERR_ServerNotStarted)
|
|
{
|
|
dwErr = ERROR_SUCCESS;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ULONG cbBuffer = MAX_ENTRIES * sizeof(SHARE_INFO_502);
|
|
ULONG nEntriesRead = 0;
|
|
ULONG nTotalEntries = 0;
|
|
ULONG i;
|
|
SHARE_INFO_502* pBuf = NULL;
|
|
SHARE_INFO_502* pTmpBuf = NULL;
|
|
|
|
pNetShareEnum = (ScanNetShareEnumNT) GetProcAddress(hInst,
|
|
"NetShareEnum");
|
|
if (pNetShareEnum == NULL)
|
|
{
|
|
ChkErr (ERROR_INVALID_DLL);
|
|
}
|
|
//
|
|
// Call the NetShareEnum function to list the
|
|
// shares, specifying information level 502.
|
|
//
|
|
dwErr = (*pNetShareEnum)(NULL,
|
|
nLevel,
|
|
(BYTE **) &pBuf,
|
|
cbBuffer,
|
|
&nEntriesRead,
|
|
&nTotalEntries,
|
|
NULL);
|
|
|
|
//
|
|
// Loop through the entries; process errors.
|
|
//
|
|
if (dwErr == ERROR_SUCCESS)
|
|
{
|
|
if ((pTmpBuf = pBuf) != NULL)
|
|
{
|
|
for (i = 0; (i < nEntriesRead); i++)
|
|
{
|
|
//
|
|
// Display the information for each entry retrieved.
|
|
//
|
|
ChkErr (Win32Printf (h, "%ws, %ws, %d, %ws\r\n",
|
|
pTmpBuf->shi502_netname, pTmpBuf->shi502_path,
|
|
pTmpBuf->shi502_permissions, pTmpBuf->shi502_remark));
|
|
|
|
pTmpBuf++;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Win32PrintfResource (LogFile, IDS_CANNOT_ENUM_NETSHARES);
|
|
LogFormatError (dwErr);
|
|
dwErr = ERROR_SUCCESS; // continue with other settings
|
|
}
|
|
|
|
if (pBuf != NULL)
|
|
{
|
|
ScanNetApiBufferFreeNT pNetApiBufferFree = NULL;
|
|
|
|
pNetApiBufferFree = (ScanNetApiBufferFreeNT) GetProcAddress (hInst,
|
|
"NetApiBufferFree");
|
|
if (pNetApiBufferFree != NULL)
|
|
(*pNetApiBufferFree) (pBuf);
|
|
}
|
|
}
|
|
|
|
|
|
Err:
|
|
if (Verbose && dwErr != ERROR_SUCCESS)
|
|
Win32Printf (LogFile, "Out ScanEnumerateShares => 0x%x\r\n", dwErr);
|
|
return dwErr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: ScanEnumeratePrinters
|
|
//
|
|
// Synopsis: list connected printers
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: Appropriate status code
|
|
//
|
|
// History: 20-Sep-99 HenryLee Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
DWORD ScanEnumeratePrinters (HANDLE h)
|
|
{
|
|
DWORD dwErr;
|
|
DWORD cbBuffer = 16384; // 16K is a good size
|
|
DWORD cbReceived;
|
|
DWORD nPrinters;
|
|
DWORD i;
|
|
PRINTER_INFO_2 *pPrinterEnum;
|
|
|
|
for(i = 0; i < 2; i++)
|
|
{
|
|
dwErr = ERROR_SUCCESS;
|
|
|
|
pPrinterEnum = (PRINTER_INFO_2 *) GlobalAlloc(GPTR, cbBuffer);
|
|
if (pPrinterEnum == NULL)
|
|
ChkErr (ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
if (FALSE == EnumPrintersA (Win9x ? PRINTER_ENUM_LOCAL :
|
|
PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS,
|
|
NULL,
|
|
2,
|
|
(BYTE *) pPrinterEnum,
|
|
cbBuffer,
|
|
&cbReceived,
|
|
&nPrinters))
|
|
{
|
|
dwErr = GetLastError();
|
|
if (RPC_S_SERVER_UNAVAILABLE == dwErr)
|
|
{
|
|
// If the print spooler is turned off, then
|
|
// assume there are no printers to migrate
|
|
dwErr = ERROR_SUCCESS;
|
|
goto Err;
|
|
}
|
|
|
|
if( dwErr == ERROR_INSUFFICIENT_BUFFER || dwErr == ERROR_MORE_DATA )
|
|
{
|
|
GlobalFree(pPrinterEnum);
|
|
cbBuffer = cbReceived;
|
|
|
|
// Try again.
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// Success, or some other error besides buffer to small.. so bail.
|
|
break;
|
|
}
|
|
ChkErr (dwErr);
|
|
|
|
ChkErr (Win32Printf (h, (CHAR *) PRINTERS));
|
|
for (i=0; i < nPrinters; i++)
|
|
{
|
|
if (Win9x)
|
|
{
|
|
ChkErr (Win32Printf(h, "%s\r\n", pPrinterEnum[i].pPortName));
|
|
}
|
|
else
|
|
{
|
|
ChkErr (Win32Printf(h, "%s\r\n", pPrinterEnum[i].pPrinterName));
|
|
}
|
|
}
|
|
|
|
Err:
|
|
if (pPrinterEnum != NULL)
|
|
GlobalFree (pPrinterEnum);
|
|
|
|
if (Verbose && dwErr != ERROR_SUCCESS)
|
|
Win32Printf (LogFile, "Out ScanEnumeratePrinters => 0x%x\r\n", dwErr);
|
|
return dwErr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: ScanEnumerateNetResources
|
|
//
|
|
// Synopsis: lists connected remote drives and resources
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: Appropriate status code
|
|
//
|
|
// History: 20-Sep-99 HenryLee Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
DWORD ScanEnumerateNetResources (HANDLE h, DWORD dwScope, NETRESOURCEA *lpnr)
|
|
{
|
|
|
|
DWORD dwErr, dwResultEnum;
|
|
HANDLE hEnum;
|
|
DWORD cbBuffer = 16384; // 16K is a good size
|
|
DWORD cEntries = 0xFFFFFFFF; // enumerate all possible entries
|
|
LPNETRESOURCEA lpnrLocal; // pointer to enumerated structures
|
|
DWORD i;
|
|
|
|
dwErr = WNetOpenEnumA(dwScope,
|
|
RESOURCETYPE_ANY,
|
|
0, // enumerate all resources
|
|
lpnr, // NULL first time this function is called
|
|
&hEnum); // handle to resource
|
|
|
|
if (dwErr != NO_ERROR)
|
|
{
|
|
// An application-defined error handler is demonstrated in the
|
|
// section titled "Retrieving Network Errors."
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
lpnrLocal = (LPNETRESOURCEA) GlobalAlloc(GPTR, cbBuffer);
|
|
if (lpnrLocal == NULL)
|
|
ChkErr (ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
do
|
|
{
|
|
ZeroMemory(lpnrLocal, cbBuffer);
|
|
|
|
dwResultEnum = WNetEnumResourceA (hEnum, // resource handle
|
|
&cEntries, // defined locally as 0xFFFFFFFF
|
|
lpnrLocal, // LPNETRESOURCE
|
|
&cbBuffer); // buffer size
|
|
|
|
if (dwResultEnum == NO_ERROR)
|
|
{
|
|
for(i = 0; i < cEntries; i++)
|
|
{
|
|
// Following is an application-defined function for
|
|
// displaying contents of NETRESOURCE structures.
|
|
|
|
if (lpnrLocal[i].lpLocalName != NULL)
|
|
{
|
|
ChkErr (Win32Printf (h, "%s, %s, %s\r\n", lpnrLocal[i].lpLocalName,
|
|
lpnrLocal[i].lpRemoteName == NULL ? "" : lpnrLocal[i].lpRemoteName,
|
|
lpnrLocal[i].dwScope == RESOURCE_REMEMBERED ? "persist" : ""));
|
|
}
|
|
|
|
#if 0
|
|
// If this NETRESOURCE is a container, call the function
|
|
// recursively.
|
|
|
|
// Looking at the docs, it appears that the dwUsage is only applicable for
|
|
// GLOBALNET enumerations, and not for CONNECTED enumerations. We shouldn't
|
|
// have to worry about recursively finding resources, because all we care
|
|
// about is what is currently connected. This was a problem for Netware
|
|
// shares, in which case it recursively found itself until it aborted or AV'd.
|
|
|
|
if(RESOURCEUSAGE_CONTAINER == (lpnrLocal[i].dwUsage
|
|
& RESOURCEUSAGE_CONTAINER))
|
|
if((dwErr = ScanEnumerateNetResources (h, dwScope, &lpnrLocal[i])) !=
|
|
ERROR_SUCCESS)
|
|
return dwErr;
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
while(dwResultEnum != ERROR_NO_MORE_ITEMS);
|
|
|
|
if (lpnrLocal != NULL)
|
|
GlobalFree((HGLOBAL)lpnrLocal);
|
|
|
|
dwErr = WNetCloseEnum(hEnum);
|
|
|
|
Err:
|
|
return dwErr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: ScanReadKey
|
|
//
|
|
// Synopsis: retrieves a string or blob from the registry
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: Appropriate status code
|
|
//
|
|
// History: 20-Sep-99 HenryLee Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
DWORD ScanReadKey (HKEY hKeyStart,
|
|
CHAR *szKey,
|
|
CHAR *szName,
|
|
CHAR *szValue,
|
|
ULONG ulLen)
|
|
{
|
|
HKEY hKey = NULL;
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
|
|
ChkErr (RegOpenKeyExA(hKeyStart, szKey, NULL, KEY_READ, &hKey));
|
|
ChkErr (RegQueryValueExA(hKey, szName, NULL, NULL,(BYTE*)szValue, &ulLen));
|
|
|
|
Err:
|
|
if (hKey != NULL)
|
|
RegCloseKey (hKey);
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: ScanGetTimeZone
|
|
//
|
|
// Synopsis: retrieves the time zone name
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: Appropriate status code
|
|
//
|
|
// History: 20-Sep-99 HenryLee Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
DWORD ScanGetTimeZone (HANDLE h)
|
|
{
|
|
CHAR szValue[LINEBUFSIZE];
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
|
|
if (ERROR_SUCCESS == ScanReadKey (HKEY_LOCAL_MACHINE,
|
|
(CHAR*) REGKEY_TIMEZONE,
|
|
(CHAR*) REGVAL_TIMEZONE,
|
|
(CHAR*) szValue, sizeof(szValue)))
|
|
{
|
|
dwErr = Win32Printf (h, "%s=%s\r\n", TIMEZONE, szValue);
|
|
}
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: ScanGetComputerName
|
|
//
|
|
// Synopsis: retrieves the current NETBIOS machine name
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: Appropriate status code
|
|
//
|
|
// History: 20-Sep-99 HenryLee Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#if 0 // currently not used, but may be needed in the future
|
|
DWORD ScanGetComputerName (CHAR *szValue, ULONG ulLen)
|
|
{
|
|
if (FALSE == GetComputerNameA(szValue, &ulLen))
|
|
return GetLastError();
|
|
|
|
return ERROR_SUCCESS;
|
|
}
|
|
#endif
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: ScanGetFullName
|
|
//
|
|
// Synopsis: retrieves the registered name
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: Appropriate status code
|
|
//
|
|
// History: 20-Sep-99 HenryLee Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
DWORD ScanGetFullName (HANDLE h)
|
|
{
|
|
CHAR szValue[LINEBUFSIZE];
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
|
|
if (ERROR_SUCCESS == ScanReadKey (HKEY_LOCAL_MACHINE,
|
|
Win9x ? (CHAR*)REGKEY_VERSION_9x :(CHAR*)REGKEY_VERSION,
|
|
(CHAR*) REGVAL_FULLNAME, szValue, sizeof(szValue)))
|
|
{
|
|
dwErr = Win32Printf (h, "%s=%s\r\n", FULLNAME, szValue);
|
|
}
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: ScanGetOrgName
|
|
//
|
|
// Synopsis: retrieves the organization name
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: Appropriate status code
|
|
//
|
|
// History: 20-Sep-99 HenryLee Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
DWORD ScanGetOrgName (HANDLE h)
|
|
{
|
|
CHAR szValue[LINEBUFSIZE];
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
|
|
if (ERROR_SUCCESS == ScanReadKey (HKEY_LOCAL_MACHINE,
|
|
Win9x ? (CHAR*)REGKEY_VERSION_9x :(CHAR*)REGKEY_VERSION,
|
|
(CHAR*)REGVAL_ORGNAME, szValue, sizeof(szValue)))
|
|
{
|
|
dwErr = Win32Printf (h, "%s=%s\r\n", ORGNAME, szValue);
|
|
}
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
//
|
|
// IsLanguageMatched : if source and target language are matched (or compatible)
|
|
//
|
|
// 1. if SourceNativeLangID == TargetNativeLangID
|
|
//
|
|
// 2. if SourceNativeLangID's alternative ID == TargetNative LangID
|
|
//
|
|
|
|
typedef struct _tagLANGINFO {
|
|
LANGID LangID;
|
|
INT Count;
|
|
} LANGINFO,*PLANGINFO;
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: EnumLangProc
|
|
//
|
|
// Synopsis: callback to pull out the langid while enumerating
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: bool to continue to stop enumeration
|
|
//
|
|
// History: 20-Sep-99 HenryLee Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
BOOL CALLBACK EnumLangProc(
|
|
HANDLE hModule, // resource-module handle
|
|
LPCTSTR lpszType, // pointer to resource type
|
|
LPCTSTR lpszName, // pointer to resource name
|
|
WORD wIDLanguage, // resource language identifier
|
|
LONG_PTR lParam // application-defined parameter
|
|
)
|
|
{
|
|
PLANGINFO LangInfo;
|
|
|
|
LangInfo = (PLANGINFO) lParam;
|
|
|
|
LangInfo->Count++;
|
|
|
|
//
|
|
// for localized build contains multiple resource,
|
|
// it usually contains 0409 as backup lang.
|
|
//
|
|
// if LangInfo->LangID != 0 means we already assigned an ID to it
|
|
//
|
|
// so when wIDLanguage == 0x409, we keep the one we got from last time
|
|
//
|
|
if ((wIDLanguage == 0x409) && (LangInfo->LangID != 0)) {
|
|
return TRUE;
|
|
}
|
|
|
|
LangInfo->LangID = wIDLanguage;
|
|
|
|
return TRUE; // continue enumeration
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: GetNTDLLNativeLangID
|
|
//
|
|
// Synopsis: pull the language id from ntdll for NT systems only
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: Native lang ID in ntdll.dll
|
|
//
|
|
// History: 20-Sep-99 HenryLee Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
LANGID GetNTDLLNativeLangID()
|
|
{
|
|
LPCTSTR Type = (LPCTSTR) RT_VERSION;
|
|
LPCTSTR Name = (LPCTSTR) 1;
|
|
|
|
LANGINFO LangInfo;
|
|
|
|
ZeroMemory(&LangInfo,sizeof(LangInfo));
|
|
|
|
EnumResourceLanguages(
|
|
GetModuleHandle(TEXT("ntdll.dll")),
|
|
Type,
|
|
Name,
|
|
(ENUMRESLANGPROC) EnumLangProc,
|
|
(LONG_PTR) &LangInfo
|
|
);
|
|
|
|
return LangInfo.LangID;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: IsHongKongVersion
|
|
//
|
|
// Synopsis: identifies HongKong NT 4.0 (English UI w/ Chinese locale)
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: TRUE/FALSE
|
|
//
|
|
// History: 20-Sep-99 HenryLee Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
BOOL IsHongKongVersion()
|
|
{
|
|
HMODULE hMod;
|
|
BOOL bRet = FALSE;
|
|
typedef BOOL (*IMMRELEASECONTEXT) (HWND,HANDLE);
|
|
IMMRELEASECONTEXT pImmReleaseContext;
|
|
|
|
LANGID TmpID = GetNTDLLNativeLangID();
|
|
|
|
if (((GetVersion() >> 16) == 1381) && (TmpID == 0x0409))
|
|
{
|
|
|
|
hMod = LoadLibrary(TEXT("imm32.dll"));
|
|
if (hMod)
|
|
{
|
|
pImmReleaseContext = (IMMRELEASECONTEXT)
|
|
GetProcAddress(hMod,"ImmReleaseContext");
|
|
|
|
if (pImmReleaseContext) {
|
|
bRet = pImmReleaseContext(NULL,NULL);
|
|
}
|
|
|
|
FreeLibrary(hMod);
|
|
}
|
|
}
|
|
return (bRet);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: GetDefaultUserLangID
|
|
//
|
|
// Synopsis: retrieves the language of the OS
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: .DEFAULT user's LANGID
|
|
//
|
|
// History: 20-Sep-99 HenryLee Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
LANGID GetDefaultUserLangID()
|
|
{
|
|
LONG dwErr;
|
|
HKEY hkey;
|
|
DWORD dwSize;
|
|
CHAR buffer[512];
|
|
LANGID langid = 0;
|
|
|
|
dwErr = RegOpenKeyEx( HKEY_USERS,
|
|
TEXT(".DEFAULT\\Control Panel\\International"),
|
|
0,
|
|
KEY_READ,
|
|
&hkey );
|
|
|
|
if( dwErr == ERROR_SUCCESS )
|
|
{
|
|
|
|
dwSize = sizeof(buffer);
|
|
dwErr = RegQueryValueExA(hkey,
|
|
"Locale",
|
|
NULL, //reserved
|
|
NULL, //type
|
|
(BYTE *)buffer,
|
|
&dwSize );
|
|
|
|
if(dwErr == ERROR_SUCCESS)
|
|
{
|
|
langid = LANGIDFROMLCID(strtoul(buffer,NULL,16));
|
|
|
|
}
|
|
RegCloseKey(hkey);
|
|
}
|
|
return langid;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: ScanGetLang
|
|
//
|
|
// Synopsis: retrieves the language of the OS
|
|
//
|
|
// Arguments: [pdwLang] -- output Language ID
|
|
//
|
|
// Returns: Appropriate status code
|
|
//
|
|
// History: 20-Sep-99 HenryLee Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
DWORD ScanGetLang (DWORD *pdwLang)
|
|
{
|
|
HKEY hKey;
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
DWORD langid = 0;
|
|
DWORD dwSize;
|
|
BYTE buffer[LINEBUFSIZE];
|
|
|
|
if (Win9x)
|
|
{
|
|
dwErr = RegOpenKeyEx( HKEY_USERS,
|
|
TEXT(".Default\\Control Panel\\desktop\\ResourceLocale"),
|
|
0, KEY_READ, &hKey );
|
|
|
|
if (dwErr == ERROR_SUCCESS)
|
|
{
|
|
dwSize = sizeof(buffer);
|
|
dwErr = RegQueryValueExA( hKey,
|
|
"",
|
|
NULL, //reserved
|
|
NULL, //type
|
|
buffer,
|
|
&dwSize );
|
|
|
|
if(dwErr == ERROR_SUCCESS)
|
|
{
|
|
langid = LANGIDFROMLCID(strtoul((CHAR*)buffer,NULL,16));
|
|
*pdwLang = langid;
|
|
}
|
|
RegCloseKey(hKey);
|
|
}
|
|
if ( dwErr != ERROR_SUCCESS )
|
|
{
|
|
dwErr = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
|
TEXT("System\\CurrentControlSet\\Control\\Nls\\Locale"),
|
|
0, KEY_READ, &hKey );
|
|
|
|
if (dwErr == ERROR_SUCCESS)
|
|
{
|
|
dwSize = sizeof(buffer);
|
|
dwErr = RegQueryValueExA( hKey,
|
|
"",
|
|
NULL, //reserved
|
|
NULL, //type
|
|
buffer,
|
|
&dwSize );
|
|
|
|
if (dwErr == ERROR_SUCCESS)
|
|
{
|
|
langid = LANGIDFROMLCID(strtoul((CHAR*)buffer,NULL,16));
|
|
*pdwLang = langid;
|
|
}
|
|
RegCloseKey(hKey);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
langid = GetNTDLLNativeLangID();
|
|
if (langid == 0x0409)
|
|
{
|
|
if (IsHongKongVersion()) // block Pan-Chinese upgrade to English
|
|
{
|
|
langid = 0x0C04; // map to Chinese (Hong Kong SAR)
|
|
}
|
|
}
|
|
*pdwLang = langid;
|
|
}
|
|
if (Verbose && dwErr != ERROR_SUCCESS)
|
|
Win32Printf (LogFile, "ScanGetLang %d, LangID=%x\n", dwErr, langid);
|
|
return dwErr;
|
|
}
|
|
|
|
#define ACCESS_KEY TEXT("Control Panel\\Accessibility\\")
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: ScanConvertFlags
|
|
//
|
|
// Synopsis: convert accessibility flags
|
|
//
|
|
// Arguments: [pcsObject] -- registry key name
|
|
// [pOptions] -- conversion table
|
|
// [dwForceValues] -- force these options to be on
|
|
//
|
|
// Returns: Appropriate status code
|
|
//
|
|
// History: 20-Sep-99 HenryLee Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
DWORD ScanConvertFlags (HANDLE h,
|
|
TCHAR *pcsObject,
|
|
ACCESS_OPTION *pOptions,
|
|
DWORD dwForceValues)
|
|
{
|
|
HKEY hKey = NULL;
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
DWORD Flags;
|
|
DWORD dw;
|
|
BYTE *lpBuffer = NULL;
|
|
DWORD dwBufferSize = 0;
|
|
DWORD dwRequiredSize;
|
|
|
|
if (ERROR_SUCCESS == RegOpenKeyEx( HKEY_CURRENT_USER,
|
|
pcsObject, 0, KEY_READ, &hKey ))
|
|
{
|
|
//
|
|
// Get flag settings from Win95 registry and convert them to Flags
|
|
//
|
|
|
|
Flags = 0;
|
|
|
|
while (pOptions->ValueName)
|
|
{
|
|
// How big of a buffer do we need?
|
|
RegQueryValueEx(hKey, pOptions->ValueName, NULL, NULL, NULL, &dwRequiredSize);
|
|
if (dwRequiredSize > dwBufferSize)
|
|
{
|
|
if (lpBuffer == NULL)
|
|
{
|
|
lpBuffer = (BYTE *)malloc(dwRequiredSize * sizeof(BYTE));
|
|
}
|
|
else
|
|
{
|
|
lpBuffer = (BYTE *)realloc(lpBuffer, dwRequiredSize * sizeof(BYTE));
|
|
}
|
|
dwBufferSize = dwRequiredSize;
|
|
}
|
|
|
|
ZeroMemory(lpBuffer, dwBufferSize);
|
|
|
|
// Read value
|
|
if (ERROR_SUCCESS == RegQueryValueEx( hKey,
|
|
pOptions->ValueName,
|
|
NULL, //reserved
|
|
NULL, //type
|
|
lpBuffer,
|
|
&dwBufferSize ))
|
|
{
|
|
// Convert to int
|
|
dw = atoi((const char *)lpBuffer);
|
|
|
|
//
|
|
// Most flags are identical on Win9x and NT, but there's one
|
|
// MouseKey flag that needs to be inverted.
|
|
//
|
|
|
|
if (pOptions->FlagVal & SPECIAL_INVERT_OPTION)
|
|
{
|
|
if (dw == 0)
|
|
{
|
|
Flags |= (pOptions->FlagVal & (~SPECIAL_INVERT_OPTION));
|
|
}
|
|
}
|
|
else if (dw != 0)
|
|
{
|
|
Flags |= pOptions->FlagVal;
|
|
}
|
|
}
|
|
pOptions++;
|
|
}
|
|
Flags |= dwForceValues;
|
|
Win32Printf (h, "HKR, \"%s\", \"Flags\", 0x0, \"%d\"\r\n",
|
|
pcsObject, Flags);
|
|
|
|
RegCloseKey (hKey);
|
|
}
|
|
return dwErr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: ScanAccessibility
|
|
//
|
|
// Synopsis: convertes Accessibility settings
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: Appropriate status code
|
|
//
|
|
// History: 20-Sep-99 HenryLee Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
DWORD ScanAccessibility (HANDLE h)
|
|
{
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
|
|
const TCHAR ACCESS_AVAILABLE[] = TEXT("Available");
|
|
const TCHAR ACCESS_CLICKON[] = TEXT("ClickOn");
|
|
const TCHAR ACCESS_CONFIRMHOTKEY[] = TEXT("ConfirmHotKey");
|
|
const TCHAR ACCESS_HOTKEYACTIVE[] = TEXT("HotKeyActive");
|
|
const TCHAR ACCESS_HOTKEYSOUND[] = TEXT("HotKeySound");
|
|
const TCHAR ACCESS_ON[] = TEXT("On");
|
|
const TCHAR ACCESS_ONOFFFEEDBACK[] = TEXT("OnOffFeedback");
|
|
const TCHAR ACCESS_SHOWSTATUSINDICATOR[]= TEXT("ShowStatusIndicator");
|
|
const TCHAR ACCESS_MODIFIERS[] = TEXT("Modifiers");
|
|
const TCHAR ACCESS_REPLACENUMBERS[] = TEXT("ReplaceNumbers");
|
|
const TCHAR ACCESS_AUDIBLEFEEDBACK[] = TEXT("AudibleFeedback");
|
|
const TCHAR ACCESS_TRISTATE[] = TEXT("TriState");
|
|
const TCHAR ACCESS_TWOKEYSOFF[] = TEXT("TwoKeysOff");
|
|
const TCHAR ACCESS_HOTKEYAVAILABLE[] = TEXT("HotKeyAvailable");
|
|
|
|
ACCESS_OPTION FilterKeys[] = {
|
|
ACCESS_ON, BASICS_ON,
|
|
ACCESS_AVAILABLE, BASICS_AVAILABLE,
|
|
ACCESS_HOTKEYACTIVE, BASICS_HOTKEYACTIVE,
|
|
ACCESS_CONFIRMHOTKEY, BASICS_CONFIRMHOTKEY,
|
|
ACCESS_HOTKEYSOUND, BASICS_HOTKEYSOUND,
|
|
ACCESS_SHOWSTATUSINDICATOR, BASICS_INDICATOR,
|
|
ACCESS_CLICKON, FKF_CLICKON,
|
|
NULL, 0
|
|
};
|
|
|
|
ACCESS_OPTION MouseKeys[] = {
|
|
ACCESS_ON, BASICS_ON,
|
|
ACCESS_AVAILABLE, BASICS_AVAILABLE,
|
|
ACCESS_HOTKEYACTIVE, BASICS_HOTKEYACTIVE,
|
|
ACCESS_CONFIRMHOTKEY, BASICS_CONFIRMHOTKEY,
|
|
ACCESS_HOTKEYSOUND, BASICS_HOTKEYSOUND,
|
|
ACCESS_SHOWSTATUSINDICATOR, BASICS_INDICATOR,
|
|
ACCESS_MODIFIERS, MKF_MODIFIERS|SPECIAL_INVERT_OPTION,
|
|
ACCESS_REPLACENUMBERS, MKF_REPLACENUMBERS,
|
|
NULL, 0
|
|
};
|
|
|
|
ACCESS_OPTION StickyKeys[] = {
|
|
ACCESS_ON, BASICS_ON,
|
|
ACCESS_AVAILABLE, BASICS_AVAILABLE,
|
|
ACCESS_HOTKEYACTIVE, BASICS_HOTKEYACTIVE,
|
|
ACCESS_CONFIRMHOTKEY, BASICS_CONFIRMHOTKEY,
|
|
ACCESS_HOTKEYSOUND, BASICS_HOTKEYSOUND,
|
|
ACCESS_SHOWSTATUSINDICATOR, BASICS_INDICATOR,
|
|
ACCESS_AUDIBLEFEEDBACK, SKF_AUDIBLEFEEDBACK,
|
|
ACCESS_TRISTATE, SKF_TRISTATE,
|
|
ACCESS_TWOKEYSOFF, SKF_TWOKEYSOFF,
|
|
NULL, 0
|
|
};
|
|
|
|
ACCESS_OPTION SoundSentry[] = {
|
|
ACCESS_ON, BASICS_ON,
|
|
ACCESS_AVAILABLE, BASICS_AVAILABLE,
|
|
ACCESS_SHOWSTATUSINDICATOR, BASICS_INDICATOR,
|
|
NULL, 0
|
|
};
|
|
|
|
ACCESS_OPTION TimeOut[] = {
|
|
ACCESS_ON, BASICS_ON,
|
|
ACCESS_ONOFFFEEDBACK, ATF_ONOFFFEEDBACK,
|
|
NULL, 0
|
|
};
|
|
|
|
ACCESS_OPTION ToggleKeys[] = {
|
|
ACCESS_ON, BASICS_ON,
|
|
ACCESS_AVAILABLE, BASICS_AVAILABLE,
|
|
ACCESS_HOTKEYACTIVE, BASICS_HOTKEYACTIVE,
|
|
ACCESS_CONFIRMHOTKEY, BASICS_CONFIRMHOTKEY,
|
|
ACCESS_HOTKEYSOUND, BASICS_HOTKEYSOUND,
|
|
ACCESS_SHOWSTATUSINDICATOR, BASICS_INDICATOR,
|
|
NULL, 0
|
|
};
|
|
|
|
ACCESS_OPTION HighContrast[] = {
|
|
ACCESS_ON, BASICS_ON,
|
|
ACCESS_AVAILABLE, BASICS_AVAILABLE,
|
|
ACCESS_HOTKEYACTIVE, BASICS_HOTKEYACTIVE,
|
|
ACCESS_CONFIRMHOTKEY, BASICS_CONFIRMHOTKEY,
|
|
ACCESS_HOTKEYSOUND, BASICS_HOTKEYSOUND,
|
|
ACCESS_SHOWSTATUSINDICATOR, BASICS_INDICATOR,
|
|
ACCESS_HOTKEYAVAILABLE, HCF_HOTKEYAVAILABLE,
|
|
NULL, 0
|
|
};
|
|
|
|
ChkErr (Win32Printf (h, "\r\n[Accessibility]\r\n"));
|
|
ChkErr (ScanConvertFlags (h, ACCESS_KEY "KeyboardResponse", &FilterKeys[0], BASICS_AVAILABLE));
|
|
ChkErr (ScanConvertFlags (h, ACCESS_KEY "MouseKeys", &MouseKeys[0], BASICS_AVAILABLE));
|
|
ChkErr (ScanConvertFlags (h, ACCESS_KEY "StickyKeys", &StickyKeys[0], BASICS_AVAILABLE));
|
|
ChkErr (ScanConvertFlags (h, ACCESS_KEY "SoundSentry", &SoundSentry[0], BASICS_AVAILABLE));
|
|
ChkErr (ScanConvertFlags (h, ACCESS_KEY "TimeOut", &TimeOut[0], 0));
|
|
ChkErr (ScanConvertFlags (h, ACCESS_KEY "ToggleKeys", &ToggleKeys[0], 0));
|
|
ChkErr (ScanConvertFlags (h, ACCESS_KEY "HighContrast",&HighContrast[0],
|
|
BASICS_AVAILABLE | BASICS_INDICATOR | HCF_HOTKEYAVAILABLE));
|
|
|
|
Err:
|
|
if (Verbose && dwErr != ERROR_SUCCESS)
|
|
Win32Printf (LogFile, "Out ScanAccessibility => %d\n", dwErr);
|
|
return dwErr;
|
|
}
|
|
|
|
#define DESKTOP_KEY TEXT("Control Panel\\desktop")
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Function: ScanGetScreenSaverExe
|
|
//
|
|
// Synopsis: get screen saver name from system.ini
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: Appropriate status code
|
|
//
|
|
// History: 20-Sep-99 HenryLee Created
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
|
|
DWORD ScanGetScreenSaverExe (HANDLE h)
|
|
{
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
TCHAR IniFileSetting[MAX_PATH];
|
|
|
|
GetPrivateProfileString (
|
|
TEXT("boot"),
|
|
SCRNSAVE,
|
|
TEXT(""),
|
|
IniFileSetting,
|
|
MAX_PATH,
|
|
TEXT("SYSTEM.INI"));
|
|
|
|
if (IniFileSetting[0] == '\0')
|
|
return ERROR_SUCCESS;
|
|
|
|
dwErr = Win32Printf (h, "HKR, \"%s\", \"%s\", 0x%x, \"%s\"\r\n",
|
|
DESKTOP_KEY, SCRNSAVE, FLG_ADDREG_TYPE_SZ, IniFileSetting);
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Function: ScanDesktop
|
|
//
|
|
// Synopsis: convert desktop settings
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: Appropriate status code
|
|
//
|
|
// History: 20-Sep-99 HenryLee Created
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
|
|
DWORD ScanDesktop (HANDLE h)
|
|
{
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
|
|
if (Win9x) // screen savers are already in the registry on NT
|
|
{
|
|
ChkErr (Win32Printf (h, "\r\n[Desktop]\r\n"));
|
|
ChkErr (ScanGetScreenSaverExe (h));
|
|
ChkErr (Win32Printf (h, "\r\n"));
|
|
|
|
Err:
|
|
if (Verbose && dwErr != ERROR_SUCCESS)
|
|
Win32Printf (LogFile, "Out ScanDesktop => %x\r\n", dwErr);
|
|
}
|
|
return dwErr;
|
|
}
|
|
|
|
#define IS_IME_KBDLAYOUT(hkl) ((HIWORD((ULONG_PTR)(hkl)) & 0xf000) == 0xe000)
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Function: ScanGetKeyboardLayouts
|
|
//
|
|
// Synopsis: retrieve all active input locales
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: Appropriate status code
|
|
//
|
|
// History: 20-Sep-99 HenryLee Created
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
|
|
DWORD ScanGetKeyboardLayouts (HANDLE h)
|
|
{
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
TCHAR kbname[KL_NAMELENGTH];
|
|
int nLayout = GetKeyboardLayoutList(0, NULL);
|
|
HKL hkl = GetKeyboardLayout (0);
|
|
HKL * phkl = new HKL [nLayout];
|
|
if (phkl == NULL)
|
|
ChkErr (ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
if (FALSE != GetKeyboardLayoutName (kbname))
|
|
{
|
|
// get the default input locale
|
|
//
|
|
ChkErr (Win32Printf (h, "%s=%s", INPUTLOCALE, kbname));
|
|
GetKeyboardLayoutList (nLayout, phkl);
|
|
|
|
for (int i=0; i < nLayout; i++)
|
|
{
|
|
if (hkl != phkl[i]) // get the alternate layouts
|
|
{
|
|
if (0 == ActivateKeyboardLayout (phkl[i], 0))
|
|
{
|
|
if (!IS_IME_KBDLAYOUT(phkl[i])) // use locale default
|
|
wsprintf (kbname, "%08x", LOWORD(phkl[i]));
|
|
ChkErr (Win32Printf (h, ",%s", kbname));
|
|
}
|
|
else if (FALSE != GetKeyboardLayoutName (kbname))
|
|
ChkErr (Win32Printf (h, ",%s", kbname));
|
|
}
|
|
}
|
|
ChkErr (Win32Printf (h, "\r\n"));
|
|
}
|
|
|
|
Err:
|
|
ActivateKeyboardLayout (hkl, 0); // restore current input locale
|
|
if (phkl != NULL)
|
|
delete [] phkl;
|
|
return dwErr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: ScanSystem
|
|
//
|
|
// Synopsis: scan system settings
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: Appropriate status code
|
|
//
|
|
// History: 20-Sep-99 HenryLee Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
DWORD ScanSystem()
|
|
{
|
|
DWORD result = ERROR_SUCCESS;
|
|
|
|
if (!CopySystem && !SchedSystem)
|
|
goto cleanup;
|
|
|
|
#if 0
|
|
result = ScanEnumerateShares (OutputFile);
|
|
if (result != ERROR_SUCCESS)
|
|
goto cleanup;
|
|
#else
|
|
Win32Printf (OutputFile, (CHAR *) SHARES);
|
|
#endif
|
|
|
|
if (DebugOutput)
|
|
Win32Printf(LogFile, " Enumerating Net Resources\r\n");
|
|
result = ScanEnumerateNetResources (OutputFile, RESOURCE_CONNECTED, NULL);
|
|
if (result != ERROR_SUCCESS)
|
|
goto cleanup;
|
|
|
|
if (DebugOutput)
|
|
Win32Printf(LogFile, " Enumerating Printers\r\n");
|
|
result = ScanEnumeratePrinters (OutputFile);
|
|
if (result != ERROR_SUCCESS)
|
|
goto cleanup;
|
|
|
|
if (DebugOutput)
|
|
Win32Printf(LogFile, " Scanning RAS Settings\r\n");
|
|
result = InitializeRasApi();
|
|
if (result == ERROR_SUCCESS)
|
|
{
|
|
result = ScanRasSettings (OutputFile);
|
|
if (result != ERROR_SUCCESS)
|
|
goto cleanup;
|
|
}
|
|
|
|
if (Win9x) // Accessibility settings on NT are registry compatible and forced
|
|
{
|
|
if (DebugOutput)
|
|
Win32Printf(LogFile, " Scanning Accessibility options\r\n");
|
|
result = ScanAccessibility (OutputFile); // convert the settings
|
|
if (result != ERROR_SUCCESS)
|
|
goto cleanup;
|
|
}
|
|
|
|
if (DebugOutput)
|
|
Win32Printf(LogFile, " Scanning Desktop\r\n");
|
|
result = ScanDesktop (OutputFile);
|
|
if (result != ERROR_SUCCESS)
|
|
goto cleanup;
|
|
|
|
cleanup:
|
|
if (result != ERROR_SUCCESS)
|
|
LogFormatError (result);
|
|
|
|
return result;
|
|
}
|
|
|