The RegisterVirtualMachine() method cannot access virtual machine configuration files in Virtual Server 2005 (887730)



The information in this article applies to:

  • Microsoft Virtual Server 2005

SYMPTOMS

You try to call the RegisterVirtualMachine() method in Microsoft Visual C# .NET to register an existing virtual machine configuration file (.vmc). However, the RegisterVirtualMachine() method cannot access the .vmc files in Microsoft Virtual Server 2005.

CAUSE

This problem occurs because Visual C# .NET uses the SecurityIdentification impersonation level to call the RegisterVirtualMachine() method. This method identifies the caller and performs the access check. However, in this case, Visual C# .NET cannot create or delete files on behalf of the user. When COM objects are accessed by using the common language runtime, they run in the context of a user with restricted permissions. Therefore, the RegisterVirtualMachine() method cannot access the .vmc file, and registration fails.

WORKAROUND

By default, SecurityIdentification is the COM impersonation level. To set a different level, the COM client must call the CoInitializeSecurity() function. The following code must be added to the Visual C# .NET test programs.

Add the following code to your class declaration.

	[ DllImport( "Ole32.dll", ExactSpelling=true, EntryPoint="CoInitialize", 
CallingConvention=CallingConvention.StdCall, SetLastError=false ) ]
	static extern int CoInitialize(
		IntPtr pvReserved
		);

	[ DllImport( "Ole32.dll", ExactSpelling=true, EntryPoint="CoUninitialize", 
CallingConvention=CallingConvention.StdCall, SetLastError=false ) ]
	static extern int CoUninitialize();


[ DllImport( "Ole32.dll", ExactSpelling=true, EntryPoint="CoInitializeSecurity", 
CallingConvention=CallingConvention.StdCall, SetLastError=false ) ]
	static extern int CoInitializeSecurity(
		IntPtr pVoid,
		uint cAuthSvc,
		IntPtr asAuthSvc,
		IntPtr pReserved1,
		uint  dwAuthnLevel,
		uint dwImpLevel,
		IntPtr pAuthList,
		uint dwCapabilities,
		IntPtr pReserved3
		);


Add the following code to the start of your program.
int hResult = CoInitialize( IntPtr.Zero );
	if ( hResult != 0 )  Marshal.ThrowExceptionForHR( hResult );

	hResult = CoInitializeSecurity( IntPtr.Zero, 0, IntPtr.Zero, IntPtr.Zero, 
RPC_C_AUTHN_LEVEL_NONE, RPC_C_IMP_LEVEL_IMPERSONATE, IntPtr.Zero, 0, 
IntPtr.Zero );
	if ( hResult != 0 ) Marshal.ThrowExceptionForHR( hResult );


Add the following using code at the start of your program with other using statements.
using System.Runtime.InteropServices;
Add the following code at the end of your program.
CoUninitialize();

Microsoft provides programming examples for illustration only, without warranty either expressed or implied. This includes, but is not limited to, the implied warranties of merchantability or fitness for a particular purpose. This article assumes that you are familiar with the programming language that is being demonstrated and with the tools that are used to create and to debug procedures. Microsoft support engineers can help explain the functionality of a particular procedure, but they will not modify these examples to provide added functionality or construct procedures to meet your specific requirements.

Modification Type:MajorLast Reviewed:7/5/2005
Keywords:kbinfo kbBug kbtshoot kbprb KB887730 kbAudDeveloper kbAudITPRO