Microsoft KB Archive/292631

= How To Call WTSSetUserConfig and WTSQueryUserConfig from Visual Basic =

Article ID: 292631

Article Last Modified on 11/21/2006

-

APPLIES TO


 * Microsoft Win32 Application Programming Interface, when used with:
 * Microsoft Windows 2000 Standard Edition

-



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 &quot;wtsapi32.dll&quot; _ Alias &quot;WTSSetUserConfigA&quot; (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 &quot;wtsapi32.dll&quot; _ Alias &quot;WTSSetUserConfigA&quot; (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 &quot;wtsapi32.dll&quot; _ Alias &quot;WTSQueryUserConfigA&quot; (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 &quot;wtsapi32.dll&quot; _ (ByVal pMemory As Any)

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

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

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

Private Declare Sub lstrcpyW Lib &quot;kernel32&quot; _ (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(&quot;Enter a user name&quot;, &quot;User&quot;, &quot;&quot;) If UserName = &quot;&quot; Then Exit Sub ' Get the domain name Domain = InputBox(&quot;Enter the domain for &quot; & UserName, &quot;Domain&quot;, &quot;&quot;) If Domain = &quot;&quot; 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 &quot;NetGetDCName failed with error &quot; & 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 &quot;WTSQueryUserConfig failed with error &quot; & 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 &quot;The initial program for &quot; & UserName & &quot; is &quot;&quot;&quot; & InitProgram _ & &quot;&quot;&quot;&quot;, vbInformation WTSFreeMemory (Buffer)

' Query a DWORD value (the inherit initial program setting) RetVal = WTSQueryUserConfig(DCName, UserName, _        WTSUserConfigfInheritInitialProgram, Buffer, Size) If (RetVal = 0) Then MsgBox &quot;WTSQueryUserConfig failed with error &quot; & 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 &quot;This initial program will always be used for &quot; & UserName _ & &quot;'s sessions.&quot;, vbInformation Else MsgBox &quot;The initial program will be specified by the client for &quot; _ & UserName & &quot;'s sessions.&quot;, 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(&quot;Enter a user name&quot;, &quot;User&quot;, &quot;&quot;) If UserName = &quot;&quot; Then Exit Sub ' Get the domainname Domain = InputBox(&quot;Enter the domain for &quot; & UserName, &quot;Domain&quot;, &quot;&quot;) If Domain = &quot;&quot; Then Exit Sub ' Get the initial program for the user InitProgram = InputBox(&quot;Enter a fully qualified path for the initial &quot; _        & &quot;program for &quot; & UserName, &quot;Initial Program&quot;, _         &quot;c:\winnt\explorer.exe&quot;) If InitProgram = &quot;&quot; Then Exit Sub ' Get the inherit program setting for the user RetVal = MsgBox(&quot;Should &quot; & UserName & &quot;'s sessions always be forced &quot; _        & &quot;to use this initial program?&quot;, vbYesNo, _         &quot;Always Use This Initial Program?&quot;) 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 &quot;NetGetDCName failed with error &quot; & 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 &quot;WTSSetUserConfig failed with error &quot; & 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 &quot;WTSSetUserConfig failed with error &quot; & Err.LastDllError Exit Sub End If  MsgBox &quot;The configuration information for &quot; & UserName _ & &quot; has been set.&quot;, vbInformation End Sub

Private Sub Command1_Click QueryUserConfig End Sub

Private Sub Command2_Click SetUserConfig End Sub

Private Sub Form_Load Command1.Caption = &quot;Query&quot; Command2.Caption = &quot;Set&quot; End Sub

