using System; using System.IO; using System.Runtime.InteropServices; namespace Wayne.Lib.Log { internal class GlobalLogEntryCounter : IDisposable { #region Win32 Semaphore APIs [DllImport("kernel32", EntryPoint = "CreateSemaphore", SetLastError = true, CharSet = CharSet.Unicode)] private static extern uint CreateSemaphore(int auth, int initialCount, int maximumCount, string name); [DllImport("kernel32", EntryPoint = "OpenSemaphore", SetLastError = true, CharSet = CharSet.Unicode)] private static extern uint OpenSemaphore(int auth, bool bInheritHandle, string name); [DllImport("kernel32", EntryPoint = "ReleaseSemaphore", SetLastError = true, CharSet = CharSet.Unicode)] [return: MarshalAs(UnmanagedType.VariantBool)] private static extern bool ReleaseSemaphore(uint hHandle, int lReleaseCount, out int lpPreviousCount); [DllImport("kernel32", EntryPoint = "CloseHandle", SetLastError = true, CharSet = CharSet.Unicode)] [return: MarshalAs(UnmanagedType.VariantBool)] private static extern bool CloseHandle(uint hHandle); #endregion #region Fields private const string GlobalName = "Wayne.Lib.Log.GlobalLogEntryCounter"; private bool disposed; private readonly bool fullWindows; private uint fullWindowsSemaphoreHandle; #endregion #region Construction /// /// Constructor. /// public GlobalLogEntryCounter() { fullWindows = Directory.Exists(@"C:\"); if (fullWindows) { int suffix = 0; do { suffix++; var wayneLibLogGloballogentrycounter = GlobalName + "." + suffix; fullWindowsSemaphoreHandle = OpenSemaphore(0, true, wayneLibLogGloballogentrycounter); if (fullWindowsSemaphoreHandle == 0) fullWindowsSemaphoreHandle = CreateSemaphore(0, 1, int.MaxValue, wayneLibLogGloballogentrycounter); } while (fullWindowsSemaphoreHandle == 0); } } /// /// Finalizer. /// ~GlobalLogEntryCounter() { Dispose(false); } #endregion #region IDisposable Members /// /// Releases all resources used by this object. /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } private void Dispose(bool disposing) { if (!disposed) { disposed = true; if (disposing) { // Dispose managed resources here! } if (fullWindowsSemaphoreHandle != 0) { CloseHandle(fullWindowsSemaphoreHandle); fullWindowsSemaphoreHandle = 0; } } } #endregion #region Methods public UInt64 GetNextValue() { if (fullWindows) { if (fullWindowsSemaphoreHandle != 0) { int lastCount; if (ReleaseSemaphore(fullWindowsSemaphoreHandle, 1, out lastCount)) return (UInt64)lastCount; } } return 0; } #endregion } }