/// <summary>
        ///  The NetrLogonGetDomainInfo method Supported in windows_2000_server,
        ///  windows_xp, windows_server_2003, windows_vista, and
        ///  windows_server_2008, windows_7, and windows_server_7.
        ///  returns information that describes the current domain
        ///  to which the specified client belongs. Opnum: 29 
        /// </summary>
        /// <param name="ServerName">
        ///  The custom RPC binding handle, as specified in section
        ///  .
        /// </param>
        /// <param name="ComputerName">
        ///  The null-terminated Unicode string that contains the
        ///  name of the client computer issuing the request.
        /// </param>
        /// <param name="Authenticator">
        ///  A pointer to a NETLOGON_AUTHENTICATOR structure, as
        ///  specified in section , that contains the client authenticator.
        /// </param>
        /// <param name="ReturnAuthenticator">
        ///  A pointer to a NETLOGON_AUTHENTICATOR structure, as
        ///  specified in section , that contains the server return
        ///  authenticator.
        /// </param>
        /// <param name="Level">
        ///  The information level requested by the client. The buffer
        ///  contains one of the following structures, based on
        ///  the value of this field.
        /// </param>
        /// <param name="WkstaBuffer">
        ///  A pointer to a NETLOGON_WORKSTATION_INFORMATION structure,
        ///  as specified in section , that contains information
        ///  about the client workstation.
        /// </param>
        /// <param name="DomBuffer">
        ///  A pointer to a NETLOGON_DOMAIN_INFORMATION structure,
        ///  as specified in section , that contains information
        ///  about the domain or policy information.
        /// </param>
        public NtStatus NetrLogonGetDomainInfo(
            string ServerName,
            string ComputerName,
            _NETLOGON_AUTHENTICATOR? Authenticator,
            ref _NETLOGON_AUTHENTICATOR? ReturnAuthenticator,
            Level_Values Level,
            _NETLOGON_WORKSTATION_INFORMATION? WkstaBuffer,
            out _NETLOGON_DOMAIN_INFORMATION? DomBuffer)
        {
            const ushort opnum = 29;

            byte[] requestStub;
            byte[] responseStub;
            Int3264[] paramList;
            int retVal;

            SafeIntPtr pServerName = Marshal.StringToHGlobalUni(ServerName);
            SafeIntPtr pComputerName = Marshal.StringToHGlobalUni(ComputerName);
            SafeIntPtr pAuthenticator = TypeMarshal.ToIntPtr(Authenticator);
            SafeIntPtr pReturnAuthenticatorIn = TypeMarshal.ToIntPtr(ReturnAuthenticator);
            SafeIntPtr pWkstaBuffer = TypeMarshal.ToIntPtr(WkstaBuffer, Level, null, null);

            paramList = new Int3264[] {
                pServerName,
                pComputerName,
                pAuthenticator,
                pReturnAuthenticatorIn,
                (uint)Level,
                pWkstaBuffer,
                IntPtr.Zero,
                0 // retVal
            };

            requestStub = RpceStubEncoder.ToBytes(
                     RpceStubHelper.GetPlatform(),
                    NrpcRpcStubFormatString.TypeFormatString,
                    new RpceStubExprEval[] { new RpceStubExprEval(logon__NETLOGON_DELTA_USERExprEval_0000) },
                    NrpcRpcStubFormatString.ProcFormatString,
                    NrpcRpcStubFormatString.ProcFormatStringOffsetTable[opnum],
                    true,
                    paramList);

            rpceClientTransport.Call(opnum, requestStub, rpceTimeout, out responseStub);

            using (RpceInt3264Collection outParamList = RpceStubDecoder.ToParamList(
                     RpceStubHelper.GetPlatform(),
                    NrpcRpcStubFormatString.TypeFormatString,
                    new RpceStubExprEval[] { new RpceStubExprEval(logon__NETLOGON_DELTA_USERExprEval_0000) },
                    NrpcRpcStubFormatString.ProcFormatString,
                    NrpcRpcStubFormatString.ProcFormatStringOffsetTable[opnum],
                    true,
                    responseStub,
                    paramList))
            {
                IntPtr pReturnAuthenticatorOut = outParamList[3];
                ReturnAuthenticator = TypeMarshal.ToNullableStruct<_NETLOGON_AUTHENTICATOR>(pReturnAuthenticatorOut);

                IntPtr pDomBuffer = outParamList[6];
                DomBuffer = TypeMarshal.ToNullableStruct<_NETLOGON_DOMAIN_INFORMATION>(
                    pDomBuffer,
                    Level,
                    null,
                    null);

                retVal = outParamList[7].ToInt32();
            }

            pServerName.Dispose();
            pComputerName.Dispose();
            pAuthenticator.Dispose();
            pReturnAuthenticatorIn.Dispose();
            pWkstaBuffer.Dispose();

            return (NtStatus)retVal;
        }
        public _NETLOGON_WORKSTATION_INFORMATION CreateNetlogonWorkstationInformation(
            Level_Values level,
            string dnsHostName,
            string siteName,
            OSVERSIONINFOEX? osVersion,
            string osName,
            NrpcWorkstationFlags workstationFlags,
            uint kerberosSupportedEncryptionTypes)
        {
            _NETLOGON_WORKSTATION_INFORMATION netlogonWorkstationInfo = new _NETLOGON_WORKSTATION_INFORMATION();

            //TODO: TDI 48704: 3.5.5.3.9 said:
            //The WkstaBuffer parameter contains one of the following structures,
            //based on the value of level field. Value Meaning
            //0x00000001: The WkstaBuffer contains a NETLOGON_DOMAIN_INFO structure.
            //0x00000002: The WkstaBuffer contains a NETLOGON_LSA_POLICY_INFO structure.
            //
            //But in 2.2.1.3.9,
            //union _NETLOGON_WORKSTATION_INFORMATION {
            //  [case(1)]
            //  PNETLOGON_WORKSTATION_INFO WorkstationInfo;
            //  [case(2)]
            //  PNETLOGON_WORKSTATION_INFO LsaPolicyInfo;
            //}

            switch (level)
            {
                case Level_Values.NetlogonDomainInfo:
                    netlogonWorkstationInfo.WorkstationInfo = new _NETLOGON_WORKSTATION_INFO[1];
                    netlogonWorkstationInfo.WorkstationInfo[0] = new _NETLOGON_WORKSTATION_INFO();
                    netlogonWorkstationInfo.WorkstationInfo[0].DnsHostName = dnsHostName;
                    netlogonWorkstationInfo.WorkstationInfo[0].SiteName = siteName;
                    netlogonWorkstationInfo.WorkstationInfo[0].Dummy1 = null;
                    netlogonWorkstationInfo.WorkstationInfo[0].Dummy2 = null;
                    netlogonWorkstationInfo.WorkstationInfo[0].Dummy3 = null;
                    netlogonWorkstationInfo.WorkstationInfo[0].Dummy4 = null;
                    if (osVersion != null)
                    {
                        const int CSD_VERSION_LENGTH = 256;
                        if (osVersion.Value.OSVersionInfo.szCSDVersion == null)
                        {
                            throw new ArgumentException("szCSDVersion of osVersion cannot be null.", "osVersion");
                        }
                        if (osVersion.Value.OSVersionInfo.szCSDVersion.Length != CSD_VERSION_LENGTH / sizeof(ushort))
                        {
                            throw new ArgumentException("Length of szCSDVersion should be 256 bytes.", "osVersion");
                        }

                        netlogonWorkstationInfo.WorkstationInfo[0].OsVersion
                            = DtypUtility.ToRpcUnicodeString(
                                Encoding.Unicode.GetString(TypeMarshal.ToBytes(osVersion.Value)));
                    }
                    else
                    {
                        netlogonWorkstationInfo.WorkstationInfo[0].OsVersion
                            = DtypUtility.ToRpcUnicodeString(null);
                    }
                    netlogonWorkstationInfo.WorkstationInfo[0].OsName
                        = DtypUtility.ToRpcUnicodeString(osName);
                    netlogonWorkstationInfo.WorkstationInfo[0].DummyString3
                        = DtypUtility.ToRpcUnicodeString((string)null);
                    netlogonWorkstationInfo.WorkstationInfo[0].DummyString4
                        = DtypUtility.ToRpcUnicodeString((string)null);
                    netlogonWorkstationInfo.WorkstationInfo[0].WorkstationFlags
                        = (uint)workstationFlags;
                    netlogonWorkstationInfo.WorkstationInfo[0].KerberosSupportedEncryptionTypes
                        = kerberosSupportedEncryptionTypes;
                    netlogonWorkstationInfo.WorkstationInfo[0].DummyLong3 = 0;
                    netlogonWorkstationInfo.WorkstationInfo[0].DummyLong4 = 0;
                    break;

                case Level_Values.NetlogonLsaPolicyInfo:
                    netlogonWorkstationInfo.LsaPolicyInfo = new _NETLOGON_WORKSTATION_INFO[1];
                    netlogonWorkstationInfo.LsaPolicyInfo[0] = new _NETLOGON_WORKSTATION_INFO();
                    netlogonWorkstationInfo.LsaPolicyInfo[0].LsaPolicy = new _NETLOGON_LSA_POLICY_INFO();
                    netlogonWorkstationInfo.LsaPolicyInfo[0].LsaPolicy.LsaPolicy = new byte[0];
                    netlogonWorkstationInfo.LsaPolicyInfo[0].LsaPolicy.LsaPolicySize = 0;
                    break;

                default:
                    throw new ArgumentException("level is invalid.", "level");
            }

            return netlogonWorkstationInfo;
        }
 /// <summary>
 ///  Decodes the request stub, and fills the fields of the class
 /// </summary>
 /// <param name="sessionContext">The session context of the request received</param>
 /// <param name="requestStub">The request stub got from RPCE layer</param>
 internal override void Decode(NrpcServerSessionContext sessionContext, byte[] requestStub)
 {
     using (RpceInt3264Collection outParamList = RpceStubDecoder.ToParamList(
       RpceStubHelper.GetPlatform(),
         NrpcRpcStubFormatString.TypeFormatString,
         new RpceStubExprEval[] {
             new RpceStubExprEval(NrpcRpcAdapter.logon__NETLOGON_DELTA_USERExprEval_0000) },
         NrpcRpcStubFormatString.ProcFormatString,
         NrpcRpcStubFormatString.ProcFormatStringOffsetTable[(int)Opnum],
         false,
         requestStub))
     {
         ServerName = Marshal.PtrToStringUni(outParamList[0]);
         ComputerName = Marshal.PtrToStringUni(outParamList[1]);
         Authenticator = TypeMarshal.ToNullableStruct<_NETLOGON_AUTHENTICATOR>(outParamList[2]);
         ReturnAuthenticator = TypeMarshal.ToNullableStruct<_NETLOGON_AUTHENTICATOR>(outParamList[3]);
         Level = (Level_Values)outParamList[4].ToUInt32();
         WkstaBuffer = TypeMarshal.ToNullableStruct<_NETLOGON_WORKSTATION_INFORMATION>(outParamList[5], Level, null, null);
     }
 }
        /// <summary>
        ///  The NetrLogonGetDomainInfo method Supported in windows_2000_server,
        ///  windows_xp, windows_server_2003, windows_vista, and
        ///  windows_server_2008, windows_7, and windows_server_7.
        ///  returns information that describes the current domain
        ///  to which the specified client belongs. Opnum: 29 
        /// </summary>
        /// <param name="serverName">
        ///  The custom RPC binding handle.
        /// </param>
        /// <param name="computerName">
        ///  The null-terminated Unicode string that contains the
        ///  name of the client computer issuing the request.
        /// </param>
        /// <param name="authenticator">
        ///  A pointer to a NETLOGON_AUTHENTICATOR structure, 
        ///  that contains the client authenticator.
        /// </param>
        /// <param name="returnAuthenticator">
        ///  A pointer to a NETLOGON_AUTHENTICATOR structure, 
        ///  that contains the server return
        ///  authenticator.
        /// </param>
        /// <param name="level">
        ///  The information level requested by the client. The buffer
        ///  contains one of the following structures, based on
        ///  the value of this field.
        /// </param>
        /// <param name="wkstaBuffer">
        ///  A pointer to a NETLOGON_WORKSTATION_INFORMATION structure,
        ///  that contains information
        ///  about the client workstation.
        /// </param>
        /// <param name="domBuffer">
        ///  A pointer to a NETLOGON_DOMAIN_INFORMATION structure,
        ///  that contains information
        ///  about the domain or policy information.
        /// </param>
        /// <returns>
        /// The method returns 0x00000000 on success; 
        /// otherwise, it returns a nonzero error code.
        /// </returns>
        public NtStatus NetrLogonGetDomainInfo(
            string serverName,
            string computerName,
            _NETLOGON_AUTHENTICATOR? authenticator,
            ref _NETLOGON_AUTHENTICATOR? returnAuthenticator,
            Level_Values level,
            _NETLOGON_WORKSTATION_INFORMATION? wkstaBuffer,
            out _NETLOGON_DOMAIN_INFORMATION? domBuffer)
        {
            NtStatus status = rpc.NetrLogonGetDomainInfo(
                serverName,
                computerName,
                authenticator,
                ref returnAuthenticator,
                level,
                wkstaBuffer,
                out domBuffer);

            context.ConnectionStatus = status;
            return status;
        }