/// <summary> /// Parse the STAT from the response data. /// </summary> /// <param name="rawData">The response data.</param> /// <param name="startIndex">The start index.</param> /// <returns>The result of STAT.</returns> public static STAT Parse(byte[] rawData, ref int startIndex) { STAT state = new STAT(); state.SortType = BitConverter.ToUInt32(rawData, startIndex); startIndex += sizeof(uint); state.ContainerID = BitConverter.ToUInt32(rawData, startIndex); startIndex += sizeof(uint); state.CurrentRec = BitConverter.ToUInt32(rawData, startIndex); startIndex += sizeof(uint); state.Delta = BitConverter.ToInt32(rawData, startIndex); startIndex += sizeof(int); state.NumPos = BitConverter.ToUInt32(rawData, startIndex); startIndex += sizeof(uint); state.TotalRecs = BitConverter.ToUInt32(rawData, startIndex); startIndex += sizeof(uint); state.CodePage = BitConverter.ToUInt32(rawData, startIndex); startIndex += sizeof(uint); state.TemplateLocale = BitConverter.ToUInt32(rawData, startIndex); startIndex += sizeof(uint); state.SortLocale = BitConverter.ToUInt32(rawData, startIndex); startIndex += sizeof(uint); return(state); }
/// <summary> /// The NspiBind method initiates a session between a client and the server. /// </summary> /// <param name="flags">A DWORD value that contains a set of bit flags.</param> /// <param name="stat">A STAT block that describes a logical position in a specific address book container.</param> /// <param name="serverGuid">The value NULL or a pointer to a GUID value that is associated with the specific server.</param> /// <returns>Status of NSPI method.</returns> public ErrorCodeValue Bind(uint flags, STAT stat, ref FlatUID_r? serverGuid) { ErrorCodeValue result; BindRequestBody bindRequestBody = this.BuildBindRequestBody(stat, flags); byte[] rawBuffer = null; ChunkedResponse chunkedResponse = null; BindResponseBody bindResponseBody = null; // Send the execute HTTP request and get the response HttpWebResponse response = MapiHttpAdapter.SendMAPIHttpRequest(this.site, this.addressBookUrl, this.userName, this.domainName, this.password, bindRequestBody, RequestType.Bind.ToString(), AdapterHelper.SessionContextCookies); // Read the HTTP response buffer and parse the response to correct format rawBuffer = MapiHttpAdapter.ReadHttpResponse(response); result = (ErrorCodeValue)int.Parse(response.Headers["X-ResponseCode"]); if (result == ErrorCodeValue.Success) { chunkedResponse = ChunkedResponse.ParseChunkedResponse(rawBuffer); bindResponseBody = BindResponseBody.Parse(chunkedResponse.ResponseBodyRawData); result = (ErrorCodeValue)bindResponseBody.ErrorCode; if (bindResponseBody.ServerGuid != null) { FlatUID_r newGuid = new FlatUID_r(); newGuid.Ab = bindResponseBody.ServerGuid.ToByteArray(); serverGuid = newGuid; } else { serverGuid = null; } } response.GetResponseStream().Close(); AdapterHelper.SessionContextCookies = response.Cookies; return result; }
/// <summary> /// Initialize Bind request body. /// </summary> /// <param name="stat">A STAT block that describes a logical position in a specific address book container.</param> /// <param name="flags">A set of bit flags that specify options to the server.</param> /// <returns>An instance of the Bind request body.</returns> private BindRequestBody BuildBindRequestBody(STAT stat, uint flags) { BindRequestBody bindRequestBody = new BindRequestBody(); bindRequestBody.State = stat; bindRequestBody.Flags = flags; bindRequestBody.HasState = true; byte[] auxIn = new byte[] { }; bindRequestBody.AuxiliaryBuffer = auxIn; bindRequestBody.AuxiliaryBufferSize = (uint)auxIn.Length; return(bindRequestBody); }
/// <summary> /// The NspiQueryRows method returns a number of rows from a specified table to the client. /// </summary> /// <param name="flags">A DWORD value that contains a set of bit flags.</param> /// <param name="stat">A STAT block that describes a logical position in a specific address book container.</param> /// <param name="tableCount">A DWORD value that contains the number values in the input parameter table. /// This value is limited to 100,000.</param> /// <param name="table">An array of DWORD values, representing an Explicit Table.</param> /// <param name="count">A DWORD value that contains the number of rows the client is requesting.</param> /// <param name="propTags">The value NULL or a reference to a PropertyTagArray_r value, /// containing a list of the proptags of the properties that the client requires to be returned for each row returned.</param> /// <param name="rows">A nullable PropertyRowSet_r value, it contains the address book container rows that the server returns in response to the request.</param> /// <returns>Status of NSPI method.</returns> public ErrorCodeValue QueryRows(uint flags, ref STAT stat, uint tableCount, uint[] table, uint count, PropertyTagArray_r?propTags, out PropertyRowSet_r?rows) { ErrorCodeValue result; QueryRowsRequestBody queryRowsRequestBody = new QueryRowsRequestBody(); LargePropTagArray propetyTags = new LargePropTagArray(); if (propTags != null) { propetyTags.PropertyTagCount = propTags.Value.Values; propetyTags.PropertyTags = new PropertyTag[propetyTags.PropertyTagCount]; for (int i = 0; i < propTags.Value.Values; i++) { propetyTags.PropertyTags[i].PropertyId = (ushort)((propTags.Value.AulPropTag[i] & 0xFFFF0000) >> 16); propetyTags.PropertyTags[i].PropertyType = (ushort)(propTags.Value.AulPropTag[i] & 0x0000FFFF); } queryRowsRequestBody.HasColumns = true; queryRowsRequestBody.Columns = propetyTags; } queryRowsRequestBody.Flags = flags; queryRowsRequestBody.HasState = true; queryRowsRequestBody.State = stat; queryRowsRequestBody.ExplicitTableCount = tableCount; queryRowsRequestBody.ExplicitTable = table; queryRowsRequestBody.RowCount = count; byte[] auxIn = new byte[] { }; queryRowsRequestBody.AuxiliaryBuffer = auxIn; queryRowsRequestBody.AuxiliaryBufferSize = (uint)auxIn.Length; ChunkedResponse chunkedResponse = this.SendAddressBookRequest(queryRowsRequestBody, RequestType.QueryRows); QueryRowsResponseBody queryRowsResponseBody = QueryRowsResponseBody.Parse(chunkedResponse.ResponseBodyRawData); result = (ErrorCodeValue)queryRowsResponseBody.ErrorCode; if (queryRowsResponseBody.RowCount != null) { PropertyRowSet_r newRows = AdapterHelper.ParsePropertyRowSet_r(queryRowsResponseBody.Columns.Value, queryRowsResponseBody.RowCount.Value, queryRowsResponseBody.RowData); rows = newRows; } else { rows = null; } if (queryRowsResponseBody.HasState) { stat = queryRowsResponseBody.State.Value; } return(result); }
/// <summary> /// The NspiBind method initiates a session between a client and the server. /// </summary> /// <param name="flags">A DWORD value that contains a set of bit flags.</param> /// <param name="stat">A pointer to a STAT block that describes a logical position in a specific address book container.</param> /// <param name="serverGuid">The value NULL or a pointer to a GUID value that is associated with the specific server.</param> /// <param name="needRetry">A Boolean value indicates if need to retry to get an expected result. This parameter is designed to avoid meaningless retry when an error response is expected.</param> /// <returns>Status of NSPI method.</returns> public ErrorCodeValue NspiBind(uint flags, STAT stat, ref FlatUID_r?serverGuid) { ErrorCodeValue result; if (this.transport == "ncacn_http" || this.transport == "ncacn_ip_tcp") { result = this.nspiRpcAdapter.NspiBind(flags, stat, ref serverGuid); } else { result = this.nspiMapiHttpAdapter.Bind(flags, stat, ref serverGuid); } return(result); }
/// <summary> /// The NspiQueryRows method returns a number of rows from a specified table to the client. /// </summary> /// <param name="flags">A DWORD value that contains a set of bit flags.</param> /// <param name="stat">A STAT block that describes a logical position in a specific address book container.</param> /// <param name="tableCount">A DWORD value that contains the number values in the input parameter table. /// This value is limited to 100,000.</param> /// <param name="table">An array of DWORD values, representing an Explicit Table.</param> /// <param name="count">A DWORD value that contains the number of rows the client is requesting.</param> /// <param name="propTags">The value NULL or a reference to a PropertyTagArray_r value, /// containing a list of the proptags of the properties that the client requires to be returned for each row returned.</param> /// <param name="rows">A nullable PropertyRowSet_r value, it contains the address book container rows that the server returns in response to the request.</param> /// <param name="needRetry">A Boolean value indicates if need to retry to get an expected result. This parameter is designed to avoid meaningless retry when an error response is expected.</param> /// <returns>Status of NSPI method.</returns> public ErrorCodeValue NspiQueryRows(uint flags, ref STAT stat, uint tableCount, uint[] table, uint count, PropertyTagArray_r?propTags, out PropertyRowSet_r?rows, bool needRetry = true) { ErrorCodeValue result; STAT inputStat = stat; if (this.transport == "ncacn_http" || this.transport == "ncacn_ip_tcp") { result = this.nspiRpcAdapter.NspiQueryRows(flags, ref stat, tableCount, table, count, propTags, out rows, needRetry); } else { result = this.nspiMapiHttpAdapter.QueryRows(flags, ref stat, tableCount, table, count, propTags, out rows); } return(result); }
/// <summary> /// The NspiBind method initiates a session between a client and the server. /// </summary> /// <param name="flags">A DWORD value that contains a set of bit flags.</param> /// <param name="stat">A STAT block that describes a logical position in a specific address book container.</param> /// <param name="serverGuid">The value NULL or a pointer to a GUID value that is associated with the specific server.</param> /// <returns>Status of NSPI method.</returns> public ErrorCodeValue Bind(uint flags, STAT stat, ref FlatUID_r?serverGuid) { ErrorCodeValue result; BindRequestBody bindRequestBody = this.BuildBindRequestBody(stat, flags); byte[] rawBuffer = null; ChunkedResponse chunkedResponse = null; BindResponseBody bindResponseBody = null; // Send the execute HTTP request and get the response HttpWebResponse response = MapiHttpAdapter.SendMAPIHttpRequest(this.site, this.addressBookUrl, this.userName, this.domainName, this.password, bindRequestBody, RequestType.Bind.ToString(), AdapterHelper.SessionContextCookies); // Read the HTTP response buffer and parse the response to correct format rawBuffer = MapiHttpAdapter.ReadHttpResponse(response); result = (ErrorCodeValue)int.Parse(response.Headers["X-ResponseCode"]); if (result == ErrorCodeValue.Success) { chunkedResponse = ChunkedResponse.ParseChunkedResponse(rawBuffer); bindResponseBody = BindResponseBody.Parse(chunkedResponse.ResponseBodyRawData); result = (ErrorCodeValue)bindResponseBody.ErrorCode; if (bindResponseBody.ServerGuid != null) { FlatUID_r newGuid = new FlatUID_r(); newGuid.Ab = bindResponseBody.ServerGuid.ToByteArray(); serverGuid = newGuid; } else { serverGuid = null; } } response.GetResponseStream().Close(); AdapterHelper.SessionContextCookies = response.Cookies; return(result); }
/// <summary> /// Parse the response data into response body. /// </summary> /// <param name="rawData">The raw data of response</param> /// <returns>The response body of the request</returns> public static QueryRowsResponseBody Parse(byte[] rawData) { QueryRowsResponseBody responseBody = new QueryRowsResponseBody(); int index = 0; responseBody.StatusCode = BitConverter.ToUInt32(rawData, index); index += sizeof(uint); responseBody.ErrorCode = BitConverter.ToUInt32(rawData, index); index += sizeof(uint); responseBody.HasState = BitConverter.ToBoolean(rawData, index); index += sizeof(bool); if (responseBody.HasState) { responseBody.State = STAT.Parse(rawData, ref index); } responseBody.HasColumnsAndRows = BitConverter.ToBoolean(rawData, index); index += sizeof(bool); if (responseBody.HasColumnsAndRows) { responseBody.Columns = LargePropTagArray.Parse(rawData, ref index); responseBody.RowCount = BitConverter.ToUInt32(rawData, index); index += sizeof(uint); responseBody.RowData = new AddressBookPropertyRow[(uint)responseBody.RowCount]; for (int i = 0; i < responseBody.RowCount; i++) { responseBody.RowData[i] = AddressBookPropertyRow.Parse(rawData, (LargePropTagArray)responseBody.Columns, ref index); } } responseBody.AuxiliaryBufferSize = BitConverter.ToUInt32(rawData, index); index += 4; responseBody.AuxiliaryBuffer = new byte[responseBody.AuxiliaryBufferSize]; Array.Copy(rawData, index, responseBody.AuxiliaryBuffer, 0, responseBody.AuxiliaryBufferSize); return(responseBody); }
public static extern int NspiUpdateStat(IntPtr contextHandle, uint reserved, ref STAT stat, IntPtr ptrDelta);
public static extern int NspiGetSpecialTable(IntPtr contextHandle, uint flags, ref STAT stat, ref uint version, out IntPtr ptrRows);
/// <summary> /// Get properties from NSPI table. /// </summary> /// <param name="server">Server address.</param> /// <param name="userName">The value of user name.</param> /// <param name="domain">The value of Domain.</param> /// <param name="password">Password of the user.</param> /// <param name="columns">PropertyTags to be query.</param> /// <returns>Results in PropertyRowSet format.</returns> public PropertyRowSet_r? GetRecipientInfo(string server, string userName, string domain, string password, PropertyTagArray_r? columns) { #region Call NspiBind method to initiate a session between the client and the server. uint flags = 0; STAT stat = new STAT(); stat.CodePage = 0x4e4; // Set a valid code page. stat.TemplateLocale = 0x409; // Set a valid LCID. stat.SortLocale = 0x409; // Set a valid LCID. // Set value for serverGuid FlatUID_r guid = new FlatUID_r { Ab = new byte[16] }; FlatUID_r? serverGuid = guid; ErrorCodeValue result = this.nspiAdapter.NspiBind(flags, stat, ref serverGuid); Site.Assert.AreEqual<ErrorCodeValue>(ErrorCodeValue.Success, result, "NspiBind should return Success!"); #endregion #region Call NspiQueryRows method to get the recipient information. stat.ContainerID = 0; // Set the container id to the id of default global address book container uint tableCount = 0; uint[] table = null; uint requestCount = 5000; PropertyRowSet_r? propertyRowSet = null; result = this.nspiAdapter.NspiQueryRows(flags, ref stat, tableCount, table, requestCount, columns, out propertyRowSet); Site.Assert.AreEqual<ErrorCodeValue>(ErrorCodeValue.Success, result, "NspiQueryRows should return Success!"); #endregion uint returnValue = this.nspiAdapter.NspiUnbind(0); Site.Assert.AreEqual<uint>(1, returnValue, "NspiUnbind method should return 1 (Success)."); return propertyRowSet; }
/// <summary> /// Initialize Bind request body. /// </summary> /// <param name="stat">A STAT block that describes a logical position in a specific address book container.</param> /// <param name="flags">A set of bit flags that specify options to the server.</param> /// <returns>An instance of the Bind request body.</returns> private BindRequestBody BuildBindRequestBody(STAT stat, uint flags) { BindRequestBody bindRequestBody = new BindRequestBody(); bindRequestBody.State = stat; bindRequestBody.Flags = flags; bindRequestBody.HasState = true; byte[] auxIn = new byte[] { }; bindRequestBody.AuxiliaryBuffer = auxIn; bindRequestBody.AuxiliaryBufferSize = (uint)auxIn.Length; return bindRequestBody; }
public static extern int NspiUpdateStat(IntPtr contextHandle, uint reserved, ref STAT stat, IntPtr ptrDelta);
public static extern int NspiBind(IntPtr ptrRpc, uint flags, ref STAT stat, IntPtr ptrServerGuid, ref IntPtr contextHandle);
/// <summary> /// The NspiQueryRows method returns a number of rows from a specified table to the client. /// </summary> /// <param name="flags">A DWORD value that contains a set of bit flags.</param> /// <param name="stat">A STAT block that describes a logical position in a specific address book container.</param> /// <param name="tableCount">A DWORD value that contains the number values in the input parameter table. /// This value is limited to 100,000.</param> /// <param name="table">An array of DWORD values, representing an Explicit Table.</param> /// <param name="count">A DWORD value that contains the number of rows the client is requesting.</param> /// <param name="propTags">The value NULL or a reference to a PropertyTagArray_r value, /// containing a list of the proptags of the properties that the client requires to be returned for each row returned.</param> /// <param name="rows">A nullable PropertyRowSet_r value, it contains the address book container rows that the server returns in response to the request.</param> /// <param name="needRetry">A bool value indicates if need to retry to get an expected result. This parameter is designed to avoid meaningless retry when an error response is expected.</param> /// <returns>Status of NSPI method.</returns> public ErrorCodeValue NspiQueryRows(uint flags, ref STAT stat, uint tableCount, uint[] table, uint count, PropertyTagArray_r? propTags, out PropertyRowSet_r? rows, bool needRetry = true) { int result; IntPtr ptrRows = IntPtr.Zero; IntPtr ptrPropTags = IntPtr.Zero; IntPtr ptrStat = AdapterHelper.AllocStat(stat); if (propTags != null) { ptrPropTags = AdapterHelper.AllocPropertyTagArray_r(propTags.Value); } int retryCount = 0; do { try { result = OxnspiInterop.NspiQueryRows(this.contextHandle, flags, ref stat, tableCount, table, count, ptrPropTags, out ptrRows); } catch (SEHException e) { result = (int)NativeMethods.RpcExceptionCode(e); this.site.Log.Add(LogEntryKind.Comment, "RPC component throws exception, the error code is {0}, the error message is: {1}", result, new Win32Exception(result).ToString()); } if ((ErrorCodeValue)result == ErrorCodeValue.GeneralFailure && needRetry) { Thread.Sleep(this.waitTime); } else { break; } retryCount++; } while ((ErrorCodeValue)result == ErrorCodeValue.GeneralFailure && retryCount < this.maxRetryCount); if (!Enum.IsDefined(typeof(ErrorCodeValue), (uint)result)) { throw new ArgumentException(string.Format("An unknown error is returned, the error code is: {0} and the error message is: {1}", result, new Win32Exception(result).ToString())); } if (propTags != null) { Marshal.FreeHGlobal(ptrPropTags); } // Parse rows according to ptrRows. if (ptrRows == IntPtr.Zero) { rows = null; } else { rows = AdapterHelper.ParsePropertyRowSet_r(ptrRows); } // Free stat. Marshal.FreeHGlobal(ptrStat); return (ErrorCodeValue)result; }
public static extern int NspiGetMatches(IntPtr contextHandle, uint reserved, ref STAT stat, IntPtr ptrReserved, uint reserved2, IntPtr ptrFilter, IntPtr ptrPropName, uint requested, out IntPtr ptrOutMids, IntPtr ptrPropTags, out IntPtr ptrRows);
public static extern int NspiQueryRows(IntPtr contextHandle, uint flags, ref STAT stat, uint tableCount, [Size("dwETableCount")] uint[] table, uint count, IntPtr ptrPropTags, out IntPtr ptrRows);
/// <summary> /// The NspiBind method initiates a session between a client and the server. /// </summary> /// <param name="flags">A DWORD value that contains a set of bit flags.</param> /// <param name="stat">A pointer to a STAT block that describes a logical position in a specific address book container.</param> /// <param name="serverGuid">The value NULL or a pointer to a GUID value that is associated with the specific server.</param> /// <param name="needRetry">A Boolean value indicates if need to retry to get an expected result. This parameter is designed to avoid meaningless retry when an error response is expected.</param> /// <returns>Status of NSPI method.</returns> public ErrorCodeValue NspiBind(uint flags, STAT stat, ref FlatUID_r?serverGuid, bool needRetry = true) { int result; IntPtr ptrServerGuid = IntPtr.Zero; IntPtr ptrStat = AdapterHelper.AllocStat(stat); if (serverGuid.HasValue && serverGuid.Value.Ab != null) { ptrServerGuid = AdapterHelper.AllocFlatUID_r(serverGuid.Value); } int retryCount = 0; do { try { result = OxnspiInterop.NspiBind(this.rpcBinding, flags, ref stat, ptrServerGuid, ref this.contextHandle); } catch (SEHException e) { result = (int)NativeMethods.RpcExceptionCode(e); this.site.Log.Add(LogEntryKind.Comment, "RPC component throws exception, the error code is {0}, the error message is: {1}", result, new Win32Exception(result).ToString()); } if ((ErrorCodeValue)result == ErrorCodeValue.GeneralFailure && needRetry) { Thread.Sleep(this.waitTime); } else { break; } retryCount++; }while ((ErrorCodeValue)result == ErrorCodeValue.GeneralFailure && retryCount < this.maxRetryCount); if (!Enum.IsDefined(typeof(ErrorCodeValue), (uint)result)) { throw new ArgumentException(string.Format("An unknown error is returned, the error code is: {0} and the error message is: {1}", result, new Win32Exception(result).ToString())); } // Parse ServerGuid from ptrServerGuid. if (ptrServerGuid == IntPtr.Zero) { serverGuid = null; } else { serverGuid = AdapterHelper.ParseFlatUID_r(ptrServerGuid); } // Free allocated memory for serverGuid. if (serverGuid.HasValue) { if (serverGuid.Value.Ab != null) { Marshal.FreeHGlobal(ptrServerGuid); } } // Free allocated memory for stat. Marshal.FreeHGlobal(ptrStat); return((ErrorCodeValue)result); }
/// <summary> /// Parse a STAT structure instance from pointer. /// </summary> /// <param name="ptr">Pointer points to the memory.</param> /// <returns>A STAT structure.</returns> public static STAT ParseStat(IntPtr ptr) { STAT stat = new STAT(); int offset = 0; stat.SortType = (uint)Marshal.ReadInt32(ptr, offset); offset += sizeof(int); stat.ContainerID = (uint)Marshal.ReadInt32(ptr, offset); offset += sizeof(int); stat.CurrentRec = (uint)Marshal.ReadInt32(ptr, offset); offset += sizeof(int); stat.Delta = Marshal.ReadInt32(ptr, offset); offset += sizeof(int); stat.NumPos = (uint)Marshal.ReadInt32(ptr, offset); offset += sizeof(int); stat.TotalRecs = (uint)Marshal.ReadInt32(ptr, offset); offset += sizeof(int); stat.CodePage = (uint)Marshal.ReadInt32(ptr, offset); offset += sizeof(int); stat.TemplateLocale = (uint)Marshal.ReadInt32(ptr, offset); offset += sizeof(int); stat.SortLocale = (uint)Marshal.ReadInt32(ptr, offset); return stat; }
/// <summary> /// Allocate memory for stat instance. /// </summary> /// <param name="stat">The stat instance.</param> /// <returns>The pointer points to the allocated memory.</returns> public static IntPtr AllocStat(STAT stat) { IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(stat)); int offset = 0; Marshal.WriteInt32(ptr, offset, (int)stat.SortType); offset += sizeof(int); Marshal.WriteInt32(ptr, offset, (int)stat.ContainerID); offset += sizeof(int); Marshal.WriteInt32(ptr, offset, (int)stat.CurrentRec); offset += sizeof(int); Marshal.WriteInt32(ptr, offset, stat.Delta); offset += sizeof(int); Marshal.WriteInt32(ptr, offset, (int)stat.NumPos); offset += sizeof(int); Marshal.WriteInt32(ptr, offset, (int)stat.TotalRecs); offset += sizeof(int); Marshal.WriteInt32(ptr, offset, (int)stat.CodePage); offset += sizeof(int); Marshal.WriteInt32(ptr, offset, (int)stat.TemplateLocale); offset += sizeof(int); Marshal.WriteInt32(ptr, offset, (int)stat.SortLocale); return ptr; }
/// <summary> /// The NspiBind method initiates a session between a client and the server. /// </summary> /// <param name="flags">A DWORD value that contains a set of bit flags.</param> /// <param name="stat">A pointer to a STAT block that describes a logical position in a specific address book container.</param> /// <param name="serverGuid">The value NULL or a pointer to a GUID value that is associated with the specific server.</param> /// <param name="needRetry">A Boolean value indicates if need to retry to get an expected result. This parameter is designed to avoid meaningless retry when an error response is expected.</param> /// <returns>Status of NSPI method.</returns> public ErrorCodeValue NspiBind(uint flags, STAT stat, ref FlatUID_r? serverGuid, bool needRetry = true) { int result; IntPtr ptrServerGuid = IntPtr.Zero; IntPtr ptrStat = AdapterHelper.AllocStat(stat); if (serverGuid.HasValue && serverGuid.Value.Ab != null) { ptrServerGuid = AdapterHelper.AllocFlatUID_r(serverGuid.Value); } int retryCount = 0; do { try { result = OxnspiInterop.NspiBind(this.rpcBinding, flags, ref stat, ptrServerGuid, ref this.contextHandle); } catch (SEHException e) { result = (int)NativeMethods.RpcExceptionCode(e); this.site.Log.Add(LogEntryKind.Comment, "RPC component throws exception, the error code is {0}, the error message is: {1}", result, new Win32Exception(result).ToString()); } if ((ErrorCodeValue)result == ErrorCodeValue.GeneralFailure && needRetry) { Thread.Sleep(this.waitTime); } else { break; } retryCount++; } while ((ErrorCodeValue)result == ErrorCodeValue.GeneralFailure && retryCount < this.maxRetryCount); if (!Enum.IsDefined(typeof(ErrorCodeValue), (uint)result)) { throw new ArgumentException(string.Format("An unknown error is returned, the error code is: {0} and the error message is: {1}", result, new Win32Exception(result).ToString())); } // Parse ServerGuid from ptrServerGuid. if (ptrServerGuid == IntPtr.Zero) { serverGuid = null; } else { serverGuid = AdapterHelper.ParseFlatUID_r(ptrServerGuid); } // Free allocated memory for serverGuid. if (serverGuid.HasValue) { if (serverGuid.Value.Ab != null) { Marshal.FreeHGlobal(ptrServerGuid); } } // Free allocated memory for stat. Marshal.FreeHGlobal(ptrStat); return (ErrorCodeValue)result; }
/// <summary> /// The NspiQueryRows method returns a number of rows from a specified table to the client. /// </summary> /// <param name="flags">A DWORD value that contains a set of bit flags.</param> /// <param name="stat">A STAT block that describes a logical position in a specific address book container.</param> /// <param name="tableCount">A DWORD value that contains the number values in the input parameter table. /// This value is limited to 100,000.</param> /// <param name="table">An array of DWORD values, representing an Explicit Table.</param> /// <param name="count">A DWORD value that contains the number of rows the client is requesting.</param> /// <param name="propTags">The value NULL or a reference to a PropertyTagArray_r value, /// containing a list of the proptags of the properties that the client requires to be returned for each row returned.</param> /// <param name="rows">A nullable PropertyRowSet_r value, it contains the address book container rows that the server returns in response to the request.</param> /// <param name="needRetry">A bool value indicates if need to retry to get an expected result. This parameter is designed to avoid meaningless retry when an error response is expected.</param> /// <returns>Status of NSPI method.</returns> public ErrorCodeValue NspiQueryRows(uint flags, ref STAT stat, uint tableCount, uint[] table, uint count, PropertyTagArray_r?propTags, out PropertyRowSet_r?rows, bool needRetry = true) { int result; IntPtr ptrRows = IntPtr.Zero; IntPtr ptrPropTags = IntPtr.Zero; IntPtr ptrStat = AdapterHelper.AllocStat(stat); if (propTags != null) { ptrPropTags = AdapterHelper.AllocPropertyTagArray_r(propTags.Value); } int retryCount = 0; do { try { result = OxnspiInterop.NspiQueryRows(this.contextHandle, flags, ref stat, tableCount, table, count, ptrPropTags, out ptrRows); } catch (SEHException e) { result = (int)NativeMethods.RpcExceptionCode(e); this.site.Log.Add(LogEntryKind.Comment, "RPC component throws exception, the error code is {0}, the error message is: {1}", result, new Win32Exception(result).ToString()); } if ((ErrorCodeValue)result == ErrorCodeValue.GeneralFailure && needRetry) { Thread.Sleep(this.waitTime); } else { break; } retryCount++; }while ((ErrorCodeValue)result == ErrorCodeValue.GeneralFailure && retryCount < this.maxRetryCount); if (!Enum.IsDefined(typeof(ErrorCodeValue), (uint)result)) { throw new ArgumentException(string.Format("An unknown error is returned, the error code is: {0} and the error message is: {1}", result, new Win32Exception(result).ToString())); } if (propTags != null) { Marshal.FreeHGlobal(ptrPropTags); } // Parse rows according to ptrRows. if (ptrRows == IntPtr.Zero) { rows = null; } else { rows = AdapterHelper.ParsePropertyRowSet_r(ptrRows); } // Free stat. Marshal.FreeHGlobal(ptrStat); return((ErrorCodeValue)result); }
public static extern int NspiGetProps(IntPtr contextHandle, uint flags, ref STAT stat, IntPtr ptrPropTags, out IntPtr ptrRows);
public static extern int NspiCompareMIds(IntPtr contextHandle, uint reserved, ref STAT stat, uint mid1, uint mid2, out int result);
public static extern int NspiGetProps(IntPtr contextHandle, uint flags, ref STAT stat, IntPtr ptrPropTags, out IntPtr ptrRows);
public static extern int NspiQueryRows(IntPtr contextHandle, uint flags, ref STAT stat, uint tableCount, [Size("dwETableCount")]uint[] table, uint count, IntPtr ptrPropTags, out IntPtr ptrRows);
public static extern int NspiSeekEntries(IntPtr contextHandle, uint reserved, ref STAT stat, IntPtr ptrTarget, IntPtr table, IntPtr ptrPropTags, out IntPtr ptrRows);
public static extern int NspiSeekEntries(IntPtr contextHandle, uint reserved, ref STAT stat, IntPtr ptrTarget, IntPtr table, IntPtr ptrPropTags, out IntPtr ptrRows);
public static extern int NspiResortRestriction(IntPtr contextHandle, uint reserved, ref STAT stat, IntPtr ptrInmids, ref IntPtr ptrOutMIds);
public static extern int NspiGetMatches(IntPtr contextHandle, uint reserved, ref STAT stat, IntPtr ptrReserved, uint reserved2, IntPtr ptrFilter, IntPtr ptrPropName, uint requested, out IntPtr ptrOutMids, IntPtr ptrPropTags, out IntPtr ptrRows);
public static extern int NspiModProps(IntPtr contextHandle, uint reserved, ref STAT stat, IntPtr ptrPropTags, IntPtr ptrRow);
public static extern int NspiResortRestriction(IntPtr contextHandle, uint reserved, ref STAT stat, IntPtr ptrInmids, ref IntPtr ptrOutMIds);
public static extern int NspiGetSpecialTable(IntPtr contextHandle, uint flags, ref STAT stat, ref uint version, out IntPtr ptrRows);
public static extern int NspiCompareMIds(IntPtr contextHandle, uint reserved, ref STAT stat, uint mid1, uint mid2, out int result);
/// <summary> /// The NspiQueryRows method returns a number of rows from a specified table to the client. /// </summary> /// <param name="flags">A DWORD value that contains a set of bit flags.</param> /// <param name="stat">A STAT block that describes a logical position in a specific address book container.</param> /// <param name="tableCount">A DWORD value that contains the number values in the input parameter table. /// This value is limited to 100,000.</param> /// <param name="table">An array of DWORD values, representing an Explicit Table.</param> /// <param name="count">A DWORD value that contains the number of rows the client is requesting.</param> /// <param name="propTags">The value NULL or a reference to a PropertyTagArray_r value, /// containing a list of the proptags of the properties that the client requires to be returned for each row returned.</param> /// <param name="rows">A nullable PropertyRowSet_r value, it contains the address book container rows that the server returns in response to the request.</param> /// <returns>Status of NSPI method.</returns> public ErrorCodeValue QueryRows(uint flags, ref STAT stat, uint tableCount, uint[] table, uint count, PropertyTagArray_r? propTags, out PropertyRowSet_r? rows) { ErrorCodeValue result; QueryRowsRequestBody queryRowsRequestBody = new QueryRowsRequestBody(); LargePropTagArray propetyTags = new LargePropTagArray(); if (propTags != null) { propetyTags.PropertyTagCount = propTags.Value.Values; propetyTags.PropertyTags = new PropertyTag[propetyTags.PropertyTagCount]; for (int i = 0; i < propTags.Value.Values; i++) { propetyTags.PropertyTags[i].PropertyId = (ushort)((propTags.Value.AulPropTag[i] & 0xFFFF0000) >> 16); propetyTags.PropertyTags[i].PropertyType = (ushort)(propTags.Value.AulPropTag[i] & 0x0000FFFF); } queryRowsRequestBody.HasColumns = true; queryRowsRequestBody.Columns = propetyTags; } queryRowsRequestBody.Flags = flags; queryRowsRequestBody.HasState = true; queryRowsRequestBody.State = stat; queryRowsRequestBody.ExplicitTableCount = tableCount; queryRowsRequestBody.ExplicitTable = table; queryRowsRequestBody.RowCount = count; byte[] auxIn = new byte[] { }; queryRowsRequestBody.AuxiliaryBuffer = auxIn; queryRowsRequestBody.AuxiliaryBufferSize = (uint)auxIn.Length; ChunkedResponse chunkedResponse = this.SendAddressBookRequest(queryRowsRequestBody, RequestType.QueryRows); QueryRowsResponseBody queryRowsResponseBody = QueryRowsResponseBody.Parse(chunkedResponse.ResponseBodyRawData); result = (ErrorCodeValue)queryRowsResponseBody.ErrorCode; if (queryRowsResponseBody.RowCount != null) { PropertyRowSet_r newRows = AdapterHelper.ParsePropertyRowSet_r(queryRowsResponseBody.Columns.Value, queryRowsResponseBody.RowCount.Value, queryRowsResponseBody.RowData); rows = newRows; } else { rows = null; } if (queryRowsResponseBody.HasState) { stat = queryRowsResponseBody.State.Value; } return result; }
public static extern int NspiModProps(IntPtr contextHandle, uint reserved, ref STAT stat, IntPtr ptrPropTags, IntPtr ptrRow);
public static extern int NspiBind(IntPtr ptrRpc, uint flags, ref STAT stat, IntPtr ptrServerGuid, ref IntPtr contextHandle);
/// <summary> /// Parse the STAT from the response data. /// </summary> /// <param name="rawData">The response data.</param> /// <param name="startIndex">The start index.</param> /// <returns>The result of STAT.</returns> public static STAT Parse(byte[] rawData, ref int startIndex) { STAT state = new STAT(); state.SortType = BitConverter.ToUInt32(rawData, startIndex); startIndex += sizeof(uint); state.ContainerID = BitConverter.ToUInt32(rawData, startIndex); startIndex += sizeof(uint); state.CurrentRec = BitConverter.ToUInt32(rawData, startIndex); startIndex += sizeof(uint); state.Delta = BitConverter.ToInt32(rawData, startIndex); startIndex += sizeof(int); state.NumPos = BitConverter.ToUInt32(rawData, startIndex); startIndex += sizeof(uint); state.TotalRecs = BitConverter.ToUInt32(rawData, startIndex); startIndex += sizeof(uint); state.CodePage = BitConverter.ToUInt32(rawData, startIndex); startIndex += sizeof(uint); state.TemplateLocale = BitConverter.ToUInt32(rawData, startIndex); startIndex += sizeof(uint); state.SortLocale = BitConverter.ToUInt32(rawData, startIndex); startIndex += sizeof(uint); return state; }