windows-nt/Source/XPSP1/NT/ds/netapi/netlib/confenum.c
2020-09-26 16:20:57 +08:00

257 lines
7.9 KiB
C

/*++
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);
}