PeerDistClientStreamRead function (peerdist.h)

The PeerDistClientStreamRead reads a sequence of bytes from content stream.


DWORD PeerDistClientStreamRead(
  [in]                PEERDIST_INSTANCE_HANDLE hPeerDist,
  [in]                PEERDIST_CONTENT_HANDLE  hContentHandle,
                      DWORD                    cbMaxNumberOfBytes,
  [in, out, optional] PBYTE                    pBuffer,
                      DWORD                    dwTimeoutInMilliseconds,
  [in]                LPOVERLAPPED             lpOverlapped


[in] hPeerDist

A PEERDIST_INSTANCE_HANDLE returned by PeerDistStartup.

[in] hContentHandle

A content handle opened by the PeerDistClientOpenContent function call.


The maximum number of bytes to read. If the cbMaxNumberOfBytesToRead is equal to 0, it indicates that the PeerDistClientStreamRead function is querying the length of available consecutive content bytes in the local cache at the current stream read offset. The query will neither download content from the peers, nor return the count of bytes present in the peer cache.

[in, out, optional] pBuffer

Pointer to the buffer that receives the data from the local cache. This buffer must remain valid for the duration of the read operation. The caller must not use this buffer until the read operation is completed. If the cbMaxNumberOfBytesToRead argument is equal to 0, the pBuffer parameter can be NULL.


Timeout value for the read, in milliseconds. There are two special values that may be specified:

Value Meaning
Specifies that a read should not cause any additional network traffic by contacting peers or a Hosted Cache.
Specifies the default timeout of 5 seconds.

[in] lpOverlapped

Pointer to an OVERLAPPED structure. Stream read does not allow the caller to specify the start Offset for the reading. The next stream read offset is implicitly maintained per hContentHandle.

Return value

If the function succeeds, the return value is ERROR_IO_PENDING. Otherwise, the function may return one of the following values:

Return code Description
One or more parameters are invalid.
The hPeerDist or hContent handle is invalid.
The feature is disabled by Group Policy.
The service is unavailable.


PeerDistClientStreamRead queues the read and immediately returns to the caller. As a result, multiple reads can be issued simultaneously with the data buffers utilized in a first-in/first-out manner. PeerDistClientStreamRead will complete a read as soon as any data is available and will not wait for the buffer to fill completely.

If the PeerDistClientStreamRead function operation completes successfully, the Offset and OffsetHigh fields of the OVERLAPPED structure will be populated with the ULONGLONG offset at which the read started. The OffsetHigh member will be set to the higher 32 bits of the offset and the Offset member will be set to the lower 32 bits of the offset. GetOverlappedResult populates lpNumberOfBytesTransferred with the number of bytes transferred. In the event the caller is using a completion port to process Peer Distribution API completions then the lpNumberOfBytes argument of GetQueuedCompletionStatus will be populated with the number of bytes transferred. The stream offset will be advanced by the number of bytes reported as read. To query the length of available content for content larger than 4GB, PeerDistClientBlockRead can be used with cbMaxNumberOfBytesToRead equal to 0 and appropriate offsets.

If the API completes with the error value PEERDIST_ERROR_MISSING_DATA or ERROR_TIMEOUT, the Offset and OffsetHigh fields of the OVERLAPPED structure specify the ULONGLONG offset at which the missing data range begins. The OffsetHigh member will be set to the higher 32 bits of the offset and the Offset member will be set to the lower 32 bits of the offset. This missing data range is the start offset (relative to start of the content) and length, in bytes, which needs to be retrieved from an alternate source, like the original content server., In order to allow the Peer Distribution service to satisfy the same read in the future, add this data to the local cache by calling PeerDistClientAddData. The length of the missing data range is specified by the number of bytes transferred (obtained via GetQueuedCompletionStatus or GetOverlappedResult). The stream offset is advanced by the number of bytes reported as the length of the missing data range.

If PeerDistClientStreamRead is called after the stream offset has advanced beyond the end of the content, the API will complete with ERROR_NO_MORE.

It is important to note that the missing data range can start at any offset in the content and be any length up to the end of the content. In the event the content information passed to PeerDistClientAddContentInformation was generated in response to a range request, then the missing data range will be constrained to the range request bounds. This will happen when the call to PeerDistServerOpenContentInformation on the content server specified an offset and a length which was a sub-range of the content as a whole. A completion with ERROR_NO_MORE in this case indicates that the read offset is outside of the sub-range of the content.

Range Requests

If a client is interested in only a portion of the original content, a range request can be used to retrieve that portion. A range request contains an offset and length of the original content. The size of the content information is directly proportional to the size of the content requested.

PeerDistServerOpenContentInformation supports generating content information for a range request via the ullContentOffset and cbContentLength parameters. The ullContentOffset parameter represents the offset in the original content where the range begins and cbContentLength represents the length of the range.

Once a client obtains content information representing a particular content range, that content information works seamlessly with the PeerDistClientOpenContent, PeerDistClientAddContentInformation and PeerDistClientCompleteContentInformation APIs. The content information can be passed to PeerDistServerOpenContentInformation and will associate the PEERDIST_CONTENT_HANDLE with the content range. PeerDistClientStreamRead is constrained by the ullContentOffset offset and cbContentLength length specified in the server side call to PeerDistServerRetrieveContentInformation. PeerDistClientStreamRead will begin at ullContentOffset and will complete with the error code PEERDIST_ERROR_NO_MORE when the end of the content range is reached at ullContentOffset + cbContentLength. PeerDistClientBlockRead will complete with the error code PEERDIST_ERROR_NO_MORE if the offset specified in the OVERLAPPED parameter is less than ullContentOffset or greater than ullContentOffset + cbContentLength. PeerDistClientStreamRead and PeerDistClientBlockRead both limit the amount of missing data reported to the content range specified in the content information associated with the PEERDIST_CONTENT_HANDLE. For example, if the content information represents only the first half of the content, missing data will be limited to the first half of the content. In all other respects, PeerDistClientBlockRead and PeerDistClientStreamRead work with content ranges in exactly the same manner in which they work with the content as a whole.

A client can use PeerDistClientStreamRead or PeerDistClientBlockRead to retrieve the content from the offset specified by the ullContentOffset up to the length specified by cbContentLength in the PeerDistServerRetrieveContentInformation call. Both PeerDistClientStreamRead and PeerDistClientBlockRead will complete with PEERDIST_ERROR_NO_MORE if the client tries to read beyond the range specified by the ullContentOffset and cbContentLength. Additionally, PeerDistClientBlockRead will also complete with the error code PEERDIST_ERROR_NO_MORE if the offset specified in the OVERLAPPED parameter is less than ullContentOffset

If the read cannot not be completed from either the local cache or the peer cache, both PeerDistClientStreamRead and PeerDistClientBlockRead will report PEERDIST_ERROR_MISSING_DATA. When using the ranged content information, PeerDistClientStreamRead will report a missing data from the start offset of the range up to the end of the range. PeerDistClientBlockRead will report missing data from start offset of the range up to the end of the range.

PeerDistClientAddData allows content data to be added even if it lies outside the content range. This extended data will be validated after the corresponding content information has been added to the local cache. Once validated, it becomes available to peers. In other words, if a client adds only content information for the first half of content, PeerDistClientAddData still allows the client to add data for the entire content. However, the second half of the content will not be validated until the corresponding content information for the second half has been added. No other Peer Distribution APIs are affected by range requests.


Minimum supported client Windows 7 Professional [desktop apps only]
Minimum supported server Windows Server 2008 R2 [desktop apps only]
Target Platform Windows
Header peerdist.h
Library PeerDist.lib
DLL PeerDist.dll

See also