How To Call WTSSetUserConfig() and WTSQueryUserConfig() from Visual Basic (292631)



The information in this article applies to:

  • Microsoft Win32 Application Programming Interface (API), when used with:
    • the operating system: Microsoft Windows 2000

This article was previously published under Q292631

SUMMARY

This article demonstrates how to call the WTSSetUserConfig() and WTSQueryUserConfig() APIs from Microsoft Visual Basic.

MORE INFORMATION

The WTSSetUserConfig() function modifies configuration information for the specified user on the specified domain controller or Terminal Server. To set configuration information for a domain user, you must specify the name of the primary domain controller in the call to WTSSetUserConfig(). You can retrieve the name of the primary domain controller by using the NetGetDCName() function.

The WTSQueryUserConfig() function retrieves configuration information for the specified user on the specified domain controller or Terminal Server. To query configuration information for a domain user, you can specify the name of any (primary or backup) domain controller.

NOTE: In order to call WTSSetUserConfig() on a domain user account you must be a domain administrator.

Sample Code

The following Visual Basic sample code demonstrates how to use the APIs described in this article to retrieve and set a user's Terminal Server configuration settings. Each configuration setting is stored as either a string or a DWORD. The sample code demonstrates how to set and query both types of values.

To generate this sample, use the following steps:
  1. Start a new StdEXE Visual Basic Project. Form1 is created by default.
  2. Place two command buttons on the form.
  3. Paste the following code into the form:
Option Explicit

Private Declare Function WTSSetUserConfigString Lib "wtsapi32.dll" _
      Alias "WTSSetUserConfigA" (ByVal pServerName As String, _
      ByVal pUserName As String, ByVal WTSConfigClass As Long, _
      ByVal pBuffer As String, ByVal pBytes As Long) As Long

Private Declare Function WTSSetUserConfigDWord Lib "wtsapi32.dll" _
      Alias "WTSSetUserConfigA" (ByVal pServerName As String, _
      ByVal pUserName As String, ByVal WTSConfigClass As Long, _
      ByRef pBuffer As Long, ByVal pBytes As Long) As Long

Private Declare Function WTSQueryUserConfig Lib "wtsapi32.dll" _
      Alias "WTSQueryUserConfigA" (ByVal pServerName As String, _
      ByVal pUserName As String, ByVal WTSConfigClass As Long, _
      ByRef pBuffer As Long, ByRef pBytesReturned As Long) As Long

Private Declare Sub WTSFreeMemory Lib "wtsapi32.dll" _
      (ByVal pMemory As Any)

Private Declare Function NetGetDCName Lib "netapi32.dll" ( _
      ServerName As Long, domainname As Byte, bufptr As Long) As Long

Private Declare Function NetApiBufferFree& Lib "netapi32" _
      (ByVal Buffer As Long)

Private Declare Sub CopyMemory Lib "kernel32.dll" _
      Alias "RtlMoveMemory" (ByRef aDestination As Long, _
      ByVal lSource As Long, ByVal lBytesToCopy As Long)
          
Private Declare Sub CopyMemoryString Lib "kernel32" _
      Alias "RtlMoveMemory" (ByVal hpvDest As String, _
      ByVal hpvSource As Long, ByVal cbCopy As Long)

Private Declare Sub lstrcpyW Lib "kernel32" _
      (dest As Any, ByVal src As Any)

' VB Constant declarations for WTS_CONFIG_CLASS
Const WTSUserConfigInitialProgram = &H0                ' string
Const WTSUserConfigWorkingDirectory = &H1              ' string
Const WTSUserConfigfInheritInitialProgram = &H2        ' DWORD
Const WTSUserConfigfAllowLogonTerminalServer = &H3     ' DWORD

' Timeout settings
Const WTSUserConfigTimeoutSettingsConnections = &H4    ' DWORD
Const WTSUserConfigTimeoutSettingsDisconnections = &H5 ' DWORD
Const WTSUserConfigTimeoutSettingsIdle = &H6           ' DWORD

' Client device settings
Const WTSUserConfigfDeviceClientDrives = &H7           ' DWORD
Const WTSUserConfigfDeviceClientPrinters = &H8         ' DWORD
Const WTSUserConfigfDeviceClientDefaultPrinter = &H9   ' DWORD

' Connection settings
Const WTSUserConfigBrokenTimeoutSettings = &HA         ' DWORD
Const WTSUserConfigReconnectSettings = &HB             ' DWORD

' Modem settings
Const WTSUserConfigModemCallbackSettings = &HC         ' DWORD
Const WTSUserConfigModemCallbackPhoneNumber = &HD      ' string

' Shadow settings
Const WTSUserConfigShadowingSettings = &HE             ' DWORD

' User Profile settings
Const WTSUserConfigTerminalServerProfilePath = &HF     ' string

' Terminal Server home directory
Const WTSUserConfigTerminalServerHomeDir = &H10        ' string
Const WTSUserConfigTerminalServerHomeDirDrive = &H11   ' string
Const WTSUserConfigfTerminalServerRemoteHomeDir = &H12 ' DWORD

Const NERR_Success = 0&
    
Private Sub QueryUserConfig()

   Dim Size As Long
   Dim Domain As String
   Dim Buffer As Long
   Dim RetVal As Long
   Dim InitProgram As String
   Dim InheritProgram As Long
   Dim UserName As String
   Dim Status As Long
   Dim DNArray() As Byte
   Dim DCNArray(100) As Byte
   Dim DCName As String
   
   ' Get the user name
   UserName = InputBox("Enter a user name", "User", "")
   If UserName = "" Then Exit Sub
   
   ' Get the domain name
   Domain = InputBox("Enter the domain for " & UserName, "Domain", "")
   If Domain = "" Then Exit Sub
   
   ' Call NetGetDCName to get the name of the domain controller
   DNArray = Domain & vbNullChar
   Status = NetGetDCName(0&, DNArray(0), Buffer)
   If Status <> NERR_Success Then
      MsgBox "NetGetDCName failed with error " & Status, _
            vbExclamation
      Exit Sub
   End If
   
   lstrcpyW DCNArray(0), Buffer
   Status = NetApiBufferFree(Buffer)
   DCName = DCNArray()
   
   ' Query a string value (the user's initial program)
   RetVal = WTSQueryUserConfig(DCName, UserName, _
         WTSUserConfigInitialProgram, Buffer, Size)
   If (RetVal = 0) Then
      MsgBox "WTSQueryUserConfig failed with error " & Err.LastDllError
      Exit Sub
   End If
   
   ' Copy the string value from the buffer into a VB String variable
   InitProgram = Space(Size - 1)
   CopyMemoryString InitProgram, Buffer, Size
   MsgBox "The initial program for " & UserName & " is """ & InitProgram _
         & """", vbInformation
   
   WTSFreeMemory (Buffer)

   ' Query a DWORD value (the inherit initial program setting)
   RetVal = WTSQueryUserConfig(DCName, UserName, _
         WTSUserConfigfInheritInitialProgram, Buffer, Size)
   If (RetVal = 0) Then
      MsgBox "WTSQueryUserConfig failed with error " & Err.LastDllError
      Exit Sub
   End If
   
   ' Copy the DWORD value from the buffer into a Long variable
   CopyMemory InheritProgram, Buffer, 4
   If InheritProgram = 0 Then
      MsgBox "This initial program will always be used for " & UserName _
            & "'s sessions.", vbInformation
   Else
      MsgBox "The initial program will be specified by the client for " _
            & UserName & "'s sessions.", vbInformation
   End If

   WTSFreeMemory (Buffer)
   
End Sub

Private Sub SetUserConfig()

   Dim RetVal As Long
   Dim Domain As String
   Dim UserName As String
   Dim InitProgram As String
   Dim InheritProgram As Long
   Dim Status As Long
   Dim Buffer As Long
   Dim DNArray() As Byte
   Dim DCNArray(100) As Byte
   Dim DCName As String
   
   ' Get the username
   UserName = InputBox("Enter a user name", "User", "")
   If UserName = "" Then Exit Sub
   
   ' Get the domainname
   Domain = InputBox("Enter the domain for " & UserName, "Domain", "")
   If Domain = "" Then Exit Sub
   
   ' Get the initial program for the user
   InitProgram = InputBox("Enter a fully qualified path for the initial " _
         & "program for " & UserName, "Initial Program", _
         "c:\winnt\explorer.exe")
   If InitProgram = "" Then Exit Sub
   
   ' Get the inherit program setting for the user
   RetVal = MsgBox("Should " & UserName & "'s sessions always be forced " _
         & "to use this initial program?", vbYesNo, _
         "Always Use This Initial Program?")
   If RetVal = vbYes Then
      InheritProgram = 0
   Else
      InheritProgram = 1
   End If
   
   ' Call NetGetDCName to get the name of the domain controller
   DNArray = Domain & vbNullChar
   Status = NetGetDCName(0&, DNArray(0), Buffer)
   If Status <> NERR_Success Then
      MsgBox "NetGetDCName failed with error " & Status, _
            vbExclamation
      Exit Sub
   End If
   
   lstrcpyW DCNArray(0), Buffer
   Status = NetApiBufferFree(Buffer)
   DCName = DCNArray()
   
   ' Call WTSSetUserConfig API to set the user's initial program
   RetVal = WTSSetUserConfigString(DCName, UserName, _
         WTSUserConfigInitialProgram, InitProgram, Len(InitProgram))
   If (RetVal = 0) Then
      MsgBox "WTSSetUserConfig failed with error " & Err.LastDllError
      Exit Sub
   End If

   ' Call WTSSetUserConfig API to set the user's initial program
   RetVal = WTSSetUserConfigDWord(DCName, UserName, _
         WTSUserConfigfInheritInitialProgram, InheritProgram, 4)
   If (RetVal = 0) Then
      MsgBox "WTSSetUserConfig failed with error " & Err.LastDllError
      Exit Sub
   End If
   
   MsgBox "The configuration information for " & UserName _
         & " has been set.", vbInformation
   
End Sub

Private Sub Command1_Click()
   QueryUserConfig
End Sub

Private Sub Command2_Click()
   SetUserConfig
End Sub

Private Sub Form_Load()
   Command1.Caption = "Query"
   Command2.Caption = "Set"
End Sub
				

REFERENCES

See the MSDN Online Library (http://msdn.microsoft.com/library) for full documentation on the Terminal Services APIs.

Modification Type:MinorLast Reviewed:6/29/2004
Keywords:kbhowto KB292631