Sunday, August 31, 2008

Probing thread state in .NET application

In multi-threaded application, some threads could be running fine, others might have problem. While trouble-shooting bug in a multi-threaded application, someone pointed me out that there are 2 set of thread id and thread state can be probed:
1) ThreadState Enumeration in System.Diagnostics (in system.dll)
2) ThreadState Enumeration in System.Threading (in mscorlib.dll)

While the enumerate members can be found in MSDN easily, the associate integer value is a bit tricky. And using Reflector, its values are:


and


While it's easy to use "Thread.CurrentThread" to check the state of the current thread, most of the time we need to monitor all the threads. Furthermore you will get a whole different set of thread id, if using property "Thread.CurrentThread.ManagedThreadId". Thus, classes like "ProcessThreadCollection":

For Each threCurr As ProcessThread In Process.GetCurrentProcess().Threads
Console.WriteLine("ID : " + CStr(threCurr.Id) + " ; State : " + CStr(threCurr.ThreadState))
Next

will be useful to enumerate all the threads in your application, especially you can simply use any other third party tool like Process-Explorer to probe all the thread easily, in real-time:

Friday, August 29, 2008

Red Gate has acquired .NET Reflector

Reflector is an useful tool for developer to figure out the inner work of .NET framework, and Red Gate, a software company that famous with the SQL tool likes SQL Compare, SQL Prompt, SQL Data Compare, has acquired it last week. Here's what's on Lutz Roeder's weblog. Hope it can remain free: The Future of Reflector

Sunday, August 17, 2008

Impersonation in VB6

Since VB6 is released around 1998 or earlier, and now we are on year 2008, this topic might be obsolete for some to discuss. Since supporting legacy system is inevitable, I have something simple but might useful to share, on impersonation.

(Sample source discussed can be downloaded here.)

When an application needs to perform any operation on a network folder, using UNC path, it's not like what we can simply do anything in our own drives. Let's say we try to do file copy with vb6 app using:

FileCopy App.Path & "\HelloWorld.txt", txtCurrNetworkPath.Text & "\HelloWorld.txt"

You will get this:

Some folders in the network only permit for certain personnel to access, to deal with it you must able to prove you are authorized to access it. By using LogonUser() API function, you can achieve it.

Visual Basic 6 provides an Win32 API viewer for you to invoke (copy-and-paste in source) it, it's normally located at: "Start">"All Programs">"Microsoft Visual Studio 6.0">"Microsoft Visual Studio 6.0 Tools">"API Text Viewer".

For the first-time user, you might need to load the look-up files or database before you can see the available API.

Type the API that you are looking for and the result will be filtered in real-time. Now you can get what you want, but beware the gotcha. It mentions you need to add reference with "Kernel32.lib":

From MSDN mentioned earlier, the actual library you need is "Advapi32.lib". OK, now you refer it using the correct library in the source with:

Private Declare Function LogonUser Lib "advapi32.dll" Alias _
"LogonUserA" _
(ByVal lpszUsername As String, _
ByVal lpszDomain As String, _
ByVal lpszPassword As String, _
ByVal dwLogonType As Long, _
ByVal dwLogonProvider As Long, _
phToken As Long) As Long

And we find a remote pc with a folder shared.

Let set "everybody" can access on it.


using this account in system account database, as shown in "Computer Management":

Next if you follow this tutorial (How to impersonate a user from Active Server Pages) or another tutorial (How to start a process as another user from Visual Basic), and apply it on a simple "Standard EXE".

You might use "LOGON32_LOGON_INTERACTIVE" as parameter "dwLogonType". Now you try to run it and you will get this error message:


What the heck?

Could it be this parameter "dwLogonType" that casue the error? So we browse to Win32 header file (usually at: C:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\Include) first and check the possible value for parameter "dwLogonType" since we know the domain/user/password are all correct. From "winbase.h", "9" represent another constant for "LOGON32_LOGON_NEW_CREDENTIALS".

Declaring it at our VB6 application:

Private Const LOGON32_LOGON_NEW_CREDENTIALS = 9

replaces "LOGON32_LOGON_INTERACTIVE" with it as parameter "dwLogonType" for LogonUser() function and eventually it works.

Note that in some pc, the impersonation might take long time.

Also, the allowed user for accessing the shared folder must be taken note as well. Previously we use PC name or IP address as our domain for a shared folder that can be accessed by "everyone"; if only a particular user in Active Directory (AD) can access a network folder, then you must provide AD account to impersonate, instead of account in system account database.

If you have logon-ed the remote shared folder from "Run" before, the previous example might be useless to prove its worth. Try reboot your pc before you try example above.

Friday, August 8, 2008

Finally, MSSQL 2008 is RTM-ed.

After its initial launch on February, MSSQL 2008 reaches RTM. With the new logo,

it comes with a lots of useful resources:
1) Quick-Start Installation of SQL Server 2008
2) Installing SQL Server 2008
3) Editions and Components of SQL Server 2008
4) Webcasts
5) What's New
6) how can we forget the most important one: Tutorials
Wait no more, start your engine with full-throttle and go!