コード例 #1
0
ファイル: CalloutNative.cs プロジェクト: gbachs/DhcpServerApi
        private static uint HandleChainDlls(IntPtr ChainDlls, uint CalloutVersion)
        {
            // ChainDlls is in REG_MULTI_SZ format (non-empty strings separated by null, terminated with an additional null)
            // read next dll in chain
            var chainDllPath = Marshal.PtrToStringUni(ChainDlls);

            // check if no dlls (or we are the last in the chain)
            if (chainDllPath == null || chainDllPath.Length == 0)
            {
                ChainTable = new DHCP_CALLOUT_TABLE();
                return(ERROR_SUCCESS);
            }

            // ensure dll exists
            if (!File.Exists(chainDllPath))
            {
                return(0x2); // FILE_NOT_FOUND
            }

            // load dll
            ChainLibraryHandle = Win32Api.LoadLibrary(chainDllPath);
            if (ChainLibraryHandle == IntPtr.Zero)
            {
                return((uint)Marshal.GetLastWin32Error());
            }

            // locate DhcpServerCalloutEntry export
            var chainCalloutEntryAddress = Win32Api.GetProcAddress(ChainLibraryHandle, "DhcpServerCalloutEntry");

            if (chainCalloutEntryAddress == IntPtr.Zero)
            {
                return((uint)Marshal.GetLastWin32Error());
            }

            // prepare arguments
            var chainCalloutEntryDelegate = (DhcpServerCalloutEntryDelegate)Marshal.GetDelegateForFunctionPointer
                                                (chainCalloutEntryAddress, typeof(DhcpServerCalloutEntryDelegate));

            // ChainDlls should pass a pointer to the next dll (or the final termination null)
            var chainDllsNext = ChainDlls + Encoding.Unicode.GetByteCount(chainDllPath) + 2;
            var calloutTbl    = new DHCP_CALLOUT_TABLE();

            // call chain dll
            var subsequentResult = chainCalloutEntryDelegate(chainDllsNext, CalloutVersion, ref calloutTbl);

            if (subsequentResult != ERROR_SUCCESS)
            {
                return(subsequentResult);
            }

            // store chain dll's callout table
            ChainTable = calloutTbl;

            return(ERROR_SUCCESS);
        }
コード例 #2
0
ファイル: CalloutNative.cs プロジェクト: gbachs/DhcpServerApi
        private static uint DeriveHooks(ref DHCP_CALLOUT_TABLE CalloutTbl)
        {
            // always hook control
            CalloutTbl.DhcpControlHook = new DhcpControlHookUnsafeDelegate(HandleControlHook);

            // NewPkt
            if (ConsumerRequirements.HasFlag(CalloutConsumerSupportFlags.NewPacket))
            {
                // consumer required
                CalloutTbl.DhcpNewPktHook = new DhcpNewPktHookUnsafeDelegate(HandleNewPktHook);
            }
            else if (ChainTable.DhcpNewPktHook != null)
            {
                // only chain required
                CalloutTbl.DhcpNewPktHook = ChainTable.DhcpNewPktHook;
            }
            else
            {
                CalloutTbl.DhcpNewPktHook = null;
            }

            // PktDrop
            if (ConsumerRequirements.HasFlag(CalloutConsumerSupportFlags.PacketDrop))
            {
                // consumer required
                CalloutTbl.DhcpPktDropHook = new DhcpPktDropHookUnsafeDelegate(HandleDhcpPktDropHook);
            }
            else if (ChainTable.DhcpPktDropHook != null)
            {
                // only chain required
                CalloutTbl.DhcpPktDropHook = ChainTable.DhcpPktDropHook;
            }
            else
            {
                CalloutTbl.DhcpPktDropHook = null;
            }

            // PktSend
            if (ConsumerRequirements.HasFlag(CalloutConsumerSupportFlags.PacketSend))
            {
                // consumer required
                CalloutTbl.DhcpPktSendHook = new DhcpPktSendHookUnsafeDelegate(HandlePktSendHook);
            }
            else if (ChainTable.DhcpPktSendHook != null)
            {
                // only chain required
                CalloutTbl.DhcpPktSendHook = ChainTable.DhcpPktSendHook;
            }
            else
            {
                CalloutTbl.DhcpPktSendHook = null;
            }

            // AddressDel
            if (ConsumerRequirements.HasFlag(CalloutConsumerSupportFlags.AddressDelete))
            {
                // consumer required
                CalloutTbl.DhcpAddressDelHook = new DhcpAddressDelHookUnsafeDelegate(HandleAddressDelHook);
            }
            else if (ChainTable.DhcpAddressDelHook != null)
            {
                // only chain required
                CalloutTbl.DhcpAddressDelHook = ChainTable.DhcpAddressDelHook;
            }
            else
            {
                CalloutTbl.DhcpAddressDelHook = null;
            }

            // AddressOffer
            if (ConsumerRequirements.HasFlag(CalloutConsumerSupportFlags.AddressOffer))
            {
                // consumer required
                CalloutTbl.DhcpAddressOfferHook = new DhcpAddressOfferHookUnsafeDelegate(HandleAddressOfferHook);
            }
            else if (ChainTable.DhcpAddressOfferHook != null)
            {
                // only chain required
                CalloutTbl.DhcpAddressOfferHook = ChainTable.DhcpAddressOfferHook;
            }
            else
            {
                CalloutTbl.DhcpAddressOfferHook = null;
            }

            // HandleOptions
            // Hook is only derived if the ApiVersion is 0 (as the ServerOptions could change if the version is incremented).
            if (ApiVersion == 0 && ConsumerRequirements.HasFlag(CalloutConsumerSupportFlags.HandleOptions))
            {
                // consumer required
                CalloutTbl.DhcpHandleOptionsHook = new DhcpHandleOptionsHookUnsafeDelegate(HandleHandleOptionsHook);
            }
            else if (ChainTable.DhcpHandleOptionsHook != null)
            {
                // only chain required
                CalloutTbl.DhcpHandleOptionsHook = ChainTable.DhcpHandleOptionsHook;
            }
            else
            {
                CalloutTbl.DhcpHandleOptionsHook = null;
            }

            // DeleteClient
            if (ConsumerRequirements.HasFlag(CalloutConsumerSupportFlags.DeleteClient))
            {
                // consumer required
                CalloutTbl.DhcpDeleteClientHook = new DhcpDeleteClientHookUnsafeDelegate(HandleDeleteClientHook);
            }
            else if (ChainTable.DhcpDeleteClientHook != null)
            {
                // only chain required
                CalloutTbl.DhcpDeleteClientHook = ChainTable.DhcpDeleteClientHook;
            }
            else
            {
                CalloutTbl.DhcpDeleteClientHook = null;
            }

            // Extension - not supported by DhcpServerAPI
            if (ChainTable.DhcpExtensionHook != IntPtr.Zero)
            {
                CalloutTbl.DhcpExtensionHook = ChainTable.DhcpExtensionHook;
            }
            else
            {
                CalloutTbl.DhcpExtensionHook = IntPtr.Zero;
            }

            // Reserved - not supported by DhcpServerAPI
            if (ChainTable.DhcpReservedHook != IntPtr.Zero)
            {
                CalloutTbl.DhcpReservedHook = ChainTable.DhcpReservedHook;
            }
            else
            {
                CalloutTbl.DhcpReservedHook = IntPtr.Zero;
            }

            return(ERROR_SUCCESS);
        }
コード例 #3
0
ファイル: CalloutNative.cs プロジェクト: gbachs/DhcpServerApi
        private static uint DhcpServerCalloutEntry(IntPtr ChainDlls, uint CalloutVersion, ref DHCP_CALLOUT_TABLE CalloutTbl)
        {
            AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;

            ApiVersion = CalloutVersion;

            // locate and initialize consumers
            var initConsumersResult = InitializeConsumers();

            if (initConsumersResult != ERROR_SUCCESS)
            {
                return(initConsumersResult);
            }

            // chain subsequent dll
            var chainDllResult = HandleChainDlls(ChainDlls, CalloutVersion);

            if (chainDllResult != ERROR_SUCCESS)
            {
                return(chainDllResult);
            }

            // derive hooks
            var deriveResult = DeriveHooks(ref CalloutTbl);

            if (deriveResult != ERROR_SUCCESS)
            {
                return(deriveResult);
            }

            return(ERROR_SUCCESS);
        }