Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

1455 lines
34 KiB

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1995.
//
// File: domcache.c
//
// Contents: Restructuring the Domain Cache to get away from direct LSA
// calls whenever possible.
//
// Classes:
//
// Functions:
//
// History: 3-29-96 RichardW Created
//
//----------------------------------------------------------------------------
#include <msgina.h>
#include <stdio.h>
#if DBG
DWORD DomCacheLock;
#define LockDomainCache( p, x ) \
RtlEnterCriticalSection( & ((PDOMAIN_CACHE)p)->CriticalSection ); \
DomCacheLock = x;
#define UnlockDomainCache( p ) \
DomCacheLock = 0; \
RtlLeaveCriticalSection( & ((PDOMAIN_CACHE) p)->CriticalSection );
#else
#define LockDomainCache( p, x ) \
RtlEnterCriticalSection( & ((PDOMAIN_CACHE)p)->CriticalSection );
#define UnlockDomainCache( p ) \
RtlLeaveCriticalSection( & ((PDOMAIN_CACHE) p)->CriticalSection );
#endif
#define DCACHE_LOAD 1
#define DCACHE_SAVE 2
#define DCACHE_THREAD 3
#define DCACHE_UPDATE 4
#define DCACHE_DLGPROC 5
#define DCACHE_FILL 6
#define DCACHE_WAIT 7
#define DCACHE_VALID 8
#define DCACHE_CREATE 9
WCHAR szWinlogonKey[] = TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon");
WCHAR szCacheValue[] = TEXT("DCache");
WCHAR szCacheUpdate[] = TEXT("DCacheUpdate");
WCHAR szCacheInterval[] = TEXT("DCacheMinInterval");
WCHAR szCachePrimary[] = TEXT("CachePrimaryDomain");
LONGLONG CacheUpdateMin;
LONGLONG CacheUpdateMax;
#define WM_CACHE_UPDATE_COMPLETE WM_USER+2
typedef enum _CACHE_VALIDITY {
CacheValid, // Valid in time
CacheGoodEnough, // No domain change, so presumed ok
CacheStale, // No domain change, but very old
CacheInvalid // Not valid in any fashion
} CACHE_VALIDITY;
VOID
FillDomainCB(
PDOMAIN_CACHE pCache,
HWND hCB);
//+---------------------------------------------------------------------------
//
// Function: DCacheInitialize
//
// Synopsis: Initialize the cache
//
// Arguments: [pCache] --
//
// History: 3-29-96 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
BOOL
DCacheInitialize(
PDOMAIN_CACHE pCache)
{
NTSTATUS Status;
HKEY hKey;
int err;
DWORD Interval;
DWORD dwType;
DWORD dwLen;
UCHAR szUpdateTemp[32];
PUCHAR pMigratedList;
PWSTR pScan;
//
// Cache times: 2 min, 2 weeks
//
CacheUpdateMin = (LONGLONG) 120 * 10000000;
CacheUpdateMax = (LONGLONG) 14 * 86400 * 10000000;
err = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
szWinlogonKey,
0,
KEY_READ | KEY_WRITE | DELETE,
&hKey );
if ( err == 0 )
{
dwLen = sizeof(DWORD) ;
err = RegQueryValueEx(hKey,
szCacheInterval,
NULL,
&dwType,
(PUCHAR) &Interval,
&dwLen );
if ( (err == 0) && (dwType == REG_DWORD) )
{
CacheUpdateMin = (LONGLONG) Interval * 10000000;
}
//
// Clean out old values, if necessary
//
dwLen = sizeof(szUpdateTemp);
err = RegQueryValueEx( hKey,
TEXT("CacheLastUpdate"),
NULL,
&dwType,
szUpdateTemp,
&dwLen );
if ( (err != ERROR_FILE_NOT_FOUND ) && (err != ERROR_PATH_NOT_FOUND ) )
{
//
// Migrate the old cache to the new cache to avoid messy upgrade
// problems
//
dwLen = 0;
err = RegQueryValueEx( hKey,
TEXT("CacheTrustedDomains"),
NULL,
&dwType,
NULL,
&dwLen );
if ( dwLen )
{
dwLen += sizeof(WCHAR);
pMigratedList = LocalAlloc( LMEM_FIXED, dwLen );
if ( pMigratedList )
{
err = RegQueryValueEx( hKey,
TEXT("CacheTrustedDomains"),
NULL,
&dwType,
pMigratedList,
&dwLen );
if ( err == 0 )
{
//
// Convert to a real multi-sz
//
pScan = (PWSTR) pMigratedList;
pScan = wcschr( pScan, TEXT(','));
while ( pScan )
{
*pScan++ = TEXT('\0');
pScan = wcschr( pScan, TEXT(','));
}
//
// Add the extra null terminator. Remember, before we
// allocated, we added one so that we could do this.
// dwlen was reset by RegQuery so that it is the correct
// length again, and we do this magic
//
pScan = (PWSTR) pMigratedList;
pScan[ (dwLen / sizeof(WCHAR)) ] = TEXT('\0');
err = RegSetValueEx(hKey,
szCacheValue,
0,
REG_MULTI_SZ,
pMigratedList,
dwLen + sizeof(WCHAR) );
//
// we gave it our best effort.
//
LocalFree( pMigratedList );
}
}
}
//
// Clean up time.
//
(void) RegDeleteValue( hKey,
TEXT("CacheLastUpdate") );
(void) RegDeleteValue( hKey,
TEXT("CacheLastController") );
(void) RegDeleteValue( hKey,
TEXT("CacheTrustedDomains") );
(void) RegDeleteValue( hKey,
TEXT("CacheValid") );
}
RegCloseKey( hKey );
}
ZeroMemory( pCache, sizeof(DOMAIN_CACHE) );
Status = RtlInitializeCriticalSection( & pCache->CriticalSection );
return( NT_SUCCESS( Status ) );
}
//+---------------------------------------------------------------------------
//
// Function: DCacheLoad
//
// Synopsis: Load Cache information from registry
//
// Arguments: [pCache] --
//
// History: 3-29-96 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
BOOL
DCacheLoad(
PDOMAIN_CACHE pCache )
{
HKEY hKey;
DWORD dwType;
DWORD dwLen;
int err;
err = RegOpenKey( HKEY_LOCAL_MACHINE,
szWinlogonKey,
&hKey );
if ( err )
{
return( FALSE );
}
//
// See if the cache is there, and if so, how many big it is.
//
dwLen = 0;
dwType = 0;
err = RegQueryValueEx( hKey,
szCacheValue,
NULL,
&dwType,
NULL,
&dwLen );
//
// If not there, bail now.
//
if ( err && (err != ERROR_BUFFER_OVERFLOW) )
{
RegCloseKey( hKey );
return( FALSE );
}
//
// Lock the cache, and prepare to party on it.
//
LockDomainCache( pCache, DCACHE_LOAD );
if ( pCache->TrustedDomainSet )
{
LocalFree( pCache->TrustedDomainSet );
}
pCache->TrustedDomainSet = LocalAlloc( LMEM_FIXED, dwLen );
//
// If we failed to allocate, just bail out.
//
if ( ! pCache->TrustedDomainSet )
{
UnlockDomainCache( pCache );
RegCloseKey( hKey );
return( FALSE );
}
pCache->Size = dwLen;
err = RegQueryValueEx( hKey,
szCacheValue,
NULL,
&dwType,
(PUCHAR) pCache->TrustedDomainSet,
&dwLen );
if ( (err) || (dwType != REG_MULTI_SZ) )
{
LocalFree( pCache->TrustedDomainSet );
pCache->TrustedDomainSet = NULL;
UnlockDomainCache( pCache );
RegCloseKey( hKey );
return( FALSE );
}
dwLen = sizeof( LARGE_INTEGER );
err = RegQueryValueEx( hKey,
szCacheUpdate,
NULL,
&dwType,
(PUCHAR) &pCache->CacheUpdateTime,
&dwLen );
if ( err )
{
DebugLog((DEB_TRACE_DOMAIN, "No last update value in cache.\n"));
}
dwLen = 0;
err = RegQueryValueEx( hKey,
szCachePrimary,
NULL,
&dwType,
NULL,
&dwLen );
if ( err || ( dwType != REG_SZ ) )
{
LocalFree( pCache->TrustedDomainSet );
pCache->TrustedDomainSet = NULL;
UnlockDomainCache( pCache );
RegCloseKey( hKey );
return( FALSE );
}
pCache->Primary = LocalAlloc( LMEM_FIXED, dwLen );
if ( !pCache->Primary )
{
LocalFree( pCache->TrustedDomainSet );
pCache->TrustedDomainSet = NULL;
UnlockDomainCache( pCache );
RegCloseKey( hKey );
return( FALSE );
}
err = RegQueryValueEx( hKey,
szCachePrimary,
NULL,
&dwType,
(PUCHAR) pCache->Primary,
&dwLen );
if ( err )
{
LocalFree( pCache->TrustedDomainSet );
pCache->TrustedDomainSet = NULL;
LocalFree( pCache->Primary );
pCache->Primary = NULL;
UnlockDomainCache( pCache );
RegCloseKey( hKey );
return( FALSE );
}
RegCloseKey( hKey );
UnlockDomainCache( pCache );
return( TRUE );
}
//+---------------------------------------------------------------------------
//
// Function: DCacheValid
//
// Synopsis: Quick check to see if the cache is valid
//
// Arguments: [pCache] --
//
// History: 4-02-96 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
CACHE_VALIDITY
DCacheValid(
PDOMAIN_CACHE pCache)
{
LARGE_INTEGER Now;
BOOL Valid;
CACHE_VALIDITY CacheValidity;
UNICODE_STRING Domain;
UNICODE_STRING CacheDomain;
LockDomainCache( pCache, DCACHE_VALID );
//
// If there is no trusted domain list at all, then the list is not
// valid.
//
if ( !pCache->TrustedDomainSet )
{
UnlockDomainCache( pCache );
return( CacheInvalid );
}
NtQuerySystemTime( &Now );
Now.QuadPart -= CacheUpdateMin;
if ( pCache->CacheUpdateTime.QuadPart > Now.QuadPart )
{
CacheValidity = CacheValid;
}
else
{
//
// If not valid in time, see if the primary is still the same. We'll
//
Now.QuadPart += CacheUpdateMin;
Now.QuadPart -= CacheUpdateMax;
CacheValidity = CacheInvalid;
if ( GetPrimaryDomain( &Domain, NULL ) )
{
RtlInitUnicodeString( &CacheDomain, pCache->Primary );
if ( RtlCompareUnicodeString( &CacheDomain, &Domain, TRUE ) )
{
//
// Oops, didn't match
//
CacheValidity = CacheInvalid;
}
else
{
if ( pCache->CacheUpdateTime.QuadPart > Now.QuadPart )
{
CacheValidity = CacheGoodEnough;
}
else
{
CacheValidity = CacheStale;
}
}
RtlFreeUnicodeString( &Domain );
}
}
UnlockDomainCache( pCache );
DebugLog((DEB_TRACE, "DCacheValid - returning %d\n", CacheValidity ));
return( CacheValidity );
}
//+---------------------------------------------------------------------------
//
// Function: DCacheSave
//
// Synopsis: Saves the cache back out to the registry
//
// Arguments: [pCache] --
//
// History: 3-29-96 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
BOOL
DCacheSave(
PDOMAIN_CACHE pCache)
{
HKEY hKey;
int err;
err = RegOpenKey( HKEY_LOCAL_MACHINE,
szWinlogonKey,
&hKey );
if ( err )
{
return( FALSE );
}
LockDomainCache( pCache, DCACHE_SAVE );
err = RegSetValueEx(hKey,
szCacheValue,
0,
REG_MULTI_SZ,
(PUCHAR) pCache->TrustedDomainSet,
pCache->Size );
err = RegSetValueEx(hKey,
szCacheUpdate,
0,
REG_BINARY,
(PUCHAR) &pCache->CacheUpdateTime,
sizeof( LARGE_INTEGER ) );
if ( pCache->Primary )
{
err = RegSetValueEx(hKey,
szCachePrimary,
0,
REG_SZ,
(PUCHAR) pCache->Primary,
(wcslen( pCache->Primary ) + 1 ) * sizeof(WCHAR) );
}
UnlockDomainCache( pCache );
RegCloseKey( hKey );
return( TRUE );
}
//+---------------------------------------------------------------------------
//
// Function: DCacheNetThread
//
// Synopsis: Asynchronous filling of the domain cache from netlogon
//
// Arguments: [pvParam] -- points to the domain cache
//
// History: 3-29-96 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
DWORD
DCacheNetThread(
PVOID pvParam)
{
PDOMAIN_CACHE pCache;
PWSTR pList;
PWSTR pScan;
NTSTATUS Status;
DWORD Retry;
UNICODE_STRING Primary;
BOOL SynchronousCall;
BOOL CBFilled;
WPARAM wParam;
Retry = 60; // Retry for 60 * 3 seconds, or 3 minutes.
pCache = (PDOMAIN_CACHE) pvParam;
SynchronousCall = FALSE;
CBFilled = FALSE;
LockDomainCache( pCache, DCACHE_THREAD );
if ( pCache->RetryCount )
{
Retry = pCache->RetryCount;
SynchronousCall = TRUE;
pCache->RetryCount = 0;
}
UnlockDomainCache( pCache );
while ( Retry-- )
{
Status = NetEnumerateTrustedDomains( NULL, &pList );
if ( NT_SUCCESS ( Status ) )
{
pScan = pList;
while ( *pScan )
{
DebugLog(( DEB_TRACE_CACHE, "Found %ws\n", pScan ));
while (*pScan)
{
pScan++;
}
pScan++;
}
LockDomainCache( pCache, DCACHE_THREAD );
if ( pCache->TrustedDomainSet )
{
LocalFree( pCache->TrustedDomainSet );
}
pCache->Size = (DWORD) ((PUCHAR) pScan - (PUCHAR) pList) + sizeof(WCHAR);
pCache->TrustedDomainSet = LocalAlloc( LMEM_FIXED, pCache->Size );
if ( pCache->TrustedDomainSet )
{
CopyMemory( pCache->TrustedDomainSet,
pList,
pCache->Size );
NtQuerySystemTime( &pCache->CacheUpdateTime );
}
else
{
pCache->CacheUpdateTime.QuadPart = 0;
}
if ( pCache->ComboBox )
{
FillDomainCB( pCache, pCache->ComboBox );
pCache->ComboBox = NULL;
CBFilled = TRUE;
}
if ( pCache->UpdateNotifyWindow )
{
if (CBFilled)
{
wParam = DCACHE_UPDATE_COMBOBOX;
}
else
{
if ( pCache->TrustedDomainSet )
{
wParam = DCACHE_UPDATE_SUCCESSFUL;
}
else
{
wParam = DCACHE_UPDATE_FAILURE;
}
}
DebugLog((DEB_TRACE_CACHE, "Notifying %x that we were %d\n",
pCache->UpdateNotifyWindow, wParam ));
PostMessage( pCache->UpdateNotifyWindow,
pCache->Message,
wParam,
0 );
}
else
{
DebugLog((DEB_TRACE_CACHE, "No update window\n"));
}
if ( GetPrimaryDomain( &Primary, NULL ) )
{
if ( pCache->Primary )
{
LocalFree( pCache->Primary );
}
pCache->Primary = LocalAlloc( LMEM_FIXED, Primary.Length + 2 );
if ( pCache->Primary )
{
CopyMemory( pCache->Primary, Primary.Buffer, Primary.Length );
pCache->Primary[ Primary.Length / sizeof(WCHAR) ] = TEXT('\0');
}
}
DCacheSave( pCache );
//
// Clean up, since we're about to exit.
//
if ( !SynchronousCall )
{
if ( pCache->UpdateThread )
{
CloseHandle( pCache->UpdateThread );
pCache->UpdateThread = NULL;
}
}
NetApiBufferFree( pList );
UnlockDomainCache( pCache );
return ( 1 );
}
else
{
DebugLog((DEB_TRACE_CACHE, "NetEnumerate failed, %x\n", Status ));
if ( (Status == STATUS_NOT_SUPPORTED) ||
(Status == STATUS_NO_LOGON_SERVERS) ||
(Status == STATUS_NO_TRUST_LSA_SECRET) ||
(Status == STATUS_NO_TRUST_SAM_ACCOUNT) )
{
//
// One of these errors indicates that it's not going to get any
// better, so we should break out now.
//
break;
}
}
//
// Failure case. Unable to contact netlogon service.
//
if (Retry)
{
Sleep(3000);
}
}
LockDomainCache( pCache, DCACHE_THREAD );
if ( pCache->UpdateNotifyWindow )
{
PostMessage( pCache->UpdateNotifyWindow,
pCache->Message,
DCACHE_UPDATE_FAILURE,
0 );
}
//
// Clean up, since we're about to exit.
//
if ( !SynchronousCall )
{
if ( pCache->UpdateThread )
{
CloseHandle( pCache->UpdateThread );
pCache->UpdateThread = NULL;
}
}
UnlockDomainCache( pCache );
return( 0 );
}
//+---------------------------------------------------------------------------
//
// Function: DCacheDlgProc
//
// Synopsis: Dialog proc for the "Wait while domain list..."
//
// Arguments: [hDlg] --
// [Message] --
// [wParam] --
// [lParam] --
//
// History: 3-29-96 RichardW Created
//
// Notes: On WM_INITDIALOG, Cache is still locked by this thread.
// we free it here, allowing the other thread to continue.
// this lets us make sure the window handle etc are filled
// in appropriately.
//
//----------------------------------------------------------------------------
BOOL
CALLBACK
DCacheDlgProc(
HWND hDlg,
UINT Message,
WPARAM wParam,
LPARAM lParam )
{
PDOMAIN_CACHE pCache;
pCache = (PDOMAIN_CACHE) GetWindowLong( hDlg, GWL_USERDATA );
switch ( Message )
{
case WM_INITDIALOG:
SetWindowLong( hDlg, GWL_USERDATA, lParam );
pCache = (PDOMAIN_CACHE) lParam ;
pCache->UpdateNotifyWindow = hDlg;
pCache->Message = WM_CACHE_UPDATE_COMPLETE;
UnlockDomainCache( pCache );
CentreWindow( hDlg );
return( TRUE );
break;
case WM_CACHE_UPDATE_COMPLETE:
EndDialog( hDlg, wParam );
return( TRUE );
break;
case WM_DESTROY:
LockDomainCache( pCache, DCACHE_DLGPROC );
pCache->UpdateNotifyWindow = NULL;
pCache->Message = 0;
UnlockDomainCache( pCache );
SetupCursor( FALSE );
break;
}
return( FALSE );
}
//+---------------------------------------------------------------------------
//
// Function: DCacheWaitDialog
//
// Synopsis: Kicks off the network thread, also puts up the wait dlg
//
// Arguments: [hDlg] --
// [pCache] --
//
// History: 3-29-96 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
DCacheWaitDialog(
HWND hDlg,
PDOMAIN_CACHE pCache )
{
DWORD tid;
LONG Result;
LockDomainCache( pCache, DCACHE_DLGPROC );
if ( pCache->UpdateNotifyWindow )
{
//
// BUGBUG: Need to track down why this is happening. Quick fix:
// get out now.
//
UnlockDomainCache( pCache );
return( DCACHE_UPDATE_CONFLICT );
}
if ( ! pCache->UpdateThread )
{
DebugLog((DEB_TRACE_CACHE, "DCacheWaitDialog: Starting a thread\n"));
pCache->UpdateThread = CreateThread( NULL, 0,
DCacheNetThread,
pCache,
0,
&tid );
}
if ( pCache->UpdateThread )
{
//
// Start the dialog. The dialog proc will unlock the cache, allowing
// the thread to proceed.
//
Result = pWlxFuncs->WlxDialogBoxParam( hGlobalWlx,
hDllInstance,
MAKEINTRESOURCE( IDD_WAIT_DOMAIN_CACHE_VALID ),
hDlg,
DCacheDlgProc,
(LPARAM) pCache );
LockDomainCache( pCache, DCACHE_WAIT );
if ( pCache->UpdateThread )
{
CloseHandle( pCache->UpdateThread );
pCache->UpdateThread = NULL;
}
UnlockDomainCache( pCache );
}
else
{
Result = GetLastError();
}
return( Result );
}
//+---------------------------------------------------------------------------
//
// Function: FillDomainCB
//
// Synopsis: Fills the combo box with the strings
//
// Arguments: [pCache] --
// [hCB] --
//
// History: 4-01-96 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
VOID
FillDomainCB(
PDOMAIN_CACHE pCache,
HWND hCB)
{
PWSTR pszString;
LockDomainCache( pCache, DCACHE_FILL );
pszString = pCache->TrustedDomainSet;
if ( pszString )
{
while (*pszString)
{
SendMessage( hCB, CB_ADDSTRING, 0, (LPARAM) pszString );
DebugLog((DEB_TRACE_CACHE, "Adding %ws\n", pszString ));
while ( *pszString )
{
pszString++;
}
pszString++;
}
}
UnlockDomainCache( pCache );
}
//+---------------------------------------------------------------------------
//
// Function: DCacheUpdateCB
//
// Synopsis: Updates a combo box from the domain cache
//
// Arguments: [hDlg] --
// [Id] --
// [pCache] --
//
// History: 3-29-96 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
BOOL
DCacheUpdateCB(
HWND hDlg,
DWORD Id,
BOOL Block,
PDOMAIN_CACHE pCache )
{
HWND hCB;
LARGE_INTEGER Now;
LONG result;
DWORD tid;
CACHE_VALIDITY Valid;
BOOL ReloadOk;
hCB = GetDlgItem( hDlg, Id );
DebugLog(( DEB_TRACE_CACHE, "Updating combo box\n" ));
LockDomainCache( pCache, DCACHE_UPDATE );
Valid = DCacheValid( pCache );
ReloadOk = FALSE;
if ( Valid != CacheInvalid )
{
DebugLog((DEB_TRACE_CACHE, "Filling CB from cache\n"));
//
// If the cache was good, but not really good, try and freshen it with
// a quick check on netlogon. Don't do this if there is already a
// thread trying to do that.
//
if ( ( Valid == CacheGoodEnough ) &&
( pCache->UpdateThread == NULL ) )
{
DebugLog((DEB_TRACE_CACHE, "Cache older than 2min, trying a quick call\n"));
pCache->RetryCount = 1;
//
// Call it synchronously, once, to see if we can get it quickly from
// netlogon.
//
ReloadOk = DCacheNetThread( pCache );
}
FillDomainCB( pCache, hCB );
}
if ( (Valid == CacheValid) || (Valid == CacheGoodEnough) )
{
//
// If it was out of date, but not too bad, and we were not successful
// in freshening it up, and there isn't already a thread running async
// trying to do this, kick one off.
//
if ( (Valid == CacheGoodEnough) &&
(!ReloadOk) &&
(pCache->UpdateThread == NULL) )
{
DebugLog((DEB_TRACE_CACHE, "DCacheUpdateCB: Starting a thread\n"));
pCache->UpdateThread = CreateThread( NULL, 0,
DCacheNetThread,
pCache,
0,
&tid );
}
UnlockDomainCache( pCache );
return( TRUE );
}
//
// Ok, the cache is either totally invalid, or stale.
//
//
// If this is the non-blocking call, and the cache is empty, kick off
// a thread to populate it in the background.
//
pCache->ComboBox = hCB;
if ( !Block )
{
pCache->RetryCount = 1;
//
// Call it synchronously, once, to see if we can get it quickly from
// netlogon.
//
if (DCacheNetThread( pCache ))
{
UnlockDomainCache( pCache );
return( TRUE );
}
//
// Failing that, let it come around asynchronously.
//
if ( !pCache->UpdateThread )
{
DebugLog((DEB_TRACE_CACHE, "DCacheUpdateCB : Creating a thread\n"));
//
// Reset the CB value
//
pCache->ComboBox = NULL;
pCache->UpdateThread = CreateThread( NULL, 0,
DCacheNetThread,
pCache,
0, &tid );
}
UnlockDomainCache( pCache );
return( Valid == CacheStale );
}
UnlockDomainCache( pCache );
DebugLog(( DEB_TRACE_CACHE, "Putting up dialog\n" ));
result = DCacheWaitDialog( hDlg, pCache );
if ( result == DCACHE_UPDATE_CONFLICT )
{
return( FALSE );
}
if ( result != DCACHE_UPDATE_FAILURE )
{
if ( result == DCACHE_UPDATE_SUCCESSFUL )
{
FillDomainCB( pCache, hCB );
}
DCacheSave( pCache );
}
else
{
(VOID) TimeoutMessageBox(hDlg,
IDS_NO_TRUSTED_DOMAINS,
IDS_WINDOWS_MESSAGE,
MB_OK | MB_ICONINFORMATION,
TIMEOUT_CURRENT);
}
if ( result == DCACHE_UPDATE_FAILURE )
{
return( FALSE );
}
return( TRUE );
}
//+---------------------------------------------------------------------------
//
// Function: CreateDomainCache
//
// Synopsis: Place holder functions
//
// Arguments: [pCache] -- Cache to create/init
//
// History: 4-02-96 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
BOOL
CreateDomainCache(
PDOMAIN_CACHE pCache)
{
DWORD tid;
CACHE_VALIDITY Valid;
if ( DCacheInitialize( pCache ) )
{
if ( DCacheLoad( pCache ) )
{
Valid = DCacheValid( pCache );
if (Valid != CacheValid )
{
LockDomainCache( pCache, DCACHE_CREATE );
DebugLog((DEB_TRACE_CACHE, "CreateDomainCache - Creating a thread\n"));
pCache->UpdateThread = CreateThread( NULL, 0,
DCacheNetThread,
pCache,
0, &tid );
UnlockDomainCache( pCache );
}
}
return( TRUE );
}
return( FALSE );
}
//+---------------------------------------------------------------------------
//
// Function: FillTrustedDomainCB
//
// Synopsis: Fill the CB with the domains and machine name, etc.
//
// Arguments: [pGlobals] --
// [hDlg] --
// [ComboBoxID] --
// [DefaultDomain] --
// [FastFake] -- Block/Non-block
//
// History: 4-02-96 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
int
FillTrustedDomainCB(
PGLOBALS pGlobals,
HWND hDlg,
int ComboBoxID,
LPTSTR DefaultDomain,
BOOL FastFake
)
{
PDOMAIN_CACHE pCache;
NT_PRODUCT_TYPE NtProductType;
TCHAR ComputerName[MAX_COMPUTERNAME_LENGTH + 1];
UNICODE_STRING PrimaryDomainName;
UNICODE_STRING Compare;
LONG DefaultItemIndex = 0;
BOOL TrustedDomainsAdded;
HWND ComboBox;
DWORD Key;
WCHAR Buffer[2];
//
// Simplify things a little.
//
pCache = &pGlobals->DomainCache;
ComboBox = GetDlgItem(hDlg, ComboBoxID);
//
// Empty the combo-box before we start
//
SendMessage( ComboBox, CB_RESETCONTENT, 0, 0);
//
// Find out what product we are installed as
// This always defaults to something useful even on failure
//
RtlGetNtProductType(&NtProductType);
//
// Add computer name to combo box if appropriate
//
if (IsWorkstation(NtProductType)) {
DWORD ComputerNameLength = sizeof(ComputerName) / sizeof(*ComputerName);
if (GetComputerName(ComputerName, &ComputerNameLength)) {
DefaultItemIndex = SendMessage(ComboBox, CB_ADDSTRING, 0, (LONG)ComputerName);
}
}
//
// Assume the best. This is so that on unjoined workstations,
// we'll get success.
//
TrustedDomainsAdded = TRUE;
//
// Add our primary domain name (if we have one) to the list
//
if (GetPrimaryDomain(&PrimaryDomainName, NULL)) {
ASSERT(PrimaryDomainName.MaximumLength > PrimaryDomainName.Length);
PrimaryDomainName.Buffer[ PrimaryDomainName.Length/
sizeof(*(PrimaryDomainName.Buffer)) ] = 0;
LockDomainCache( pCache, DCACHE_FILL );
if ( pCache->Primary )
{
RtlInitUnicodeString( &Compare, pCache->Primary );
if ( RtlCompareUnicodeString( &PrimaryDomainName, &Compare, TRUE ) != 0 )
{
//
// Whoa! Purge cache, it's invalid
//
LocalFree( pCache->Primary );
pCache->Primary = LocalAlloc( LMEM_FIXED,
PrimaryDomainName.Length + 2);
if ( pCache->Primary )
{
wcscpy( pCache->Primary, PrimaryDomainName.Buffer );
}
LocalFree( pCache->TrustedDomainSet );
pCache->TrustedDomainSet = NULL;
pCache->CacheUpdateTime.QuadPart = 0;
}
}
UnlockDomainCache( pCache );
DefaultItemIndex = SendMessageW(ComboBox, CB_ADDSTRING, 0, (LONG)PrimaryDomainName.Buffer);
RtlFreeUnicodeString(&PrimaryDomainName);
TrustedDomainsAdded = DCacheUpdateCB( hDlg, ComboBoxID, FastFake, pCache );
}
Key = (TCHAR)GetWindowLong(ComboBox, GWL_USERDATA);
if ( Key == 0 ) {
if (SendMessage(ComboBox, CB_SELECTSTRING, (WPARAM)-1, (LONG)DefaultDomain)
== CB_ERR)
{
//
// Oh well, our default domain was not in the list. Set it to
// our domain or the wksta
//
SendMessage(ComboBox, CB_SETCURSEL, DefaultItemIndex, 0);
}
} else {
//
// We stored a key away, try using it
//
SetWindowLong(ComboBox, GWL_USERDATA, 0);
_snwprintf( Buffer, sizeof(Buffer), TEXT("%c"), Key);
DebugLog((DEB_TRACE, "Posting Key %s to the combo box\n", Buffer ));
if (SendMessage(ComboBox, CB_SELECTSTRING, (WPARAM)-1, (LPARAM)Buffer) == CB_ERR) {
SendMessage(ComboBox, CB_SETCURSEL, DefaultItemIndex, 0);
}
}
return( TrustedDomainsAdded ? MSGINA_DLG_SUCCESS : MSGINA_DLG_FAILURE );
}