|
|
/*++
Copyright (c) 1991-1993 Microsoft Corporation
Module Name:
ConfEnum.c
Abstract:
This module contains helper routines to _read fields out of the NT configuration files. This is for temporary use until the Configuration Registry is available.
Author:
John Rogers (JohnRo) 27-Nov-1991
Revision History:
27-Nov-1991 JohnRo Prepare for revised config handlers. (Actually swiped the NtRtl version of this code from RitaW.) 12-Mar-1992 JohnRo Added support for using the real Win32 registry. Added support for FAKE_PER_PROCESS_RW_CONFIG handling. 01-Apr-1992 JohnRo Use NetApiBufferAllocate() instead of private version. 06-May-1992 JohnRo REG_SZ now implies a UNICODE string, so we can't use REG_USZ anymore. 13-Jun-1992 JohnRo Title index parm is defunct (now lpReserved). Use PREFIX_ equates. 13-Apr-1993 JohnRo RAID 5483: server manager: wrong path given in repl dialog. Made changes suggested by PC-LINT 5.0
--*/
// These must be included first:
#include <nt.h> // NT definitions
#include <ntrtl.h> // NT Rtl structures
#include <nturtl.h> // NT Rtl structures
#include <windows.h> // Needed by <configp.h> and <winreg.h>
#include <lmcons.h> // LAN Manager common definitions
#include <netdebug.h> // (Needed by config.h)
// These may be included in any order:
#include <config.h> // My prototype, LPNET_CONFIG_HANDLE, etc.
#include <configp.h> // NET_CONFIG_HANDLE.
#include <debuglib.h> // IF_DEBUG()
#include <lmapibuf.h> // NetApiBufferAllocate(), NetApiBufferFree().
#include <lmerr.h> // LAN Manager network error definitions
#include <prefix.h> // PREFIX_ equates.
NET_API_STATUS NetpEnumConfigSectionValues( IN LPNET_CONFIG_HANDLE ConfigHandle, OUT LPTSTR * KeywordBuffer, // Must be freed by NetApiBufferFree().
OUT LPTSTR * ValueBuffer, // Must be freed by NetApiBufferFree().
IN BOOL FirstTime )
/*++
Routine Description:
This function gets the keyword value string from the configuration file.
Arguments:
ConfigHandle - Supplies a handle from NetpOpenConfigData for the appropriate section of the config data.
KeywordBuffer - Returns the string of the keyword value which is copied into this buffer. This string will be allocated by this routine and must be freed by NetApiBufferFree().
ValueBuffer - Returns the string of the keyword value which is copied into this buffer. This string will be allocated by this routine and must be freed by NetApiBufferFree().
FirstTime - TRUE if caller wants to start at first keyword for this section. FALSE if caller wants to continue a previous enum on this handle.
Return Value:
NET_API_STATUS - NERR_Success or reason for failure. (NERR_CfgParamNotFound if no other values exist for this section.)
--*/ { NET_CONFIG_HANDLE * lpnetHandle = ConfigHandle; // conv from opaque type
NET_API_STATUS ApiStatus;
NetpAssert( KeywordBuffer != NULL ); NetpAssert( ValueBuffer != NULL ); NetpAssert( (FirstTime==TRUE) || (FirstTime==FALSE) );
//
// Assume error until proven otherwise.
//
*KeywordBuffer = NULL; *ValueBuffer = NULL;
{ DWORD dwType; LONG Error; DWORD MaxKeywordSize, MaxValueSize; DWORD NumberOfKeywords; LPTSTR ValueT;
//
// Find number of keys in this section.
//
ApiStatus = NetpNumberOfConfigKeywords ( lpnetHandle, & NumberOfKeywords ); NetpAssert( ApiStatus == NO_ERROR ); if (NumberOfKeywords == 0) { return (NERR_CfgParamNotFound); }
//
// Set our index to something reasonable. Note that some other
// process might have deleted a keyword since we last did an enum,
// so don't worry if the index gets larger than the number of keys.
//
if (FirstTime) { lpnetHandle->LastEnumIndex = 0; } else {
DWORD MaxKeyIndex = NumberOfKeywords - 1; // Indices start at 0.
if (MaxKeyIndex < (lpnetHandle->LastEnumIndex)) {
// Bug or someone deleted. No way to tell, so assume latter.
return (NERR_CfgParamNotFound);
} else if (MaxKeyIndex == (lpnetHandle->LastEnumIndex)) {
// This is how we normally exit at end of list.
return (NERR_CfgParamNotFound);
} else {
// Normal bump to next entry.
++(lpnetHandle->LastEnumIndex);
} }
//
// Compute sizes and allocate (maximum) buffers.
//
ApiStatus = NetpGetConfigMaxSizes ( lpnetHandle, & MaxKeywordSize, & MaxValueSize ); NetpAssert( ApiStatus == NO_ERROR );
NetpAssert( MaxKeywordSize > 0 ); NetpAssert( MaxValueSize > 0 );
ApiStatus = NetApiBufferAllocate( MaxValueSize, (LPVOID *) & ValueT); if (ApiStatus != NO_ERROR) { return (ApiStatus); } NetpAssert( ValueT != NULL);
ApiStatus = NetApiBufferAllocate( MaxKeywordSize, (LPVOID *) KeywordBuffer); if (ApiStatus != NO_ERROR) { (void) NetApiBufferFree( ValueT ); return (ApiStatus); } NetpAssert( (*KeywordBuffer) != NULL);
//
// Get the keyword name and the value.
// (Win32 reg APIs convert from TCHARs to UNICODE for us.)
//
IF_DEBUG(CONFIG) { NetpKdPrint(( PREFIX_NETLIB "NetpEnumConfigSectionValues: getting entry " FORMAT_DWORD "...\n", lpnetHandle->LastEnumIndex )); } Error = RegEnumValue ( lpnetHandle->WinRegKey, // handle to key (section)
lpnetHandle->LastEnumIndex, // index of value name
* KeywordBuffer, // value name (keyword)
& MaxKeywordSize, // value name len (updated)
NULL, // reserved
& dwType, (LPVOID) ValueT, // TCHAR value
& MaxValueSize ); // value size (updated)
IF_DEBUG(CONFIG) { NetpKdPrint(( PREFIX_NETLIB "NetpEnumConfigSectionValues: RegEnumValue() ret " FORMAT_LONG ".\n", Error )); }
if ( Error != ERROR_SUCCESS ) { NetpAssert( Error == ERROR_SUCCESS ); NetApiBufferFree( ValueT ); return (Error); }
if (dwType == REG_SZ) { *ValueBuffer = ValueT; ApiStatus = NO_ERROR; } else if (dwType == REG_EXPAND_SZ) { LPTSTR UnexpandedString = ValueT; LPTSTR ExpandedString = NULL;
// Expand string, using remote environment if necessary.
ApiStatus = NetpExpandConfigString( lpnetHandle->UncServerName, // server name (or null char)
UnexpandedString, &ExpandedString ); // expanded: alloc and set ptr
if (ApiStatus != NO_ERROR) { NetpKdPrint(( PREFIX_NETLIB "NetpEnumConfigSectionValues: NetpExpandConfigString " " returned API status " FORMAT_API_STATUS ".\n", ApiStatus )); ExpandedString = NULL; }
(VOID) NetApiBufferFree( UnexpandedString ); *ValueBuffer = ExpandedString;
} else {
// Unexpected data type.
NetpAssert( dwType == REG_SZ ); *ValueBuffer = NULL; (VOID) NetApiBufferFree( ValueT ); ApiStatus = ERROR_INVALID_DATA; }
}
return (ApiStatus); }
|