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

326 lines
9.4 KiB
C

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