[DHCPCSVC] Convert the pipe based client-server interface to RPC

This commit is contained in:
Eric Kohl
2025-08-03 22:39:36 +02:00
parent a6d3787507
commit 94a6102cd2
7 changed files with 314 additions and 664 deletions

View File

@@ -1,5 +1,9 @@
include_directories(include)
include_directories(include ${REACTOS_SOURCE_DIR}/sdk/include/reactos/idl)
add_rpc_file(client ${REACTOS_SOURCE_DIR}/sdk/include/reactos/idl/dhcpcsvc.idl PREFIX_CLIENT Client_ PREFIX_SERVER Server_)
add_rpc_file(server ${REACTOS_SOURCE_DIR}/sdk/include/reactos/idl/dhcpcsvc.idl PREFIX_CLIENT Client_ PREFIX_SERVER Server_)
spec2def(dhcpcsvc.dll dhcpcsvc.spec ADD_IMPORTLIB)
list(APPEND SOURCE
@@ -11,13 +15,14 @@ list(APPEND SOURCE
dhcp/dispatch.c
dhcp/hash.c
dhcp/options.c
dhcp/pipe.c
dhcp/socket.c
dhcp/tables.c
dhcp/util.c
dhcpcsvc.c)
list(APPEND PCH_SKIP_SOURCE
${CMAKE_CURRENT_BINARY_DIR}/dhcpcsvc_c.c
${CMAKE_CURRENT_BINARY_DIR}/dhcpcsvc_s.c
${CMAKE_CURRENT_BINARY_DIR}/dhcpcsvc_stubs.c)
add_library(dhcpcsvc MODULE
@@ -26,8 +31,8 @@ add_library(dhcpcsvc MODULE
dhcpcsvc.rc
${CMAKE_CURRENT_BINARY_DIR}/dhcpcsvc.def)
target_link_libraries(dhcpcsvc oldnames)
set_module_type(dhcpcsvc win32dll)
add_importlibs(dhcpcsvc ws2_32 iphlpapi advapi32 msvcrt kernel32 ntdll)
target_link_libraries(dhcpcsvc oldnames ${PSEH_LIB})
add_importlibs(dhcpcsvc ws2_32 rpcrt4 iphlpapi advapi32 msvcrt kernel32 ntdll)
add_pch(dhcpcsvc include/rosdhcp.h "${PCH_SKIP_SOURCE}")
add_cd_file(TARGET dhcpcsvc DESTINATION reactos/system32 FOR all)

View File

@@ -31,32 +31,73 @@ VOID ApiFree() {
DeleteCriticalSection( &ApiCriticalSection );
}
DWORD
WINAPI
RpcThreadRoutine(
LPVOID lpParameter)
{
RPC_STATUS Status;
Status = RpcServerUseProtseqEpW(L"ncacn_np", 20, L"\\pipe\\dhcpcsvc", NULL);
if (Status != RPC_S_OK)
{
DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status);
return 0;
}
Status = RpcServerRegisterIf(Server_dhcpcsvc_v0_0_s_ifspec, NULL, NULL);
if (Status != RPC_S_OK)
{
DPRINT1("RpcServerRegisterIf() failed (Status %lx)\n", Status);
return 0;
}
Status = RpcServerListen(1, RPC_C_LISTEN_MAX_CALLS_DEFAULT, FALSE);
if (Status != RPC_S_OK)
{
DPRINT1("RpcServerListen() failed (Status %lx)\n", Status);
}
return 0;
}
HANDLE
InitRpc(VOID)
{
return CreateThread( NULL, 0, RpcThreadRoutine, (LPVOID)NULL, 0, NULL);
}
VOID
ShutdownRpc(VOID)
{
RpcMgmtStopServerListening(NULL);
}
/* This represents the service portion of the DHCP client API */
/* Function 0 */
DWORD
DSAcquireParams(
_In_ PipeSendFunc Send,
_In_ HANDLE CommPipe,
_Out_ COMM_DHCP_REQ *Req)
__stdcall
Server_AcquireParameters(
_In_ PDHCP_SERVER_NAME ServerName,
_In_ LPWSTR AdapterName)
{
COMM_DHCP_REPLY Reply;
PDHCP_ADAPTER Adapter;
struct protocol* proto;
DWORD ret = ERROR_SUCCESS;
DPRINT1("DSAcquireParams()\n");
Reply.Reply = ERROR_SUCCESS;
DPRINT("Server_AcquireParameters()\n");
ApiLock();
Adapter = AdapterFindName(Req->Body.AcquireParams.AdapterName);
Adapter = AdapterFindName(AdapterName);
if (Adapter == NULL || Adapter->DhclientState.state == S_STATIC)
{
Reply.Reply = ERROR_FILE_NOT_FOUND;
ret = ERROR_FILE_NOT_FOUND;
goto done;
}
DPRINT1("Adapter: %p\n", Adapter);
DPRINT("Adapter: %p\n", Adapter);
proto = find_protocol_by_adapter(&Adapter->DhclientInfo);
if (proto)
@@ -75,34 +116,33 @@ DSAcquireParams(
done:
ApiUnlock();
return Send(CommPipe, &Reply);
return ret;
}
/* Function 1 */
DWORD
DSReleaseParams(
_In_ PipeSendFunc Send,
_In_ HANDLE CommPipe,
_Out_ COMM_DHCP_REQ *Req)
__stdcall
Server_ReleaseParameters(
_In_ PDHCP_SERVER_NAME ServerName,
_In_ LPWSTR AdapterName)
{
COMM_DHCP_REPLY Reply;
PDHCP_ADAPTER Adapter;
struct protocol* proto;
DWORD ret = ERROR_SUCCESS;
DPRINT1("DSReleaseParams()\n");
Reply.Reply = ERROR_SUCCESS;
DPRINT("Server_ReleaseParameters()\n");
ApiLock();
Adapter = AdapterFindName(Req->Body.AcquireParams.AdapterName);
Adapter = AdapterFindName(AdapterName);
if (Adapter == NULL)
{
Reply.Reply = ERROR_FILE_NOT_FOUND;
ret = ERROR_FILE_NOT_FOUND;
goto done;
}
DPRINT1("Adapter: %p\n", Adapter);
DPRINT("Adapter: %p\n", Adapter);
if (Adapter->NteContext)
{
@@ -128,71 +168,98 @@ DSReleaseParams(
done:
ApiUnlock();
return Send(CommPipe, &Reply);
return ret;
}
DWORD DSQueryHWInfo( PipeSendFunc Send, HANDLE CommPipe, COMM_DHCP_REQ *Req ) {
COMM_DHCP_REPLY Reply;
/* Function 2 */
DWORD
__stdcall
Server_QueryHWInfo(
_In_ PDHCP_SERVER_NAME ServerName,
_In_ DWORD AdapterIndex,
_Out_ PDWORD MediaType,
_Out_ PDWORD Mtu,
_Out_ PDWORD Speed)
{
PDHCP_ADAPTER Adapter;
DWORD ret = ERROR_SUCCESS;
DPRINT("Server_QueryHWInfo()\n");
ApiLock();
Adapter = AdapterFindIndex( Req->AdapterIndex );
Reply.Reply = Adapter ? 1 : 0;
if (Adapter) {
Reply.QueryHWInfo.AdapterIndex = Req->AdapterIndex;
Reply.QueryHWInfo.MediaType = Adapter->IfMib.dwType;
Reply.QueryHWInfo.Mtu = Adapter->IfMib.dwMtu;
Reply.QueryHWInfo.Speed = Adapter->IfMib.dwSpeed;
Adapter = AdapterFindIndex(AdapterIndex);
if (Adapter == NULL)
{
ret = ERROR_FILE_NOT_FOUND;
goto done;
}
DPRINT("Adapter: %p\n", Adapter);
*MediaType = Adapter->IfMib.dwType;
*Mtu = Adapter->IfMib.dwMtu;
*Speed = Adapter->IfMib.dwSpeed;
done:
ApiUnlock();
return Send(CommPipe, &Reply );
return ret;
}
DWORD DSStaticRefreshParams( PipeSendFunc Send, HANDLE CommPipe, COMM_DHCP_REQ *Req ) {
NTSTATUS Status;
COMM_DHCP_REPLY Reply;
/* Function 3 */
DWORD
__stdcall
Server_StaticRefreshParams(
_In_ PDHCP_SERVER_NAME ServerName,
_In_ DWORD AdapterIndex,
_In_ DWORD Address,
_In_ DWORD Netmask)
{
PDHCP_ADAPTER Adapter;
struct protocol* proto;
DWORD ret = ERROR_SUCCESS;
DPRINT("Server_StaticRefreshParams()\n");
ApiLock();
Adapter = AdapterFindIndex( Req->AdapterIndex );
Reply.Reply = Adapter ? 1 : 0;
if( Adapter ) {
if (Adapter->NteContext)
{
DeleteIPAddress( Adapter->NteContext );
Adapter->NteContext = 0;
}
if (Adapter->RouterMib.dwForwardNextHop)
{
DeleteIpForwardEntry( &Adapter->RouterMib );
Adapter->RouterMib.dwForwardNextHop = 0;
}
Adapter->DhclientState.state = S_STATIC;
proto = find_protocol_by_adapter( &Adapter->DhclientInfo );
if (proto)
remove_protocol(proto);
Status = AddIPAddress( Req->Body.StaticRefreshParams.IPAddress,
Req->Body.StaticRefreshParams.Netmask,
Req->AdapterIndex,
&Adapter->NteContext,
&Adapter->NteInstance );
Reply.Reply = NT_SUCCESS(Status);
if (hAdapterStateChangedEvent != NULL)
SetEvent(hAdapterStateChangedEvent);
Adapter = AdapterFindIndex(AdapterIndex);
if (Adapter == NULL)
{
ret = ERROR_FILE_NOT_FOUND;
goto done;
}
DPRINT("Adapter: %p\n", Adapter);
if (Adapter->NteContext)
{
DeleteIPAddress(Adapter->NteContext);
Adapter->NteContext = 0;
}
if (Adapter->RouterMib.dwForwardNextHop)
{
DeleteIpForwardEntry(&Adapter->RouterMib);
Adapter->RouterMib.dwForwardNextHop = 0;
}
Adapter->DhclientState.state = S_STATIC;
proto = find_protocol_by_adapter(&Adapter->DhclientInfo);
if (proto)
remove_protocol(proto);
ret = AddIPAddress(Address,
Netmask,
AdapterIndex,
&Adapter->NteContext,
&Adapter->NteInstance);
if (hAdapterStateChangedEvent != NULL)
SetEvent(hAdapterStateChangedEvent);
done:
ApiUnlock();
return Send(CommPipe, &Reply );
return ret;
}

View File

@@ -1,419 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: subsys/system/dhcp/pipe.c
* PURPOSE: DHCP client pipe
* PROGRAMMER: arty
*/
#include <rosdhcp.h>
#define NDEBUG
#include <reactos/debug.h>
#define COMM_PIPE_OUTPUT_BUFFER sizeof(COMM_DHCP_REQ)
#define COMM_PIPE_INPUT_BUFFER sizeof(COMM_DHCP_REPLY)
#define COMM_PIPE_DEFAULT_TIMEOUT 1000
DWORD PipeSend( HANDLE CommPipe, COMM_DHCP_REPLY *Reply ) {
DWORD Written = 0;
OVERLAPPED Overlapped = {0};
BOOL Success =
WriteFile( CommPipe,
Reply,
sizeof(*Reply),
&Written,
&Overlapped);
if (!Success)
{
WaitForSingleObject(CommPipe, INFINITE);
Success = GetOverlappedResult(CommPipe,
&Overlapped,
&Written,
TRUE);
}
return Success ? Written : -1;
}
/**
* @brief
* Creates a security descriptor for the DHCP pipe
* service.
*
* @param[out] SecurityDescriptor
* A pointer to an allocated security descriptor
* for the DHCP pipe.
*
* @return
* ERROR_SUCCESS is returned if the function has
* successfully created the descriptor otherwise
* a Win32 error code is returned.
*
* @remarks
* Both admins and local system are given full power
* over the DHCP pipe whereas authenticated users
* and network operators can only read over this pipe.
* They can also execute it.
*/
DWORD CreateDhcpPipeSecurity( PSECURITY_DESCRIPTOR *SecurityDescriptor ) {
DWORD ErrCode;
PACL Dacl;
ULONG DaclSize, RelSDSize = 0;
PSECURITY_DESCRIPTOR AbsSD = NULL, RelSD = NULL;
PSID AuthenticatedUsersSid = NULL, NetworkOpsSid = NULL, AdminsSid = NULL, SystemSid = NULL;
static SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
if (!AllocateAndInitializeSid(&NtAuthority,
1,
SECURITY_AUTHENTICATED_USER_RID,
0, 0, 0, 0, 0, 0, 0,
&AuthenticatedUsersSid))
{
DPRINT1("CreateDhcpPipeSecurity(): Failed to create Authenticated Users SID (error code %d)\n", GetLastError());
return GetLastError();
}
if (!AllocateAndInitializeSid(&NtAuthority,
2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS,
0, 0, 0, 0, 0, 0,
&NetworkOpsSid))
{
DPRINT1("CreateDhcpPipeSecurity(): Failed to create Network Ops SID (error code %d)\n", GetLastError());
ErrCode = GetLastError();
goto Quit;
}
if (!AllocateAndInitializeSid(&NtAuthority,
2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0,
&AdminsSid))
{
DPRINT1("CreateDhcpPipeSecurity(): Failed to create Admins SID (error code %d)\n", GetLastError());
ErrCode = GetLastError();
goto Quit;
}
if (!AllocateAndInitializeSid(&NtAuthority,
1,
SECURITY_LOCAL_SYSTEM_RID,
0, 0, 0, 0, 0, 0, 0,
&SystemSid))
{
DPRINT1("CreateDhcpPipeSecurity(): Failed to create Local System SID (error code %d)\n", GetLastError());
ErrCode = GetLastError();
goto Quit;
}
AbsSD = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SECURITY_DESCRIPTOR));
if (!AbsSD)
{
DPRINT1("CreateDhcpPipeSecurity(): Failed to allocate absolute security descriptor!\n");
ErrCode = ERROR_OUTOFMEMORY;
goto Quit;
}
if (!InitializeSecurityDescriptor(AbsSD, SECURITY_DESCRIPTOR_REVISION))
{
DPRINT1("CreateDhcpPipeSecurity(): Failed to initialize absolute security descriptor (error code %d)\n", GetLastError());
ErrCode = GetLastError();
goto Quit;
}
DaclSize = sizeof(ACL) +
sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(AuthenticatedUsersSid) +
sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(NetworkOpsSid) +
sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(AdminsSid) +
sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(SystemSid);
Dacl = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, DaclSize);
if (!Dacl)
{
DPRINT1("CreateDhcpPipeSecurity(): Failed to allocate DACL!\n");
ErrCode = ERROR_OUTOFMEMORY;
goto Quit;
}
if (!InitializeAcl(Dacl, DaclSize, ACL_REVISION))
{
DPRINT1("CreateDhcpPipeSecurity(): Failed to initialize DACL (error code %d)\n", GetLastError());
ErrCode = GetLastError();
goto Quit;
}
if (!AddAccessAllowedAce(Dacl,
ACL_REVISION,
GENERIC_READ | GENERIC_EXECUTE,
AuthenticatedUsersSid))
{
DPRINT1("CreateDhcpPipeSecurity(): Failed to set up ACE for Authenticated Users SID (error code %d)\n", GetLastError());
ErrCode = GetLastError();
goto Quit;
}
if (!AddAccessAllowedAce(Dacl,
ACL_REVISION,
GENERIC_READ | GENERIC_EXECUTE,
NetworkOpsSid))
{
DPRINT1("CreateDhcpPipeSecurity(): Failed to set up ACE for Network Ops SID (error code %d)\n", GetLastError());
ErrCode = GetLastError();
goto Quit;
}
if (!AddAccessAllowedAce(Dacl,
ACL_REVISION,
GENERIC_ALL,
AdminsSid))
{
DPRINT1("CreateDhcpPipeSecurity(): Failed to set up ACE for Admins SID (error code %d)\n", GetLastError());
ErrCode = GetLastError();
goto Quit;
}
if (!AddAccessAllowedAce(Dacl,
ACL_REVISION,
GENERIC_ALL,
SystemSid))
{
DPRINT1("CreateDhcpPipeSecurity(): Failed to set up ACE for Local System SID (error code %d)\n", GetLastError());
ErrCode = GetLastError();
goto Quit;
}
if (!SetSecurityDescriptorDacl(AbsSD, TRUE, Dacl, FALSE))
{
DPRINT1("CreateDhcpPipeSecurity(): Failed to set up DACL to absolute security descriptor (error code %d)\n", GetLastError());
ErrCode = GetLastError();
goto Quit;
}
if (!SetSecurityDescriptorOwner(AbsSD, AdminsSid, FALSE))
{
DPRINT1("CreateDhcpPipeSecurity(): Failed to set up owner to absolute security descriptor (error code %d)\n", GetLastError());
ErrCode = GetLastError();
goto Quit;
}
if (!SetSecurityDescriptorGroup(AbsSD, SystemSid, FALSE))
{
DPRINT1("CreateDhcpPipeSecurity(): Failed to set up group to absolute security descriptor (error code %d)\n", GetLastError());
ErrCode = GetLastError();
goto Quit;
}
if (!MakeSelfRelativeSD(AbsSD, NULL, &RelSDSize) && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
DPRINT1("CreateDhcpPipeSecurity(): Unexpected error code (error code %d -- must be ERROR_INSUFFICIENT_BUFFER)\n", GetLastError());
ErrCode = GetLastError();
goto Quit;
}
RelSD = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, RelSDSize);
if (RelSD == NULL)
{
DPRINT1("CreateDhcpPipeSecurity(): Failed to allocate relative SD!\n");
ErrCode = ERROR_OUTOFMEMORY;
goto Quit;
}
if (!MakeSelfRelativeSD(AbsSD, RelSD, &RelSDSize) && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
DPRINT1("CreateDhcpPipeSecurity(): Failed to allocate relative SD, buffer too smal (expected size %lu)\n", RelSDSize);
ErrCode = ERROR_INSUFFICIENT_BUFFER;
goto Quit;
}
*SecurityDescriptor = RelSD;
ErrCode = ERROR_SUCCESS;
Quit:
if (ErrCode != ERROR_SUCCESS)
{
if (RelSD)
{
HeapFree(GetProcessHeap(), 0, RelSD);
}
}
if (AuthenticatedUsersSid)
{
FreeSid(AuthenticatedUsersSid);
}
if (NetworkOpsSid)
{
FreeSid(NetworkOpsSid);
}
if (AdminsSid)
{
FreeSid(AdminsSid);
}
if (SystemSid)
{
FreeSid(SystemSid);
}
if (Dacl)
{
HeapFree(GetProcessHeap(), 0, Dacl);
}
if (AbsSD)
{
HeapFree(GetProcessHeap(), 0, AbsSD);
}
return ErrCode;
}
DWORD WINAPI PipeThreadProc( LPVOID Parameter ) {
DWORD BytesRead;
COMM_DHCP_REQ Req;
COMM_DHCP_REPLY Reply;
BOOL Result, Connected;
HANDLE Events[2];
HANDLE CommPipe;
OVERLAPPED Overlapped = {0};
DWORD dwError;
SECURITY_ATTRIBUTES SecurityAttributes;
PSECURITY_DESCRIPTOR DhcpPipeSD = NULL;
DPRINT("PipeThreadProc(%p)\n", Parameter);
dwError = CreateDhcpPipeSecurity(&DhcpPipeSD);
if (dwError != ERROR_SUCCESS)
{
DbgPrint("DHCP: Could not create security descriptor for pipe\n");
return FALSE;
}
SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
SecurityAttributes.lpSecurityDescriptor = DhcpPipeSD;
SecurityAttributes.bInheritHandle = FALSE;
CommPipe = CreateNamedPipeW
( DHCP_PIPE_NAME,
PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
1,
COMM_PIPE_OUTPUT_BUFFER,
COMM_PIPE_INPUT_BUFFER,
COMM_PIPE_DEFAULT_TIMEOUT,
&SecurityAttributes );
HeapFree(GetProcessHeap(), 0, DhcpPipeSD);
if (CommPipe == INVALID_HANDLE_VALUE)
{
DbgPrint("DHCP: Could not create named pipe\n");
return FALSE;
}
Events[0] = (HANDLE)Parameter;
Events[1] = CommPipe;
while( TRUE )
{
Connected = ConnectNamedPipe(CommPipe, &Overlapped);
if (!Connected)
{
dwError = GetLastError();
if (dwError == ERROR_IO_PENDING)
{
dwError = WaitForMultipleObjects(2, Events, FALSE, INFINITE);
DPRINT("WaitForMultipleObjects() returned %lu\n", dwError);
if (dwError == WAIT_OBJECT_0 + 1)
{
Connected = GetOverlappedResult(CommPipe,
&Overlapped,
&BytesRead,
TRUE);
}
else if (dwError == WAIT_OBJECT_0)
{
CancelIo(CommPipe);
CloseHandle(CommPipe);
CommPipe = INVALID_HANDLE_VALUE;
break;
}
}
}
if (!Connected) {
DbgPrint("DHCP: Could not connect named pipe\n");
CloseHandle( CommPipe );
CommPipe = INVALID_HANDLE_VALUE;
break;
}
Result = ReadFile(CommPipe, &Req, sizeof(Req), &BytesRead, &Overlapped);
if (!Result)
{
dwError = GetLastError();
if (dwError == ERROR_IO_PENDING)
{
dwError = WaitForMultipleObjects(2, Events, FALSE, INFINITE);
DPRINT("WaitForMultipleObjects() returned %lu\n", dwError);
if (dwError == WAIT_OBJECT_0 + 1)
{
Result = GetOverlappedResult(CommPipe,
&Overlapped,
&BytesRead,
TRUE);
}
else if (dwError == WAIT_OBJECT_0)
{
CancelIo(CommPipe);
DisconnectNamedPipe( CommPipe );
CloseHandle(CommPipe);
CommPipe = INVALID_HANDLE_VALUE;
break;
}
}
}
if( Result )
{
switch( Req.Type )
{
case DhcpReqAcquireParams:
DSAcquireParams(PipeSend, CommPipe, &Req);
break;
case DhcpReqReleaseParams:
DSReleaseParams(PipeSend, CommPipe, &Req);
break;
case DhcpReqQueryHWInfo:
DSQueryHWInfo(PipeSend, CommPipe, &Req);
break;
case DhcpReqStaticRefreshParams:
DSStaticRefreshParams( PipeSend, CommPipe, &Req );
break;
default:
DPRINT1("Unrecognized request type %d\n", Req.Type);
ZeroMemory( &Reply, sizeof( COMM_DHCP_REPLY ) );
Reply.Reply = 0;
PipeSend(CommPipe, &Reply );
break;
}
}
DisconnectNamedPipe( CommPipe );
}
DPRINT("Pipe thread stopped!\n");
return TRUE;
}
HANDLE PipeInit(HANDLE hStopEvent)
{
return CreateThread( NULL, 0, PipeThreadProc, (LPVOID)hStopEvent, 0, NULL);
}

View File

@@ -19,59 +19,88 @@ SERVICE_STATUS ServiceStatus;
HANDLE hStopEvent = NULL;
HANDLE hAdapterStateChangedEvent = NULL;
static HANDLE PipeHandle = INVALID_HANDLE_VALUE;
extern SOCKET DhcpSocket;
DWORD APIENTRY
DhcpCApiInitialize(LPDWORD Version)
void __RPC_FAR * __RPC_USER MIDL_user_allocate(SIZE_T len)
{
DWORD PipeMode;
return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
}
/* Wait for the pipe to be available */
if (!WaitNamedPipeW(DHCP_PIPE_NAME, NMPWAIT_USE_DEFAULT_WAIT))
void __RPC_USER MIDL_user_free(void __RPC_FAR * ptr)
{
HeapFree(GetProcessHeap(), 0, ptr);
}
handle_t __RPC_USER
PDHCP_SERVER_NAME_bind(
_In_ PDHCP_SERVER_NAME pszServerName)
{
handle_t hBinding = NULL;
LPWSTR pszStringBinding;
RPC_STATUS status;
DPRINT("PDHCP_SERVER_NAME_bind() called\n");
status = RpcStringBindingComposeW(NULL,
L"ncacn_np",
pszServerName,
L"\\pipe\\dhcpcsvc",
NULL,
&pszStringBinding);
if (status)
{
/* No good, we failed */
return GetLastError();
DPRINT1("RpcStringBindingCompose returned 0x%x\n", status);
return NULL;
}
/* It's available, let's try to open it */
PipeHandle = CreateFileW(DHCP_PIPE_NAME,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
/* Check if we succeeded in opening the pipe */
if (PipeHandle == INVALID_HANDLE_VALUE)
/* Set the binding handle that will be used to bind to the server. */
status = RpcBindingFromStringBindingW(pszStringBinding,
&hBinding);
if (status)
{
/* We didn't */
return GetLastError();
DPRINT1("RpcBindingFromStringBinding returned 0x%x\n", status);
}
/* Change the pipe into message mode */
PipeMode = PIPE_READMODE_MESSAGE;
if (!SetNamedPipeHandleState(PipeHandle, &PipeMode, NULL, NULL))
status = RpcStringFreeW(&pszStringBinding);
if (status)
{
/* Mode change failed */
CloseHandle(PipeHandle);
PipeHandle = INVALID_HANDLE_VALUE;
return GetLastError();
DPRINT1("RpcStringFree returned 0x%x\n", status);
}
else
return hBinding;
}
void __RPC_USER
PDHCP_SERVER_NAME_unbind(
_In_ PDHCP_SERVER_NAME pszServerName,
_In_ handle_t hBinding)
{
RPC_STATUS status;
DPRINT("PDHCP_SERVER_NAME_unbind() called\n");
status = RpcBindingFree(&hBinding);
if (status)
{
/* We're good to go */
*Version = 2;
return NO_ERROR;
DPRINT1("RpcBindingFree returned 0x%x\n", status);
}
}
VOID APIENTRY
DWORD
APIENTRY
DhcpCApiInitialize(
_Out_ LPDWORD Version)
{
*Version = 2;
return NO_ERROR;
}
VOID
APIENTRY
DhcpCApiCleanup(VOID)
{
CloseHandle(PipeHandle);
PipeHandle = INVALID_HANDLE_VALUE;
}
DWORD
@@ -79,29 +108,21 @@ APIENTRY
DhcpAcquireParameters(
_In_ PWSTR AdapterName)
{
COMM_DHCP_REQ Req;
COMM_DHCP_REPLY Reply;
DWORD BytesRead;
BOOL Result;
DWORD ret;
DPRINT1("DhcpAcquireParameters(%S)\n", AdapterName);
DPRINT("DhcpAcquireParameters(%S)\n", AdapterName);
ASSERT(PipeHandle != INVALID_HANDLE_VALUE);
Req.Type = DhcpReqAcquireParams;
wcscpy(Req.Body.AcquireParams.AdapterName, AdapterName);
Result = TransactNamedPipe(PipeHandle,
&Req, sizeof(Req),
&Reply, sizeof(Reply),
&BytesRead, NULL);
if (!Result)
RpcTryExcept
{
/* Pipe transaction failed */
return GetLastError();
ret = Client_AcquireParameters(NULL, AdapterName);
}
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
{
ret = I_RpcMapWin32Status(RpcExceptionCode());
}
RpcEndExcept;
return Reply.Reply;
return ret;
}
DWORD
@@ -109,29 +130,21 @@ APIENTRY
DhcpReleaseParameters(
_In_ PWSTR AdapterName)
{
COMM_DHCP_REQ Req;
COMM_DHCP_REPLY Reply;
DWORD BytesRead;
BOOL Result;
DWORD ret;
DPRINT1("DhcpReleaseParameters(%S)\n", AdapterName);
DPRINT("DhcpReleaseParameters(%S)\n", AdapterName);
ASSERT(PipeHandle != INVALID_HANDLE_VALUE);
Req.Type = DhcpReqReleaseParams;
wcscpy(Req.Body.AcquireParams.AdapterName, AdapterName);
Result = TransactNamedPipe(PipeHandle,
&Req, sizeof(Req),
&Reply, sizeof(Reply),
&BytesRead, NULL);
if (!Result)
RpcTryExcept
{
/* Pipe transaction failed */
return GetLastError();
ret = Client_ReleaseParameters(NULL, AdapterName);
}
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
{
ret = I_RpcMapWin32Status(RpcExceptionCode());
}
RpcEndExcept;
return Reply.Reply;
return ret;
}
DWORD
@@ -167,63 +180,44 @@ DhcpQueryHWInfo(DWORD AdapterIndex,
PDWORD Mtu,
PDWORD Speed)
{
COMM_DHCP_REQ Req;
COMM_DHCP_REPLY Reply;
DWORD BytesRead;
BOOL Result;
DWORD ret;
ASSERT(PipeHandle != INVALID_HANDLE_VALUE);
DPRINT("DhcpQueryHWInfo()\n");
Req.Type = DhcpReqQueryHWInfo;
Req.AdapterIndex = AdapterIndex;
Result = TransactNamedPipe(PipeHandle,
&Req, sizeof(Req),
&Reply, sizeof(Reply),
&BytesRead, NULL);
if (!Result)
RpcTryExcept
{
/* Pipe transaction failed */
return 0;
ret = Client_QueryHWInfo(NULL, AdapterIndex, MediaType, Mtu, Speed);
}
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
{
ret = I_RpcMapWin32Status(RpcExceptionCode());
}
RpcEndExcept;
if (Reply.Reply == 0)
return 0;
*MediaType = Reply.QueryHWInfo.MediaType;
*Mtu = Reply.QueryHWInfo.Mtu;
*Speed = Reply.QueryHWInfo.Speed;
return 1;
return (ret == ERROR_SUCCESS) ? 1 : 0;
}
DWORD APIENTRY
DWORD
APIENTRY
DhcpStaticRefreshParams(DWORD AdapterIndex,
DWORD Address,
DWORD Netmask)
{
COMM_DHCP_REQ Req;
COMM_DHCP_REPLY Reply;
DWORD BytesRead;
BOOL Result;
DWORD ret;
ASSERT(PipeHandle != INVALID_HANDLE_VALUE);
DPRINT("DhcpStaticRefreshParams()\n");
Req.Type = DhcpReqStaticRefreshParams;
Req.AdapterIndex = AdapterIndex;
Req.Body.StaticRefreshParams.IPAddress = Address;
Req.Body.StaticRefreshParams.Netmask = Netmask;
Result = TransactNamedPipe(PipeHandle,
&Req, sizeof(Req),
&Reply, sizeof(Reply),
&BytesRead, NULL);
if (!Result)
RpcTryExcept
{
/* Pipe transaction failed */
return 0;
ret = Client_StaticRefreshParams(NULL, AdapterIndex, Address, Netmask);
}
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
{
ret = I_RpcMapWin32Status(RpcExceptionCode());
}
RpcEndExcept;
return Reply.Reply;
return (ret == ERROR_SUCCESS) ? 1 : 0;
}
/*!
@@ -378,7 +372,7 @@ ServiceMain(DWORD argc, LPWSTR* argv)
UpdateServiceStatus(SERVICE_START_PENDING);
hPipeThread = PipeInit(hStopEvent);
hPipeThread = InitRpc();
if (hPipeThread == INVALID_HANDLE_VALUE)
{
DbgPrint("DHCPCSVC: PipeInit() failed!\n");
@@ -393,6 +387,7 @@ ServiceMain(DWORD argc, LPWSTR* argv)
if (hDiscoveryThread == INVALID_HANDLE_VALUE)
{
DbgPrint("DHCPCSVC: StartAdapterDiscovery() failed!\n");
ShutdownRpc();
stop_client();
CloseHandle(hAdapterStateChangedEvent);
CloseHandle(hStopEvent);
@@ -411,6 +406,7 @@ ServiceMain(DWORD argc, LPWSTR* argv)
DH_DbgPrint(MID_TRACE,("DHCPCSVC: DHCP service is shutting down\n"));
ShutdownRpc();
stop_client();
DPRINT("Wait for pipe thread to close! %p\n", hPipeThread);

View File

@@ -13,7 +13,9 @@
#define NTOS_MODE_USER
#include <ndk/rtlfuncs.h>
#include <dhcpcsdk.h>
#include <rosdhcp_pipe.h>
#include <rpc.h>
#include <dhcpcsvc_c.h>
#include <dhcpcsvc_s.h>
#include "debug.h"
@@ -76,8 +78,6 @@ typedef struct _DHCP_ADAPTER {
unsigned char recv_buf[1];
} DHCP_ADAPTER, *PDHCP_ADAPTER;
typedef DWORD (*PipeSendFunc)(HANDLE CommPipe, COMM_DHCP_REPLY *Reply );
#define random rand
#define srandom srand
@@ -93,16 +93,12 @@ extern PDHCP_ADAPTER AdapterFindIndex( unsigned int AdapterIndex );
extern PDHCP_ADAPTER AdapterFindName(const WCHAR *name);
extern PDHCP_ADAPTER AdapterFindInfo( struct interface_info *info );
extern PDHCP_ADAPTER AdapterFindByHardwareAddress( u_int8_t haddr[16], u_int8_t hlen );
extern HANDLE PipeInit(HANDLE hStopEvent);
extern HANDLE InitRpc(VOID);
extern VOID ShutdownRpc(VOID);
extern VOID ApiInit(VOID);
extern VOID ApiFree(VOID);
extern VOID ApiLock(VOID);
extern VOID ApiUnlock(VOID);
extern DWORD DSAcquireParams(PipeSendFunc Send, HANDLE CommPipe, COMM_DHCP_REQ *Req);
extern DWORD DSReleaseParams(PipeSendFunc Send, HANDLE CommPipe, COMM_DHCP_REQ *Req);
extern DWORD DSQueryHWInfo( PipeSendFunc Send, HANDLE CommPipe, COMM_DHCP_REQ *Req );
extern DWORD DSStaticRefreshParams( PipeSendFunc Send, HANDLE CommPipe, COMM_DHCP_REQ *Req );
extern DWORD DSGetAdapterInfo( PipeSendFunc Send, HANDLE CommPipe, COMM_DHCP_REQ *Req );
extern int inet_aton(const char *s, struct in_addr *addr);
int warn( char *format, ... );

View File

@@ -1,50 +0,0 @@
#ifndef ROSDHCP_PIPE_H
#define ROSDHCP_PIPE_H
enum {
DhcpReqAcquireParams,
DhcpReqReleaseParams,
DhcpReqQueryHWInfo,
DhcpReqStaticRefreshParams,
};
typedef struct _COMM_DHCP_REQ {
UINT Type;
DWORD AdapterIndex;
union
{
struct
{
WCHAR AdapterName[45];
} AcquireParams;
struct {
BOOL Inserted;
} PnpEvent;
struct {
LPWSTR AdapterName;
DHCPCAPI_PARAMS_ARRAY Params;
} RegisterParamChange;
struct {
LPWSTR AdapterName;
LPWSTR RequestId;
} RequestParams, UndoRequestParams;
struct {
DWORD IPAddress;
DWORD Netmask;
} StaticRefreshParams;
} Body;
} COMM_DHCP_REQ;
typedef union _COMM_DHCP_REPLY {
DWORD Reply;
struct {
DWORD AdapterIndex;
DWORD MediaType;
DWORD Mtu;
DWORD Speed;
} QueryHWInfo;
} COMM_DHCP_REPLY;
#define DHCP_PIPE_NAME L"\\\\.\\pipe\\dhcpclient"
#endif/*ROSDHCP_PIPE_H*/

View File

@@ -0,0 +1,55 @@
/*
* DHCP Client service interface definition
*/
#include <ms-dtyp.idl>
typedef [handle] wchar_t *PDHCP_SERVER_NAME;
[
uuid(6BFFD098-A112-3610-9833-012892020162),
version(0.0),
pointer_default(unique),
#ifdef __midl
ms_union,
#endif
endpoint("ncacn_np:[\\pipe\\dhcpcsvc]")
#ifndef __midl
,explicit_handle
#endif
]
interface dhcpcsvc
{
/* Function 0 */
DWORD
__stdcall
AcquireParameters(
[in, string, unique] PDHCP_SERVER_NAME ServerName,
[in, string] LPWSTR AdapterName);
/* Function 1 */
DWORD
__stdcall
ReleaseParameters(
[in, string, unique] PDHCP_SERVER_NAME ServerName,
[in, string] LPWSTR AdapterName);
/* Function 2 */
DWORD
__stdcall
QueryHWInfo(
[in, string, unique] PDHCP_SERVER_NAME ServerName,
[in] DWORD AdapterIndex,
[out] PDWORD MediaType,
[out] PDWORD Mtu,
[out] PDWORD Speed);
/* Function 3 */
DWORD
__stdcall
StaticRefreshParams(
[in, string, unique] PDHCP_SERVER_NAME ServerName,
[in] DWORD AdapterIndex,
[in] DWORD Address,
[in] DWORD Netmask);
}