Retired Microsoft Blog disclaimer

This directory is a mirror of retired "Decrypt My World" MSDN blog and is provided as is. All posting authorship and copyrights belong to respective authors.

Posts on this page:

Original URL: https://blogs.msdn.microsoft.com/alejacma/2009/06/30/sos-cheat-sheet-net-2-03-03-5/
Post name: SOS Cheat Sheet (.NET 2.0/3.0/3.5)
Original author: Alejandro Campos Magencio
Posting date: 2009-06-30T11:34:00+00:00


Hi all,


This is the list of commands related to the SOS extension that I use when debugging with WinDbg most of the .NET issues I face:

========================================================================
HELP
========================================================================

.hh
-> Open Debugger.chm.
!SOS.help
-> See all commands in an extension.
!SOS.help !command
-> Get help for one command in an extension.

========================================================================
PREPARE THE ENVIRONMENT
========================================================================

---------------
SET SYMBOL PATH
---------------

.sympath
-> Shows current symbol path.
.sympath srv*c:\symbols*\\symbols\symbols
-> Sets symbol path.
.sympath+ srv*c:\symbolspub*http://msdl.microsoft.com/downloads/symbols
-> Adds path to symbol path.

--------------------
SET SOURCE CODE PATH
--------------------

.srcpath
-> Shows current source path.
.srcpath \\dubitgfila04\DevDivServicing\whidbey\50727.42\sources
-> Sets source path.
.srcpath+ C:\path
-> Adds path to source path.

----------------
LOAD EXTENSIONS
----------------

.chain
-> Shows loaded extensions.
!EEVersion
-> Shows .NET version and SOS version.
.load SOS
-> Loads extension.
sxe ld mscorwks.dll; g; .loadby SOS mscorwks
sxe -c "" clrn; g; .loadby SOS mscorwks
sxe -c ".loadby sos mscorwks; g" ld mscorwks.dll
-> Loads the right version of SOS when mscorwks.dll gets loaded.
.unload SOS
-> Unloads extension

========================================================================
SET A BREAKPOINT
========================================================================

-----------
FIND METHOD
-----------

!DumpDomain
-> Shows all app domains and their assemblies/modules.
!DumpAssembly <Assembly>
-> Shows assembly info: name, modules...
!DumpModule -mt <Module>
-> Shows Method Tables (types) defined and referenced by a module.
!DumpMT -md <Method Table>
-> Shows Method Descriptors of a Method Table.
!DumpMD <Method Descriptor>
-> Shows Method Descriptor info. We can see Code Address if method
is jitted.
!Name2EE <Module> <NameSpace.Class.Method>
!Name2EE <Module>!<NameSpace.Class.Method>
-> Shows Method Descriptor and jitted Code Address of a method.
!Name2EE * <NameSpace.Class.Method>
!Name2EE *!<NameSpace.Class.Method>
-> Shows Module, Method Descriptor and jitted Code Address of a
method.

--------------
SET BREAKPOINT
--------------

!BPMD -md <Method Descriptor>
-> Sets breakpoint on method by Method Descriptor.
bp <Code Address>
-> Sets breakpoint on method by jitted Code Address.
!BPMD <Module> <NameSpace.Class.Method>
-> Sets breakpoint on method by module and name.
bl
-> Lists breakpoints.
bd 0
bd *
-> Disables breakpoints.
be 1
-> Enables breakpoint.
bc 0
-> Removes breakpoints.

-----------------
STEP THROUGH CODE
-----------------

l+t
-> Enables source code mode. With private symbols and source code,
Windbg will open source code files automatically.
l-t
-> Enables assembly mode.
p
-> Steps over (F10).
t
-> Steps into (F11 or F8).

========================================================================
CALL STACKS
========================================================================

--------------------------
INSPECT CURRENT CALL STACK
--------------------------

k
-> Shows unmanaged + managed call stack.
kp
-> Shows unmanaged + managed call stack with unmanaged parameters.
!DumpStack
-> Shows raw call stack with unmanaged + managed calls and managed
Method Descriptors.
!CLRStack
-> Shows managed call stack.
!DumpStack -EE
-> Shows managed call stack with Method Descriptors.
!CLRStack -p
-> Shows managed call stack with parameters.
!CLRStack -l
-> Shows managed call stack with locals (we will only see memory
addresses in the stack).
!CLRStack -a
-> Shows managed call stack with parameters and locals.

---------------
INSPECT OBJECTS
---------------

!DumpObj <Object>
!do <Object>
-> Shows object info: Method Table, EEClass, size, fields...
!DumpArray <Array>
!da <Array>
-> Shows array info: # of elements, elements, their type...

-------------------
INSPECT SOURCE CODE
-------------------

kn
-> Shows unmanaged + managed call stack with frame numbers.
.frame <Frame Number>
-> Changes the local context to a specific method frame. With Source
Code Mode enabled, private symbols and source code, Windbg will
open the source code file automatically.

------------
INSPECT MSIL
------------

!IP2MD <Instruction Pointer>
!CLRStack; !IP2MD <Instruction Pointer>
!DumpStack -EE
!IP2MD @eip
-> Gets a Method Descriptor that we can use with !DumpIL.
!DumpIL <Method Descriptor>
-> Shows IL of a method. ILDASM.exe and Reflector.exe show the same
IL, but also locals.

-------------------
INSPECT SOURCE CODE
-------------------
lm; !SaveModule <Dll start> c:\sample.dll
-> Writes a loaded dll to disk.

----------------
INSPECT ASSEMBLY
----------------

k
!DumpMD <Method Descriptor>
!DumpStack -EE; !DumpMD <Method Descriptor>
-> Gets Code Address of an unmanaged or managed jitted method.
u <Code Address>
-> Shows several lines of assembly code at a given Code Address, and
source code lines if we have private symbols.
uf <Code Address>
-> Shows all the assembly code of the managed or unmanaged function
containing the Code Address, and source code lines if we have
private symbols.
!u <Code Address>
-> Shows all the assembly code of the managed method containing the
Code Address, and marks that address with ">>>".
If address is in unmanaged method and we have private symbols and
source code, it shows all the assembly in that method along with
the source code itself!

-----------------
INSPECT REGISTERS
-----------------

r ecx
-> When hitting a breakpoint on a managed function, it shows its
first parameter (_fastcall calling convention). First parameter
is usually the 'this' pointer.
r edx
-> When hitting a breakpoint on a managed function, it shows its
second parameter (_fastcall calling convention).
r esi
-> Typically used to hold the 'this' pointer as copied from ecx.

========================================================================
THREADS
========================================================================

-------------------
INSPECT ALL THREADS
-------------------

~
-> Shows all threads (managed and unmanaged).
!runaway
-> Shows time consumed by each thread.
~0s
-> Switches to thread 0.
~#s
-> Switches to the thread where the debugger broke.
~*k100
-> Shows all unmanaged + managed call stacks in all threads.
!Threads
-> Shows all managed threads.
~*e !CLRStack
-> Shows managed calls in all threads.
!Threads -special
-> Shows all .NET related threads (managed and unmanaged).
!ThreadPool
-> Shows ThreadPool info: number of work requests in the queue,
timers and completion port threads.

========================================================================
THREAD STACKS
========================================================================

----------------------------
INSPECT OBJECTS IN THE STACK
----------------------------

!DumpStackObjects
!dso
-> Shows a list of references to objects that are still on the
thread’s stack.

---------------
INSPECT OBJECTS
---------------

!do <Object>
-> Shows object info: Method Table, EEClass, size, fields...
!do -nofields <Object>
-> Shows object info but not fields. Good to see i.e. Strings.
!da <Array>
-> Shows array info: # of elements, elements, their type...
!DumpVC <Method Table> <Value Type Address>
-> Shows value type structs ('VT = 1' in '!do').
!DumpClass <EEClass>
-> Shows the static fields of an object/class ('Attr = static' in
'!do'). These fields are part of the EEClass, a representation of
a class created before any method invocations are made on it.
!DumpClass <EEClass>
!Name2EE <Module> <NameSpace.Class>; !DumpClass <EEClass>
-> Shows the static fields of a class.

========================================================================
MANAGED HEAP
========================================================================

------------
INSPECT HEAP
------------

!EEVersion
-> Shows version of GC heap (server/workstation) and how many GC
heaps we have in server mode.
!EEHeap -gc
-> Shows how many GC heaps there are and how much memory is taken by
them.
!Threads
-> Shows if Preemptive GC is enabled on a thread.

---------------------------
INSPECT OBJECTS IN THE HEAP
---------------------------

!DumpHeap
-> Shows all objects in the heap.
!DumpHeap -stat
-> Shows statistics of all objects in the heap: # of objects of
a given type/Method Table, etc.
!DumpHeap -mt <Method Table>
!Name2EE * <NameSpace.Class.Method>; !DumpHeap -mt <Method Table>
-> Shows all objects in the heap of a given type/Method Table.
!DumpHeap -type <Partial Class Name>
-> Shows all objects in the heap which class name contains a text.
!DumpHeap -min 85000
!EEHeap -GC; !DumpHeap <LOH begin> <LOH allocated>
-> Shows all objects in Large Object Heap (LOH/Gen 3).
!FinalizeQueue
-> Shows which objects are ready for finalization and in general
which objects in the heap have a Finalize method.
!FinalizeQueue; dd <generation 0 begin> <generation 0 end>-4
-> Shows all finalizable objects in Gen 0.
!FinalizeQueue; !DumpHeap -mt <Method Table>
-> Shows all finalizable objects of a given Method Table/type.
!DumpMT -md <Method Table>
-> Useful to check if an object/class has Finalize and Dispose
methods.
!FinalizeQueue -detail
-> Shows SyncBlocks and RuntimeCallableWrappers (RCW) registered
for finalization.
!GCRoot <Object>
-> Shows references to an object.
!ObjSize <Object>
-> Shows the size of an object including its child objects.

------------------------
TROUBLESHOOT HEAP ISSUES
------------------------

!TraverseHeap c:\memory.log
-> Generates a log file which can be analyzed with CLR Profiler.
!VerifyHeap
-> Checks the heap for signs of corruption.

---------------------------
TROUBLESHOOT GCHANDLE LEAKS
---------------------------

!GCHandles
-> Shows statistics of GCHandles.
!GCHandleLeaks
-> Tracks down GCHandle leaks.
!GCHandleLeaks; !DumpObj poi(<GCHandle>)
-> Shows the object a GCHandle references.

-------------------------------
TROUBLESHOOT LOADER HEAP ISSUES
-------------------------------

!DumpHeap -stat -type Assembly
-> Shows the number of assemblies in the heap.
!DumpDomain
-> Shows all assemblies.
!DumpDomain; !DumpModule <Module>; dc <MetaData start> <MetaData start>+<Metadata size>
-> Shows metadata of a module in an assembly.
!EEHeap -loader
-> Shows Loader Heap size and modules.

========================================================================
BREAK ON AN EXCEPTION
========================================================================

-----------------------
BREAK ON CLR EXCEPTIONS
-----------------------

sxe clr
sxe 0xe0434f4d
-> Break on all CLR exceptions.
!StopOnException -create <Exception Type> 1
!soe -create <Exception Type> 1
-> Break on a specific CLR exception type.
!soe -derived -create <Base Exception Type> 1
-> Break on all exceptions which derive from a certain type.
sxn clr
-> Stops breaking on CLR exceptions. If we used '!soe' before, we
can still see the exception types of the CLR exceptions that we
hit, but the debugger won't break on them.
sxr
-> Resets to defaults.

----------------------
INSPECT CLR EXCEPTIONS
----------------------

kp; !do <Object from mscorwks!RaiseTheExceptionInternalOnly>
-> Shows exception object info.
!PrintException <Object>
!pe <Object>
-> Shows exception info.
!pe
-> Shows exception info of last exception thrown in current thread.
!dso; !pe <Object>
-> Shows exception info of an exception in the stack of current
thread.
!DumpHeap -type Exception; !DumpHeap -mt <Method Table>; !pe <Object>
-> Shows exception info of an exception in the heap.
.foreach(ex {!DumpHeap -type <Partial Class Name> -short}){!pe ex;.echo}
-> Shows exception info of all exceptions of a given type in the
heap.

-----------------------------------------
INSPECT METHOD WHERE WE GOT THE EXCEPTION
-----------------------------------------

!pe <Object>; !u <Instruction Pointer>; u <Memory Address>
-> Shows the line of code where the exception happened.

========================================================================
LOCKS
========================================================================

---------------------
INSPECT MANAGED LOCKS
---------------------

!SyncBlk
-> Shows the Index of the syncblock in the syncblock table, the
address of the syncblock, the thread holding it & the object
which syncblock we are waiting for. MonitorHeld = 1 for each
owner and 2 for each waiter. Used with i.e.
System.Threading.Monitor.
~*kp; ~*e !CLRStack -p; ~*e !dso; !SyncBlk
-> Helps to find out which threads are waiting on the syncblock of
which object.

-----------------------
INSPECT UNMANAGED LOCKS
-----------------------

!locks
!critsec
!SIEExt.critlist
-> Shows info of a critical sections (unmanaged). Use with i.e.
System.Threading.Mutex (not based on syncblocks).



Check out my post MANAGED DEBUGGING with WINDBG. Introduction and Indexfor additional info and samples on how to use these commands


Regards,



Alex (Alejandro Campos Magencio)

Original URL: https://blogs.msdn.microsoft.com/alejacma/2009/06/23/how-to-call-interneterrordlg-to-deal-with-certificate-issues-on-ssl-connections-c/
Post name: How to call InternetErrorDlg to deal with certificate issues on SSL connections (C#)
Original author: Alejandro Campos Magencio
Posting date: 2009-06-23T05:28:00+00:00


Hi all,

The following C# sample shows how to call WinInet APIs to make an SSL request and deal with possible certificate issues with InternetErrorDlg (which will show the same standard dialogs that Internet Explorer shows when something is wrong with server or client certs):
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Net;

namespace WindowsApplication1
{
class Tester
{
public static string TestSSLRequest(IntPtr hWnd, string lpszServerName, short nServerPort, string lpszUrl)
{
// Variables
IntPtr hInternet = IntPtr.Zero;
string lpszAgent;
int dwAccessType = 0;
string lpszProxyName;
string lpszProxyBypass;
int dwFlags = 0;
string lpszUserName;
string lpszPassword;
int dwService = 0;
IntPtr dwContext = IntPtr.Zero;
IntPtr hConnect = IntPtr.Zero;
string lpszVerb;
string lpszObjectName;
string lpszVersion;
string lpszReferer;
IntPtr lplpszAcceptTypes = IntPtr.Zero;
IntPtr hRequest = IntPtr.Zero;
IntPtr lpOptional = IntPtr.Zero;
int dwError = 0;
string lpszHeaders;
int dwHeadersLength = 0;
int dwOptionalLength = 0;
IntPtr lppvData = IntPtr.Zero;
int dwNumberOfBytesAvailable = 0;
IntPtr lpBuffer = IntPtr.Zero;
int dwOption = 0;
ulong ulOptionMask = 0;
int dwBufferLength = 0;
int dwNumberOfBytesToRead = 0;
int dwNumberOfBytesRead = 0;

bool bResult = false;
int iResult = 0;

// Let's begin!!!
try
{
// Initializes the app's use of the WinINet functions
lpszAgent = "AlejaCMa";
dwAccessType = Win32API.INTERNET_OPEN_TYPE_PRECONFIG;
lpszProxyName = null;
lpszProxyBypass = null;
dwFlags = 0;
hInternet = Win32API.InternetOpen(lpszAgent, dwAccessType, lpszProxyName, lpszProxyBypass, dwFlags);
if (hInternet.Equals(IntPtr.Zero))
{
throw new Exception("InternetOpen: Error #" + Marshal.GetLastWin32Error().ToString());
}

// Opens HTTP session for the site
lpszUserName = null;
lpszPassword = null;
dwService = Win32API.INTERNET_SERVICE_HTTP;
dwFlags = 0;
dwContext = IntPtr.Zero;
hConnect = Win32API.InternetConnect(hInternet, lpszServerName, nServerPort, lpszUserName, lpszPassword, dwService, dwFlags, dwContext);
if (hConnect.Equals(IntPtr.Zero))
{
throw new Exception("InternetConnect: Error #" + Marshal.GetLastWin32Error().ToString());
}

// Create HTTP request handle
lpszVerb = "GET";
lpszObjectName = lpszUrl;
lpszVersion = null;
lpszReferer = null;
lplpszAcceptTypes = IntPtr.Zero;
dwFlags = Win32API.INTERNET_FLAG_SECURE;
dwContext = IntPtr.Zero;
hRequest = Win32API.HttpOpenRequest(hConnect, lpszVerb, lpszObjectName, lpszVersion, lpszReferer, lplpszAcceptTypes, dwFlags, dwContext);
if (hRequest.Equals(IntPtr.Zero))
{
throw new Exception("HttpOpenRequest: Error #" + Marshal.GetLastWin32Error().ToString());
}

// Configure request to get combined cert errors
dwOption = Win32API.INTERNET_OPTION_ERROR_MASK;
ulOptionMask = Win32API.INTERNET_ERROR_MASK_COMBINED_SEC_CERT;
dwBufferLength = Marshal.SizeOf(lpBuffer);
bResult = Win32API.InternetSetOption(hRequest, dwOption, ref ulOptionMask, dwBufferLength);
if (!bResult)
{
throw new Exception("InternetSetOption: Error #" + Marshal.GetLastWin32Error().ToString());
}

do
{
// Send request to the server
lpszHeaders = null;
dwHeadersLength = 0;
lpOptional = IntPtr.Zero;
dwOptionalLength = 0;
bResult = Win32API.HttpSendRequest(hRequest, lpszHeaders, dwHeadersLength, lpOptional, dwOptionalLength);

if (!bResult)
{
// Deal with possible errors
switch (Marshal.GetLastWin32Error())
{
case Win32API.ERROR_INTERNET_SEC_CERT_ERRORS:
dwError = Win32API.ERROR_INTERNET_SEC_CERT_ERRORS;
break;
case Win32API.ERROR_INTERNET_INVALID_CA:
dwError = Win32API.ERROR_INTERNET_INVALID_CA;
break;
case Win32API.ERROR_INTERNET_SEC_CERT_CN_INVALID:
dwError = Win32API.ERROR_INTERNET_SEC_CERT_CN_INVALID;
break;
case Win32API.ERROR_INTERNET_SEC_CERT_DATE_INVALID:
dwError = Win32API.ERROR_INTERNET_SEC_CERT_DATE_INVALID;
break;
case Win32API.ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED:
dwError = Win32API.ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED;
break;
default:
// Unknown error
throw new Exception("HttpSendRequest: Error #" + Marshal.GetLastWin32Error().ToString());
}

// Display cert error dialog box
dwFlags = Win32API.FLAGS_ERROR_UI_FLAGS_GENERATE_DATA + Win32API.FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS;
lppvData = IntPtr.Zero;
iResult = Win32API.InternetErrorDlg(hWnd, hRequest, dwError, dwFlags, lppvData);
switch (iResult)
{
case Win32API.ERROR_SUCCESS:
break;
case Win32API.ERROR_CANCELLED:
throw new Exception("InternetErrorDlg: The function was canceled by the user");
case Win32API.ERROR_INTERNET_FORCE_RETRY:
throw new Exception("InternetErrorDlg: Function needs to redo its request. In the case of authentication this indicates that the user clicked the OK button.");
case Win32API.ERROR_INVALID_HANDLE:
throw new Exception("InternetErrorDlg: The handle to the parent window is invalid");
default:
throw new Exception("InternetErrorDlg: Error #" + iResult.ToString());
}
}
} while (!bResult);

// Determine the amount of data available
dwNumberOfBytesAvailable = 0;
dwFlags = 0;
dwContext = IntPtr.Zero;
bResult = Win32API.InternetQueryDataAvailable(hRequest, ref dwNumberOfBytesAvailable, dwFlags, dwContext);
if (!bResult)
{
throw new Exception("InternetQueryDataAvailable: Error #" + Marshal.GetLastWin32Error().ToString());
}

// Read data
lpBuffer = Marshal.AllocHGlobal(dwNumberOfBytesAvailable);
dwNumberOfBytesToRead = dwNumberOfBytesAvailable;
dwNumberOfBytesRead = 0;
bResult = Win32API.InternetReadFile(hRequest, lpBuffer, dwNumberOfBytesToRead, ref dwNumberOfBytesRead);
if (!bResult)
{
throw new Exception("InternetReadFile: Error #" + Marshal.GetLastWin32Error().ToString());
}

// Everything went well. Return data
return Marshal.PtrToStringAnsi(lpBuffer, dwNumberOfBytesRead);
}
catch (Exception ex)
{
// Show error
MessageBox.Show("Exception: " + ex.Message);
return "";
}
finally
{
// Clean up
if (!lpBuffer.Equals(IntPtr.Zero))
{
Marshal.FreeHGlobal(lpBuffer);
}
if (!hInternet.Equals(IntPtr.Zero))
{
Win32API.InternetCloseHandle(hInternet);
}
if (!hConnect.Equals(IntPtr.Zero))
{
Win32API.InternetCloseHandle(hConnect);
}
if (!hRequest.Equals(IntPtr.Zero))
{
Win32API.InternetCloseHandle(hRequest);
}
}
}
}
}


These are the P/Invoke declarations of the APIs that I've used before:

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace WindowsApplication1
{
class Win32API
{
// #define INTERNET_OPEN_TYPE_DIRECT 1
public const int INTERNET_OPEN_TYPE_DIRECT = 1;

//#define INTERNET_OPEN_TYPE_PRECONFIG 0
public const int INTERNET_OPEN_TYPE_PRECONFIG = 0;

// #define INTERNET_SERVICE_HTTP 3
public const int INTERNET_SERVICE_HTTP = 3;

// #define INTERNET_FLAG_SECURE 0x00800000
public const int INTERNET_FLAG_SECURE = 0x00800000;

// #define INTERNET_OPTION_SECURITY_CERTIFICATE 35
public const int INTERNET_OPTION_SECURITY_CERTIFICATE = 35;

// #define ERROR_SUCCESS 0L
public const int ERROR_SUCCESS = 0;

// #define ERROR_INVALID_HANDLE 6L
public const int ERROR_INVALID_HANDLE = 6;

// #define ERROR_INSUFFICIENT_BUFFER 122L
public const int ERROR_INSUFFICIENT_BUFFER = 122;

// #define ERROR_CANCELLED 1223L
public const int ERROR_CANCELLED = 1223;

// #define INTERNET_OPTION_ERROR_MASK 62
public const int INTERNET_OPTION_ERROR_MASK = 62;

// #define INTERNET_ERROR_MASK_COMBINED_SEC_CERT 0x2
public const ulong INTERNET_ERROR_MASK_COMBINED_SEC_CERT = 0x2;

// #define INTERNET_ERROR_BASE 12000
public const int INTERNET_ERROR_BASE = 12000;

// #define ERROR_INTERNET_FORCE_RETRY (INTERNET_ERROR_BASE + 32)
public const int ERROR_INTERNET_FORCE_RETRY = INTERNET_ERROR_BASE + 32;

// #define ERROR_INTERNET_SEC_CERT_DATE_INVALID (INTERNET_ERROR_BASE + 37)
public const int ERROR_INTERNET_SEC_CERT_DATE_INVALID = INTERNET_ERROR_BASE + 37;

// #define ERROR_INTERNET_SEC_CERT_CN_INVALID (INTERNET_ERROR_BASE + 38)
public const int ERROR_INTERNET_SEC_CERT_CN_INVALID = INTERNET_ERROR_BASE + 38;

// #define ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED (INTERNET_ERROR_BASE + 44)
public const int ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED = INTERNET_ERROR_BASE + 44;

// #define ERROR_INTERNET_SEC_CERT_ERRORS (INTERNET_ERROR_BASE + 55)
public const int ERROR_INTERNET_SEC_CERT_ERRORS = INTERNET_ERROR_BASE + 55;

//#define ERROR_INTERNET_INVALID_CA (INTERNET_ERROR_BASE + 45)
public const int ERROR_INTERNET_INVALID_CA = INTERNET_ERROR_BASE + 45;

// #define FLAGS_ERROR_UI_FILTER_FOR_ERRORS 0x01
public const int FLAGS_ERROR_UI_FILTER_FOR_ERRORS = 0x01;

// #define FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS 0x02
public const int FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS = 0x02;

// #define FLAGS_ERROR_UI_FLAGS_GENERATE_DATA 0x04
public const int FLAGS_ERROR_UI_FLAGS_GENERATE_DATA = 0x04;

// DWORD InternetErrorDlg(
// __in HWND hWnd,
// __inout HINTERNET hRequest,
// __in DWORD dwError,
// __in DWORD dwFlags,
// __inout LPVOID *lppvData
// );
[DllImport("wininet.dll", SetLastError = true)]
public extern static int InternetErrorDlg
(
IntPtr hWnd,
IntPtr hRequest,
int dwError,
int dwFlags,
IntPtr lppvData
);

// BOOL HttpSendRequest(
// __in HINTERNET hRequest,
// __in LPCTSTR lpszHeaders,
// __in DWORD dwHeadersLength,
// __in LPVOID lpOptional,
// __in DWORD dwOptionalLength
// );
[DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
public extern static bool HttpSendRequest
(
IntPtr hRequest,
string lpszHeaders,
int dwHeadersLength,
IntPtr lpOptional,
int dwOptionalLength
);

// HINTERNET HttpOpenRequest(
// __in HINTERNET hConnect,
// __in LPCTSTR lpszVerb,
// __in LPCTSTR lpszObjectName,
// __in LPCTSTR lpszVersion,
// __in LPCTSTR lpszReferer,
// __in LPCTSTR *lplpszAcceptTypes,
// __in DWORD dwFlags,
// __in DWORD_PTR dwContext
// );
[DllImport("wininet.dll", CharSet=CharSet.Auto, SetLastError = true)]
public extern static IntPtr HttpOpenRequest
(
IntPtr hConnect,
string lpszVerb,
string lpszObjectName,
string lpszVersion,
string lpszReferer,
IntPtr lplpszAcceptTypes,
int dwFlags,
IntPtr dwContext
);

// HINTERNET InternetConnect(
// __in HINTERNET hInternet,
// __in LPCTSTR lpszServerName,
// __in INTERNET_PORT nServerPort,
// __in LPCTSTR lpszUsername,
// __in LPCTSTR lpszPassword,
// __in DWORD dwService,
// __in DWORD dwFlags,
// __in DWORD_PTR dwContext
// );
[DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
public extern static IntPtr InternetConnect
(
IntPtr hInternet,
string lpszServerName,
short nServerPort,
string lpszUsername,
string lpszPassword,
int dwService,
int dwFlags,
IntPtr dwContext
);

// BOOL WINAPI InternetCloseHandle(
// HINTERNET hInternet
// );
[DllImport("wininet.dll", SetLastError = true)]
public extern static bool InternetCloseHandle
(
IntPtr hInternet
);

// HINTERNET InternetOpen(
// __in LPCTSTR lpszAgent,
// __in DWORD dwAccessType,
// __in LPCTSTR lpszProxyName,
// __in LPCTSTR lpszProxyBypass,
// __in DWORD dwFlags
//);
[DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
public extern static IntPtr InternetOpen
(
string lpszAgent,
int dwAccessType,
string lpszProxyName,
string lpszProxyBypass,
int dwFlags
);

// BOOL InternetReadFile(
// __in HINTERNET hFile,
// __out LPVOID lpBuffer,
// __in DWORD dwNumberOfBytesToRead,
// __out LPDWORD lpdwNumberOfBytesRead
// );
[DllImport("wininet.dll", SetLastError = true)]
public extern static bool InternetReadFile
(
IntPtr hFile,
IntPtr lpBuffer,
int dwNumberOfBytesToRead,
ref int dwNumberOfBytesRead
);

// BOOL InternetQueryDataAvailable(
// __in HINTERNET hFile,
// __out LPDWORD lpdwNumberOfBytesAvailable,
// __in DWORD dwFlags,
// __in DWORD_PTR dwContext
// );
[DllImport("wininet.dll", SetLastError = true)]
public extern static bool InternetQueryDataAvailable
(
IntPtr hFile,
ref int dwNumberOfBytesAvailable,
int dwFlags,
IntPtr dwContext
);

// BOOL InternetSetOption(
// __in HINTERNET hInternet,
// __in DWORD dwOption,
// __in LPVOID lpBuffer,
// __in DWORD dwBufferLength
// );
[DllImport("wininet.dll", SetLastError = true)]
public extern static bool InternetSetOption
(
IntPtr hInternet,
int dwOption,
ref ulong lpBuffer,
int dwBufferLength
);
}
}


And this is a sample Form that shows how to use my sample code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
this.textBox1.Text = Tester.TestSSLRequest(this.Handle, "127.0.0.1", 443, "TEST.ASPX");
}
}
}



I hope this helps.


Regards,



Alex (Alejandro Campos Magencio)

Original URL: https://blogs.msdn.microsoft.com/alejacma/2009/05/28/certenrollcx509enrollmentp_createrequest-returns-error-0x8009000b/
Post name: CertEnroll::CX509Enrollment::p_CreateRequest returns error 0x8009000b
Original author: Alejandro Campos Magencio
Posting date: 2009-05-28T06:36:00+00:00


Hi all,

One of the issues we may find when trying the code in my post How to create a certificate request that uses key archival with CertEnroll (JavaScript)is the following error when creating the request:

CertEnroll::CX509Enrollment::p_CreateRequest: Key not valid for use in specified state. 0x8009000b (-2146893813)

If the issue happens on Vista RTM but not on Vista SP1/Server 2008or later, then this may be the issue:

When CertEnroll creates the request, it needs to export the private key of the certificate we are requesting to encode it so we can send it to the CA for key archival. This operation will fail if the key doesn't have at least one of these flags: CRYPT_EXPORTABLE or CRYPT_ARCHIVABLE. These are flags that CertEnroll should pass to CryptGenKey API when generating the key under the hood.

Those flags are calculated from ExportPolicyfield of the X509Enrollment.CX509PrivateKey object. If we specify XCN_NCRYPT_ALLOW_EXPORT_FLAG or XCN_NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG, we get the key created with CRYPT_EXPORTABLE flag, and if we specify XCN_NCRYPT_ALLOW_ARCHIVING_FLAG or XCN_NCRYPT_ALLOW_PLAINTEXT_ARCHIVING_FLAG, we get the key created with CRYPT_ARCHIVABLE flag.

On Vista SP1/2008 Server and later, XCN_NCRYPT_ALLOW_ARCHIVING_FLAG is being set by default. This won't happen on Vista RTM, so setting ExportPolicy to XCN_NCRYPT_ALLOW_ARCHIVING_FLAG (0x4) should make things work there. Or even better, update to Vista SP2, and you forget about this and many other issues ??

I hope this helps.

Regards,

Alex (Alejandro Campos Magencio)

Original URL: https://blogs.msdn.microsoft.com/alejacma/2009/05/28/certenrollcx509enrollmentp_createrequest-returns-error-0x80092012/
Post name: CertEnroll::CX509Enrollment::p_CreateRequest returns error 0x80092012
Original author: Alejandro Campos Magencio
Posting date: 2009-05-28T06:10:00+00:00


Hi all,

One of the issues we may find when trying the code in my post How to create a certificate request that uses key archival with CertEnroll (JavaScript)is the following error when creating the request:

CertEnroll::CX509Enrollment::p_CreateRequest: The revocation function was unable to check revocation for the certificate. 0x80092012 (-2146885614)

This error will happen if the CRL of the certificate passed to theKeyArchivalCertificate property of the CMC request can't be accessed.One reason for instancemay be that the certificate is just missing a CRL distribution point.

We can check if we can properly download the CRL of a certificate with the following command:

certutil -url certificate.cer

A URL Retrieval Tool will appear for that certificate. We can select "CRLs (from CDP)" in the "Retrieve" section and press the "Retrieve" button. This tool will check if we can access the CRL or not.

Note: check this post if you need to clear the CRL cache: CRL gets cached after we do an Online verification with X509Chain.

I hope this helps.

Regards,

Alex (Alejandro Campos Magencio)

Original URL: https://blogs.msdn.microsoft.com/alejacma/2009/05/28/certenrollcx509enrollmentp_createrequest-returns-error-0x800b0112/
Post name: CertEnroll::CX509Enrollment::p_CreateRequest returns error 0x800b0112
Original author: Alejandro Campos Magencio
Posting date: 2009-05-28T05:44:00+00:00


Hi all,

One of the issues we may find when trying the code in my post How to create a certificate request that uses key archival with CertEnroll (JavaScript)is the following error when creating the request:

CertEnroll::CX509Enrollment::p_CreateRequest: A certification chain processed correctly, but one of the CA certificates is not trusted by the policy provider. 0x800b0112 (-2146762478)

This issue can occur if the CA certificate is not in client's Enterprise NTAuth store. The local NTAuth store can be manually populated using the utility certutil.exe:

Certutil -enterprise -addstore NTAuth CaCertificate.cer

More info here:

How to import third-party certification authority (CA) certificates into the Enterprise NTAuth store

I hope this helps.

Regards,

Alex (Alejandro Campos Magencio)