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
}
}