public static bool GetNextLogArchiveExtentSingle(
            SafeArchiveContext pvArchiveContext,
            ref CLFS_ARCHIVE_DESCRIPTOR rgadExtent,
            out int pcDescriptorsReturned)
        {
            if (!_GetNextLogArchiveExtent(pvArchiveContext,
                                          ref rgadExtent,
                                          1,
                                          out pcDescriptorsReturned))
            {
                uint errorCode = (uint)Marshal.GetLastWin32Error();
                switch (errorCode)
                {
                    case Error.ERROR_NO_MORE_ITEMS:
                        return false;

                    case Error.ERROR_LOG_READ_CONTEXT_INVALID:
                    case Error.ERROR_INVALID_PARAMETER:
                    case Error.ERROR_INVALID_STATE:
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ExceptionForKnownCode(errorCode));

                    default:
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ExceptionForUnknownCode(errorCode));
                }
            }

            return true;
        }
 extern static bool _GetNextLogArchiveExtent(
     SafeArchiveContext pvArchiveContext,
     ref CLFS_ARCHIVE_DESCRIPTOR rgadExtent,
     int cDescriptors, // Must be 1
     out int pcDescriptorsReturned);
Exemple #3
0
        internal LogArchiveSnapshot(LogStore store,
                                    ulong lsnLow,
                                    ulong lsnHigh)
        {
            StringBuilder baseLogFileName = new StringBuilder(MaxFileNameLength);
            int actualLength;
            ulong baseLogFileOffset;
            ulong baseLogFileLength;
            ulong lsnBase;
            ulong lsnLast;
            ulong lsnArchiveTail;

            SafeArchiveContext archiveContext = null;
            try
            {
                while (!UnsafeNativeMethods.PrepareLogArchive(
                        store.Handle,
                        baseLogFileName,
                        baseLogFileName.Capacity,
                        ref lsnLow,
                        ref lsnHigh,
                        out actualLength,
                        out baseLogFileOffset,
                        out baseLogFileLength,
                        out lsnBase,
                        out lsnLast,
                        out lsnArchiveTail,
                        out archiveContext))
                {
                    baseLogFileName.EnsureCapacity(actualLength + 1);
                }

                this.archiveTail = new SequenceNumber(lsnArchiveTail);
                this.baseSequenceNumber = new SequenceNumber(lsnBase);
                this.lastSequenceNumber = new SequenceNumber(lsnLast);

                List<FileRegion> regions = new List<FileRegion>();

                byte[] readBuffer = new byte[checked((uint)baseLogFileLength)];
                uint actualDataLength = 0;
                unsafe
                {
                    fixed (byte* pbReadBuffer = readBuffer)
                    {
                        UnsafeNativeMethods.ReadLogArchiveMetadata(
                            archiveContext,
                            0,
                            readBuffer.Length,
                            pbReadBuffer,
                            out actualDataLength);
                    }
                }

                byte[] baseFileData;
                if (actualDataLength == (uint)baseLogFileLength)
                {
                    baseFileData = readBuffer;
                }
                else
                {
                    baseFileData = new byte[actualDataLength];
                    Array.Copy(readBuffer, baseFileData, baseFileData.Length);
                }
                regions.Add(new FileRegion((long)baseLogFileLength,
                                           baseLogFileName.ToString(),
                                           (long)baseLogFileOffset,
                                           baseFileData));


                CLFS_ARCHIVE_DESCRIPTOR descriptor = new CLFS_ARCHIVE_DESCRIPTOR();
                while (true)
                {
                    int returnedCount;
                    if (!UnsafeNativeMethods.GetNextLogArchiveExtentSingle(
                            archiveContext,
                            ref descriptor,
                            out returnedCount))
                    {
                        break;
                    }

                    if (returnedCount < 1) break;

                    long start = checked((long)descriptor.coffLow);
                    long length = checked((long)(descriptor.coffHigh - descriptor.coffLow));
                    string fileName = descriptor.infoContainer.GetActualFileName(store.Handle);

                    FileInfo containerInfo;
                    containerInfo = new FileInfo(fileName);

                    regions.Add(new FileRegion(containerInfo.Length,
                                               fileName,
                                               start,
                                               length));
                }

                this.regions = regions.AsReadOnly();
            }
            finally
            {
                if (archiveContext != null && !archiveContext.IsInvalid)
                {
                    archiveContext.Close();
                }
            }
        }