|
|
/*++
Copyright (c) 1991-1993 Microsoft Corporation
Module Name:
ConfOpen.c
Abstract:
This module contains:
NetpOpenConfigDataWithPath NetpOpenConfigDataWithPathEx
Author:
John Rogers (JohnRo) 02-Dec-1991 Mike Swift (MikeSw) 30-Aug-1996
Environment:
Portable to any flat, 32-bit environment. (Uses Win32 typedefs.) Requires ANSI C extensions: slash-slash comments, long external names.
Revision History:
02-Dec-1991 JohnRo Created this routine, to prepare for revised config handlers. (Actually, I swiped some of this code from RitaW.) 06-Jan-1992 JohnRo Added support for FAKE_PER_PROCESS_RW_CONFIG handling. 09-Jan-1992 JohnRo Try workaround for lib/linker problem with NetpIsRemote(). 22-Mar-1992 JohnRo Added support for using the real Win32 registry. Added debug code to print the fake array. Fixed a UNICODE bug which PC-LINT caught. Fixed double _close of RTL config file. Fixed memory _access error in setting fake end of array. Use DBGSTATIC where applicable. 05-May-1992 JohnRo Reflect movement of keys to under System\CurrentControlSet\Services. 08-May-1992 JohnRo Use <prefix.h> equates. 21-May-1992 JohnRo RAID 9826: Match revised winreg error codes. 08-Jul-1992 JohnRo RAID 10503: srv mgr: repl dialog doesn't come up. Added more debug output to track down bad error code during logoff. 23-Jul-1992 JohnRo RAID 2274: repl svc should impersonate caller. 22-Sep-1992 JohnRo Avoid GP fault printing first part of winreg handle. 28-Oct-1992 JohnRo RAID 10136: NetConfig APIs don't work to remote NT server. 12-Apr-1993 JohnRo RAID 5483: server manager: wrong path given in repl dialog. 30-Aug-1996 MikeSw Copied from NetpOpenConfigData to allow configuring non-services
--*/
// These must be included first:
#include <nt.h> // NT definitions
#include <ntrtl.h> // NT Rtl structures
#include <nturtl.h> // NT config Rtl routines
#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.
#include <configp.h> // NET_CONFIG_HANDLE, etc.
#include <debuglib.h> // IF_DEBUG().
#include <icanon.h> // NetpIsRemote(), etc.
#include <lmerr.h> // LAN Manager network error definitions
#include <netlib.h> // NetpMemoryAllocate(), etc.
#include <netlibnt.h> // NetpNtStatusToApiStatus
#include <prefix.h> // PREFIX_ equates.
#include <tstring.h> // NetpAlloc{type}From{type}, STRICMP(), etc.
#define DEFAULT_AREA TEXT("Parameters")
#define DEFAULT_ROOT_KEY HKEY_LOCAL_MACHINE
DBGSTATIC NET_API_STATUS NetpSetupConfigSection ( IN NET_CONFIG_HANDLE * ConfigHandle, IN LPTSTR SectionName );
NET_API_STATUS NetpOpenConfigDataWithPath( OUT LPNET_CONFIG_HANDLE *ConfigHandle, IN LPTSTR UncServerName OPTIONAL, IN LPTSTR SectionName, IN BOOL ReadOnly )
/*++
Routine Description:
This function opens the system configuration file.
Arguments:
ConfigHandle - Points to a pointer which will be set to point to a net config handle for this section name. ConfigHandle will be set to NULL if any error occurs.
SectionName - Points to the new (NT) section name to be opened.
ReadOnly - Indicates whether all access through this net config handle is to be read only.
Return Value:
NET_API_STATUS - NO_ERROR or reason for failure.
--*/
{ return ( NetpOpenConfigDataWithPathEx( ConfigHandle, UncServerName, SectionName, // Must be a SECT_NT_ name.
DEFAULT_AREA, ReadOnly) );
} // NetpOpenConfigData
// NetpOpenConfigDataEx opens any area of a given service.
NET_API_STATUS NetpOpenConfigDataWithPathEx( OUT LPNET_CONFIG_HANDLE *ConfigHandle, IN LPTSTR UncServerName OPTIONAL, IN LPTSTR SectionName, // Must be a SECT_NT_ name.
IN LPTSTR AreaUnderSection OPTIONAL, IN BOOL ReadOnly ) {
NET_API_STATUS ApiStatus; DWORD LocalOrRemote; // Will be set to ISLOCAL or ISREMOTE.
NET_CONFIG_HANDLE * MyHandle = NULL; LONG Error; HKEY RootKey = DEFAULT_ROOT_KEY;
NetpAssert( ConfigHandle != NULL ); *ConfigHandle = NULL; // Assume error until proven innocent.
if ( (SectionName == NULL) || (*SectionName == TCHAR_EOS) ) { return (ERROR_INVALID_PARAMETER); } NetpAssert( (ReadOnly==TRUE) || (ReadOnly==FALSE) );
if ( (UncServerName != NULL ) && ((*UncServerName) != TCHAR_EOS) ) {
if( STRLEN(UncServerName) > MAX_PATH ) { return (ERROR_INVALID_PARAMETER); }
//
// Name was given. Canonicalize it and check if it's remote.
//
ApiStatus = NetpIsRemote( UncServerName, // input: uncanon name
& LocalOrRemote, // output: local or remote flag
NULL, // dont need output (canon name)
0, // length of canon name
0); // flags: normal
IF_DEBUG(CONFIG) { NetpKdPrint(( PREFIX_NETLIB "NetpOpenConfigDataEx: canon status is " FORMAT_API_STATUS ", Lcl/rmt=" FORMAT_HEX_DWORD ".\n", ApiStatus, LocalOrRemote)); } if (ApiStatus != NO_ERROR) { return (ApiStatus); }
if (LocalOrRemote == ISREMOTE) {
//
// Explicit remote name given.
//
Error = RegConnectRegistry( UncServerName, DEFAULT_ROOT_KEY, & RootKey ); // result key
if (Error != ERROR_SUCCESS) { NetpKdPrint(( PREFIX_NETLIB "NetpOpenConfigDataEx: RegConnectRegistry(machine '" FORMAT_LPTSTR "') ret error " FORMAT_LONG ".\n", UncServerName, Error )); return ((NET_API_STATUS) Error); } NetpAssert( RootKey != DEFAULT_ROOT_KEY );
} } else {
LocalOrRemote = ISLOCAL;
}
MyHandle = NetpMemoryAllocate( sizeof(NET_CONFIG_HANDLE) ); if (MyHandle == NULL) {
if (RootKey != DEFAULT_ROOT_KEY) { (VOID) RegCloseKey( RootKey ); }
return (ERROR_NOT_ENOUGH_MEMORY); }
{ LPTSTR AreaToUse = DEFAULT_AREA; DWORD DesiredAccess; DWORD SubKeySize; LPTSTR SubKeyString; HKEY SectionKey;
#define LM_SUBKEY_UNDER_LOCAL_MACHINE \
TEXT("System\\CurrentControlSet\\Services\\")
if (AreaUnderSection != NULL) { if ((*AreaUnderSection) != TCHAR_EOS) { AreaToUse = AreaUnderSection; } }
SubKeySize = ( STRLEN(SectionName) + 1 // backslash
+ STRLEN(AreaToUse) + 1 ) // trailing null
* sizeof(TCHAR); SubKeyString = NetpMemoryAllocate( SubKeySize ); if (SubKeyString == NULL) { if (MyHandle != NULL) { NetpMemoryFree( MyHandle ); MyHandle = NULL; }
if(RootKey != DEFAULT_ROOT_KEY) { RegCloseKey(RootKey); RootKey = DEFAULT_ROOT_KEY; }
return (ERROR_NOT_ENOUGH_MEMORY); }
(void) STRCPY( SubKeyString, SectionName ); (void) STRCAT( SubKeyString, TEXT("\\") ); (void) STRCAT( SubKeyString, AreaToUse );
if ( ReadOnly ) { DesiredAccess = KEY_READ; } else { DesiredAccess = KEY_READ | KEY_WRITE; // DesiredAccess = KEY_ALL_ACCESS; // Everything but SYNCHRONIZE.
}
Error = RegOpenKeyEx ( RootKey, SubKeyString, REG_OPTION_NON_VOLATILE, DesiredAccess, & SectionKey ); IF_DEBUG(CONFIG) { NetpKdPrint(( PREFIX_NETLIB "NetpOpenConfigDataEx: RegOpenKeyEx(subkey '" FORMAT_LPTSTR "') ret " FORMAT_LONG ", win reg handle at " FORMAT_LPVOID " is " FORMAT_LPVOID ".\n", SubKeyString, Error, (LPVOID) &(MyHandle->WinRegKey), SectionKey )); } if (Error == ERROR_FILE_NOT_FOUND) { ApiStatus = NERR_CfgCompNotFound; // Code below will free MyHandle, etc., based on ApiStatus.
} else if (Error != ERROR_SUCCESS) { ApiStatus = (NET_API_STATUS) Error; // Code below will free MyHandle, etc., based on ApiStatus.
} else { ApiStatus = NO_ERROR; }
NetpMemoryFree( SubKeyString );
if (RootKey != DEFAULT_ROOT_KEY) { (VOID) RegCloseKey( RootKey ); }
MyHandle->WinRegKey = SectionKey; }
if (ApiStatus != NO_ERROR) { NetpMemoryFree( MyHandle ); MyHandle = NULL; }
if (MyHandle != NULL) { if (LocalOrRemote == ISREMOTE) {
(VOID) STRCPY( MyHandle->UncServerName, // dest
UncServerName ); // src
} else {
MyHandle->UncServerName[0] = TCHAR_EOS; } }
*ConfigHandle = MyHandle; // Points to private handle, or is NULL on err.
return (ApiStatus);
} // NetpOpenConfigDataEx
|