Ejemplo n.º 1
0
        /// <summary>
        /// SWN client invoke WitnessrRegister to register for resource state change notifications of a NetName and IPAddress.
        /// </summary>
        /// <param name="Version">The version of the Witness protocol currently in use by the client.</param>
        /// <param name="NetName">Specifies a null-terminated string that specifies the name of the resource for which the client requires notifications.</param>
        /// <param name="IpAddr">Specifies a null-terminated string that specifies the IP address to which the client application connection is established.</param>
        /// <param name="ClientName">Specifies a null-terminated string that is used to identify the Witness client.</param>
        /// <param name="pContext">A context handle to identifies the client on the server. </param>
        /// <returns>Return zero if success, otherwise return nonzero.</returns>
        public int WitnessrRegister(SwnVersion Version, string NetName, string IpAddr, string ClientName, out IntPtr pContext)
        {
            Int3264[] paramList;
            int       retVal = 0;

            SafeIntPtr pNetName    = Marshal.StringToHGlobalUni(NetName);
            SafeIntPtr pIpAddr     = Marshal.StringToHGlobalUni(IpAddr);
            SafeIntPtr pClientName = Marshal.StringToHGlobalUni(ClientName);

            paramList = new Int3264[] {
                IntPtr.Zero,//out param
                (uint)Version,
                pNetName,
                pIpAddr,
                pClientName,
                IntPtr.Zero //return value
            };

            try
            {
                using (RpceInt3264Collection outParamList = RpceCall(paramList, (ushort)SWN_OPNUM.WitnessrRegister))
                {
                    pContext = Marshal.ReadIntPtr(outParamList[0]);
                    retVal   = outParamList[paramList.Length - 1].ToInt32();
                }
            }
            finally
            {
                pNetName.Dispose();
                pIpAddr.Dispose();
                pClientName.Dispose();
            }

            return(retVal);
        }
 internal override byte[] EncodeBuffer()
 {
     using (SafeIntPtr ptr = TypeMarshal.ToIntPtr(NativeClaimsSetMetadata))
     {
         return(PacUtility.NdrMarshal(ptr, FormatString.OffsetClientClaim));
     }
 }
        /// <summary>
        /// This call waits until all the shadowcopy preparation is done on the file server.
        /// It is used to avoid the long preparation time on file server break the
        /// 60 seconds freeze/thaw window on the application server
        /// It must be called between the last AddToShadowCopySet and CommitShadowCopySet
        /// </summary>
        /// <param name="ShadowCopySetId">The GUID of shadow copy set</param>
        /// <param name="TimeOutInMilliseconds">The maximum total time in milliseconds for which the server MUST wait for the expose operation.</param>
        /// <returns></returns>
        public int PrepareShadowCopySet(
            Guid ShadowCopySetId,
            uint TimeOutInMilliseconds
            )
        {
            Int3264[] paramList;
            int       retVal = 0;

            SafeIntPtr pShadowCopySetId = TypeMarshal.ToIntPtr(ShadowCopySetId);

            paramList = new Int3264[] {
                pShadowCopySetId,
                TimeOutInMilliseconds,
                IntPtr.Zero
            };

            try
            {
                using (RpceInt3264Collection outParamList = RpceCall(paramList, (ushort)FSRVP_OPNUM.PrepareShadowCopySet))
                {
                    retVal = outParamList[2].ToInt32();
                }
            }
            finally
            {
                pShadowCopySetId.Dispose();
            }

            return(retVal);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// The NetrShareGetInfo method retrieves information about a particular shared resource on the server from the ShareList.
        /// </summary>
        /// <param name="ServerName">A string that identifies the server. If this parameter is NULL, the local computer is used.</param>
        /// <param name="NetName">The name of the share to return information for.</param>
        /// <param name="Level">Specifies the information level of the data. This parameter MUST be one of the following values.</param>
        /// <param name="InfoStruct">Its contents are determined by the value of the Level parameter, as shown in the preceding table.</param>
        /// <returns>The method returns 0x00000000 (NERR_Success) to indicate success; otherwise, it returns a nonzero error code.</returns>
        public uint NetrShareGetInfo(string ServerName, string NetName, SHARE_ENUM_STRUCT_LEVEL Level, out SHARE_INFO?InfoStruct)
        {
            /*
             * NET_API_STATUS NetrShareGetInfo(
             * [in, string, unique] SRVSVC_HANDLE ServerName,
             * [in, string] WCHAR* NetName,
             * [in] DWORD Level,
             * [out, switch_is(Level)] LPSHARE_INFO InfoStruct
             * );
             */
            Int3264[] paramList;
            uint      retVal = 0;

            InfoStruct = null;
            using (SafeIntPtr pServerName = Marshal.StringToHGlobalUni(ServerName), pNetName = Marshal.StringToHGlobalUni(NetName))
            {
                paramList = new Int3264[] {
                    pServerName,
                    pNetName,
                    (uint)Level,
                    IntPtr.Zero, // out value
                    IntPtr.Zero  // return value
                };
                using (RpceInt3264Collection outParamList = RpceCall(paramList, (ushort)SRVS_OPNUM.NetrShareGetInfo))
                {
                    retVal = outParamList[paramList.Length - 1].ToUInt32();
                    if (retVal == (uint)Win32ErrorCode_32.ERROR_SUCCESS)
                    {
                        InfoStruct = TypeMarshal.ToStruct <SHARE_INFO>(outParamList[3], Level, null, null);
                    }
                }
            }
            return(retVal);
        }
 /// <summary>
 /// Encode the instance of current class into byte array,
 /// according to TD specification.
 /// </summary>
 /// <returns>The encoded byte array</returns>
 internal override byte[] EncodeBuffer()
 {
     using (SafeIntPtr ptr = TypeMarshal.ToIntPtr(NativeS4uDelegationInfo))
     {
         return(PacUtility.NdrMarshal(ptr, FormatString.OffsetS4u));
     }
 }
        /// <summary>
        /// The IsPathShadowCopied method is invoked by the client to query if any shadow copy for a share already exists.
        /// </summary>
        /// <param name="ShareName">The full path of the share in UNC format.</param>
        /// <param name="ShadowCopyPresent">On output, a Boolean, when set to TRUE, indicates that shadow
        /// copies of this share are supported by the server.</param>
        /// <param name="ShadowCopyCompatibility">On output, this indicates whether certain I/O operations on the object
        /// store containing the shadow copy are disabled. This MUST be zero or a combination of the values
        /// as specified in section 2.2.2.2.</param>
        /// <returns></returns>
        public int IsPathShadowCopied(
            string ShareName,
            out bool ShadowCopyPresent,
            out long ShadowCopyCompatibility)
        {
            Int3264[] paramList;
            int       retVal = 0;

            SafeIntPtr pShareName = Marshal.StringToHGlobalUni(ShareName);

            paramList = new Int3264[] {
                pShareName,
                IntPtr.Zero,
                IntPtr.Zero,
                IntPtr.Zero
            };

            try
            {
                using (RpceInt3264Collection outParamList = RpceCall(paramList, (ushort)FSRVP_OPNUM.IsPathShadowCopied))
                {
                    retVal                  = outParamList[paramList.Length - 1].ToInt32();
                    ShadowCopyPresent       = TypeMarshal.ToStruct <bool>(outParamList[1]);
                    ShadowCopyCompatibility = Marshal.ReadInt32(outParamList[2]);
                    retVal                  = outParamList[3].ToInt32();
                }
            }
            finally
            {
                pShareName.Dispose();
            }

            return(retVal);
        }
        /// <summary>
        /// The DeleteShareMapping method deletes the mapping of a share’s shadow copy from a shadow copy set.
        /// </summary>
        /// <param name="ShadowCopySetId">The GUID of the shadow copy set.</param>
        /// <param name="ShadowCopyId">The GUID of the shadow copy associated with the share.</param>
        /// <param name="ShareName">The name of the share for which the share mapping is to be deleted.</param>
        /// <returns></returns>
        public int DeleteShareMapping(
            Guid ShadowCopySetId,
            Guid ShadowCopyId,
            string ShareName)
        {
            Int3264[] paramList;
            int       retVal = 0;

            SafeIntPtr pShadowCopySetId = TypeMarshal.ToIntPtr(ShadowCopySetId);
            SafeIntPtr pShadowCopyId    = TypeMarshal.ToIntPtr(ShadowCopyId);
            SafeIntPtr pShareName       = Marshal.StringToHGlobalUni(ShareName);

            paramList = new Int3264[] {
                pShadowCopySetId,
                pShadowCopyId,
                pShareName,
                IntPtr.Zero
            };

            try
            {
                using (RpceInt3264Collection outParamList = RpceCall(paramList, (ushort)FSRVP_OPNUM.DeleteShareMapping))
                {
                    retVal = outParamList[3].ToInt32();
                }
            }
            finally
            {
                pShadowCopySetId.Dispose();
                pShadowCopyId.Dispose();
                pShareName.Dispose();
            }

            return(retVal);
        }
        /// <summary>
        /// The IsPathSupported method is invoked by client to query if a given share is supported by the server
        /// for shadow copy operations.
        /// </summary>
        /// <param name="ShareName">The full path of the share in UNC format.</param>
        /// <param name="SupportedByThisProvider">On output, a Boolean, when set to TRUE, indicates that shadow
        /// copies of this share are supported by the server.</param>
        /// <param name="OwnerMachineName">On output, the name of the server machine to which the client MUST
        /// connect to create shadow copies of the specified ShareName.</param>
        /// <returns></returns>
        public int IsPathSupported(
            string ShareName,
            out bool SupportedByThisProvider,
            out string OwnerMachineName)
        {
            Int3264[] paramList;
            int       retVal = 0;

            SafeIntPtr pShareName = Marshal.StringToHGlobalUni(ShareName);

            paramList = new Int3264[] {
                pShareName,
                IntPtr.Zero,
                IntPtr.Zero,
                IntPtr.Zero
            };

            try
            {
                using (RpceInt3264Collection outParamList = RpceCall(paramList, (ushort)FSRVP_OPNUM.IsPathSupported))
                {
                    SupportedByThisProvider = TypeMarshal.ToStruct <bool>(outParamList[1]);//(Marshal.ReadInt32(outParamList[1]) == 1);
                    OwnerMachineName        = Marshal.PtrToStringUni(Marshal.ReadIntPtr(outParamList[2]));
                    retVal = outParamList[3].ToInt32();
                }
            }
            finally
            {
                pShareName.Dispose();
            }

            return(retVal);
        }
        /// <summary>
        /// The AbortShadowCopySet method is invoked by the client to delete a given shadow copy set on the server.
        /// </summary>
        /// <param name="ShadowCopySetId">The GUID of the shadow copy set to which ShareName is to be added.</param>
        /// <returns></returns>
        public int AbortShadowCopySet(Guid ShadowCopySetId)
        {
            Int3264[] paramList;
            int       retVal = 0;

            SafeIntPtr pShadowCopySetId = TypeMarshal.ToIntPtr(ShadowCopySetId);

            paramList = new Int3264[] {
                pShadowCopySetId,
                IntPtr.Zero
            };

            try
            {
                using (RpceInt3264Collection outParamList = RpceCall(paramList, (ushort)FSRVP_OPNUM.AbortShadowCopySet))
                {
                    retVal = outParamList[1].ToInt32();
                }
            }
            finally
            {
                pShadowCopySetId.Dispose();
            }

            return(retVal);
        }
        /// <summary>
        /// The StartShadowCopySet method is called by the client to initiate a new shadow copy set for shadow copy creation.
        /// </summary>
        /// <param name="pShadowCopySetId">On output, the GUID of the shadow copy set that must be created by server.</param>
        /// <returns></returns>
        public int StartShadowCopySet(
            Guid clientShadowCopySetId,
            out Guid pShadowCopySetId)
        {
            Int3264[] paramList;
            int       retVal = 0;

            SafeIntPtr pClientShadowCopySetId = TypeMarshal.ToIntPtr(clientShadowCopySetId);

            paramList = new Int3264[] {
                pClientShadowCopySetId,
                IntPtr.Zero,
                IntPtr.Zero
            };

            try
            {
                using (RpceInt3264Collection outParamList = RpceCall(paramList, (ushort)FSRVP_OPNUM.StartShadowCopySet))
                {
                    pShadowCopySetId = TypeMarshal.ToStruct <Guid>(outParamList[1]);
                    retVal           = outParamList[2].ToInt32();
                }
            }
            finally
            {
                pClientShadowCopySetId.Dispose();
            }

            return(retVal);
        }
        /// <summary>
        ///  The IDL_DSAExecuteScript method executes a maintenance script.
        ///  Opnum: 1
        /// </summary>
        /// <param name="hRpc">
        ///  The RPC binding handle, as specified in [C706].
        /// </param>
        /// <param name="dwInVersion">
        ///  The version of the request message.
        /// </param>
        /// <param name="pmsgIn">
        ///  A pointer to the request message.
        /// </param>
        /// <param name="pdwOutVersion">
        ///  A pointer to the version of the response message.
        /// </param>
        /// <param name="pmsgOut">
        ///  A pointer to the response message.
        /// </param>
        public uint IDL_DSAExecuteScript(
            IntPtr hRpc,
            uint dwInVersion,
            //[Switch("dwInVersion")]
            DSA_MSG_EXECUTE_SCRIPT_REQ?pmsgIn,
            out uint?pdwOutVersion,
            //[Switch("*pdwOutVersion")]
            out DSA_MSG_EXECUTE_SCRIPT_REPLY?pmsgOut)
        {
            const ushort opnum = 1;

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

            SafeIntPtr ptrMsgIn = TypeMarshal.ToIntPtr(pmsgIn, dwInVersion, null, null);

            paramList = new Int3264[]
            {
                dwInVersion,
                ptrMsgIn,
                IntPtr.Zero,
                IntPtr.Zero,
                0//retVal
            };

            requestStub = RpceStubEncoder.ToBytes(
                RpceStubHelper.GetPlatform(),
                DrsrRpcStubFormatString.TypeFormatString,
                null,
                DrsrRpcStubFormatString.ProcFormatString,
                DrsrRpcStubFormatString.Dsaop_ProcFormatStringOffsetTable[opnum],
                true,
                paramList);

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

            using (RpceInt3264Collection outParamList = RpceStubDecoder.ToParamList(
                       RpceStubHelper.GetPlatform(),
                       DrsrRpcStubFormatString.TypeFormatString,
                       null,
                       DrsrRpcStubFormatString.ProcFormatString,
                       DrsrRpcStubFormatString.Dsaop_ProcFormatStringOffsetTable[opnum],
                       true,
                       responseStub,
                       rpceClientTransport.Context.PackedDataRepresentationFormat,
                       paramList))
            {
                pdwOutVersion = TypeMarshal.ToNullableStruct <uint>(outParamList[2]);
                pmsgOut       = TypeMarshal.ToNullableStruct <DSA_MSG_EXECUTE_SCRIPT_REPLY>(
                    outParamList[3], pdwOutVersion, null, null);
                retVal = outParamList[4].ToUInt32();
            }

            ptrMsgIn.Dispose();

            return(retVal);
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Encrypt a PacCredentialData instance. The encrypted data
        /// can be accessed from SerializedData property.
        /// </summary>
        /// <param name="credentialData">The _PAC_CREDENTIAL_DATA instance to be encrypted.</param>
        /// <param name="key">The encrypt key.</param>
        public void Encrypt(_PAC_CREDENTIAL_DATA credentialData, byte[] key)
        {
            if (key == null)
            {
                throw new ArgumentNullException("key");
            }

            byte[] plain = null;
            using (SafeIntPtr ptr = TypeMarshal.ToIntPtr(credentialData))
            {
                plain = PacUtility.NdrMarshal(ptr, FormatString.OffsetCredentialData);
            }
            NativePacCredentialInfo.SerializedData = Encrypt(key, plain, NativePacCredentialInfo.EncryptionType);
        }
        /// <summary>
        /// The GetShareMapping method is invoked by the client to get the shadow copy information on a given
        /// file share on the server.
        /// </summary>
        /// <param name="ShadowCopyId">The GUID of the shadow copy associated with the share.</param>
        /// <param name="ShadowCopySetId">The GUID of the shadow copy set.</param>
        /// <param name="ShareName">The name of the share in UNC format.</param>
        /// <param name="Level">The format of this data depends on the value of the level parameter.</param>
        /// <param name="ShareMapping">On output, a FSSAGENT_SHARE_MAPPING structure, as specified in section 2.2.3.1.</param>
        /// <returns></returns>
        public int GetShareMapping(
            Guid ShadowCopyId,
            Guid ShadowCopySetId,
            string ShareName,
            uint Level,
            out FSSAGENT_SHARE_MAPPING ShareMapping)
        {
            Int3264[] paramList;
            int       retVal = 0;

            SafeIntPtr pShadowCopyId    = TypeMarshal.ToIntPtr(ShadowCopyId);
            SafeIntPtr pShadowCopySetId = TypeMarshal.ToIntPtr(ShadowCopySetId);
            SafeIntPtr pShareName       = Marshal.StringToHGlobalUni(ShareName);

            paramList = new Int3264[] {
                pShadowCopyId,
                pShadowCopySetId,
                pShareName,
                Level,
                IntPtr.Zero,
                IntPtr.Zero
            };

            try
            {
                using (RpceInt3264Collection outParamList = RpceCall(paramList, (ushort)FSRVP_OPNUM.GetShareMapping))
                {
                    retVal       = outParamList[5].ToInt32();
                    ShareMapping = new FSSAGENT_SHARE_MAPPING();
                    if ((FsrvpErrorCode)retVal == FsrvpErrorCode.FSRVP_SUCCESS)
                    {
                        ShareMapping.ShareMapping1       = TypeMarshal.ToStruct <FSSAGENT_SHARE_MAPPING_1>(Marshal.ReadIntPtr(outParamList[4]));
                        ShareMapping.ShareMapping1IsNull = false;
                    }
                    else
                    {
                        ShareMapping.ShareMapping1IsNull = true;
                    }
                }
            }
            finally
            {
                pShadowCopyId.Dispose();
                pShadowCopySetId.Dispose();
                pShareName.Dispose();
            }

            return(retVal);
        }
Ejemplo n.º 14
0
        /// <summary>
        /// The NetrShareEnum method retrieves information about each shared resource on a server.
        /// </summary>
        /// <param name="serverName">A string that identifies the server. If this parameter is NULL, the local computer is used.</param>
        /// <param name="infoStruct">A SHARE_ENUM_STRUCT structure. The SHARE_ENUM_STRUCT structure has a Level member
        /// that specifies the type of structure to return in the ShareInfo member.</param>
        /// <param name="PreferedMaximumLength">Specifies the preferred maximum length, in bytes, of the returned data.
        /// If the specified value is MAX_PREFERRED_LENGTH, the method MUST attempt to return all entries.</param>
        /// <param name="TotalEntries">The total number of entries that could have been enumerated if the buffer had been big enough to hold all the entries.</param>
        /// <param name="ResumeHandle">A pointer to a value that contains a handle, which is used to continue an existing share search in ShareList.
        /// handle MUST be zero on the first call and remain unchanged for subsequent calls. If the ResumeHandle parameter is NULL, no resume handle MUST be stored.
        /// If this parameter is not NULL and the method returns ERROR_MORE_DATA, this parameter receives a nonzero value that can be passed in subsequent
        /// calls to this method to continue with the enumeration in ShareList. If this parameter is NULL or points to 0x00000000, the enumeration starts from the beginning of the ShareList.
        /// </param>
        /// <returns>The method returns 0x00000000 (NERR_Success) to indicate success; otherwise, it returns a nonzero error code.</returns>
        public uint NetrShareEnum(
            string serverName,
            ref SHARE_ENUM_STRUCT infoStruct,
            uint PreferedMaximumLength,
            out uint?TotalEntries,
            ref uint?ResumeHandle)
        {
            /*  NET_API_STATUS NetrShareEnum(
             *    [in, string, unique] SRVSVC_HANDLE ServerName,
             *    [in, out] LPSHARE_ENUM_STRUCT InfoStruct,
             *    [in] DWORD PreferedMaximumLength,
             *    [out] DWORD* TotalEntries,
             *    [in, out, unique] DWORD* ResumeHandle
             *  );
             */

            Int3264[] paramList;
            TotalEntries = 0;
            uint retVal = 0;

            using (SafeIntPtr pServerName = Marshal.StringToHGlobalUni(serverName),
                   pInfoStruct = TypeMarshal.ToIntPtr(infoStruct),
                   pResumeHandle = TypeMarshal.ToIntPtr(ResumeHandle))
            {
                paramList = new Int3264[] {
                    pServerName,
                    pInfoStruct,
                    PreferedMaximumLength,
                    IntPtr.Zero, // out value
                    pResumeHandle,
                    IntPtr.Zero  // return value
                };

                using (RpceInt3264Collection outParamList = RpceCall(paramList, (ushort)SRVS_OPNUM.NetrShareEnum))
                {
                    retVal = outParamList[paramList.Length - 1].ToUInt32();
                    if (retVal == (uint)Win32ErrorCode_32.ERROR_SUCCESS)
                    {
                        infoStruct   = TypeMarshal.ToStruct <SHARE_ENUM_STRUCT>(outParamList[1].ToIntPtr());
                        TotalEntries = TypeMarshal.ToNullableStruct <uint>(outParamList[3]);
                        ResumeHandle = TypeMarshal.ToNullableStruct <uint>(outParamList[4]);
                    }
                }
            }
            return(retVal);
        }
Ejemplo n.º 15
0
        /// <summary>
        /// The NetrShareSetInfo method sets the parameters of a shared resource in a ShareList.
        /// </summary>
        /// <param name="ServerName">A string that identifies the server. If this parameter is NULL, the local computer is used.</param>
        /// <param name="NetName">The name of the share to return information for.</param>
        /// <param name="Level">Specifies the information level of the data. This parameter MUST be one of the following values.</param>
        /// <param name="InfoStruct">Its contents are determined by the value of the Level parameter, as shown in the preceding table.
        /// This parameter MUST NOT contain a null value. </param>
        /// <param name="ParmErr">An integer value that receives the index of the first member of the share information
        /// structure that caused the ERROR_INVALID_PARAMETER error, if it occurs</param>
        /// <returns>The method returns 0x00000000 (NERR_Success) to indicate success; otherwise, it returns a nonzero error code.</returns>
        public uint NetrShareSetInfo(string ServerName, string NetName, SHARE_ENUM_STRUCT_LEVEL Level, SHARE_INFO InfoStruct, ref uint?ParmErr)
        {
            /*
             * NET_API_STATUS NetrShareSetInfo(
             *  [in, string, unique] SRVSVC_HANDLE ServerName,
             *  [in, string] WCHAR* NetName,
             *  [in] DWORD Level,
             *  [in, switch_is(Level)] LPSHARE_INFO ShareInfo,
             *  [in, out, unique] DWORD* ParmErr
             * );
             */

            Int3264[] paramList;
            uint      retVal = 0;

            using (SafeIntPtr pServerName = Marshal.StringToHGlobalUni(ServerName),
                   pNetName = Marshal.StringToHGlobalUni(NetName),
                   pShareInfo = TypeMarshal.ToIntPtr(InfoStruct, Level, null, null),
                   pParmErr = TypeMarshal.ToIntPtr(ParmErr))
            {
                paramList = new Int3264[] {
                    pServerName,
                    pNetName,
                    (uint)Level,
                    pShareInfo, // out value
                    pParmErr,
                    IntPtr.Zero // return value
                };
                using (RpceInt3264Collection outParamList = RpceCall(paramList, (ushort)SRVS_OPNUM.NetrShareSetInfo))
                {
                    retVal = outParamList[paramList.Length - 1].ToUInt32();
                    if (retVal == (uint)Win32ErrorCode_32.ERROR_INVALID_PARAMETER)
                    {
                        ParmErr = TypeMarshal.ToNullableStruct <uint>(outParamList[4]);
                    }
                }
            }
            return(retVal);
        }
        /// <summary>
        /// The AddToShadowCopySet method adds a share to an existing shadow copy set.
        /// </summary>
        /// <param name="ClientShadowCopyId">The GUID of the client. This MUST be set to NULL.</param>
        /// <param name="ShadowCopySetId">The GUID of the shadow copy set to which ShareName is to be added.</param>
        /// <param name="ShareName">The name of the share in UNC format for which a shadow copy is required.</param>
        /// <param name="pShadowCopyId">On output, the GUID of the shadow copy associated to the share.</param>
        /// <returns></returns>
        public int AddToShadowCopySet(
            Guid ClientShadowCopyId,
            Guid ShadowCopySetId,
            string ShareName,
            out Guid pShadowCopyId)
        {
            Int3264[] paramList;
            int       retVal = 0;

            SafeIntPtr pClientShadowCopyId = TypeMarshal.ToIntPtr(ClientShadowCopyId);
            SafeIntPtr pShadowCopySetId    = TypeMarshal.ToIntPtr(ShadowCopySetId);
            SafeIntPtr pShareName          = Marshal.StringToHGlobalUni(ShareName);

            paramList = new Int3264[] {
                pClientShadowCopyId,
                pShadowCopySetId,
                pShareName,
                IntPtr.Zero,
                IntPtr.Zero
            };

            try
            {
                using (RpceInt3264Collection outParamList = RpceCall(paramList, (ushort)FSRVP_OPNUM.AddToShadowCopySet))
                {
                    pShadowCopyId = TypeMarshal.ToStruct <Guid>(outParamList[3]);
                    retVal        = outParamList[4].ToInt32();
                }
            }
            finally
            {
                pClientShadowCopyId.Dispose();
                pShadowCopySetId.Dispose();
                pShareName.Dispose();
            }

            return(retVal);
        }