Instrument Control (GPIB, Serial, VISA, IVI)

cancel
Showing results for 
Search instead for 
Did you mean: 

NI-CAN application fails when run as a .NET web service

Ok, I've tried changing the permission on the account used to run web services under IIS.  I even went so far as to make the account an administrator account.  Unfortunately this made no difference.  I'm still getting the error identified above.

 

What are the parameters to the Mutex creation call that's failing?  Perhaps that will give me a clue as to what's wrong.

 

Thanks,

Richard 

0 Kudos
Message 11 of 16
(1,543 Views)

Ok, after considerable digging with a debugger, and doing some experimentation, I have a much better handle on what's going on here.

 

The failing CreateMutex call is trying to create the Named Mutex "_NICAN_FRM_DEVICE@CAN9".  The call is failing the second time I call ncOpenObject.  The way my application uses NI-CAN is by opening the interface using a set of default attributes.  Then, under some circumstances, it closes the interface, changes some attributes, and attempts to re-open the interface.  It is the second open attempt that is failing.  Since I can't change attributes without closing and re-opening, I have to make a second ncOpenObject call.  One of the key aspects of this failure is that the second ncOpenObject call is made on a different thread from the first call.  Now the parameters to the CreateMutex call in the NI-CAN DLL specifies NULL in the lpSecurityDescriptor of the SECURITY_ATTRIBUTES structure.  This implies the use of the DEFAULT SecurityDescriptor for the newly created Mutex.  The problem arises because the default SecurityDescriptor within the ASPNET web service process is different from the default SecurityDescriptor of a user application.  Because I close and re-open the interface on a different thread from the one used to originally open it, the second call fails in the web service context but not in the normal user context due to the different SecurityDescriptor's.

 

This documentation: http://msdn.microsoft.com/en-us/library/ms682411(VS.85).aspx addresses the situation in which a second call to CreateMutex is made with the same NAME.  It says "The handle returned by CreateMutex has the MUTEX_ALL_ACCESS access right; it can be used in any function that requires a handle to a mutex object, provided that the caller has been granted access. If a mutex is created from a service or a thread that is impersonating a different user, you can either apply a security descriptor to the mutex when you create it, or change the default security descriptor for the creating process by changing its default DACL. For more information, see Synchronization Object Security and Access Rights."

 

I see several ways of addressing this problem.  First though, I have a question.  Why is a second attempt to call CreateMutex happening at all?  Mutex handles can be shared among multiple threads, as I understand them so there is no reason to call CreateMutex a second time for a given interface.  If the second call is necessary, then, if it fails with the ACCESS_DENIED error, it would be appropriate to call OpenMutex which should succeed in getting a second handle to the already existing Mutex.  A third approach would be to specify a SecurityDescriptor which would allow other threads to successfully call CreateMutex after the Mutex already exists.  This last method would address the situation in which multiple Applications were attempting to concurrently access the same interface regardless of the default SecurityDescriptor they were running with.

 

I hope this clarifies the situation and points the way to a timely correction to this problem.

 

Thanks for reading.

Richard

0 Kudos
Message 12 of 16
(1,517 Views)

Hi Richard,

 

You mention this:

"Since I can't change attributes without closing and re-opening,"

 

Which attributes are you trying to change?  You can call ncStop (stopping the interface) and then call setProperty to change some attributes. I know that's solving the issue, but it may be a temporary workaround.

 

O. Proulx
National Instruments
www.ni.com/support
0 Kudos
Message 13 of 16
(1,480 Views)

O,

 

Thanks for the response.  I'm aware that some properties are modifiable by stopping the interface before changing them.  The documentation on the ncConfig function says "Attributes with Config permissions must be initialized prior to opening the object, and cannot be changed using ncSetAttribute. Attributes with Config permissions must be initialized prior to opening the object, and cannot be changed using ncSetAttribute. These include the setting of BaudRate and Comparator settings, which are among those that I need to set.

 

If I'm not reading the documentation correctly, can you explain how I can identify those properties that are settable without closing the interface?

 

I'm studying whether or not I can either defer the opening of the interface until after I know the settings of all the properties, and/or make all open/close and ncConfig calls on the same thread.  Either of these would be considered "work-around" efforts which will introduce undesirable complexity, don't really address the underlying problem, and would need to be removed once the NI-CAN library is corrected.

 

Thanks again for looking into this issue,

Richard

0 Kudos
Message 14 of 16
(1,468 Views)

Hello Richard,

 

We may have a possible fix.  Please send an email to canpse@ni.com so we can go over more details directly.

 

Thanks,

O. Proulx
National Instruments
www.ni.com/support
0 Kudos
Message 15 of 16
(1,454 Views)

Great!  Email sent.

0 Kudos
Message 16 of 16
(1,435 Views)