private IntPtr OpenStore(bool readOnly, bool createAlways, bool throwIfNotExist)
{
IntPtr wszStoreName = IntPtr.Zero;
IntPtr hStore = IntPtr.Zero;
try
{
// check for a valid name.
if (String.IsNullOrEmpty(m_symbolicName))
{
if (throwIfNotExist)
{
throw ServiceResultException.Create(
StatusCodes.BadConfigurationError,
"WindowsCertificateStore object has not been initialized properly.");
}
return IntPtr.Zero;
}
// allocate the store base name.
wszStoreName = DuplicateString(m_symbolicName);
uint dwFlags = GetFlags(m_storeType);
if (readOnly)
{
dwFlags |= CERT_STORE_READONLY_FLAG;
}
// open or create the store.
if (!readOnly && createAlways)
{
hStore = NativeMethods.CertOpenStore(
new IntPtr(CERT_STORE_PROV_SYSTEM),
0,
IntPtr.Zero,
dwFlags | CERT_STORE_CREATE_NEW_FLAG,
wszStoreName);
}
else
{
hStore = NativeMethods.CertOpenStore(
new IntPtr(CERT_STORE_PROV_SYSTEM),
0,
IntPtr.Zero,
dwFlags | CERT_STORE_OPEN_EXISTING_FLAG,
wszStoreName);
}
// check result.
if (hStore == IntPtr.Zero)
{
int dwError = Marshal.GetLastWin32Error();
// try to open an existing store if create failed.
if (!readOnly && createAlways)
{
hStore = NativeMethods.CertOpenStore(
new IntPtr(CERT_STORE_PROV_SYSTEM),
0,
IntPtr.Zero,
dwFlags | CERT_STORE_OPEN_EXISTING_FLAG,
wszStoreName);
}
if (hStore == IntPtr.Zero)
{
// throw error.
if (throwIfNotExist)
{
throw ServiceResultException.Create(
StatusCodes.BadUnexpectedError,
"Could not open the certificate store.\r\nType={0}, Name={1}, Error={2:X8}",
m_storeType,
m_symbolicName,
dwError);
}
// graceful failure if store not found.
return IntPtr.Zero;
}
}
// return the handle.
return hStore;
}
finally
{
if (wszStoreName != IntPtr.Zero)
{
Marshal.FreeHGlobal(wszStoreName);
}
}
}