Processes, threads and DLLs

Commands related to processes, threads and dynamic link libraries

SYNOPSIS

package require twapi
create_process PROGRAM ?options?
end_process PID ?options?
free_library HMODULE
get_current_process_id
get_current_thread_id
get_device_drivers ?options?
get_priority_class PID
get_process_commandline PID
get_process_exit_code HPROCESS
get_process_handle PID ACCESSRIGHTS ?INHERITMODE?
get_process_ids ?options?
get_process_info PID ?options?
get_process_modules PID ?options?
get_process_name PID
get_process_parent PID
get_process_path PID
get_process_thread_ids PID
get_thread_handle TID ACCESSMODE ?INHERITMODE?
get_thread_info TID ?options?
get_thread_relative_priority TID
get_thread_parent_process_id TID
is_idle_pid PID
is_system_pid PID
load_library FILEPATH ?options?
process_exists PID ?options?
process_waiting_for_input PID ?-wait MILLISECONDS?
resume_thread TID
set_priority_class PID PRIORITYCLASS
set_thread_relative_priority TID PRIORITY
suspend_thread TID

DESCRIPTION

This module provides procedures related to process, thread and shared library management.

Overview

The commands get_process_ids and get_current_process_id retrieve process id (PID) information. get_process_parent returns the PID for the parent process. The commands is_system_pid and is_idle_pid determine if the given PID is that of the system or idle process.

The command get_current_thread_id retrieves the current thread id (TID). get_thread_parent_process_id retrieves the PID of the process containing the specified thread. get_process_thread_ids retrieves the TID's of all threads in the specified process.

Process and thread handles with the appropriate access rights may retrieved through the get_process_handle and get_thread_handle commands respectively.

get_process_name and get_process_path get the name and path respectively for a process. The command get_process_info retrieves detailed information about internal process data. Similarly, get_thread_info retrieves detailed information about a thread.

get_process_commandline retrieves the command line with which a process was invoked.

process_exists checks for the existence of a process. The command process_waiting_for_input can be used to check if a process is waiting for input, and more specifically if it has finished initialization.

get_process_modules retrieves information pertaining to the modules and DLL's loaded into a process. The commands load_library and free_library can be used to load and free DLL's.

The commands create_process and end_process allow creation and termination of a process. The exit code from a process can be retrieved with the get_process_exit_code command.

The commands suspend_thread and resume_thread allow threads to be suspended and resumed.

The commands get_priority_class, set_priority_class, get_thread_relative_priority and set_thread_relative_priority deal with retrieving and setting process and thread scheduling priorities.

get_device_drivers retrieves information about the device drivers loaded on the system.

Commands

create_process PROGRAM ?options?
Creates a new child process. PROGRAM specifies the program to be run and must either include the full path to the program or the program must be in the current working directory. The function does not search the PATH environment variable to locate the program. PROGRAM may be specified as an empty string if the -cmdline option is specified and includes the path to the program as the first argument.

The command returns a list of two elements - the process id and the thread id of the child process. If the -returnhandles option is specified, two additional elements are returned - handles to the child process and thread. Both these handles must be closed when no longer required by calling close_handles.

The following arguments control various characteristics of the child process. For all options that take a boolean argument, the default is 0 (false) unless stated otherwise.
-background COLORLIST Specifies the background color if the child process receives a new console. COLORLIST is a list of one or more of the following values: blue, red, green, bright, white and black. The specified colors are combined to form the foreground color. The default is black.
-cmdline CMDLINE Specifies the command line to be passed to the created process. This generally includes the program being executed as the first token in CMDLINE. Caller should ensure that CMDLINE is quoted appropriately. The -cmdline option must be specified if the PROGRAM parameter is empty.
-childprocesssecd SECURITY_DESCRIPTOR Specifies a security descriptor for the child process. If unspecified, the default security descriptor is used.
-childthreadsecd SECURITY_DESCRIPTOR Specifies a security descriptor for the child thread. If unspecified, the default security descriptor is used.
-createsuspended BOOLEAN If BOOLEAN is true, the process and thread are created suspended. The process will not run until the thread is resumed with a call to resume_thread.
-debugchild BOOLEAN If BOOLEAN is true, indicates that the calling thread will be debugging the child process being created. The thread is notified of debug events in the child process. There is currently no way to receive these events.
-dontdebugchild BOOLEAN If the calling process is itself being debugged, then any debug events from the child process are sent to the debugger if BOOLEAN is false. Otherwise, the child process has no interaction with the debugger.
-desktop DESKTOPNAME Specifies the desktop, optionally along with the window station, for the new process. By default, this is the same as the current process. If DESKTOPNAME is the empty string, the system determines if a new desktop and window station need to be created.
-detached BOOLEAN This option only affects console processes. If BOOLEAN is 0, the child process inherits the current process' console. If BOOLEAN is 1, the console is not inherited.
-env LIST Specifies the environment variables inherited by the child process. LIST is a flat list of the form returned by array get consisting of ENVVARNAME VALUE pairs. By default, the child process inherits the same environment variables as the current process.
-feedbackcursoron BOOLEAN If true, specifies that the feedback cursor (normally a pointer with an hourglass) is shown while the new process starts up.
-feedbackcursoroff BOOLEAN If true, specifies that the feedback cursor is not shown while the new process starts up.
-foreground COLORLIST Specifies the foreground color if the child process receives a new console. COLORLIST is a list of one or more of the following values: blue, red, green, bright, white and black. The specified colors are combined to form the foreground color. The default is white.
-fullscreen BOOLEAN If true, the child process is run in full screen mode if it is a console process.
-inheritablechildprocess BOOLEAN If true, the handle to the child process is inheritable by other child processes spawned off later.
-inheritablechildthread BOOLEAN If true, the handle to the thread in the child process is inheritable by other child processes spawned off later.
-inheriterrormode BOOLEAN If true (default), the child process inherits the error mode setting of the current process.
-inherithandles BOOLEAN If true, the child process will inherit all inheritable handles of the current process.
-newconsole BOOLEAN If true, a new console is created for the child process if it is a console mode program. By default, the child process inherites the console of the current process if that latter is also a console mode program. This option cannot be used with the -detached option.
-priority PRIORITY Specifies the priority of the child process. This should have one of the values normal, abovenormal, belownormal, high, realtime, or idle.
-returnhandles BOOLEAN Normally the create_process command returns only the ids of the created process and thread. If this option is specified as true, the command appends handles of the child process and thread to the return value. These must later be closed by calling the close_handles command.
-screenbuffersize XY For console processes, this controls the initial width and height of the screen buffer in characters. XY can be specified as either a list of two integers or as a X,Y string.
-separatevdm BOOLEAN If true, child processes that are 16-bit executables are started in a separate virtual machine. By default, the system will follow the setting specified in the registry.
-sharedvdm BOOLEAN If true, child processes that are 16-bit executables are started in a common virtual machine. By default, the system will follow the setting specified in the registry.
-showwindow WINDOWMODE Specifies the mode in which the first window of the child process is displayed. WINDOWMODE must be one of normal, minimized, maximized or hidden.
-startdir PATH Specifies the initial starting directory of the child process. By default the child process starts in the calling thread's current directory.
-stdhandles HANDLELIST Specifies the standard input and output handles for the child process. HANDLELIST is a list of three elements corresponding to the handles to be used for standard input, standard output and standard error respectively. The handle values passed must be Windows handles and must be inheritable. Also, the -inherithandles option must be true if -stdhandles is specified. Note that if these handles correspond to files, the file position pointer is shared with the child process.

This option cannot be used together with the -stdchannels option.
-stdchannels CHANNELS Specifies the standard input and output handles for the child process. CHANNELS is a list of three elements corresponding to the Tcl channels to be used for standard input, standard output and standard error respectively. Note that if these channels correspond to files, the file position pointer is shared with the child process.

This option cannot be used together with the -stdhandles option. Also, the -inherithandles option must be true if -stdchannels is specified.
-title TITLE Specifies the text to diaplay in the title bar if the child process is a console program and receives a new console. By default, the name of the executable is displayed.
-windowpos XY Specifies the initial position in pixels of the top left corner of the main window of the child process if the child creates the window using defaults. XY can be specified as either a list of two integers or as a X,Y string.
-windowsize XY Specifies the initial size in pixels of the main window of the child process if the child creates the window using defaults. XY can be specified as either a list of two integers or as a X,Y string.
For further details, see the documentation of CreateProcess in the Windows SDK documentation.
end_process PID ?options?
Terminates the process with id PID. This function will first try to gracefully end the process by sending all its toplevel windows a WM_CLOSE command. If the process does not have any toplevels or if it does not end by this means and the -force option is specified, it is forcibly terminated.

The function returns 1 if the process ended and 0 otherwise. Note that if -wait has not been specified, or is too short, the function may return a value of 0 in the case where the process is in the process of terminating but has not fully exited by the time the command returns.

The following options may be specified with this command:
-force If this option is specified, the process will be forcibly terminated if it does not terminate in response to WM_CLOSE messages.
-wait MS Normally, the function will return without actually waiting for the process to end. If this option is specified, the function returns after waiting for MS milliseconds for the process to end.
-exitcode EXITCODE Specifies the exit code that should be returned by the terminating process. This is 1 by default. Depending on the application being terminated, this may not be the actual exit code returned on application exit. Caller should not rely on this.
Example: Gracefully exit all programs with a given name or path

Example: Forcibly kill all programs with a given name or path
free_library HMODULE
Frees a loaded module. HMODULE must be a handle previously returned through load_library.
get_current_process_id
Returns the PID of the current process.
get_current_thread_id
Returns the TID of the current thread.
get_device_drivers ?options?
This command returns information about the device drivers loaded in the system. The returned information is in the form of a list of sublist with each sublist corresponding to a loaded driver. Each sublist is a flat list of "option value" pairs. The following options may be specified:
-all Returns all device driver attributes below.
-base Returns the base address in memory where the driver is loaded
-path Returns the path to the file from which the driver was loaded. In some cases, this may not contain a fully qualified path.
-name Returns the name of the driver - generally the file name portion of the file from which the driver was loaded.
get_priority_class PID
Returns the scheduling priority class of the process with id PID.
get_process_commandline PID
Returns the command line with which the process with id PID was invoked. The following options may be specified with the command.
-noaccess DEFAULTVALUE If a process exists but cannot be accessed to retrieve the name, the command normally returns the string "(unknown)". This option may be used to specify a different string to be returned in such cases.
get_process_exit_code HPROCESS
Returns the exit code for a process. HPROCESS is a handle to the process of interest. If the process is still running, a null string is returned.
get_process_handle PID ACCESSRIGHTS ?INHERITMODE?
Returns a handle to the process with id PID. ACCESSRIGHTS specifies the desired access rights and may be specified as a list of integer access rights flags or symbols as described in Access Rights. If INHERITMODE is non-0, the returned handle can be inherited by child processes. If it is 0 (default), the handle cannot be inherited by child processes.
get_process_ids ?options?
This command returns a list of the process ids. If no options are specified, the list includes all processes on the system. The following options may be specified to return a subset of these:
-glob This option modifies the meaning of the -path and -name options. Normally, the match is done using case-insensitive, exact comparison. If -glob is specified, the PROCESSNAME and EXECUTABLEPATH are matched using glob-style pattern matching as in Tcl's string match command.
-name PROCESSNAME If this option is specified, the returned list only includes those processes whose name matches PROCESSNAME. Generally the name is the same as the filename portion of the executable file path. If this information is not available for a process, it is not included in the returned list. This option cannot be used with the -path option.
-path EXECUTABLEPATH If this option is specified, the returned list only includes those processes created from the executable file matching EXECUTABLEPATH. If this information is not available for a process, it is not included in the returned list. This option cannot be used with the -name option.
-logonsession LUID If this option is specified, the returned list only includes those processes running inside the logon session identified by the specified LUID.
-user ACCOUNT If this option is specified, the returned list only includes those processes running under the specified account. ACCOUNT may be either a user name or its SID.
Example: Minimize all windows for an application

Example: Exit all programs with a given name or path
get_process_info PID ?options?
Returns various pieces of information related to the process whose id is PID. The information returned depends on the options specified and is in the form of a flat list of the form "option1 value1 ...". The values returned may be scalars (e.g. -name) or rate based measured over an interval (e.g. -processorutilization). The option -interval may be used to indicate the interval over which the rate based fields are measured. One of more of the following options may be specified with the command:
-all Returns all values except those for unsupported options.
-basepriority Returns the base priority of the process.
-commandline Returns the command line with which the process was invoked.
-createtime Returns the time the process was created as the number of 100ns units since Jan 1, 1601. This can be converted to a date and time string by passing it to large_system_time_to_secs and formatting the result using clock format.
-elapsedtime Returns the total time (seconds) that the process has been running.
-groups Returns the list of groups that the process belongs to.
-handlecount Returns the number of handles that the process currently has open.
-handles Returns the list of open handles in the process as a list of lists. Each sublist contains three elements - the handle value, the type of the handle, and name of the corresponding resource. This an unsupported option that uses undocumented Windows functions and should not be used for production systems.
-interval INTERVAL Specifies the number of milliseconds over which rate based fields are to be measured. The command will not return until this time has elapsed. By default this is 100ms. If none of the fields requested is a rate based field, this option is ignored and the command returns immediately.
-iodatabytesrate Returns the rate at which the process is reading and writing bytes.
-iodataopsrate Returns the rate at which the process is issuing I/O operation.
-iootherbytes Returns number of non-data bytes the process has read or written through I/O operations.
-iootherbytesrate Returns the rate at which the process is reading and writing non-data bytes (such as control bytes).
-iootherops Returns number of non-data I/O operations the process has executed.
-iootheropsrate Returns the rate at which the process is issuing non-data I/O operations.
-ioreadbytes Returns number of data bytes the process has read through I/O operations.
-ioreadbytesrate Returns the rate at which the process is reading bytes through I/O operations.
-ioreadops Returns number of data read I/O operations the process has executed.
-ioreadopsrate Returns the rate at which the process is issuing read I/O operations.
-iowritebytes Returns number of data bytes the process has written through I/O operations.
-iowritebytesrate Returns the rate at which the process is writing bytes through I/O operations. All types of I/O operations are including in this rate.
-iowriteops Returns number of data write I/O operations the process has executed.
-iowriteopsrate Returns the rate at which the process is issuing write I/O operations.
-logonsession Returns the LUID of the logon session for the process.
-name Returns the name of the process. This is identical to the value returned by the get_process_name function.
-noaccess DEFAULTVALUE If a process exists but cannot be accessed to retrieve the name, the command normally returns the string "(unknown)". This option may be used to specify a different string to be returned in such cases.
-noexist DEFAULTVALUE If a process does not exist, the command returns the string "(no such process)". This option may be used to specify a different string to be returned for non-existent processes.
-pagefaultrate Returns the rate at which the process is generating page faults.
-pagefilebytes Returns total number of bytes in use for this process in all the system paging files.
-pagefilebytespeak Returns the maximum number of bytes that have been used for this process in the system paging file since the process started.
-parent Returns id of the process that invoked this process. For the system and system idle processes, an empty string is returned since they have no parent process.
-path Returns the path to the executable file from which this process was invoked. This value is the same as that returned by the get_process_path command.
-pid Returns the process id of this process (which should be identical to that passed in as the PID argument.
-poolnonpagedbytes Returns the number of bytes of nonpaged pool memory in use for the process.
-poolpagedbytes Returns the number of bytes of paged pool memory in use for the process.
-primarygroup Returns the primary group that the process belongs to.
-priorityclass Returns the priority class of the process.
-privatebytes Returns the number of bytes allocated for this process' private use.
-privilegedtime The amount of privileged context CPU time used by the process in 100ns units.
-privilegedutilization Returns the percentage of elapsed time that this process has spent executing in privileged mode.
-privileges Returns the list of enabled and disabled process privileges in the same format as get_token_privileges.
-processorutilization Returns the percentage of CPU time that this process has used.
-threadcount Returns the total number of threads in the process.
-tids Returns a list of ids of the threads in the process.
-toplevels Returns a list of the window handles of all toplevel windows owned by the process.
-tssession Returns the terminal server session id of the process.
-user Returns the user account under which the process is running.
-usertime The amount of user context CPU time used by the process in 100ns units.
-userutilization Returns the percentage of elapsed time that this process has spent executing in user mode.
-virtualbytes Returns the current size of the process' virtual address space.
-virtualbytespeak Returns the maximum amount of virtual address space that the process has used in the course of its execution.
-workingset Returns the number of bytes currently in the process' working set.
-workingsetpeak Returns the maximum number of bytes in the process' working set since it began execution.
Note that all the information is not retrieved in a single snapshot so there may be discrepancies between various values. For example, the number of thread ids returned via -tids may not match the thread count returned via -threadcount.

The get_process_info command is intended for one-time retrieval of information and is too inefficient for usage in an application like performance monitoring. Direct access to the performance data should be used in those cases.
get_process_modules PID ?options?
This command returns information about the modules loaded in the process with id PID. If no options are specified, the command returns a list of handles to the modules.

If any options are specified, the returned information is in the form of a list of sublists each of which corresponds to a loaded module. The sublist for each module is in the form "option VALUE". The following options may be specified:
-all Returns the data for all options described below.
-handle Includes the handle to the module in the returned data for each module.
-path Includes the full path from which the module was loaded.
-name Includes the name of the module - generally the file name portion of the path.
-imagedata Includes the base address in memory where the module is loaded, the size of the module in memory and the address of the entry point to the module as a sublist for each module.
Example: Show the DLL's loaded in a process
get_process_name PID
Returns the name of the process with id PID. This is generally the file name component of the full path of the executable file from which the process was loaded. The following options may be specified to with the command:
-noexist DEFAULTVALUE If a process does not exist, the command returns the string "(no such process)". This option may be used to specify a different string to be returned for non-existent processes.
-noaccess DEFAULTVALUE If a process exists but cannot be accessed to retrieve the name, the command normally returns the string "(unknown)". This option may be used to specify a different string to be returned in such cases.
Example: Show the user account for each process
get_process_parent PID
Returns the PID of the process from whom the process with id PID inherited handles and environment. The following options may be specified to with the command:
-noexist DEFAULTVALUE If a process does not exist, the command returns the string "(no such process)". This option may be used to specify a different string to be returned for non-existent processes.
-noaccess DEFAULTVALUE If a process exists but cannot be accessed to retrieve the parent, the command normally returns the string "(unknown)". This option may be used to specify a different string to be returned in such cases.
get_process_path PID
Returns the full path of the executable file from which the process with id PID was loaded. The following options may be specified to with the command:
-noexist DEFAULTVALUE If a process does not exist, the command returns the string (no such process). This option may be used to specify a different string to be returned for non-existent processes.
-noaccess DEFAULTVALUE If a process exists but cannot be accessed to retrieve the path information, the command normally returns the string (unknown). This option may be used to specify a different string to be returned in such cases.
get_process_thread_ids PID
Returns a list of ids of all threads in the process whose id is PID.
get_thread_handle TID ACCESSMODE ?INHERITMODE?
Returns a handle to the thread with id TID. ACCESSMODE specifies the desired access rights and may be specified as a list of integer access rights flags or symbols. Refer to the documentation of TWAPI Security module for more details. If INHERITMODE is non-0, the returned handle can be inherited by child processes. If it is 0 (default), the handle cannot be inherited by child processes.
get_thread_info TID ?options?
Returns various pieces of information related to the thread whose id is TID. The information returned depends on the options specified and is in the form of a flat list of the form "option1 value1 ...". The values returned may be scalars (e.g. -name) or rate based measured over an interval (e.g. -processorutilization). The option -interval may be used to indicate the interval over which the rate based fields are measured. One of more of the following options may be specified with the command:
-all Returns all values.
-basepriority Returns the base priority of the thread.
-contextswitches Returns the number of context switches done by the thread.
-contextswitchrate Returns the rate of context switches for the thread.
-createtime Returns the time the thread was created as the number of 100ns units since Jan 1, 1601. This can be converted to a date and time string by passing it to large_system_time_to_secs and formatting the result using clock format.
-elapsedtime Returns the total time (seconds) that the thread has been running.
-groups Returns the list of groups that the thread belongs to.
-interval INTERVAL Specifies the number of milliseconds over which rate based fields are to be measured. The command will not return until this time has elapsed. By default this is 100ms. If none of the fields requested is a rate based field, this option is ignored and the command returns immediately.
-noaccess DEFAULTVALUE If a thread but cannot be accessed, the command normally returns the string "(unknown)". This option may be used to specify a different string to be returned in such cases.
-noexist DEFAULTVALUE If a thread does not exist, the command returns the string "(no such thread)". This option may be used to specify a different string to be returned for non-existent threads.
-pid Returns the id of the process the thread belongs to.
-primarygroup Returns the primary group that the thread belongs to.
-priority Returns the current priority of the thread.
-privilegedtime The amount of privileged context CPU time used by the thread in 100ns units.
-privilegedutilization Returns the percentage of elapsed time that this process has spent executing in privileged mode.
-privileges Returns the list of the current thread privileges.
-processorutilization Returns the percentage of CPU time that this process has used.
-relativepriority Returns the priority level of the thread relative to the priority class of the containing process.
-startaddress Returns the address at which the thread began execution.
-state Returns the current state of the thread.
-tid Returns the thread id of this process (which should be identical to that passed in as the TID argument.
-user Returns the user account under which the thread is running.
-usertime The amount of user context CPU time used by the thread in 100ns units.
-userutilization Returns the percentage of elapsed time that this process has spent executing in user mode.
-waitreason Returns the reason a thread is in wait state. This is only valid when the state field is 5 indicating the thread is in a wait state.
Note that all the information is not retrieved in a single snapshot so there may be discrepancies between various values.

Like the get_process_info command, get_thread_info is intended for one-time retrieval of information and is too inefficient for usage in an application like performance monitoring. Direct access to the performance data should be used in those cases.
get_thread_relative_priority TID
Returns the scheduling priority value of the thread with id TID. This is an integer value relative to the process' priority class as described in the Windows SDK.
get_thread_parent_process_id TID
Returns the id of the parent process of the thread with id TID.
is_idle_pid PID
Returns true if the passed PID is that of the system idle process.
is_system_pid PID
Returns true if the passed PID is that of the system process.
load_library FILEPATH ?options?
Loads a DLL and returns a handle to it. This handle may be passed to other commands, such as format_message that expect a module handle as a parameter. The handle must later be released by calling free_library. The following options may be specified:
-dontresolverefs Normally, if the module being loaded is a DLL, the system will load any other modules referenced by it and also call its DllMain function to initialize it. If this option is specified, neither of these actions will be done.
-datafile If specified, the module is loaded as a data file as opposed to an executable module. This is useful when the file is being loaded only to extract resources or messages.
-alteredpath Uses an alternative search strategy to find modules referenced by this module. See the Windows SDK for more details.


See LoadLibraryEx in the Windows SDK for more details regarding this command.
process_exists PID ?options?
This command returns 1 if a process with id PID exists and 0 otherwise. The following options may be specified to further restrict the match:
-path EXECUTABLEPATH If this option is specified, the matched process must have been created from the executable file matching EXECUTABLEPATH. This option cannot be used with the -name option.
-name PROCESSNAME If this option is specified, the matched process must have a name that matches PROCESSNAME. Generally the name is the same as the filename portion of the executable file path. This option cannot be used with the -path option.
-glob This option modifies the meaning of the -path and -name options. Normally, the match is done using case-insensitive, exact comparison. If -glob is specified, the PROCESSNAME and EXECUTABLEPATH are matched using glob-style pattern matching.
process_waiting_for_input PID ?-wait MILLISECONDS?
Returns 1 if the specified process is idle, waiting for input, and 0 otherwise. The main use of this command is to detect when a process (for example, a child process that has just been created) has finished initialization. Note that a console process will always return 1.

The command normally returns right away. Specifying the -wait option causes the command to wait until either MILLISECONDS have passed or the process is idle before returning. Specifying a value of -1 will cause the command to wait without timing out.
resume_thread TID
The command checks the suspend count (see suspend_thread) of the specified thread. If it is 0, the thread is not suspended and the command has no effect. Otherwise, the suspend count is decremented. If the value is now 0, the thread resumes execution. The command returns thread's previous suspend count - a value of 0 meaning the thread was not suspended, 1 meaning the suspending thread is not resumed, and other values signifying that the thread is still suspended.
set_priority_class PID PRIORITYCLASS
Sets the scheduling priority class of the process with id PID to PRIORITYCLASS. PRIORITYCLASS is an integer value identifying a priority class as described in the Windows SDK.
set_thread_relative_priority TID PRIORITY
Sets the scheduling priority value of the thread with id TID to PRIORITY. PRIORITY is an integer value relative to the process' priority class as described in the Windows SDK.
suspend_thread TID
Suspends execution of the thread with id TID. The system keeps track of a suspend count for each thread. This is incremented every time a call is made to suspend the thread, and decremented every time a call is made to resume it. The command returns thread's previous suspend count.

COPYRIGHT

Copyright © 2003-2007 Ashok P. Nadkarni

Tcl Windows API 2.0.12 Privacy policy